From 61b199d785187290fad27d513c44fd870511a831 Mon Sep 17 00:00:00 2001 From: Serhii Mamontov Date: Mon, 30 Jun 2025 15:01:10 +0200 Subject: [PATCH 1/5] fix(subscription-flow): fix `heartbeat` cancellation failure Fix issue because of which in new flow `heartbeat` request not cancelled properly when issued in burst. fix(cbor): fix issue with resource name as integer Fix issue because resource names, which consist only of integers, have been decoded as Unicode characters. fix(subscription): fix issue with unsubscription on entity with a similar name Fix issue because the entity that has been created with `-pnpres` suffix has been removed from subscription loop during unsubscribe from entity with presence listening capability. feat(shared-worker): start backup heartbeat timer Launch a backup heartbeat timer per registered PubNub instance in SharedWorker context to protect against browsers throttling of background (hidden) tabs. refactor(logger): use explicit names of classes instead of constructor Use string names of classes for locations instead of dynamic access to constructor names because it affect how logs looks like after minification. --- dist/web/pubnub.js | 6594 +++++++++-------- dist/web/pubnub.min.js | 4 +- dist/web/pubnub.worker.js | 34 +- dist/web/pubnub.worker.min.js | 2 +- lib/core/components/configuration.js | 4 +- lib/core/components/cryptography/index.js | 12 +- lib/core/components/deduping_manager.js | 2 +- lib/core/components/stringify_buffer_keys.js | 23 +- lib/core/components/subscription-manager.js | 6 +- lib/core/endpoints/objects/channel/set.js | 7 + lib/core/interfaces/configuration.js | 37 +- lib/core/interfaces/crypto-module.js | 2 +- lib/core/pubnub-common.js | 79 +- lib/core/types/api/subscription.js | 10 + .../modules/NodeCryptoModule/aesCbcCryptor.js | 2 +- .../modules/NodeCryptoModule/legacyCryptor.js | 2 +- lib/entities/channel-group.js | 16 + lib/entities/channel-metadata.js | 16 + lib/entities/channel.js | 16 + lib/entities/entity.js | 18 +- lib/entities/subscription-base.js | 38 +- lib/entities/subscription-set.js | 28 +- lib/entities/subscription.js | 18 +- lib/entities/user-metadata.js | 16 + lib/event-engine/core/dispatcher.js | 6 +- lib/event-engine/core/engine.js | 38 +- lib/event-engine/core/handler.js | 1 - lib/event-engine/index.js | 2 +- lib/event-engine/presence/dispatcher.js | 5 +- lib/event-engine/presence/presence.js | 9 +- .../presence/states/heartbeat_cooldown.js | 4 +- .../presence/states/heartbeat_failed.js | 4 +- .../presence/states/heartbeat_stopped.js | 4 +- .../presence/states/heartbeating.js | 4 +- lib/loggers/console-logger.js | 13 +- lib/transport/middleware.js | 4 +- lib/transport/node-transport.js | 22 +- lib/transport/react-native-transport.js | 18 +- package-lock.json | 232 +- package.json | 4 + src/core/components/configuration.ts | 6 +- src/core/components/cryptography/index.ts | 12 +- src/core/components/deduping_manager.ts | 2 +- src/core/components/stringify_buffer_keys.ts | 21 +- src/core/components/subscription-manager.ts | 6 +- src/core/endpoints/objects/channel/set.ts | 7 + src/core/interfaces/configuration.ts | 6 - src/core/interfaces/crypto-module.ts | 2 +- src/core/pubnub-common.ts | 84 +- src/core/types/api/presence.ts | 13 + src/core/types/api/subscription.ts | 10 + .../modules/NodeCryptoModule/aesCbcCryptor.ts | 2 +- .../modules/NodeCryptoModule/legacyCryptor.ts | 2 +- .../modules/WebCryptoModule/aesCbcCryptor.ts | 2 +- .../modules/WebCryptoModule/legacyCryptor.ts | 3 +- src/entities/channel-group.ts | 17 + src/entities/channel-metadata.ts | 17 + src/entities/channel.ts | 17 + src/entities/entity.ts | 19 +- src/entities/interfaces/entity-interface.ts | 15 + src/entities/subscription-base.ts | 39 +- src/entities/subscription-set.ts | 29 +- src/entities/subscription.ts | 18 +- src/entities/user-metadata.ts | 17 + src/event-engine/core/dispatcher.ts | 6 +- src/event-engine/core/engine.ts | 42 +- src/event-engine/core/handler.ts | 1 - src/event-engine/index.ts | 2 +- src/event-engine/presence/dispatcher.ts | 7 +- src/event-engine/presence/presence.ts | 9 +- .../presence/states/heartbeat_cooldown.ts | 4 +- .../presence/states/heartbeat_failed.ts | 4 +- .../presence/states/heartbeat_stopped.ts | 4 +- .../presence/states/heartbeating.ts | 4 +- src/loggers/console-logger.ts | 19 +- src/transport/middleware.ts | 4 +- src/transport/node-transport.ts | 22 +- src/transport/react-native-transport.ts | 18 +- .../subscription-worker-middleware.ts | 4 +- .../subscription-worker.ts | 51 +- src/transport/titanium-transport.ts | 16 +- src/transport/web-transport.ts | 36 +- 82 files changed, 4460 insertions(+), 3515 deletions(-) diff --git a/dist/web/pubnub.js b/dist/web/pubnub.js index 81765fdcc..b1796d9a7 100644 --- a/dist/web/pubnub.js +++ b/dist/web/pubnub.js @@ -535,7 +535,7 @@ * @returns Serialized crypto module information. */ toString() { - return `${this.constructor.name} { default: ${this.defaultCryptor.toString()}, cryptors: [${this.cryptors.map((c) => c.toString()).join(', ')}]}`; + return `AbstractCryptoModule { default: ${this.defaultCryptor.toString()}, cryptors: [${this.cryptors.map((c) => c.toString()).join(', ')}]}`; } } /** @@ -2018,7 +2018,7 @@ * @returns Serialized cryptor information. */ toString() { - return `${this.constructor.name} { cipherKey: ${this.cipherKey} }`; + return `AesCbcCryptor { cipherKey: ${this.cipherKey} }`; } } /** @@ -2152,7 +2152,7 @@ encrypt(data, customCipherKey, options) { if (this.configuration.customEncrypt) { if (this.logger) - this.logger.warn(this.constructor.name, "'customEncrypt' is deprecated. Consult docs for better alternative."); + this.logger.warn('Crypto', "'customEncrypt' is deprecated. Consult docs for better alternative."); return this.configuration.customEncrypt(data); } return this.pnEncrypt(data, customCipherKey, options); @@ -2169,7 +2169,7 @@ decrypt(data, customCipherKey, options) { if (this.configuration.customDecrypt) { if (this.logger) - this.logger.warn(this.constructor.name, "'customDecrypt' is deprecated. Consult docs for better alternative."); + this.logger.warn('Crypto', "'customDecrypt' is deprecated. Consult docs for better alternative."); return this.configuration.customDecrypt(data); } return this.pnDecrypt(data, customCipherKey, options); @@ -2188,7 +2188,7 @@ if (!decidedCipherKey) return data; if (this.logger) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('Crypto', () => ({ messageType: 'object', message: Object.assign({ data, cipherKey: decidedCipherKey }, (options !== null && options !== void 0 ? options : {})), details: 'Encrypt with parameters:', @@ -2225,7 +2225,7 @@ if (!decidedCipherKey) return data; if (this.logger) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('Crypto', () => ({ messageType: 'object', message: Object.assign({ data, cipherKey: decidedCipherKey }, (options !== null && options !== void 0 ? options : {})), details: 'Decrypt with parameters:', @@ -2247,7 +2247,7 @@ } catch (e) { if (this.logger) - this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e })); + this.logger.error('Crypto', () => ({ messageType: 'error', message: e })); return null; } } @@ -2262,7 +2262,7 @@ } catch (e) { if (this.logger) - this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e })); + this.logger.error('Crypto', () => ({ messageType: 'error', message: e })); return null; } } @@ -2660,7 +2660,7 @@ acc.push(`${key}: ${typeof value === 'function' ? '' : value}`); return acc; }, []); - return `${this.constructor.name} { ${configurationEntries.join(', ')} }`; + return `AesCbcCryptor { ${configurationEntries.join(', ')} }`; } } /** @@ -3314,7 +3314,7 @@ // Use default request flow for non-subscribe / presence leave requests. if (!req.path.startsWith('/v2/subscribe') && !req.path.endsWith('/heartbeat') && !req.path.endsWith('/leave')) return this.configuration.transport.makeSendable(req); - this.configuration.logger.debug(this.constructor.name, 'Process request with SharedWorker transport.'); + this.configuration.logger.debug('SubscriptionWorkerMiddleware', 'Process request with SharedWorker transport.'); let controller; const sendRequestEvent = { type: 'send-request', @@ -3419,7 +3419,7 @@ this.subscriptionWorker = new SharedWorker(this.configuration.workerUrl, `/pubnub-${this.configuration.sdkVersion}`); } catch (error) { - this.configuration.logger.error(this.constructor.name, () => ({ + this.configuration.logger.error('SubscriptionWorkerMiddleware', () => ({ messageType: 'error', message: error, })); @@ -3581,12 +3581,13 @@ * Re-map CBOR object keys from potentially C buffer strings to actual strings. * * @param obj CBOR which should be remapped to stringified keys. + * @param nestingLevel PAM token structure nesting level. * * @returns Dictionary with stringified keys. * * @internal */ - function stringifyBufferKeys(obj) { + function stringifyBufferKeys(obj, nestingLevel = 0) { const isObject = (value) => typeof value === 'object' && value !== null && value.constructor === Object; const isString = (value) => typeof value === 'string' || value instanceof String; const isNumber = (value) => typeof value === 'number' && isFinite(value); @@ -3597,16 +3598,18 @@ const keyIsString = isString(key); let stringifiedKey = key; const value = obj[key]; - if (keyIsString && key.indexOf(',') >= 0) { - const bytes = key.split(',').map(Number); - stringifiedKey = bytes.reduce((string, byte) => { - return string + String.fromCharCode(byte); - }, ''); - } - else if (isNumber(key) || (keyIsString && !isNaN(Number(key)))) { - stringifiedKey = String.fromCharCode(isNumber(key) ? key : parseInt(key, 10)); + if (nestingLevel < 2) { + if (keyIsString && key.indexOf(',') >= 0) { + const bytes = key.split(',').map(Number); + stringifiedKey = bytes.reduce((string, byte) => { + return string + String.fromCharCode(byte); + }, ''); + } + else if (isNumber(key) || (keyIsString && !isNaN(Number(key)))) { + stringifiedKey = String.fromCharCode(isNumber(key) ? key : parseInt(key, 10)); + } } - normalizedObject[stringifiedKey] = isObject(value) ? stringifyBufferKeys(value) : value; + normalizedObject[stringifiedKey] = isObject(value) ? stringifyBufferKeys(value, nestingLevel + 1) : value; }); return normalizedObject; } @@ -3659,10 +3662,6 @@ * Whether PubNub client should try to utilize existing TCP connection for new requests or not. */ const KEEP_ALIVE$1 = false; - /** - * Whether verbose logging should be enabled or not. - */ - const USE_VERBOSE_LOGGING = false; /** * Whether leave events should be suppressed or not. */ @@ -3711,29 +3710,28 @@ * @internal */ const setDefaults$1 = (configuration) => { - var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r; + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; // Copy configuration. const configurationCopy = Object.assign({}, configuration); - (_a = configurationCopy.logVerbosity) !== null && _a !== void 0 ? _a : (configurationCopy.logVerbosity = USE_VERBOSE_LOGGING); - (_b = configurationCopy.ssl) !== null && _b !== void 0 ? _b : (configurationCopy.ssl = USE_SSL); - (_c = configurationCopy.transactionalRequestTimeout) !== null && _c !== void 0 ? _c : (configurationCopy.transactionalRequestTimeout = TRANSACTIONAL_REQUEST_TIMEOUT); - (_d = configurationCopy.subscribeRequestTimeout) !== null && _d !== void 0 ? _d : (configurationCopy.subscribeRequestTimeout = SUBSCRIBE_REQUEST_TIMEOUT); - (_e = configurationCopy.fileRequestTimeout) !== null && _e !== void 0 ? _e : (configurationCopy.fileRequestTimeout = FILE_REQUEST_TIMEOUT); - (_f = configurationCopy.restore) !== null && _f !== void 0 ? _f : (configurationCopy.restore = RESTORE); - (_g = configurationCopy.useInstanceId) !== null && _g !== void 0 ? _g : (configurationCopy.useInstanceId = USE_INSTANCE_ID); - (_h = configurationCopy.suppressLeaveEvents) !== null && _h !== void 0 ? _h : (configurationCopy.suppressLeaveEvents = SUPPRESS_LEAVE_EVENTS); - (_j = configurationCopy.requestMessageCountThreshold) !== null && _j !== void 0 ? _j : (configurationCopy.requestMessageCountThreshold = DEDUPE_CACHE_SIZE); - (_k = configurationCopy.autoNetworkDetection) !== null && _k !== void 0 ? _k : (configurationCopy.autoNetworkDetection = AUTO_NETWORK_DETECTION); - (_l = configurationCopy.enableEventEngine) !== null && _l !== void 0 ? _l : (configurationCopy.enableEventEngine = ENABLE_EVENT_ENGINE); - (_m = configurationCopy.maintainPresenceState) !== null && _m !== void 0 ? _m : (configurationCopy.maintainPresenceState = MAINTAIN_PRESENCE_STATE); - (_o = configurationCopy.useSmartHeartbeat) !== null && _o !== void 0 ? _o : (configurationCopy.useSmartHeartbeat = USE_SMART_HEARTBEAT); - (_p = configurationCopy.keepAlive) !== null && _p !== void 0 ? _p : (configurationCopy.keepAlive = KEEP_ALIVE$1); + (_a = configurationCopy.ssl) !== null && _a !== void 0 ? _a : (configurationCopy.ssl = USE_SSL); + (_b = configurationCopy.transactionalRequestTimeout) !== null && _b !== void 0 ? _b : (configurationCopy.transactionalRequestTimeout = TRANSACTIONAL_REQUEST_TIMEOUT); + (_c = configurationCopy.subscribeRequestTimeout) !== null && _c !== void 0 ? _c : (configurationCopy.subscribeRequestTimeout = SUBSCRIBE_REQUEST_TIMEOUT); + (_d = configurationCopy.fileRequestTimeout) !== null && _d !== void 0 ? _d : (configurationCopy.fileRequestTimeout = FILE_REQUEST_TIMEOUT); + (_e = configurationCopy.restore) !== null && _e !== void 0 ? _e : (configurationCopy.restore = RESTORE); + (_f = configurationCopy.useInstanceId) !== null && _f !== void 0 ? _f : (configurationCopy.useInstanceId = USE_INSTANCE_ID); + (_g = configurationCopy.suppressLeaveEvents) !== null && _g !== void 0 ? _g : (configurationCopy.suppressLeaveEvents = SUPPRESS_LEAVE_EVENTS); + (_h = configurationCopy.requestMessageCountThreshold) !== null && _h !== void 0 ? _h : (configurationCopy.requestMessageCountThreshold = DEDUPE_CACHE_SIZE); + (_j = configurationCopy.autoNetworkDetection) !== null && _j !== void 0 ? _j : (configurationCopy.autoNetworkDetection = AUTO_NETWORK_DETECTION); + (_k = configurationCopy.enableEventEngine) !== null && _k !== void 0 ? _k : (configurationCopy.enableEventEngine = ENABLE_EVENT_ENGINE); + (_l = configurationCopy.maintainPresenceState) !== null && _l !== void 0 ? _l : (configurationCopy.maintainPresenceState = MAINTAIN_PRESENCE_STATE); + (_m = configurationCopy.useSmartHeartbeat) !== null && _m !== void 0 ? _m : (configurationCopy.useSmartHeartbeat = USE_SMART_HEARTBEAT); + (_o = configurationCopy.keepAlive) !== null && _o !== void 0 ? _o : (configurationCopy.keepAlive = KEEP_ALIVE$1); if (configurationCopy.userId && configurationCopy.uuid) throw new PubNubError("PubNub client configuration error: use only 'userId'"); - (_q = configurationCopy.userId) !== null && _q !== void 0 ? _q : (configurationCopy.userId = configurationCopy.uuid); + (_p = configurationCopy.userId) !== null && _p !== void 0 ? _p : (configurationCopy.userId = configurationCopy.uuid); if (!configurationCopy.userId) throw new PubNubError("PubNub client configuration error: 'userId' not set"); - else if (((_r = configurationCopy.userId) === null || _r === void 0 ? void 0 : _r.trim().length) === 0) + else if (((_q = configurationCopy.userId) === null || _q === void 0 ? void 0 : _q.trim().length) === 0) throw new PubNubError("PubNub client configuration error: 'userId' is empty"); // Generate default origin subdomains. if (!configurationCopy.origin) @@ -3863,1030 +3861,1037 @@ listenToBrowserNetworkEvents: (_a = configuration.listenToBrowserNetworkEvents) !== null && _a !== void 0 ? _a : LISTEN_TO_BROWSER_NETWORK_EVENTS, subscriptionWorkerUrl: configuration.subscriptionWorkerUrl, subscriptionWorkerOfflineClientsCheckInterval: (_b = configuration.subscriptionWorkerOfflineClientsCheckInterval) !== null && _b !== void 0 ? _b : SUBSCRIPTION_WORKER_OFFLINE_CLIENTS_CHECK_INTERVAL, subscriptionWorkerUnsubscribeOfflineClients: (_c = configuration.subscriptionWorkerUnsubscribeOfflineClients) !== null && _c !== void 0 ? _c : SUBSCRIPTION_WORKER_UNSUBSCRIBE_OFFLINE_CLIENTS, subscriptionWorkerLogVerbosity: (_d = configuration.subscriptionWorkerLogVerbosity) !== null && _d !== void 0 ? _d : SUBSCRIPTION_WORKER_LOG_VERBOSITY, transport: (_e = configuration.transport) !== null && _e !== void 0 ? _e : TRANSPORT, keepAlive: (_f = configuration.keepAlive) !== null && _f !== void 0 ? _f : KEEP_ALIVE }); }; - // -------------------------------------------------------- - // ------------------------ Types ------------------------- - // -------------------------------------------------------- - // region Types /** - * List of known endpoint groups (by context). + * Enum with available log levels. */ - var Endpoint; - (function (Endpoint) { - /** - * Unknown endpoint. - * - * @internal - */ - Endpoint["Unknown"] = "UnknownEndpoint"; - /** - * The endpoints to send messages. - * - * This is related to the following functionality: - * - `publish` - * - `signal` - * - `publish file` - * - `fire` - */ - Endpoint["MessageSend"] = "MessageSendEndpoint"; - /** - * The endpoint for real-time update retrieval. - * - * This is related to the following functionality: - * - `subscribe` - */ - Endpoint["Subscribe"] = "SubscribeEndpoint"; - /** - * The endpoint to access and manage `user_id` presence and fetch channel presence information. - * - * This is related to the following functionality: - * - `get presence state` - * - `set presence state` - * - `here now` - * - `where now` - * - `heartbeat` - */ - Endpoint["Presence"] = "PresenceEndpoint"; + var LogLevel; + (function (LogLevel) { /** - * The endpoint to access and manage files in channel-specific storage. - * - * This is related to the following functionality: - * - `send file` - * - `download file` - * - `list files` - * - `delete file` + * Used to notify about every last detail: + * - function calls, + * - full payloads, + * - internal variables, + * - state-machine hops. */ - Endpoint["Files"] = "FilesEndpoint"; + LogLevel[LogLevel["Trace"] = 0] = "Trace"; /** - * The endpoint to access and manage messages for a specific channel(s) in the persistent storage. - * - * This is related to the following functionality: - * - `fetch messages / message actions` - * - `delete messages` - * - `messages count` + * Used to notify about broad strokes of your SDK’s logic: + * - inputs/outputs to public methods, + * - network request + * - network response + * - decision branches. */ - Endpoint["MessageStorage"] = "MessageStorageEndpoint"; + LogLevel[LogLevel["Debug"] = 1] = "Debug"; /** - * The endpoint to access and manage channel groups. - * - * This is related to the following functionality: - * - `add channels to group` - * - `list channels in group` - * - `remove channels from group` - * - `list channel groups` + * Used to notify summary of what the SDK is doing under the hood: + * - initialized, + * - connected, + * - entity created. */ - Endpoint["ChannelGroups"] = "ChannelGroupsEndpoint"; + LogLevel[LogLevel["Info"] = 2] = "Info"; /** - * The endpoint to access and manage device registration for channel push notifications. - * - * This is related to the following functionality: - * - `enable channels for push notifications` - * - `list push notification enabled channels` - * - `disable push notifications for channels` - * - `disable push notifications for all channels` + * Used to notify about non-fatal events: + * - deprecations, + * - request retries. */ - Endpoint["DevicePushNotifications"] = "DevicePushNotificationsEndpoint"; + LogLevel[LogLevel["Warn"] = 3] = "Warn"; /** - * The endpoint to access and manage App Context objects. - * - * This is related to the following functionality: - * - `set UUID metadata` - * - `get UUID metadata` - * - `remove UUID metadata` - * - `get all UUID metadata` - * - `set Channel metadata` - * - `get Channel metadata` - * - `remove Channel metadata` - * - `get all Channel metadata` - * - `manage members` - * - `list members` - * - `manage memberships` - * - `list memberships` + * Used to notify about: + * - exceptions, + * - HTTP failures, + * - invalid states. */ - Endpoint["AppContext"] = "AppContextEndpoint"; + LogLevel[LogLevel["Error"] = 4] = "Error"; /** - * The endpoint to access and manage reactions for a specific message. - * - * This is related to the following functionality: - * - `add message action` - * - `get message actions` - * - `remove message action` + * Logging disabled. */ - Endpoint["MessageReactions"] = "MessageReactionsEndpoint"; - })(Endpoint || (Endpoint = {})); - // endregion + LogLevel[LogLevel["None"] = 5] = "None"; + })(LogLevel || (LogLevel = {})); + /** - * Failed request retry policy. + * PubNub package utilities module. + * + * @internal */ - class RetryPolicy { - static None() { - return { - shouldRetry(_request, _response, _errorCategory, _attempt) { - return false; - }, - getDelay(_attempt, _response) { - return -1; - }, - validate() { - return true; - }, - }; - } - static LinearRetryPolicy(configuration) { - var _a; - return { - delay: configuration.delay, - maximumRetry: configuration.maximumRetry, - excluded: (_a = configuration.excluded) !== null && _a !== void 0 ? _a : [], - shouldRetry(request, response, error, attempt) { - return isRetriableRequest(request, response, error, attempt !== null && attempt !== void 0 ? attempt : 0, this.maximumRetry, this.excluded); - }, - getDelay(_, response) { - let delay = -1; - if (response && response.headers['retry-after'] !== undefined) - delay = parseInt(response.headers['retry-after'], 10); - if (delay === -1) - delay = this.delay; - return (delay + Math.random()) * 1000; - }, - validate() { - if (this.delay < 2) - throw new Error('Delay can not be set less than 2 seconds for retry'); - if (this.maximumRetry > 10) - throw new Error('Maximum retry for linear retry policy can not be more than 10'); - }, - }; - } - static ExponentialRetryPolicy(configuration) { - var _a; - return { - minimumDelay: configuration.minimumDelay, - maximumDelay: configuration.maximumDelay, - maximumRetry: configuration.maximumRetry, - excluded: (_a = configuration.excluded) !== null && _a !== void 0 ? _a : [], - shouldRetry(request, response, error, attempt) { - return isRetriableRequest(request, response, error, attempt !== null && attempt !== void 0 ? attempt : 0, this.maximumRetry, this.excluded); - }, - getDelay(attempt, response) { - let delay = -1; - if (response && response.headers['retry-after'] !== undefined) - delay = parseInt(response.headers['retry-after'], 10); - if (delay === -1) - delay = Math.min(Math.pow(2, attempt), this.maximumDelay); - return (delay + Math.random()) * 1000; - }, - validate() { - if (this.minimumDelay < 2) - throw new Error('Minimum delay can not be set less than 2 seconds for retry'); - else if (this.maximumDelay > 150) - throw new Error('Maximum delay can not be set more than 150 seconds for' + ' retry'); - else if (this.maximumRetry > 6) - throw new Error('Maximum retry for exponential retry policy can not be more than 6'); - }, - }; - } - } /** - * Check whether request can be retried or not. + * Percent-encode input string. * - * @param req - Request for which retry ability is checked. - * @param res - Service response which should be taken into consideration. - * @param errorCategory - Request processing error category. - * @param retryAttempt - Current retry attempt. - * @param maximumRetry - Maximum retry attempts count according to the retry policy. - * @param excluded - List of endpoints for which retry policy won't be applied. + * **Note:** Encode content in accordance of the `PubNub` service requirements. * - * @return `true` if request can be retried. + * @param input - Source string or number for encoding. + * + * @returns Percent-encoded string. * * @internal */ - const isRetriableRequest = (req, res, errorCategory, retryAttempt, maximumRetry, excluded) => { - if (errorCategory) { - if (errorCategory === StatusCategory$1.PNCancelledCategory || - errorCategory === StatusCategory$1.PNBadRequestCategory || - errorCategory === StatusCategory$1.PNAccessDeniedCategory) - return false; - } - if (isExcludedRequest(req, excluded)) - return false; - else if (retryAttempt > maximumRetry) - return false; - return res ? res.status === 429 || res.status >= 500 : true; + const encodeString = (input) => { + return encodeURIComponent(input).replace(/[!~*'()]/g, (x) => `%${x.charCodeAt(0).toString(16).toUpperCase()}`); }; /** - * Check whether the provided request is in the list of endpoints for which retry is not allowed or not. + * Percent-encode list of names (channels). * - * @param req - Request which will be tested. - * @param excluded - List of excluded endpoints configured for retry policy. + * @param names - List of names which should be encoded. * - * @returns `true` if request has been excluded and shouldn't be retried. + * @param [defaultString] - String which should be used in case if {@link names} is empty. + * + * @returns String which contains encoded names joined by non-encoded `,`. * * @internal */ - const isExcludedRequest = (req, excluded) => excluded && excluded.length > 0 ? excluded.includes(endpointFromRequest(req)) : false; + const encodeNames = (names, defaultString) => { + const encodedNames = names.map((name) => encodeString(name)); + return encodedNames.length ? encodedNames.join(',') : (defaultString !== null && defaultString !== void 0 ? defaultString : ''); + }; /** - * Identify API group from transport request. - * - * @param req - Request for which `path` will be analyzed to identify REST API group. - * - * @returns Endpoint group to which request belongs. - * * @internal */ - const endpointFromRequest = (req) => { - let endpoint = Endpoint.Unknown; - if (req.path.startsWith('/v2/subscribe')) - endpoint = Endpoint.Subscribe; - else if (req.path.startsWith('/publish/') || req.path.startsWith('/signal/')) - endpoint = Endpoint.MessageSend; - else if (req.path.startsWith('/v2/presence')) - endpoint = Endpoint.Presence; - else if (req.path.startsWith('/v2/history') || req.path.startsWith('/v3/history')) - endpoint = Endpoint.MessageStorage; - else if (req.path.startsWith('/v1/message-actions/')) - endpoint = Endpoint.MessageReactions; - else if (req.path.startsWith('/v1/channel-registration/')) - endpoint = Endpoint.ChannelGroups; - else if (req.path.startsWith('/v2/objects/')) - endpoint = Endpoint.ChannelGroups; - else if (req.path.startsWith('/v1/push/') || req.path.startsWith('/v2/push/')) - endpoint = Endpoint.DevicePushNotifications; - else if (req.path.startsWith('/v1/files/')) - endpoint = Endpoint.Files; - return endpoint; + const removeSingleOccurrence = (source, elementsToRemove) => { + const removed = Object.fromEntries(elementsToRemove.map((prop) => [prop, false])); + return source.filter((e) => { + if (elementsToRemove.includes(e) && !removed[e]) { + removed[e] = true; + return false; + } + return true; + }); }; - - var uuid = {exports: {}}; - - /*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */ - uuid.exports; - - (function (module, exports) { - (function (root, factory) { - { - factory(exports); - if (module !== null) { - module.exports = exports.uuid; - } - } - }(commonjsGlobal, function (exports) { - var VERSION = '0.1.0'; - var uuidRegex = { - '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i, - '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i, - '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i, - all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i - }; - - function uuid() { - var uuid = '', i, random; - for (i = 0; i < 32; i++) { - random = Math.random() * 16 | 0; - if (i === 8 || i === 12 || i === 16 || i === 20) uuid += '-'; - uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16); - } - return uuid - } - - function isUUID(str, version) { - var pattern = uuidRegex[version || 'all']; - return pattern && pattern.test(str) || false - } - - uuid.isUUID = isUUID; - uuid.VERSION = VERSION; - - exports.uuid = uuid; - exports.isUUID = isUUID; - })); - } (uuid, uuid.exports)); - - var uuidExports = uuid.exports; - var uuidGenerator$1 = /*@__PURE__*/getDefaultExportFromCjs(uuidExports); - /** - * Random identifier generator helper module. + * @internal + */ + const findUniqueCommonElements = (a, b) => { + return [...a].filter((value) => b.includes(value) && a.indexOf(value) === a.lastIndexOf(value) && b.indexOf(value) === b.lastIndexOf(value)); + }; + /** + * Transform query key / value pairs to the string. + * + * @param query - Key / value pairs of the request query parameters. + * + * @returns Stringified query key / value pairs. * * @internal */ - /** @internal */ - var uuidGenerator = { - createUUID() { - if (uuidGenerator$1.uuid) { - return uuidGenerator$1.uuid(); + const queryStringFromObject = (query) => { + return Object.keys(query) + .map((key) => { + const queryValue = query[key]; + if (!Array.isArray(queryValue)) + return `${key}=${encodeString(queryValue)}`; + return queryValue.map((value) => `${key}=${encodeString(value)}`).join('&'); + }) + .join('&'); + }; + /** + * Adjust `timetoken` to represent current time in PubNub's high-precision time format. + * + * @param timetoken - Timetoken recently used for subscribe long-poll request. + * @param [referenceTimetoken] - Previously computed reference timetoken. + * + * @returns Adjusted timetoken if recent timetoken available. + */ + const subscriptionTimetokenFromReference = (timetoken, referenceTimetoken) => { + if (referenceTimetoken === '0' || timetoken === '0') + return undefined; + const timetokenDiff = adjustedTimetokenBy(`${Date.now()}0000`, referenceTimetoken, false); + return adjustedTimetokenBy(timetoken, timetokenDiff, true); + }; + /** + * Create reference timetoken based on subscribe timetoken and the user's local time. + * + * Subscription-based reference timetoken allows later computing approximate timetoken at any point in time. + * + * @param [serviceTimetoken] - Timetoken received from the PubNub subscribe service. + * @param [catchUpTimetoken] - Previously stored or user-provided catch-up timetoken. + * @param [referenceTimetoken] - Previously computed reference timetoken. **Important:** This value should be used + * in the case of restore because the actual time when service and catch-up timetokens are received is really + * different from the current local time. + * + * @returns Reference timetoken. + */ + const referenceSubscribeTimetoken = (serviceTimetoken, catchUpTimetoken, referenceTimetoken) => { + if (!serviceTimetoken || serviceTimetoken.length === 0) + return undefined; + if (catchUpTimetoken && catchUpTimetoken.length > 0 && catchUpTimetoken !== '0') { + // Compensate reference timetoken because catch-up timetoken has been used. + const timetokensDiff = adjustedTimetokenBy(serviceTimetoken, catchUpTimetoken, false); + return adjustedTimetokenBy(referenceTimetoken !== null && referenceTimetoken !== void 0 ? referenceTimetoken : `${Date.now()}0000`, timetokensDiff.replace('-', ''), Number(timetokensDiff) < 0); + } + else if (referenceTimetoken && referenceTimetoken.length > 0 && referenceTimetoken !== '0') + return referenceTimetoken; + else + return `${Date.now()}0000`; + }; + /** + * High-precision time token adjustment. + * + * @param timetoken - Source timetoken which should be adjusted. + * @param value - Value in nanoseconds which should be used for source timetoken adjustment. + * @param increment - Whether source timetoken should be incremented or decremented. + * + * @returns Adjusted high-precision PubNub timetoken. + */ + const adjustedTimetokenBy = (timetoken, value, increment) => { + // Normalize value to the PubNub's high-precision time format. + value = value.padStart(17, '0'); + const secA = timetoken.slice(0, 10); + const tickA = timetoken.slice(10, 17); + const secB = value.slice(0, 10); + const tickB = value.slice(10, 17); + let seconds = Number(secA); + let ticks = Number(tickA); + seconds += Number(secB) * (increment ? 1 : -1); + ticks += Number(tickB) * (increment ? 1 : -1); + if (ticks >= 10000000) { + seconds += Math.floor(ticks / 10000000); + ticks %= 10000000; + } + else if (ticks < 0) { + if (seconds > 0) { + seconds -= 1; + ticks += 10000000; } - // @ts-expect-error Depending on module type it may be callable. - return uuidGenerator$1(); - }, + else if (seconds < 0) + ticks *= -1; + } + return seconds !== 0 ? `${seconds}${`${ticks}`.padStart(7, '0')}` : `${ticks}`; + }; + /** + * Compute received update (message, event) fingerprint. + * + * @param input - Data payload from subscribe API response. + * + * @returns Received update fingerprint. + */ + const messageFingerprint = (input) => { + const msg = typeof input !== 'string' ? JSON.stringify(input) : input; + const mfp = new Uint32Array(1); + let walk = 0; + let len = msg.length; + while (len-- > 0) + mfp[0] = (mfp[0] << 5) - mfp[0] + msg.charCodeAt(walk++); + return mfp[0].toString(16).padStart(8, '0'); }; /** - * Enum with available log levels. + * Default console-based logger. + * + * **Important:** This logger is always added as part of {@link LoggerManager} instance configuration and can't be + * removed. + * + * @internal */ - var LogLevel; - (function (LogLevel) { + /** + * Custom {@link Logger} implementation to show a message in the native console. + */ + class ConsoleLogger { /** - * Used to notify about every last detail: - * - function calls, - * - full payloads, - * - internal variables, - * - state-machine hops. + * Process a `trace` level message. + * + * @param message - Message which should be handled by custom logger implementation. */ - LogLevel[LogLevel["Trace"] = 0] = "Trace"; + debug(message) { + this.log(message); + } /** - * Used to notify about broad strokes of your SDK’s logic: - * - inputs/outputs to public methods, - * - network request - * - network response - * - decision branches. + * Process a `debug` level message. + * + * @param message - Message which should be handled by custom logger implementation. */ - LogLevel[LogLevel["Debug"] = 1] = "Debug"; + error(message) { + this.log(message); + } /** - * Used to notify summary of what the SDK is doing under the hood: - * - initialized, - * - connected, - * - entity created. + * Process an `info` level message. + * + * @param message - Message which should be handled by custom logger implementation. */ - LogLevel[LogLevel["Info"] = 2] = "Info"; + info(message) { + this.log(message); + } /** - * Used to notify about non-fatal events: - * - deprecations, - * - request retries. + * Process a `warn` level message. + * + * @param message - Message which should be handled by custom logger implementation. */ - LogLevel[LogLevel["Warn"] = 3] = "Warn"; + trace(message) { + this.log(message); + } /** - * Used to notify about: - * - exceptions, - * - HTTP failures, - * - invalid states. - */ - LogLevel[LogLevel["Error"] = 4] = "Error"; - /** - * Logging disabled. - */ - LogLevel[LogLevel["None"] = 5] = "None"; - })(LogLevel || (LogLevel = {})); - - /** - * Logging module manager. - * - * Manager responsible for log requests handling and forwarding to the registered {@link Logger logger} implementations. - */ - class LoggerManager { - /** - * Create and configure loggers' manager. - * - * @param pubNubId - Unique identifier of PubNub instance which will use this logger. - * @param minLogLevel - Minimum messages log level to be logged. - * @param loggers - List of additional loggers which should be used along with user-provided custom loggers. - * - * @internal - */ - constructor(pubNubId, minLogLevel, loggers) { - this.pubNubId = pubNubId; - this.minLogLevel = minLogLevel; - this.loggers = loggers; - } - /** - * Get current log level. - * - * @returns Current log level. + * Process an `error` level message. * - * @internal + * @param message - Message which should be handled by custom logger implementation. */ - get logLevel() { - return this.minLogLevel; + warn(message) { + this.log(message); } /** - * Process a `trace` level message. - * - * @param location - Call site from which a log message has been sent. - * @param messageFactory - Lazy message factory function or string for a text log message. + * Process log message object. * - * @internal + * @param message - Object with information which can be used to identify level and prepare log entry payload. */ - trace(location, messageFactory) { - this.log(LogLevel.Trace, location, messageFactory); + log(message) { + const logLevelString = LogLevel[message.level]; + const level = logLevelString.toLowerCase(); + console[level === 'trace' ? 'debug' : level](`${message.timestamp.toISOString()} PubNub-${message.pubNubId} ${logLevelString.padEnd(5, ' ')}${message.location ? ` ${message.location}` : ''} ${this.logMessage(message)}`); } /** - * Process a `debug` level message. + * Get a pre-formatted log message. * - * @param location - Call site from which a log message has been sent. - * @param messageFactory - Lazy message factory function or string for a text log message. + * @param message - Log message which should be stringified. * - * @internal + * @returns String formatted for log entry in console. */ - debug(location, messageFactory) { - this.log(LogLevel.Debug, location, messageFactory); + logMessage(message) { + if (message.messageType === 'text') + return message.message; + else if (message.messageType === 'object') + return `${message.details ? `${message.details}\n` : ''}${this.formattedObject(message)}`; + else if (message.messageType === 'network-request') { + const showOnlyBasicInfo = !!message.canceled || !!message.failed; + const headersList = message.minimumLevel === LogLevel.Trace && !showOnlyBasicInfo ? this.formattedHeaders(message) : undefined; + const request = message.message; + const queryString = request.queryParameters && Object.keys(request.queryParameters).length > 0 + ? queryStringFromObject(request.queryParameters) + : undefined; + const url = `${request.origin}${request.path}${queryString ? `?${queryString}` : ''}`; + const formattedBody = !showOnlyBasicInfo ? this.formattedBody(message) : undefined; + let action = 'Sending'; + if (showOnlyBasicInfo) + action = `${!!message.canceled ? 'Canceled' : 'Failed'}${message.details ? ` (${message.details})` : ''}`; + const padding = ((formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.formData) ? 'FormData' : 'Method').length; + return `${action} HTTP request:\n ${this.paddedString('Method', padding)}: ${request.method}\n ${this.paddedString('URL', padding)}: ${url}${headersList ? `\n ${this.paddedString('Headers', padding)}:\n${headersList}` : ''}${(formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.formData) ? `\n ${this.paddedString('FormData', padding)}:\n${formattedBody.formData}` : ''}${(formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.body) ? `\n ${this.paddedString('Body', padding)}:\n${formattedBody.body}` : ''}`; + } + else if (message.messageType === 'network-response') { + const headersList = message.minimumLevel === LogLevel.Trace ? this.formattedHeaders(message) : undefined; + const formattedBody = this.formattedBody(message); + const padding = ((formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.formData) ? 'Headers' : 'Status').length; + const response = message.message; + return `Received HTTP response:\n ${this.paddedString('URL', padding)}: ${response.url}\n ${this.paddedString('Status', padding)}: ${response.status}${headersList ? `\n ${this.paddedString('Headers', padding)}:\n${headersList}` : ''}${(formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.body) ? `\n ${this.paddedString('Body', padding)}:\n${formattedBody.body}` : ''}`; + } + else if (message.messageType === 'error') { + const formattedStatus = this.formattedErrorStatus(message); + const error = message.message; + return `${error.name}: ${error.message}${formattedStatus ? `\n${formattedStatus}` : ''}`; + } + return ''; } /** - * Process an `info` level message. + * Get a pre-formatted object (dictionary / array). * - * @param location - Call site from which a log message has been sent. - * @param messageFactory - Lazy message factory function or string for a text log message. + * @param message - Log message which may contain an object for formatting. * - * @internal + * @returns String formatted for log entry in console or `undefined` if a log message doesn't have suitable data. */ - info(location, messageFactory) { - this.log(LogLevel.Info, location, messageFactory); + formattedObject(message) { + const stringify = (obj, level = 1, skipIndentOnce = false) => { + const maxIndentReached = level === 10; + const targetIndent = ' '.repeat(level * 2); + const lines = []; + const isIgnored = (key, obj) => { + if (!message.ignoredKeys) + return false; + if (typeof message.ignoredKeys === 'function') + return message.ignoredKeys(key, obj); + return message.ignoredKeys.includes(key); + }; + if (typeof obj === 'string') + lines.push(`${targetIndent}- ${obj}`); + else if (typeof obj === 'number') + lines.push(`${targetIndent}- ${obj}`); + else if (typeof obj === 'boolean') + lines.push(`${targetIndent}- ${obj}`); + else if (obj === null) + lines.push(`${targetIndent}- null`); + else if (obj === undefined) + lines.push(`${targetIndent}- undefined`); + else if (typeof obj === 'function') + lines.push(`${targetIndent}- `); + else if (typeof obj === 'object') { + if (!Array.isArray(obj) && typeof obj.toString === 'function' && obj.toString().indexOf('[object') !== 0) { + lines.push(`${skipIndentOnce ? '' : targetIndent}${obj.toString()}`); + skipIndentOnce = false; + } + else if (Array.isArray(obj)) { + for (const element of obj) { + const indent = skipIndentOnce ? '' : targetIndent; + if (element === null) + lines.push(`${indent}- null`); + else if (element === undefined) + lines.push(`${indent}- undefined`); + else if (typeof element === 'function') + lines.push(`${indent}- `); + else if (typeof element === 'object') { + const isArray = Array.isArray(element); + const entry = maxIndentReached ? '...' : stringify(element, level + 1, !isArray); + lines.push(`${indent}-${isArray && !maxIndentReached ? '\n' : ' '}${entry}`); + } + else + lines.push(`${indent}- ${element}`); + skipIndentOnce = false; + } + } + else { + const object = obj; + const keys = Object.keys(object); + const maxKeyLen = keys.reduce((max, key) => Math.max(max, isIgnored(key, object) ? max : key.length), 0); + for (const key of keys) { + if (isIgnored(key, object)) + continue; + const indent = skipIndentOnce ? '' : targetIndent; + const raw = object[key]; + const paddedKey = key.padEnd(maxKeyLen, ' '); + if (raw === null) + lines.push(`${indent}${paddedKey}: null`); + else if (raw === undefined) + lines.push(`${indent}${paddedKey}: undefined`); + else if (typeof raw === 'function') + lines.push(`${indent}${paddedKey}: `); + else if (typeof raw === 'object') { + const isArray = Array.isArray(raw); + const isEmptyArray = isArray && raw.length === 0; + const isEmptyObject = !isArray && !(raw instanceof String) && Object.keys(raw).length === 0; + const hasToString = !isArray && typeof raw.toString === 'function' && raw.toString().indexOf('[object') !== 0; + const entry = maxIndentReached + ? '...' + : isEmptyArray + ? '[]' + : isEmptyObject + ? '{}' + : stringify(raw, level + 1, hasToString); + lines.push(`${indent}${paddedKey}:${maxIndentReached || hasToString || isEmptyArray || isEmptyObject ? ' ' : '\n'}${entry}`); + } + else + lines.push(`${indent}${paddedKey}: ${raw}`); + skipIndentOnce = false; + } + } + } + return lines.join('\n'); + }; + return stringify(message.message); } /** - * Process a `warn` level message. + * Get a pre-formatted headers list. * - * @param location - Call site from which a log message has been sent. - * @param messageFactory - Lazy message factory function or string for a text log message. + * @param message - Log message which may contain an object with headers to be used for formatting. * - * @internal + * @returns String formatted for log entry in console or `undefined` if a log message not related to the network data. */ - warn(location, messageFactory) { - this.log(LogLevel.Warn, location, messageFactory); + formattedHeaders(message) { + if (!message.message.headers) + return undefined; + const headers = message.message.headers; + const maxHeaderLength = Object.keys(headers).reduce((max, key) => Math.max(max, key.length), 0); + return Object.keys(headers) + .map((key) => ` - ${key.toLowerCase().padEnd(maxHeaderLength, ' ')}: ${headers[key]}`) + .join('\n'); } /** - * Process an `error` level message. + * Get a pre-formatted body. * - * @param location - Call site from which a log message has been sent. - * @param messageFactory - Lazy message factory function or string for a text log message. + * @param message - Log message which may contain an object with `body` (request or response). * - * @internal + * @returns Object with formatted string of form data and / or body for log entry in console or `undefined` if a log + * message not related to the network data. */ - error(location, messageFactory) { - this.log(LogLevel.Error, location, messageFactory); + formattedBody(message) { + var _a; + if (!message.message.headers) + return undefined; + let stringifiedFormData; + let stringifiedBody; + const headers = message.message.headers; + const contentType = (_a = headers['content-type']) !== null && _a !== void 0 ? _a : headers['Content-Type']; + const formData = 'formData' in message.message ? message.message.formData : undefined; + const body = message.message.body; + // The presence of this object means that we are sending `multipart/form-data` (potentially uploading a file). + if (formData) { + const maxFieldLength = formData.reduce((max, { key }) => Math.max(max, key.length), 0); + stringifiedFormData = formData + .map(({ key, value }) => ` - ${key.padEnd(maxFieldLength, ' ')}: ${value}`) + .join('\n'); + } + if (!body) + return { formData: stringifiedFormData }; + if (typeof body === 'string') { + stringifiedBody = ` ${body}`; + } + else if (body instanceof ArrayBuffer || Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + if (contentType && (contentType.indexOf('javascript') !== -1 || contentType.indexOf('json') !== -1)) + stringifiedBody = ` ${ConsoleLogger.decoder.decode(body)}`; + else + stringifiedBody = ` ArrayBuffer { byteLength: ${body.byteLength} }`; + } + else { + stringifiedBody = ` File { name: ${body.name}${body.contentLength ? `, contentLength: ${body.contentLength}` : ''}${body.mimeType ? `, mimeType: ${body.mimeType}` : ''} }`; + } + return { body: stringifiedBody, formData: stringifiedFormData }; } /** - * Process log message. + * Get a pre-formatted status object. * - * @param logLevel - Logged message level. - * @param location - Call site from which a log message has been sent. - * @param messageFactory - Lazy message factory function or string for a text log message. + * @param message - Log message which may contain a {@link Status} object. * - * @internal + * @returns String formatted for log entry in console or `undefined` if a log message doesn't have {@link Status} + * object. */ - log(logLevel, location, messageFactory) { - // Check whether a log message should be handled at all or not. - if (logLevel < this.minLogLevel || this.loggers.length === 0) - return; - const level = LogLevel[logLevel].toLowerCase(); - const message = Object.assign({ timestamp: new Date(), pubNubId: this.pubNubId, level: logLevel, minimumLevel: this.minLogLevel, location }, (typeof messageFactory === 'function' ? messageFactory() : { messageType: 'text', message: messageFactory })); - this.loggers.forEach((logger) => logger[level](message)); - } - } - - /** - * PubNub package utilities module. - * - * @internal - */ - /** - * Percent-encode input string. - * - * **Note:** Encode content in accordance of the `PubNub` service requirements. - * - * @param input - Source string or number for encoding. - * - * @returns Percent-encoded string. - * - * @internal - */ - const encodeString = (input) => { - return encodeURIComponent(input).replace(/[!~*'()]/g, (x) => `%${x.charCodeAt(0).toString(16).toUpperCase()}`); - }; - /** - * Percent-encode list of names (channels). - * - * @param names - List of names which should be encoded. - * - * @param [defaultString] - String which should be used in case if {@link names} is empty. - * - * @returns String which contains encoded names joined by non-encoded `,`. - * - * @internal - */ - const encodeNames = (names, defaultString) => { - const encodedNames = names.map((name) => encodeString(name)); - return encodedNames.length ? encodedNames.join(',') : (defaultString !== null && defaultString !== void 0 ? defaultString : ''); - }; - /** - * @internal - */ - const removeSingleOccurrence = (source, elementsToRemove) => { - const removed = Object.fromEntries(elementsToRemove.map((prop) => [prop, false])); - return source.filter((e) => { - if (elementsToRemove.includes(e) && !removed[e]) { - removed[e] = true; - return false; + formattedErrorStatus(message) { + if (!message.message.status) + return undefined; + const status = message.message.status; + const errorData = status.errorData; + let stringifiedErrorData; + if (ConsoleLogger.isError(errorData)) { + stringifiedErrorData = ` ${errorData.name}: ${errorData.message}`; + if (errorData.stack) { + stringifiedErrorData += `\n${errorData.stack + .split('\n') + .map((line) => ` ${line}`) + .join('\n')}`; + } } - return true; - }); - }; - /** - * @internal - */ - const findUniqueCommonElements = (a, b) => { - return [...a].filter((value) => b.includes(value) && a.indexOf(value) === a.lastIndexOf(value) && b.indexOf(value) === b.lastIndexOf(value)); - }; - /** - * Transform query key / value pairs to the string. - * - * @param query - Key / value pairs of the request query parameters. - * - * @returns Stringified query key / value pairs. - * - * @internal - */ - const queryStringFromObject = (query) => { - return Object.keys(query) - .map((key) => { - const queryValue = query[key]; - if (!Array.isArray(queryValue)) - return `${key}=${encodeString(queryValue)}`; - return queryValue.map((value) => `${key}=${encodeString(value)}`).join('&'); - }) - .join('&'); - }; - /** - * Adjust `timetoken` to represent current time in PubNub's high-precision time format. - * - * @param timetoken - Timetoken recently used for subscribe long-poll request. - * @param [referenceTimetoken] - Previously computed reference timetoken. - * - * @returns Adjusted timetoken if recent timetoken available. - */ - const subscriptionTimetokenFromReference = (timetoken, referenceTimetoken) => { - if (referenceTimetoken === '0' || timetoken === '0') - return undefined; - const timetokenDiff = adjustedTimetokenBy(`${Date.now()}0000`, referenceTimetoken, false); - return adjustedTimetokenBy(timetoken, timetokenDiff, true); - }; - /** - * Create reference timetoken based on subscribe timetoken and the user's local time. - * - * Subscription-based reference timetoken allows later computing approximate timetoken at any point in time. - * - * @param [serviceTimetoken] - Timetoken received from the PubNub subscribe service. - * @param [catchUpTimetoken] - Previously stored or user-provided catch-up timetoken. - * @param [referenceTimetoken] - Previously computed reference timetoken. **Important:** This value should be used - * in the case of restore because the actual time when service and catch-up timetokens are received is really - * different from the current local time. - * - * @returns Reference timetoken. - */ - const referenceSubscribeTimetoken = (serviceTimetoken, catchUpTimetoken, referenceTimetoken) => { - if (!serviceTimetoken || serviceTimetoken.length === 0) - return undefined; - if (catchUpTimetoken && catchUpTimetoken.length > 0 && catchUpTimetoken !== '0') { - // Compensate reference timetoken because catch-up timetoken has been used. - const timetokensDiff = adjustedTimetokenBy(serviceTimetoken, catchUpTimetoken, false); - return adjustedTimetokenBy(referenceTimetoken !== null && referenceTimetoken !== void 0 ? referenceTimetoken : `${Date.now()}0000`, timetokensDiff.replace('-', ''), Number(timetokensDiff) < 0); + else if (errorData) { + try { + stringifiedErrorData = ` ${JSON.stringify(errorData)}`; + } + catch (_) { + stringifiedErrorData = ` ${errorData}`; + } + } + return ` Category : ${status.category}\n Operation : ${status.operation}\n Status : ${status.statusCode}${stringifiedErrorData ? `\n Error data:\n${stringifiedErrorData}` : ''}`; } - else if (referenceTimetoken && referenceTimetoken.length > 0 && referenceTimetoken !== '0') - return referenceTimetoken; - else - return `${Date.now()}0000`; - }; - /** - * High-precision time token adjustment. - * - * @param timetoken - Source timetoken which should be adjusted. - * @param value - Value in nanoseconds which should be used for source timetoken adjustment. - * @param increment - Whether source timetoken should be incremented or decremented. - * - * @returns Adjusted high-precision PubNub timetoken. - */ - const adjustedTimetokenBy = (timetoken, value, increment) => { - // Normalize value to the PubNub's high-precision time format. - value = value.padStart(17, '0'); - const secA = timetoken.slice(0, 10); - const tickA = timetoken.slice(10, 17); - const secB = value.slice(0, 10); - const tickB = value.slice(10, 17); - let seconds = Number(secA); - let ticks = Number(tickA); - seconds += Number(secB) * (increment ? 1 : -1); - ticks += Number(tickB) * (increment ? 1 : -1); - if (ticks >= 10000000) { - seconds += Math.floor(ticks / 10000000); - ticks %= 10000000; + /** + * Append the required amount of space to provide proper padding. + * + * @param str - Source string which should be appended with necessary number of spaces. + * @param maxLength - Maximum length of the string to which source string should be padded. + * @returns End-padded string. + */ + paddedString(str, maxLength) { + return str.padEnd(maxLength - str.length, ' '); } - else if (ticks < 0) { - if (seconds > 0) { - seconds -= 1; - ticks += 10000000; - } - else if (seconds < 0) - ticks *= -1; + /** + * Check whether passed object is {@link Error} instance. + * + * @param errorData - Object which should be checked. + * + * @returns `true` in case if an object actually {@link Error}. + */ + static isError(errorData) { + if (!errorData) + return false; + return errorData instanceof Error || Object.prototype.toString.call(errorData) === '[object Error]'; } - return seconds !== 0 ? `${seconds}${`${ticks}`.padStart(7, '0')}` : `${ticks}`; - }; + } /** - * Compute received update (message, event) fingerprint. - * - * @param input - Data payload from subscribe API response. - * - * @returns Received update fingerprint. + * Binary data decoder. */ - const messageFingerprint = (input) => { - const msg = typeof input !== 'string' ? JSON.stringify(input) : input; - const mfp = new Uint32Array(1); - let walk = 0; - let len = msg.length; - while (len-- > 0) - mfp[0] = (mfp[0] << 5) - mfp[0] + msg.charCodeAt(walk++); - return mfp[0].toString(16).padStart(8, '0'); - }; + ConsoleLogger.decoder = new TextDecoder(); + // -------------------------------------------------------- + // ------------------------ Types ------------------------- + // -------------------------------------------------------- + // region Types /** - * Default console-based logger. - * - * **Important:** This logger is always added as part of {@link LoggerManager} instance configuration and can't be - * removed. - * - * @internal - */ - /** - * Custom {@link Logger} implementation to show a message in the native console. + * List of known endpoint groups (by context). */ - class ConsoleLogger { + var Endpoint; + (function (Endpoint) { /** - * Process a `trace` level message. + * Unknown endpoint. * - * @param message - Message which should be handled by custom logger implementation. + * @internal */ - debug(message) { - this.log(message); - } + Endpoint["Unknown"] = "UnknownEndpoint"; /** - * Process a `debug` level message. + * The endpoints to send messages. * - * @param message - Message which should be handled by custom logger implementation. + * This is related to the following functionality: + * - `publish` + * - `signal` + * - `publish file` + * - `fire` */ - error(message) { - this.log(message); - } + Endpoint["MessageSend"] = "MessageSendEndpoint"; /** - * Process an `info` level message. + * The endpoint for real-time update retrieval. * - * @param message - Message which should be handled by custom logger implementation. + * This is related to the following functionality: + * - `subscribe` */ - info(message) { - this.log(message); - } + Endpoint["Subscribe"] = "SubscribeEndpoint"; /** - * Process a `warn` level message. + * The endpoint to access and manage `user_id` presence and fetch channel presence information. * - * @param message - Message which should be handled by custom logger implementation. + * This is related to the following functionality: + * - `get presence state` + * - `set presence state` + * - `here now` + * - `where now` + * - `heartbeat` */ - trace(message) { - this.log(message); - } + Endpoint["Presence"] = "PresenceEndpoint"; /** - * Process an `error` level message. + * The endpoint to access and manage files in channel-specific storage. * - * @param message - Message which should be handled by custom logger implementation. + * This is related to the following functionality: + * - `send file` + * - `download file` + * - `list files` + * - `delete file` */ - warn(message) { - this.log(message); - } + Endpoint["Files"] = "FilesEndpoint"; /** - * Process log message object. + * The endpoint to access and manage messages for a specific channel(s) in the persistent storage. * - * @param message - Object with information which can be used to identify level and prepare log entry payload. + * This is related to the following functionality: + * - `fetch messages / message actions` + * - `delete messages` + * - `messages count` */ - log(message) { - const logLevelString = LogLevel[message.level]; - const level = logLevelString.toLowerCase(); - console[level === 'trace' ? 'debug' : level](`${message.timestamp.toISOString()} PubNub-${message.pubNubId} ${logLevelString.padEnd(5, ' ')}${message.location ? ` ${message.location}` : ''} ${this.logMessage(message)}`); - } + Endpoint["MessageStorage"] = "MessageStorageEndpoint"; /** - * Get a pre-formatted log message. - * - * @param message - Log message which should be stringified. + * The endpoint to access and manage channel groups. * - * @returns String formatted for log entry in console. + * This is related to the following functionality: + * - `add channels to group` + * - `list channels in group` + * - `remove channels from group` + * - `list channel groups` */ - logMessage(message) { - if (message.messageType === 'text') - return message.message; - else if (message.messageType === 'object') - return `${message.details ? `${message.details}\n` : ''}${this.formattedObject(message)}`; - else if (message.messageType === 'network-request') { - const showOnlyBasicInfo = !!message.canceled || !!message.failed; - const headersList = message.minimumLevel === LogLevel.Trace && !showOnlyBasicInfo ? this.formattedHeaders(message) : undefined; - const request = message.message; - const queryString = request.queryParameters && Object.keys(request.queryParameters).length > 0 - ? queryStringFromObject(request.queryParameters) - : undefined; - const url = `${request.origin}${request.path}${queryString ? `?${queryString}` : ''}`; - const formattedBody = !showOnlyBasicInfo ? this.formattedBody(message) : undefined; - let action = 'Sending'; - if (showOnlyBasicInfo) - action = `${!!message.canceled ? 'Canceled' : 'Failed'}${message.details ? ` (${message.details})` : ''}`; - const padding = ((formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.formData) ? 'FormData' : 'Method').length; - return `${action} HTTP request:\n ${this.paddedString('Method', padding)}: ${request.method}\n ${this.paddedString('URL', padding)}: ${url}${headersList ? `\n ${this.paddedString('Headers', padding)}:\n${headersList}` : ''}${(formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.formData) ? `\n ${this.paddedString('FormData', padding)}:\n${formattedBody.formData}` : ''}${(formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.body) ? `\n ${this.paddedString('Body', padding)}:\n${formattedBody.body}` : ''}`; - } - else if (message.messageType === 'network-response') { - const headersList = message.minimumLevel === LogLevel.Trace ? this.formattedHeaders(message) : undefined; - const formattedBody = this.formattedBody(message); - const padding = ((formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.formData) ? 'Headers' : 'Status').length; - const response = message.message; - return `Received HTTP response:\n ${this.paddedString('URL', padding)}: ${response.url}\n ${this.paddedString('Status', padding)}: ${response.status}${headersList ? `\n ${this.paddedString('Headers', padding)}:\n${headersList}` : ''}${(formattedBody === null || formattedBody === void 0 ? void 0 : formattedBody.body) ? `\n ${this.paddedString('Body', padding)}:\n${formattedBody.body}` : ''}`; - } - else if (message.messageType === 'error') { - const formattedStatus = this.formattedErrorStatus(message); - const error = message.message; - return `${error.name}: ${error.message}${formattedStatus ? `\n${formattedStatus}` : ''}`; - } - return ''; - } + Endpoint["ChannelGroups"] = "ChannelGroupsEndpoint"; /** - * Get a pre-formatted object (dictionary / array). - * - * @param message - Log message which may contain an object for formatting. + * The endpoint to access and manage device registration for channel push notifications. * - * @returns String formatted for log entry in console or `undefined` if a log message doesn't have suitable data. + * This is related to the following functionality: + * - `enable channels for push notifications` + * - `list push notification enabled channels` + * - `disable push notifications for channels` + * - `disable push notifications for all channels` */ - formattedObject(message) { - const stringify = (obj, level = 1, skipIndentOnce = false) => { - const maxIndentReached = level === 10; - const targetIndent = ' '.repeat(level * 2); - const lines = []; - const isIgnored = (key, obj) => { - if (!message.ignoredKeys) - return false; - if (typeof message.ignoredKeys === 'function') - return message.ignoredKeys(key, obj); - return message.ignoredKeys.includes(key); - }; - if (typeof obj === 'string') - lines.push(`${targetIndent}- ${obj}`); - else if (typeof obj === 'number') - lines.push(`${targetIndent}- ${obj}`); - else if (typeof obj === 'boolean') - lines.push(`${targetIndent}- ${obj}`); - else if (obj === null) - lines.push(`${targetIndent}- null`); - else if (obj === undefined) - lines.push(`${targetIndent}- undefined`); - else if (typeof obj === 'function') - lines.push(`${targetIndent}- `); - else if (typeof obj === 'object') { - if (!Array.isArray(obj) && typeof obj.toString === 'function' && obj.toString().indexOf('[object') !== 0) { - lines.push(`${skipIndentOnce ? '' : targetIndent}${obj.toString()}`); - skipIndentOnce = false; - } - else if (Array.isArray(obj)) { - for (const element of obj) { - const indent = skipIndentOnce ? '' : targetIndent; - if (element === null) - lines.push(`${indent}- null`); - else if (element === undefined) - lines.push(`${indent}- undefined`); - else if (typeof element === 'function') - lines.push(`${indent}- `); - else if (typeof element === 'object') { - const isArray = Array.isArray(element); - const entry = maxIndentReached ? '...' : stringify(element, level + 1, !isArray); - lines.push(`${indent}-${isArray && !maxIndentReached ? '\n' : ' '}${entry}`); - } - else - lines.push(`${indent}- ${element}`); - skipIndentOnce = false; - } - } - else { - const object = obj; - const keys = Object.keys(object); - const maxKeyLen = keys.reduce((max, key) => Math.max(max, isIgnored(key, object) ? max : key.length), 0); - for (const key of keys) { - if (isIgnored(key, object)) - continue; - const indent = skipIndentOnce ? '' : targetIndent; - const raw = object[key]; - const paddedKey = key.padEnd(maxKeyLen, ' '); - if (raw === null) - lines.push(`${indent}${paddedKey}: null`); - else if (raw === undefined) - lines.push(`${indent}${paddedKey}: undefined`); - else if (typeof raw === 'function') - lines.push(`${indent}${paddedKey}: `); - else if (typeof raw === 'object') { - const isArray = Array.isArray(raw); - const isEmptyArray = isArray && raw.length === 0; - const hasToString = !isArray && typeof raw.toString === 'function' && raw.toString().indexOf('[object') !== 0; - const entry = maxIndentReached ? '...' : isEmptyArray ? '[]' : stringify(raw, level + 1, hasToString); - lines.push(`${indent}${paddedKey}:${maxIndentReached || hasToString || isEmptyArray ? ' ' : '\n'}${entry}`); - } - else - lines.push(`${indent}${paddedKey}: ${raw}`); - skipIndentOnce = false; - } - } - } - return lines.join('\n'); - }; - return stringify(message.message); - } + Endpoint["DevicePushNotifications"] = "DevicePushNotificationsEndpoint"; /** - * Get a pre-formatted headers list. - * - * @param message - Log message which may contain an object with headers to be used for formatting. + * The endpoint to access and manage App Context objects. * - * @returns String formatted for log entry in console or `undefined` if a log message not related to the network data. + * This is related to the following functionality: + * - `set UUID metadata` + * - `get UUID metadata` + * - `remove UUID metadata` + * - `get all UUID metadata` + * - `set Channel metadata` + * - `get Channel metadata` + * - `remove Channel metadata` + * - `get all Channel metadata` + * - `manage members` + * - `list members` + * - `manage memberships` + * - `list memberships` */ - formattedHeaders(message) { - if (!message.message.headers) - return undefined; - const headers = message.message.headers; - const maxHeaderLength = Object.keys(headers).reduce((max, key) => Math.max(max, key.length), 0); - return Object.keys(headers) - .map((key) => ` - ${key.toLowerCase().padEnd(maxHeaderLength, ' ')}: ${headers[key]}`) - .join('\n'); - } + Endpoint["AppContext"] = "AppContextEndpoint"; /** - * Get a pre-formatted body. - * - * @param message - Log message which may contain an object with `body` (request or response). + * The endpoint to access and manage reactions for a specific message. * - * @returns Object with formatted string of form data and / or body for log entry in console or `undefined` if a log - * message not related to the network data. + * This is related to the following functionality: + * - `add message action` + * - `get message actions` + * - `remove message action` */ - formattedBody(message) { + Endpoint["MessageReactions"] = "MessageReactionsEndpoint"; + })(Endpoint || (Endpoint = {})); + // endregion + /** + * Failed request retry policy. + */ + class RetryPolicy { + static None() { + return { + shouldRetry(_request, _response, _errorCategory, _attempt) { + return false; + }, + getDelay(_attempt, _response) { + return -1; + }, + validate() { + return true; + }, + }; + } + static LinearRetryPolicy(configuration) { var _a; - if (!message.message.headers) - return undefined; - let stringifiedFormData; - let stringifiedBody; - const headers = message.message.headers; - const contentType = (_a = headers['content-type']) !== null && _a !== void 0 ? _a : headers['Content-Type']; - const formData = 'formData' in message.message ? message.message.formData : undefined; - const body = message.message.body; - // The presence of this object means that we are sending `multipart/form-data` (potentially uploading a file). - if (formData) { - const maxFieldLength = formData.reduce((max, { key }) => Math.max(max, key.length), 0); - stringifiedFormData = formData - .map(({ key, value }) => ` - ${key.padEnd(maxFieldLength, ' ')}: ${value}`) - .join('\n'); - } - if (!body) - return { formData: stringifiedFormData }; - if (typeof body === 'string') { - stringifiedBody = ` ${body}`; - } - else if (body instanceof ArrayBuffer) { - if (contentType && (contentType.indexOf('javascript') !== -1 || contentType.indexOf('json') !== -1)) - stringifiedBody = ` ${ConsoleLogger.decoder.decode(body)}`; - else - stringifiedBody = ` ArrayBuffer { byteLength: ${body.byteLength} }`; - } - else { - stringifiedBody = ` File { name: ${body.name}${body.contentLength ? `, contentLength: ${body.contentLength}` : ''}${body.mimeType ? `, mimeType: ${body.mimeType}` : ''} }`; - } - return { body: stringifiedBody, formData: stringifiedFormData }; - } - /** - * Get a pre-formatted status object. - * - * @param message - Log message which may contain a {@link Status} object. - * - * @returns String formatted for log entry in console or `undefined` if a log message doesn't have {@link Status} - * object. - */ - formattedErrorStatus(message) { - if (!message.message.status) - return undefined; - const status = message.message.status; - const errorData = status.errorData; - let stringifiedErrorData; - if (ConsoleLogger.isError(errorData)) { - stringifiedErrorData = ` ${errorData.name}: ${errorData.message}`; - if (errorData.stack) { - stringifiedErrorData += `\n${errorData.stack - .split('\n') - .map((line) => ` ${line}`) - .join('\n')}`; - } - } - else if (errorData) { - try { - stringifiedErrorData = ` ${JSON.stringify(errorData)}`; - } - catch (_) { - stringifiedErrorData = ` ${errorData}`; - } - } - return ` Category : ${status.category}\n Operation : ${status.operation}\n Status : ${status.statusCode}${stringifiedErrorData ? `\n Error data:\n${stringifiedErrorData}` : ''}`; - } - /** - * Append the required amount of space to provide proper padding. - * - * @param str - Source string which should be appended with necessary number of spaces. - * @param maxLength - Maximum length of the string to which source string should be padded. - * @returns End-padded string. - */ - paddedString(str, maxLength) { - return str.padEnd(maxLength - str.length, ' '); + return { + delay: configuration.delay, + maximumRetry: configuration.maximumRetry, + excluded: (_a = configuration.excluded) !== null && _a !== void 0 ? _a : [], + shouldRetry(request, response, error, attempt) { + return isRetriableRequest(request, response, error, attempt !== null && attempt !== void 0 ? attempt : 0, this.maximumRetry, this.excluded); + }, + getDelay(_, response) { + let delay = -1; + if (response && response.headers['retry-after'] !== undefined) + delay = parseInt(response.headers['retry-after'], 10); + if (delay === -1) + delay = this.delay; + return (delay + Math.random()) * 1000; + }, + validate() { + if (this.delay < 2) + throw new Error('Delay can not be set less than 2 seconds for retry'); + if (this.maximumRetry > 10) + throw new Error('Maximum retry for linear retry policy can not be more than 10'); + }, + }; } - /** - * Check whether passed object is {@link Error} instance. - * - * @param errorData - Object which should be checked. - * - * @returns `true` in case if an object actually {@link Error}. - */ - static isError(errorData) { - if (!errorData) - return false; - return errorData instanceof Error || Object.prototype.toString.call(errorData) === '[object Error]'; + static ExponentialRetryPolicy(configuration) { + var _a; + return { + minimumDelay: configuration.minimumDelay, + maximumDelay: configuration.maximumDelay, + maximumRetry: configuration.maximumRetry, + excluded: (_a = configuration.excluded) !== null && _a !== void 0 ? _a : [], + shouldRetry(request, response, error, attempt) { + return isRetriableRequest(request, response, error, attempt !== null && attempt !== void 0 ? attempt : 0, this.maximumRetry, this.excluded); + }, + getDelay(attempt, response) { + let delay = -1; + if (response && response.headers['retry-after'] !== undefined) + delay = parseInt(response.headers['retry-after'], 10); + if (delay === -1) + delay = Math.min(Math.pow(2, attempt), this.maximumDelay); + return (delay + Math.random()) * 1000; + }, + validate() { + if (this.minimumDelay < 2) + throw new Error('Minimum delay can not be set less than 2 seconds for retry'); + else if (this.maximumDelay > 150) + throw new Error('Maximum delay can not be set more than 150 seconds for' + ' retry'); + else if (this.maximumRetry > 6) + throw new Error('Maximum retry for exponential retry policy can not be more than 6'); + }, + }; } } /** - * Binary data decoder. - */ - ConsoleLogger.decoder = new TextDecoder(); - - /** - * {@link PubNub} client configuration module. + * Check whether request can be retried or not. + * + * @param req - Request for which retry ability is checked. + * @param res - Service response which should be taken into consideration. + * @param errorCategory - Request processing error category. + * @param retryAttempt - Current retry attempt. + * @param maximumRetry - Maximum retry attempts count according to the retry policy. + * @param excluded - List of endpoints for which retry policy won't be applied. + * + * @return `true` if request can be retried. * * @internal */ - // -------------------------------------------------------- - // ----------------------- Defaults ----------------------- - // -------------------------------------------------------- - // region Defaults + const isRetriableRequest = (req, res, errorCategory, retryAttempt, maximumRetry, excluded) => { + if (errorCategory) { + if (errorCategory === StatusCategory$1.PNCancelledCategory || + errorCategory === StatusCategory$1.PNBadRequestCategory || + errorCategory === StatusCategory$1.PNAccessDeniedCategory) + return false; + } + if (isExcludedRequest(req, excluded)) + return false; + else if (retryAttempt > maximumRetry) + return false; + return res ? res.status === 429 || res.status >= 500 : true; + }; /** - * Whether encryption (if set) should use random initialization vector or not. + * Check whether the provided request is in the list of endpoints for which retry is not allowed or not. + * + * @param req - Request which will be tested. + * @param excluded - List of excluded endpoints configured for retry policy. + * + * @returns `true` if request has been excluded and shouldn't be retried. * * @internal */ - const USE_RANDOM_INITIALIZATION_VECTOR = true; + const isExcludedRequest = (req, excluded) => excluded && excluded.length > 0 ? excluded.includes(endpointFromRequest(req)) : false; /** - * Create {@link PubNub} client private configuration object. + * Identify API group from transport request. * - * @param base - User- and platform-provided configuration. - * @param setupCryptoModule - Platform-provided {@link ICryptoModule} configuration block. + * @param req - Request for which `path` will be analyzed to identify REST API group. * - * @returns `PubNub` client private configuration. + * @returns Endpoint group to which request belongs. * * @internal */ - const makeConfiguration = (base, setupCryptoModule) => { - var _a, _b, _c, _d; - // Set the default retry policy for subscribing (if new subscribe logic not used). - if (!base.retryConfiguration && base.enableEventEngine) { - base.retryConfiguration = RetryPolicy.ExponentialRetryPolicy({ - minimumDelay: 2, - maximumDelay: 150, - maximumRetry: 6, - excluded: [ - Endpoint.MessageSend, - Endpoint.Presence, - Endpoint.Files, - Endpoint.MessageStorage, - Endpoint.ChannelGroups, - Endpoint.DevicePushNotifications, - Endpoint.AppContext, - Endpoint.MessageReactions, - ], - }); + const endpointFromRequest = (req) => { + let endpoint = Endpoint.Unknown; + if (req.path.startsWith('/v2/subscribe')) + endpoint = Endpoint.Subscribe; + else if (req.path.startsWith('/publish/') || req.path.startsWith('/signal/')) + endpoint = Endpoint.MessageSend; + else if (req.path.startsWith('/v2/presence')) + endpoint = Endpoint.Presence; + else if (req.path.startsWith('/v2/history') || req.path.startsWith('/v3/history')) + endpoint = Endpoint.MessageStorage; + else if (req.path.startsWith('/v1/message-actions/')) + endpoint = Endpoint.MessageReactions; + else if (req.path.startsWith('/v1/channel-registration/')) + endpoint = Endpoint.ChannelGroups; + else if (req.path.startsWith('/v2/objects/')) + endpoint = Endpoint.ChannelGroups; + else if (req.path.startsWith('/v1/push/') || req.path.startsWith('/v2/push/')) + endpoint = Endpoint.DevicePushNotifications; + else if (req.path.startsWith('/v1/files/')) + endpoint = Endpoint.Files; + return endpoint; + }; + + /** + * Logging module manager. + * + * Manager responsible for log requests handling and forwarding to the registered {@link Logger logger} implementations. + */ + class LoggerManager { + /** + * Create and configure loggers' manager. + * + * @param pubNubId - Unique identifier of PubNub instance which will use this logger. + * @param minLogLevel - Minimum messages log level to be logged. + * @param loggers - List of additional loggers which should be used along with user-provided custom loggers. + * + * @internal + */ + constructor(pubNubId, minLogLevel, loggers) { + this.pubNubId = pubNubId; + this.minLogLevel = minLogLevel; + this.loggers = loggers; } - const instanceId = `pn-${uuidGenerator.createUUID()}`; - if (base.logVerbosity) - base.logLevel = LogLevel.Debug; - else if (base.logLevel === undefined) - base.logLevel = LogLevel.None; - // Prepare loggers manager. - const loggerManager = new LoggerManager(hashFromString(instanceId), base.logLevel, [ - ...((_a = base.loggers) !== null && _a !== void 0 ? _a : []), - new ConsoleLogger(), - ]); - if (base.logVerbosity !== undefined) - loggerManager.warn('Configuration', "'logVerbosity' is deprecated. Use 'logLevel' instead."); - // Ensure that retry policy has proper configuration (if has been set). - (_b = base.retryConfiguration) === null || _b === void 0 ? void 0 : _b.validate(); - (_c = base.useRandomIVs) !== null && _c !== void 0 ? _c : (base.useRandomIVs = USE_RANDOM_INITIALIZATION_VECTOR); - if (base.useRandomIVs) - loggerManager.warn('Configuration', "'useRandomIVs' is deprecated. Use 'cryptoModule' instead."); - // Override origin value. - base.origin = standardOrigin((_d = base.ssl) !== null && _d !== void 0 ? _d : false, base.origin); - const cryptoModule = base.cryptoModule; - if (cryptoModule) - delete base.cryptoModule; - const clientConfiguration = Object.assign(Object.assign({}, base), { _pnsdkSuffix: {}, _loggerManager: loggerManager, _instanceId: instanceId, _cryptoModule: undefined, _cipherKey: undefined, _setupCryptoModule: setupCryptoModule, get instanceId() { - if (base.useInstanceId) - return this._instanceId; - return undefined; - }, - getInstanceId() { - if (base.useInstanceId) - return this._instanceId; - return undefined; - }, - getUserId() { - return this.userId; - }, - setUserId(value) { - if (!value || typeof value !== 'string' || value.trim().length === 0) - throw new Error('Missing or invalid userId parameter. Provide a valid string userId'); - this.userId = value; - }, + /** + * Get current log level. + * + * @returns Current log level. + * + * @internal + */ + get logLevel() { + return this.minLogLevel; + } + /** + * Process a `trace` level message. + * + * @param location - Call site from which a log message has been sent. + * @param messageFactory - Lazy message factory function or string for a text log message. + * + * @internal + */ + trace(location, messageFactory) { + this.log(LogLevel.Trace, location, messageFactory); + } + /** + * Process a `debug` level message. + * + * @param location - Call site from which a log message has been sent. + * @param messageFactory - Lazy message factory function or string for a text log message. + * + * @internal + */ + debug(location, messageFactory) { + this.log(LogLevel.Debug, location, messageFactory); + } + /** + * Process an `info` level message. + * + * @param location - Call site from which a log message has been sent. + * @param messageFactory - Lazy message factory function or string for a text log message. + * + * @internal + */ + info(location, messageFactory) { + this.log(LogLevel.Info, location, messageFactory); + } + /** + * Process a `warn` level message. + * + * @param location - Call site from which a log message has been sent. + * @param messageFactory - Lazy message factory function or string for a text log message. + * + * @internal + */ + warn(location, messageFactory) { + this.log(LogLevel.Warn, location, messageFactory); + } + /** + * Process an `error` level message. + * + * @param location - Call site from which a log message has been sent. + * @param messageFactory - Lazy message factory function or string for a text log message. + * + * @internal + */ + error(location, messageFactory) { + this.log(LogLevel.Error, location, messageFactory); + } + /** + * Process log message. + * + * @param logLevel - Logged message level. + * @param location - Call site from which a log message has been sent. + * @param messageFactory - Lazy message factory function or string for a text log message. + * + * @internal + */ + log(logLevel, location, messageFactory) { + // Check whether a log message should be handled at all or not. + if (logLevel < this.minLogLevel || this.loggers.length === 0) + return; + const level = LogLevel[logLevel].toLowerCase(); + const message = Object.assign({ timestamp: new Date(), pubNubId: this.pubNubId, level: logLevel, minimumLevel: this.minLogLevel, location }, (typeof messageFactory === 'function' ? messageFactory() : { messageType: 'text', message: messageFactory })); + this.loggers.forEach((logger) => logger[level](message)); + } + } + + var uuid = {exports: {}}; + + /*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */ + uuid.exports; + + (function (module, exports) { + (function (root, factory) { + { + factory(exports); + if (module !== null) { + module.exports = exports.uuid; + } + } + }(commonjsGlobal, function (exports) { + var VERSION = '0.1.0'; + var uuidRegex = { + '3': /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i, + '4': /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i, + '5': /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i, + all: /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i + }; + + function uuid() { + var uuid = '', i, random; + for (i = 0; i < 32; i++) { + random = Math.random() * 16 | 0; + if (i === 8 || i === 12 || i === 16 || i === 20) uuid += '-'; + uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16); + } + return uuid + } + + function isUUID(str, version) { + var pattern = uuidRegex[version || 'all']; + return pattern && pattern.test(str) || false + } + + uuid.isUUID = isUUID; + uuid.VERSION = VERSION; + + exports.uuid = uuid; + exports.isUUID = isUUID; + })); + } (uuid, uuid.exports)); + + var uuidExports = uuid.exports; + var uuidGenerator$1 = /*@__PURE__*/getDefaultExportFromCjs(uuidExports); + + /** + * Random identifier generator helper module. + * + * @internal + */ + /** @internal */ + var uuidGenerator = { + createUUID() { + if (uuidGenerator$1.uuid) { + return uuidGenerator$1.uuid(); + } + // @ts-expect-error Depending on module type it may be callable. + return uuidGenerator$1(); + }, + }; + + /** + * {@link PubNub} client configuration module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Whether encryption (if set) should use random initialization vector or not. + * + * @internal + */ + const USE_RANDOM_INITIALIZATION_VECTOR = true; + /** + * Create {@link PubNub} client private configuration object. + * + * @param base - User- and platform-provided configuration. + * @param setupCryptoModule - Platform-provided {@link ICryptoModule} configuration block. + * + * @returns `PubNub` client private configuration. + * + * @internal + */ + const makeConfiguration = (base, setupCryptoModule) => { + var _a, _b, _c, _d; + // Set the default retry policy for subscribing (if new subscribe logic not used). + if (!base.retryConfiguration && base.enableEventEngine) { + base.retryConfiguration = RetryPolicy.ExponentialRetryPolicy({ + minimumDelay: 2, + maximumDelay: 150, + maximumRetry: 6, + excluded: [ + Endpoint.MessageSend, + Endpoint.Presence, + Endpoint.Files, + Endpoint.MessageStorage, + Endpoint.ChannelGroups, + Endpoint.DevicePushNotifications, + Endpoint.AppContext, + Endpoint.MessageReactions, + ], + }); + } + const instanceId = `pn-${uuidGenerator.createUUID()}`; + if (base.logVerbosity) + base.logLevel = LogLevel.Debug; + else if (base.logLevel === undefined) + base.logLevel = LogLevel.None; + // Prepare loggers manager. + const loggerManager = new LoggerManager(hashFromString(instanceId), base.logLevel, [ + ...((_a = base.loggers) !== null && _a !== void 0 ? _a : []), + new ConsoleLogger(), + ]); + if (base.logVerbosity !== undefined) + loggerManager.warn('Configuration', "'logVerbosity' is deprecated. Use 'logLevel' instead."); + // Ensure that retry policy has proper configuration (if has been set). + (_b = base.retryConfiguration) === null || _b === void 0 ? void 0 : _b.validate(); + (_c = base.useRandomIVs) !== null && _c !== void 0 ? _c : (base.useRandomIVs = USE_RANDOM_INITIALIZATION_VECTOR); + if (base.useRandomIVs) + loggerManager.warn('Configuration', "'useRandomIVs' is deprecated. Use 'cryptoModule' instead."); + // Override origin value. + base.origin = standardOrigin((_d = base.ssl) !== null && _d !== void 0 ? _d : false, base.origin); + const cryptoModule = base.cryptoModule; + if (cryptoModule) + delete base.cryptoModule; + const clientConfiguration = Object.assign(Object.assign({}, base), { _pnsdkSuffix: {}, _loggerManager: loggerManager, _instanceId: instanceId, _cryptoModule: undefined, _cipherKey: undefined, _setupCryptoModule: setupCryptoModule, get instanceId() { + if (base.useInstanceId) + return this._instanceId; + return undefined; + }, + getInstanceId() { + if (base.useInstanceId) + return this._instanceId; + return undefined; + }, + getUserId() { + return this.userId; + }, + setUserId(value) { + if (!value || typeof value !== 'string' || value.trim().length === 0) + throw new Error('Missing or invalid userId parameter. Provide a valid string userId'); + this.userId = value; + }, logger() { return this._loggerManager; }, @@ -5231,7 +5236,7 @@ if (payload) signatureInput += payload; } - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('RequestSignature', () => ({ messageType: 'text', message: `Request signature input:\n${signatureInput}`, })); @@ -5319,7 +5324,7 @@ delay = retryPolicy.getDelay(attempt, res); if (delay > 0) { attempt++; - this.logger.warn(this.constructor.name, `HTTP request retry #${attempt} in ${delay}ms.`); + this.logger.warn('PubNubMiddleware', `HTTP request retry #${attempt} in ${delay}ms.`); retryTimeout = setTimeout(() => trySendRequest(), delay); } else { @@ -5427,9 +5432,9 @@ constructor(logger, transport = 'fetch') { this.logger = logger; this.transport = transport; - logger.debug(this.constructor.name, `Create with configuration:\n - transport: ${transport}`); + logger.debug('WebTransport', `Create with configuration:\n - transport: ${transport}`); if (transport === 'fetch' && (!window || !window.fetch)) { - logger.warn(this.constructor.name, `'${transport}' not supported in this browser. Fallback to the 'xhr' transport.`); + logger.warn('WebTransport', `'${transport}' not supported in this browser. Fallback to the 'xhr' transport.`); this.transport = 'xhr'; } if (this.transport !== 'fetch') @@ -5439,12 +5444,12 @@ // Check whether `fetch` has been monkey patched or not. if (this.isFetchMonkeyPatched()) { WebTransport.originalFetch = WebTransport.getOriginalFetch(); - logger.warn(this.constructor.name, "Native Web Fetch API 'fetch' function monkey patched."); + logger.warn('WebTransport', "Native Web Fetch API 'fetch' function monkey patched."); if (!this.isFetchMonkeyPatched(WebTransport.originalFetch)) { - logger.info(this.constructor.name, "Use native Web Fetch API 'fetch' implementation from iframe as APM workaround."); + logger.info('WebTransport', "Use native Web Fetch API 'fetch' implementation from iframe as APM workaround."); } else { - logger.warn(this.constructor.name, 'Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation'); + logger.warn('WebTransport', 'Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation'); } } } @@ -5454,14 +5459,14 @@ abortController, abort: (reason) => { if (!abortController.signal.aborted) { - this.logger.trace(this.constructor.name, `On-demand request aborting: ${reason}`); + this.logger.trace('WebTransport', `On-demand request aborting: ${reason}`); abortController.abort(reason); } }, }; return [ this.webTransportRequestFromTransportRequest(req).then((request) => { - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('WebTransport', () => ({ messageType: 'network-request', message: req })); return this.sendRequest(request, cancellation) .then((response) => response.arrayBuffer().then((arrayBuffer) => [response, arrayBuffer])) .then((response) => { @@ -5471,7 +5476,7 @@ // Copy Headers object content into plain Record. requestHeaders.forEach((value, key) => (headers[key] = value.toLowerCase())); const transportResponse = { status, url: request.url, headers, body }; - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('WebTransport', () => ({ messageType: 'network-response', message: transportResponse, })); @@ -5483,7 +5488,7 @@ const errorMessage = (typeof error === 'string' ? error : error.message).toLowerCase(); let fetchError = typeof error === 'string' ? new Error(error) : error; if (errorMessage.includes('timeout')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('WebTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', @@ -5491,7 +5496,7 @@ })); } else if (errorMessage.includes('cancel') || errorMessage.includes('abort')) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('WebTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -5501,7 +5506,7 @@ fetchError.name = 'AbortError'; } else if (errorMessage.includes('network')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('WebTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', @@ -5509,7 +5514,7 @@ })); } else { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('WebTransport', () => ({ messageType: 'network-request', message: req, details: PubNubAPIError.create(fetchError).message, @@ -5664,14 +5669,14 @@ formData.append('file', new Blob([fileData], { type: 'application/octet-stream' }), file.name); } catch (toBufferError) { - this.logger.warn(this.constructor.name, () => ({ messageType: 'error', message: toBufferError })); + this.logger.warn('WebTransport', () => ({ messageType: 'error', message: toBufferError })); try { const fileData = yield file.toFileUri(); // @ts-expect-error React Native File Uri support. formData.append('file', fileData, file.name); } catch (toFileURLError) { - this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: toFileURLError })); + this.logger.error('WebTransport', () => ({ messageType: 'error', message: toFileURLError })); } } body = formData; @@ -5689,7 +5694,7 @@ }, }); body = yield new Response(bodyStream.pipeThrough(new CompressionStream('deflate'))).arrayBuffer(); - this.logger.trace(this.constructor.name, () => { + this.logger.trace('WebTransport', () => { const compressedSize = body.byteLength; const ratio = (compressedSize / initialBodySize).toFixed(2); return { @@ -6818,7 +6823,7 @@ */ constructor(config) { this.config = config; - config.logger().debug(this.constructor.name, () => ({ + config.logger().debug('DedupingManager', () => ({ messageType: 'object', message: { maximumCacheSize: config.maximumCacheSize }, details: 'Create with configuration:', @@ -6899,7 +6904,7 @@ this.subscribeCall = subscribeCall; this.heartbeatCall = heartbeatCall; this.leaveCall = leaveCall; - configuration.logger().trace(this.constructor.name, 'Create manager.'); + configuration.logger().trace('SubscriptionManager', 'Create manager.'); this.reconnectionManager = new ReconnectionManager(time); this.dedupingManager = new DedupingManager(this.configuration); this.heartbeatChannelGroups = {}; @@ -7181,7 +7186,7 @@ timetoken: this.currentTimetoken, region: this.region ? this.region : undefined, }; - this.configuration.logger().debug(this.constructor.name, () => { + this.configuration.logger().debug('SubscriptionManager', () => { const hashedEvents = messages.map((event) => { const pn_mfp = event.type === PubNubEventType.Message || event.type === PubNubEventType.Signal ? messageFingerprint(event.data.message) @@ -7193,7 +7198,7 @@ messages.forEach((message) => { if (dedupeOnSubscribe && 'message' in message.data && 'timetoken' in message.data) { if (this.dedupingManager.isDuplicate(message.data)) { - this.configuration.logger().warn(this.constructor.name, () => ({ + this.configuration.logger().warn('SubscriptionManager', () => ({ messageType: 'object', message: message.data, details: 'Duplicate message detected (skipped):', @@ -8027,11 +8032,11 @@ } transition(event) { if (!this._currentState) { - this.logger.error(this.constructor.name, 'Finite state machine is not started'); + this.logger.error('Engine', 'Finite state machine is not started'); throw new Error('Start the engine first'); } if (this._inTransition) { - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', message: event, details: 'Event engine in transition. Enqueue received event:', @@ -8041,7 +8046,7 @@ } else this._inTransition = true; - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', message: event, details: 'Event engine received event:', @@ -8053,14 +8058,14 @@ const transition = this._currentState.transition(this._currentContext, event); if (transition) { const [newState, newContext, effects] = transition; - this.logger.trace(this.constructor.name, `Exiting state: ${this._currentState.label}`); + this.logger.trace('Engine', `Exiting state: ${this._currentState.label}`); for (const effect of this._currentState.exitEffects) { this.notify({ type: 'invocationDispatched', invocation: effect(this._currentContext), }); } - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', details: `Entering '${newState.label}' state with context:`, message: newContext, @@ -8089,22 +8094,22 @@ invocation: effect(this._currentContext), }); } - this._inTransition = false; - // Check whether a pending task should be dequeued. - if (this._pendingEvents.length > 0) { - const nextEvent = this._pendingEvents.shift(); - if (nextEvent) { - this.logger.trace(this.constructor.name, () => ({ - messageType: 'object', - message: nextEvent, - details: 'De-queueing pending event:', - })); - this.transition(nextEvent); - } - } } else - this.logger.warn(this.constructor.name, `No transition from '${this._currentState.label}' found for event: ${event.type}`); + this.logger.warn('Engine', `No transition from '${this._currentState.label}' found for event: ${event.type}`); + this._inTransition = false; + // Check whether a pending task should be dequeued. + if (this._pendingEvents.length > 0) { + const nextEvent = this._pendingEvents.shift(); + if (nextEvent) { + this.logger.trace('Engine', () => ({ + messageType: 'object', + message: nextEvent, + details: 'De-queueing pending event:', + })); + this.transition(nextEvent); + } + } } } @@ -8131,7 +8136,7 @@ this.handlers.set(type, handlerCreator); } dispatch(invocation) { - this.logger.trace(this.constructor.name, `Process invocation: ${invocation.type}`); + this.logger.trace('Dispatcher', `Process invocation: ${invocation.type}`); if (invocation.type === 'CANCEL') { if (this.instances.has(invocation.payload)) { const instance = this.instances.get(invocation.payload); @@ -8142,11 +8147,11 @@ } const handlerCreator = this.handlers.get(invocation.type); if (!handlerCreator) { - this.logger.error(this.constructor.name, `Unhandled invocation '${invocation.type}'`); + this.logger.error('Dispatcher', `Unhandled invocation '${invocation.type}'`); throw new Error(`Unhandled invocation '${invocation.type}'`); } const instance = handlerCreator(invocation.payload, this.dependencies); - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Dispatcher', () => ({ messageType: 'object', details: 'Call invocation handler with parameters:', message: invocation.payload, @@ -8280,7 +8285,6 @@ } start() { this.asyncFunction(this.payload, this.abortSignal, this.dependencies).catch((error) => { - // console.log('Unhandled error:', error); // swallow the error }); } @@ -8438,9 +8442,10 @@ class PresenceEventEngineDispatcher extends Dispatcher { constructor(engine, dependencies) { super(dependencies, dependencies.config.logger()); - this.on(heartbeat.type, asyncHandler((payload_1, _1, _a) => __awaiter(this, [payload_1, _1, _a], void 0, function* (payload, _, { heartbeat, presenceState, config }) { + this.on(heartbeat.type, asyncHandler((payload_1, abortSignal_1, _a) => __awaiter(this, [payload_1, abortSignal_1, _a], void 0, function* (payload, abortSignal, { heartbeat, presenceState, config }) { + abortSignal.throwIfAborted(); try { - const result = yield heartbeat(Object.assign(Object.assign({ channels: payload.channels, channelGroups: payload.groups }, (config.maintainPresenceState && { state: presenceState })), { heartbeat: config.presenceTimeout })); + const result = yield heartbeat(Object.assign(Object.assign({ abortSignal: abortSignal, channels: payload.channels, channelGroups: payload.groups }, (config.maintainPresenceState && { state: presenceState })), { heartbeat: config.presenceTimeout })); engine.transition(heartbeatSuccess(200)); } catch (e) { @@ -8494,8 +8499,8 @@ */ const HeartbeatStoppedState = new State('HEARTBEAT_STOPPED'); HeartbeatStoppedState.on(joined.type, (context, event) => HeartbeatStoppedState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); HeartbeatStoppedState.on(left.type, (context, event) => HeartbeatStoppedState.with({ channels: context.channels.filter((channel) => !event.payload.channels.includes(channel)), @@ -8527,8 +8532,8 @@ groups: context.groups, })); HeartbeatCooldownState.on(joined.type, (context, event) => HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); HeartbeatCooldownState.on(left.type, (context, event) => HeartbeatingState.with({ channels: context.channels.filter((channel) => !event.payload.channels.includes(channel)), @@ -8556,8 +8561,8 @@ */ const HeartbeatFailedState = new State('HEARTBEAT_FAILED'); HeartbeatFailedState.on(joined.type, (context, event) => HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); HeartbeatFailedState.on(left.type, (context, event) => HeartbeatingState.with({ channels: context.channels.filter((channel) => !event.payload.channels.includes(channel)), @@ -8593,8 +8598,8 @@ emitStatus$1(Object.assign({}, event.payload)), ])); HeartbeatingState.on(joined.type, (context, event) => HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); HeartbeatingState.on(left.type, (context, event) => { return HeartbeatingState.with({ @@ -8650,7 +8655,7 @@ this.groups = []; this.engine = new Engine(dependencies.config.logger()); this.dispatcher = new PresenceEventEngineDispatcher(this.engine, dependencies); - dependencies.config.logger().debug(this.constructor.name, 'Create presence event engine.'); + dependencies.config.logger().debug('PresenceEventEngine', 'Create presence event engine.'); this._unsubscribeEngine = this.engine.subscribe((change) => { if (change.type === 'invocationDispatched') { this.dispatcher.dispatch(change.invocation); @@ -8659,8 +8664,11 @@ this.engine.start(HeartbeatInactiveState, undefined); } join({ channels, groups }) { - this.channels = [...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])]; - this.groups = [...this.groups, ...(groups !== null && groups !== void 0 ? groups : [])]; + this.channels = [...this.channels, ...(channels !== null && channels !== void 0 ? channels : []).filter((channel) => !this.channels.includes(channel))]; + this.groups = [...this.groups, ...(groups !== null && groups !== void 0 ? groups : []).filter((group) => !this.groups.includes(group))]; + // Don't make any transitions if there is no channels and groups. + if (this.channels.length === 0 && this.groups.length === 0) + return; this.engine.transition(joined(this.channels.slice(0), this.groups.slice(0))); } leave({ channels, groups }) { @@ -9245,7 +9253,7 @@ this.dependencies = dependencies; this.engine = new Engine(dependencies.config.logger()); this.dispatcher = new EventEngineDispatcher(this.engine, dependencies); - dependencies.config.logger().debug(this.constructor.name, 'Create subscribe event engine.'); + dependencies.config.logger().debug('EventEngine', 'Create subscribe event engine.'); this._unsubscribeEngine = this.engine.subscribe((change) => { if (change.type === 'invocationDispatched') { this.dispatcher.dispatch(change.invocation); @@ -9585,2587 +9593,2625 @@ } /** - * Get Presence State REST API module. - * - * @internal - */ - // endregion - /** - * Get `uuid` presence state request. + * SubscriptionCapable entity type. * * @internal */ - class GetPresenceStateRequest extends AbstractRequest { - constructor(parameters) { - var _a, _b; - var _c, _d; - super(); - this.parameters = parameters; - // Apply defaults. - (_a = (_c = this.parameters).channels) !== null && _a !== void 0 ? _a : (_c.channels = []); - (_b = (_d = this.parameters).channelGroups) !== null && _b !== void 0 ? _b : (_d.channelGroups = []); - } - operation() { - return RequestOperation$1.PNGetStateOperation; - } - validate() { - const { keySet: { subscribeKey }, channels, channelGroups, } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - const serviceResponse = this.deserializeResponse(response); - const { channels = [], channelGroups = [] } = this.parameters; - const state = { channels: {} }; - if (channels.length === 1 && channelGroups.length === 0) - state.channels[channels[0]] = serviceResponse.payload; - else - state.channels = serviceResponse.payload; - return state; - }); - } - get path() { - const { keySet: { subscribeKey }, uuid, channels, } = this.parameters; - return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}/uuid/${uuid}`; - } - get queryParameters() { - const { channelGroups } = this.parameters; - if (!channelGroups || channelGroups.length === 0) - return {}; - return { 'channel-group': channelGroups.join(',') }; - } - } + var SubscriptionType; + (function (SubscriptionType) { + /** + * Channel identifier, which is part of the URI path. + */ + SubscriptionType[SubscriptionType["Channel"] = 0] = "Channel"; + /** + * Channel group identifiers, which is part of the query parameters. + */ + SubscriptionType[SubscriptionType["ChannelGroup"] = 1] = "ChannelGroup"; + })(SubscriptionType || (SubscriptionType = {})); /** - * Set Presence State REST API module. + * User-provided channels and groups for subscription. * - * @internal - */ - // endregion - /** - * Set `uuid` presence state request. + * Object contains information about channels and groups for which real-time updates should be retrieved from the + * PubNub network. * * @internal */ - class SetPresenceStateRequest extends AbstractRequest { - constructor(parameters) { - super(); - this.parameters = parameters; - } - operation() { - return RequestOperation$1.PNSetStateOperation; + class SubscriptionInput { + /** + * Create a subscription input object. + * + * @param channels - List of channels which will be used with subscribe REST API to receive real-time updates. + * @param channelGroups - List of channel groups which will be used with subscribe REST API to receive real-time + * updates. + */ + constructor({ channels, channelGroups }) { + /** + * Whether the user input is empty or not. + */ + this.isEmpty = true; + this._channelGroups = new Set((channelGroups !== null && channelGroups !== void 0 ? channelGroups : []).filter((value) => value.length > 0)); + this._channels = new Set((channels !== null && channels !== void 0 ? channels : []).filter((value) => value.length > 0)); + this.isEmpty = this._channels.size === 0 && this._channelGroups.size === 0; } - validate() { - const { keySet: { subscribeKey }, state, channels = [], channelGroups = [], } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (!state) - return 'Missing State'; - if ((channels === null || channels === void 0 ? void 0 : channels.length) === 0 && (channelGroups === null || channelGroups === void 0 ? void 0 : channelGroups.length) === 0) - return 'Please provide a list of channels and/or channel-groups'; + /** + * Retrieve total length of subscription input. + * + * @returns Number of channels and groups in subscription input. + */ + get length() { + if (this.isEmpty) + return 0; + return this._channels.size + this._channelGroups.size; } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - return { state: this.deserializeResponse(response).payload }; - }); + /** + * Retrieve a list of user-provided channel names. + * + * @returns List of user-provided channel names. + */ + get channels() { + if (this.isEmpty) + return []; + return Array.from(this._channels); } - get path() { - const { keySet: { subscribeKey }, uuid, channels, } = this.parameters; - return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}/uuid/${encodeString(uuid)}/data`; + /** + * Retrieve a list of user-provided channel group names. + * + * @returns List of user-provided channel group names. + */ + get channelGroups() { + if (this.isEmpty) + return []; + return Array.from(this._channelGroups); } - get queryParameters() { - const { channelGroups, state } = this.parameters; - const query = { state: JSON.stringify(state) }; - if (channelGroups && channelGroups.length !== 0) - query['channel-group'] = channelGroups.join(','); - return query; + /** + * Check if the given name is contained in the channel or channel group. + * + * @param name - Containing the name to be checked. + * + * @returns `true` if the name is found in the channel or channel group, `false` otherwise. + */ + contains(name) { + if (this.isEmpty) + return false; + return this._channels.has(name) || this._channelGroups.has(name); } - } - - /** - * Announce heartbeat REST API module. - * - * @internal - */ - // endregion - /** - * Announce `uuid` presence request. - * - * @internal - */ - class HeartbeatRequest extends AbstractRequest { - constructor(parameters) { - super({ cancellable: true }); - this.parameters = parameters; + /** + * Create a new subscription input which will contain all channels and channel groups from both inputs. + * + * @param input - Another subscription input that should be used to aggregate data in new instance. + * + * @returns New subscription input instance with combined channels and channel groups. + */ + with(input) { + return new SubscriptionInput({ + channels: [...this._channels, ...input._channels], + channelGroups: [...this._channelGroups, ...input._channelGroups], + }); } - operation() { - return RequestOperation$1.PNHeartbeatOperation; + /** + * Create a new subscription input which will contain only channels and groups which not present in the input. + * + * @param input - Another subscription input which should be used to filter data in new instance. + * + * @returns New subscription input instance with filtered channels and channel groups. + */ + without(input) { + return new SubscriptionInput({ + channels: [...this._channels].filter((value) => !input._channels.has(value)), + channelGroups: [...this._channelGroups].filter((value) => !input._channelGroups.has(value)), + }); } - validate() { - const { keySet: { subscribeKey }, channels = [], channelGroups = [], } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (channels.length === 0 && channelGroups.length === 0) - return 'Please provide a list of channels and/or channel-groups'; + /** + * Add data from another subscription input to the receiver. + * + * @param input - Another subscription input whose data should be added to the receiver. + * + * @returns Receiver instance with updated channels and channel groups. + */ + add(input) { + if (input._channelGroups.size > 0) + this._channelGroups = new Set([...this._channelGroups, ...input._channelGroups]); + if (input._channels.size > 0) + this._channels = new Set([...this._channels, ...input._channels]); + this.isEmpty = this._channels.size === 0 && this._channelGroups.size === 0; + return this; } - parse(response) { - const _super = Object.create(null, { - parse: { get: () => super.parse } - }); - return __awaiter(this, void 0, void 0, function* () { - return _super.parse.call(this, response).then((_) => ({})); - }); + /** + * Remove data from another subscription input from the receiver. + * + * @param input - Another subscription input whose data should be removed from the receiver. + * + * @returns Receiver instance with updated channels and channel groups. + */ + remove(input) { + if (input._channelGroups.size > 0) + this._channelGroups = new Set([...this._channelGroups].filter((value) => !input._channelGroups.has(value))); + if (input._channels.size > 0) + this._channels = new Set([...this._channels].filter((value) => !input._channels.has(value))); + return this; } - get path() { - const { keySet: { subscribeKey }, channels, } = this.parameters; - return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}/heartbeat`; + /** + * Remove all data from subscription input. + * + * @returns Receiver instance with updated channels and channel groups. + */ + removeAll() { + this._channels.clear(); + this._channelGroups.clear(); + this.isEmpty = true; + return this; } - get queryParameters() { - const { channelGroups, state, heartbeat } = this.parameters; - const query = { heartbeat: `${heartbeat}` }; - if (channelGroups && channelGroups.length !== 0) - query['channel-group'] = channelGroups.join(','); - if (state) - query.state = JSON.stringify(state); - return query; + /** + * Serialize a subscription input to string. + * + * @returns Printable string representation of a subscription input. + */ + toString() { + return `SubscriptionInput { channels: [${this.channels.join(', ')}], channelGroups: [${this.channelGroups.join(', ')}], is empty: ${this.isEmpty ? 'true' : 'false'}} }`; } } + // endregion /** - * Announce leave REST API module. + * Subscription state object. * - * @internal - */ - // endregion - /** - * Announce user leave request. + * State object used across multiple subscription object clones. * * @internal */ - class PresenceLeaveRequest extends AbstractRequest { - constructor(parameters) { - super(); - this.parameters = parameters; - if (this.parameters.channelGroups) - this.parameters.channelGroups = Array.from(new Set(this.parameters.channelGroups)); - if (this.parameters.channels) - this.parameters.channels = Array.from(new Set(this.parameters.channels)); - } - operation() { - return RequestOperation$1.PNUnsubscribeOperation; - } - validate() { - const { keySet: { subscribeKey }, channels = [], channelGroups = [], } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (channels.length === 0 && channelGroups.length === 0) - return 'At least one `channel` or `channel group` should be provided.'; - } - parse(response) { - const _super = Object.create(null, { - parse: { get: () => super.parse } - }); - return __awaiter(this, void 0, void 0, function* () { - return _super.parse.call(this, response).then((_) => ({})); - }); + class SubscriptionBaseState { + /** + * Create a base subscription state object. + * + * @param client - PubNub client which will work with a subscription object. + * @param subscriptionInput - User's input to be used with subscribe REST API. + * @param options - Subscription behavior options. + * @param referenceTimetoken - High-precision timetoken of the moment when subscription was created for entity. + */ + constructor(client, subscriptionInput, options, referenceTimetoken) { + /** + * Whether a subscribable object subscribed or not. + */ + this._isSubscribed = false; + /** + * The list of references to all {@link SubscriptionBase} clones created for this reference. + */ + this.clones = {}; + /** + * List of a parent subscription state objects list. + * + * List is used to track usage of a subscription object in other subscription object sets. + * + * **Important:** Tracking is required to prevent unexpected unsubscriptions if an object still has a parent. + */ + this.parents = []; + /** + * Unique subscription object identifier. + */ + this._id = uuidGenerator.createUUID(); + this.referenceTimetoken = referenceTimetoken; + this.subscriptionInput = subscriptionInput; + this.options = options; + this.client = client; } - get path() { - var _a; - const { keySet: { subscribeKey }, channels, } = this.parameters; - return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames((_a = channels === null || channels === void 0 ? void 0 : channels.sort()) !== null && _a !== void 0 ? _a : [], ',')}/leave`; + /** + * Get unique subscription object identifier. + * + * @returns Unique subscription object identifier. + */ + get id() { + return this._id; } - get queryParameters() { - const { channelGroups } = this.parameters; - if (!channelGroups || channelGroups.length === 0) - return {}; - return { 'channel-group': channelGroups.sort().join(',') }; + /** + * Check whether a subscription object is the last clone or not. + * + * @returns `true` if a subscription object is the last clone. + */ + get isLastClone() { + return Object.keys(this.clones).length === 1; } - } - - /** - * `uuid` presence REST API module. - * - * @internal - */ - // endregion - /** - * Get `uuid` presence request. - * - * @internal - */ - class WhereNowRequest extends AbstractRequest { - constructor(parameters) { - super(); - this.parameters = parameters; + /** + * Get whether a subscribable object subscribed or not. + * + * **Warning:** This method shouldn't be overridden by {@link SubscriptionSet}. + * + * @returns Whether a subscribable object subscribed or not. + */ + get isSubscribed() { + if (this._isSubscribed) + return true; + // Checking whether any of "parents" is subscribed. + return this.parents.length > 0 && this.parents.some((state) => state.isSubscribed); } - operation() { - return RequestOperation$1.PNWhereNowOperation; + /** + * Update active subscription state. + * + * @param value - New subscription state. + */ + set isSubscribed(value) { + if (this.isSubscribed === value) + return; + this._isSubscribed = value; } - validate() { - if (!this.parameters.keySet.subscribeKey) - return 'Missing Subscribe Key'; + /** + * Add a parent subscription state object to mark the linkage. + * + * @param parent - Parent subscription state object. + * + * @internal + */ + addParentState(parent) { + if (!this.parents.includes(parent)) + this.parents.push(parent); } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - const serviceResponse = this.deserializeResponse(response); - if (!serviceResponse.payload) - return { channels: [] }; - return { channels: serviceResponse.payload.channels }; - }); + /** + * Remove a parent subscription state object. + * + * @param parent - Parent object for which linkage should be broken. + * + * @internal + */ + removeParentState(parent) { + const parentStateIndex = this.parents.indexOf(parent); + if (parentStateIndex !== -1) + this.parents.splice(parentStateIndex, 1); } - get path() { - const { keySet: { subscribeKey }, uuid, } = this.parameters; - return `/v2/presence/sub-key/${subscribeKey}/uuid/${encodeString(uuid)}`; + /** + * Store a clone of a {@link SubscriptionBase} instance with a given instance ID. + * + * @param id - The instance ID to associate with clone. + * @param instance - Reference to the subscription instance to store as a clone. + */ + storeClone(id, instance) { + if (!this.clones[id]) + this.clones[id] = instance; } } - - /** - * Channels / channel groups presence REST API module. - * - * @internal - */ - // -------------------------------------------------------- - // ----------------------- Defaults ----------------------- - // -------------------------------------------------------- - // region Defaults /** - * Whether `uuid` should be included in response or not. - */ - const INCLUDE_UUID$1 = true; - /** - * Whether state associated with `uuid` should be included in response or not. - */ - const INCLUDE_STATE = false; - // endregion - /** - * Channel presence request. + * Base subscribe object. * - * @internal + * Implementation of base functionality used by {@link SubscriptionObject Subscription} and {@link SubscriptionSet}. */ - class HereNowRequest extends AbstractRequest { - constructor(parameters) { - var _a, _b, _c; - var _d, _e, _f; - super(); - this.parameters = parameters; - // Apply defaults. - (_a = (_d = this.parameters).queryParameters) !== null && _a !== void 0 ? _a : (_d.queryParameters = {}); - (_b = (_e = this.parameters).includeUUIDs) !== null && _b !== void 0 ? _b : (_e.includeUUIDs = INCLUDE_UUID$1); - (_c = (_f = this.parameters).includeState) !== null && _c !== void 0 ? _c : (_f.includeState = INCLUDE_STATE); + class SubscriptionBase { + /** + * Create a subscription object from the state. + * + * @param state - Subscription state object. + * + * @internal + */ + constructor(state) { + /** + * Unique subscription object identifier. + * + * @internal + */ + this.id = uuidGenerator.createUUID(); + /** + * Event emitter, which will notify listeners about updates received for channels / groups. + * + * @internal + */ + this.eventDispatcher = new EventDispatcher(); + this._state = state; } - operation() { - const { channels = [], channelGroups = [] } = this.parameters; - return channels.length === 0 && channelGroups.length === 0 - ? RequestOperation$1.PNGlobalHereNowOperation - : RequestOperation$1.PNHereNowOperation; + /** + * Retrieve subscription type. + * + * There is two types: + * - Subscription + * - SubscriptionSet + * + * @returns One of subscription types. + * + * @internal + */ + get subscriptionType() { + return 'Subscription'; } - validate() { - if (!this.parameters.keySet.subscribeKey) - return 'Missing Subscribe Key'; + /** + * Subscription state. + * + * @returns Subscription state object. + * + * @internal + */ + get state() { + return this._state; } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - var _a, _b; - const serviceResponse = this.deserializeResponse(response); - // Extract general presence information. - const totalChannels = 'occupancy' in serviceResponse ? 1 : serviceResponse.payload.total_channels; - const totalOccupancy = 'occupancy' in serviceResponse ? serviceResponse.occupancy : serviceResponse.payload.total_occupancy; - const channelsPresence = {}; - let channels = {}; - // Remap single channel presence to multiple channels presence response. - if ('occupancy' in serviceResponse) { - const channel = this.parameters.channels[0]; - channels[channel] = { uuids: (_a = serviceResponse.uuids) !== null && _a !== void 0 ? _a : [], occupancy: totalOccupancy }; - } - else - channels = (_b = serviceResponse.payload.channels) !== null && _b !== void 0 ? _b : {}; - Object.keys(channels).forEach((channel) => { - const channelEntry = channels[channel]; - channelsPresence[channel] = { - occupants: this.parameters.includeUUIDs - ? channelEntry.uuids.map((uuid) => { - if (typeof uuid === 'string') - return { uuid, state: null }; - return uuid; - }) - : [], - name: channel, - occupancy: channelEntry.occupancy, - }; - }); - return { - totalChannels, - totalOccupancy, - channels: channelsPresence, - }; - }); - } - get path() { - const { keySet: { subscribeKey }, channels, channelGroups, } = this.parameters; - let path = `/v2/presence/sub-key/${subscribeKey}`; - if ((channels && channels.length > 0) || (channelGroups && channelGroups.length > 0)) - path += `/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}`; - return path; - } - get queryParameters() { - const { channelGroups, includeUUIDs, includeState, queryParameters } = this.parameters; - return Object.assign(Object.assign(Object.assign(Object.assign({}, (!includeUUIDs ? { disable_uuids: '1' } : {})), ((includeState !== null && includeState !== void 0 ? includeState : false) ? { state: '1' } : {})), (channelGroups && channelGroups.length > 0 ? { 'channel-group': channelGroups.join(',') } : {})), queryParameters); + /** + * Get a list of channels which is used for subscription. + * + * @returns List of channel names. + */ + get channels() { + return this.state.subscriptionInput.channels.slice(0); } - } - - /** - * Delete messages REST API module. - * - * @internal - */ - // endregion - /** - * Delete messages from channel history. - * - * @internal - */ - class DeleteMessageRequest extends AbstractRequest { - constructor(parameters) { - super({ method: TransportMethod.DELETE }); - this.parameters = parameters; + /** + * Get a list of channel groups which is used for subscription. + * + * @returns List of channel group names. + */ + get channelGroups() { + return this.state.subscriptionInput.channelGroups.slice(0); } - operation() { - return RequestOperation$1.PNDeleteMessagesOperation; + // -------------------------------------------------------- + // -------------------- Event emitter --------------------- + // -------------------------------------------------------- + // region Event emitter + /** + * Set a new message handler. + * + * @param listener - Listener function, which will be called each time when a new message + * is received from the real-time network. + */ + set onMessage(listener) { + this.eventDispatcher.onMessage = listener; } - validate() { - if (!this.parameters.keySet.subscribeKey) - return 'Missing Subscribe Key'; - if (!this.parameters.channel) - return 'Missing channel'; + /** + * Set a new presence events handler. + * + * @param listener - Listener function, which will be called each time when a new + * presence event is received from the real-time network. + */ + set onPresence(listener) { + this.eventDispatcher.onPresence = listener; } - parse(response) { - const _super = Object.create(null, { - parse: { get: () => super.parse } - }); - return __awaiter(this, void 0, void 0, function* () { - return _super.parse.call(this, response).then((_) => ({})); - }); + /** + * Set a new signal handler. + * + * @param listener - Listener function, which will be called each time when a new signal + * is received from the real-time network. + */ + set onSignal(listener) { + this.eventDispatcher.onSignal = listener; } - get path() { - const { keySet: { subscribeKey }, channel, } = this.parameters; - return `/v3/history/sub-key/${subscribeKey}/channel/${encodeString(channel)}`; + /** + * Set a new app context event handler. + * + * @param listener - Listener function, which will be called each time when a new + * app context event is received from the real-time network. + */ + set onObjects(listener) { + this.eventDispatcher.onObjects = listener; } - get queryParameters() { - const { start, end } = this.parameters; - return Object.assign(Object.assign({}, (start ? { start } : {})), (end ? { end } : {})); + /** + * Set a new message reaction event handler. + * + * @param listener - Listener function, which will be called each time when a + * new message reaction event is received from the real-time network. + */ + set onMessageAction(listener) { + this.eventDispatcher.onMessageAction = listener; } - } - - /** - * Messages count REST API module. - * - * @internal - */ - // endregion - /** - * Count messages request. - * - * @internal - */ - class MessageCountRequest extends AbstractRequest { - constructor(parameters) { - super(); - this.parameters = parameters; + /** + * Set a new file handler. + * + * @param listener - Listener function, which will be called each time when a new file + * is received from the real-time network. + */ + set onFile(listener) { + this.eventDispatcher.onFile = listener; } - operation() { - return RequestOperation$1.PNMessageCounts; + /** + * Set events handler. + * + * @param listener - Events listener configuration object, which lets specify handlers for multiple + * types of events. + */ + addListener(listener) { + this.eventDispatcher.addListener(listener); } - validate() { - const { keySet: { subscribeKey }, channels, timetoken, channelTimetokens, } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (!channels) - return 'Missing channels'; - if (timetoken && channelTimetokens) - return '`timetoken` and `channelTimetokens` are incompatible together'; - if (!timetoken && !channelTimetokens) - return '`timetoken` or `channelTimetokens` need to be set'; - if (channelTimetokens && channelTimetokens.length > 1 && channelTimetokens.length !== channels.length) - return 'Length of `channelTimetokens` and `channels` do not match'; + /** + * Remove events handler. + * + * @param listener - Event listener configuration, which should be removed from the list of notified + * listeners. **Important:** Should be the same object which has been passed to the {@link addListener}. + */ + removeListener(listener) { + this.eventDispatcher.removeListener(listener); } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - return { channels: this.deserializeResponse(response).channels }; - }); + /** + * Remove all events listeners. + */ + removeAllListeners() { + this.eventDispatcher.removeAllListeners(); } - get path() { - return `/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${encodeNames(this.parameters.channels)}`; + /** + * Dispatch received a real-time update. + * + * @param cursor - A time cursor for the next portion of events. + * @param event - A real-time event from multiplexed subscription. + * + * @return `true` if receiver has consumed event. + * + * @internal + */ + handleEvent(cursor, event) { + var _a; + if (!this.state.cursor || cursor > this.state.cursor) + this.state.cursor = cursor; + // Check whether this is an old `old` event and it should be ignored or not. + if (this.state.referenceTimetoken && event.data.timetoken < this.state.referenceTimetoken) { + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Event timetoken (${event.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`, + })); + return; + } + // Don't pass events which are filtered out by the user-provided function. + if (((_a = this.state.options) === null || _a === void 0 ? void 0 : _a.filter) && !this.state.options.filter(event)) { + this.state.client.logger.trace(this.subscriptionType, `Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`); + return; + } + const clones = Object.values(this.state.clones); + if (clones.length > 0) { + this.state.client.logger.trace(this.subscriptionType, `Notify ${this.id} subscription object clones (count: ${clones.length}) about received event.`); + } + clones.forEach((subscription) => subscription.eventDispatcher.handleEvent(event)); } - get queryParameters() { - let { channelTimetokens } = this.parameters; - if (this.parameters.timetoken) - channelTimetokens = [this.parameters.timetoken]; - return Object.assign(Object.assign({}, (channelTimetokens.length === 1 ? { timetoken: channelTimetokens[0] } : {})), (channelTimetokens.length > 1 ? { channelsTimetoken: channelTimetokens.join(',') } : {})); + /** + * Graceful object destruction. + * + * This is an instance destructor, which will properly deinitialize it: + * - remove and unset all listeners, + * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). + * + * **Important:** {@link SubscriptionBase#dispose dispose} won't have any effect if a subscription object is part of + * set. To gracefully dispose an object, it should be removed from the set using + * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of + * {@link SubscriptionBase#dispose dispose} not required. + * + * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. + */ + dispose() { + const keys = Object.keys(this.state.clones); + if (keys.length > 1) { + this.state.client.logger.debug(this.subscriptionType, `Remove subscription object clone on dispose: ${this.id}`); + delete this.state.clones[this.id]; + } + else if (keys.length === 1 && this.state.clones[this.id]) { + this.state.client.logger.debug(this.subscriptionType, `Unsubscribe subscription object on dispose: ${this.id}`); + this.unsubscribe(); + } } - } - - /** - * Get history REST API module. - * - * @internal - */ - // -------------------------------------------------------- - // ---------------------- Defaults ------------------------ - // -------------------------------------------------------- - // region Defaults - /** - * Whether verbose logging enabled or not. - */ - const LOG_VERBOSITY$1 = false; - /** - * Whether associated message metadata should be returned or not. - */ - const INCLUDE_METADATA = false; - /** - * Whether timetokens should be returned as strings by default or not. - */ - const STRINGIFY_TIMETOKENS$1 = false; - /** - * Default and maximum number of messages which should be returned. - */ - const MESSAGES_COUNT = 100; - // endregion - /** - * Get single channel messages request. - * - * @internal - */ - class GetHistoryRequest extends AbstractRequest { - constructor(parameters) { - var _a, _b, _c; - super(); - this.parameters = parameters; - // Apply defaults. - if (parameters.count) - parameters.count = Math.min(parameters.count, MESSAGES_COUNT); - else - parameters.count = MESSAGES_COUNT; - (_a = parameters.stringifiedTimeToken) !== null && _a !== void 0 ? _a : (parameters.stringifiedTimeToken = STRINGIFY_TIMETOKENS$1); - (_b = parameters.includeMeta) !== null && _b !== void 0 ? _b : (parameters.includeMeta = INCLUDE_METADATA); - (_c = parameters.logVerbosity) !== null && _c !== void 0 ? _c : (parameters.logVerbosity = LOG_VERBOSITY$1); - } - operation() { - return RequestOperation$1.PNHistoryOperation; - } - validate() { - if (!this.parameters.keySet.subscribeKey) - return 'Missing Subscribe Key'; - if (!this.parameters.channel) - return 'Missing channel'; + /** + * Invalidate subscription object. + * + * Clean up resources used by a subscription object. + * + * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. + * + * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. + * + * @internal + */ + invalidate(forDestroy = false) { + this.state._isSubscribed = false; + if (forDestroy) { + delete this.state.clones[this.id]; + if (Object.keys(this.state.clones).length === 0) { + this.state.client.logger.trace(this.subscriptionType, 'Last clone removed. Reset shared subscription state.'); + this.state.subscriptionInput.removeAll(); + this.state.parents = []; + } + } } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - const serviceResponse = this.deserializeResponse(response); - const messages = serviceResponse[0]; - const startTimeToken = serviceResponse[1]; - const endTimeToken = serviceResponse[2]; - // Handle malformed get history response. - if (!Array.isArray(messages)) - return { messages: [], startTimeToken, endTimeToken }; - return { - messages: messages.map((payload) => { - const processedPayload = this.processPayload(payload.message); - const item = { - entry: processedPayload.payload, - timetoken: payload.timetoken, - }; - if (processedPayload.error) - item.error = processedPayload.error; - if (payload.meta) - item.meta = payload.meta; - return item; - }), - startTimeToken, - endTimeToken, - }; + /** + * Start receiving real-time updates. + * + * @param parameters - Additional subscription configuration options which should be used + * for request. + */ + subscribe(parameters) { + if (this.state.isSubscribed) { + this.state.client.logger.trace(this.subscriptionType, 'Already subscribed. Ignoring subscribe request.'); + return; + } + this.state.client.logger.debug(this.subscriptionType, () => { + if (!parameters) + return { messageType: 'text', message: 'Subscribe' }; + return { messageType: 'object', message: parameters, details: 'Subscribe with parameters:' }; }); + this.state.isSubscribed = true; + this.updateSubscription({ subscribing: true, timetoken: parameters === null || parameters === void 0 ? void 0 : parameters.timetoken }); } - get path() { - const { keySet: { subscribeKey }, channel, } = this.parameters; - return `/v2/history/sub-key/${subscribeKey}/channel/${encodeString(channel)}`; - } - get queryParameters() { - const { start, end, reverse, count, stringifiedTimeToken, includeMeta } = this.parameters; - return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ count: count, include_token: 'true' }, (start ? { start } : {})), (end ? { end } : {})), (stringifiedTimeToken ? { string_message_token: 'true' } : {})), (reverse !== undefined && reverse !== null ? { reverse: reverse.toString() } : {})), (includeMeta ? { include_meta: 'true' } : {})); + /** + * Stop real-time events processing. + * + * **Important:** {@link SubscriptionBase#unsubscribe unsubscribe} won't have any effect if a subscription object + * is part of active (subscribed) set. To unsubscribe an object, it should be removed from the set using + * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of + * {@link SubscriptionBase#unsubscribe unsubscribe} not required. + * + * **Note:** Unsubscribed instance won't call the dispatcher to deliver updates to the listeners. + */ + unsubscribe() { + // Check whether an instance-level subscription flag not set or parent has active subscription. + if (!this.state._isSubscribed || this.state.isSubscribed) { + // Warn if a user tries to unsubscribe using specific subscription which subscribed as part of a subscription set. + if (!this.state._isSubscribed && this.state.parents.length > 0 && this.state.isSubscribed) { + this.state.client.logger.warn(this.subscriptionType, () => ({ + messageType: 'object', + details: 'Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:', + message: this.state.parents.filter((subscriptionSet) => subscriptionSet.isSubscribed), + })); + return; + } + else if (!this.state._isSubscribed) { + this.state.client.logger.trace(this.subscriptionType, 'Not subscribed. Ignoring unsubscribe request.'); + return; + } + } + this.state.client.logger.debug(this.subscriptionType, 'Unsubscribe'); + this.state.isSubscribed = false; + delete this.state.cursor; + this.updateSubscription({ subscribing: false }); } - processPayload(payload) { - const { crypto, logVerbosity } = this.parameters; - if (!crypto || typeof payload !== 'string') - return { payload }; - let decryptedPayload; - let error; - try { - const decryptedData = crypto.decrypt(payload); - decryptedPayload = - decryptedData instanceof ArrayBuffer - ? JSON.parse(GetHistoryRequest.decoder.decode(decryptedData)) - : decryptedData; + /** + * Update channels and groups used by subscription loop. + * + * @param parameters - Subscription loop update parameters. + * @param parameters.subscribing - Whether subscription updates as part of subscription or unsubscription. + * @param [parameters.timetoken] - Subscription catch-up timetoken. + * @param [parameters.subscriptions] - List of subscriptions which should be used to modify a subscription loop + * object. + * + * @internal + */ + updateSubscription(parameters) { + var _a, _b; + if (parameters === null || parameters === void 0 ? void 0 : parameters.timetoken) { + if (((_a = this.state.cursor) === null || _a === void 0 ? void 0 : _a.timetoken) && ((_b = this.state.cursor) === null || _b === void 0 ? void 0 : _b.timetoken) !== '0') { + if (parameters.timetoken !== '0' && parameters.timetoken > this.state.cursor.timetoken) + this.state.cursor.timetoken = parameters.timetoken; + } + else + this.state.cursor = { timetoken: parameters.timetoken }; } - catch (err) { - if (logVerbosity) - console.log(`decryption error`, err.message); - decryptedPayload = payload; - error = `Error while decrypting message content: ${err.message}`; + const subscriptions = parameters.subscriptions && parameters.subscriptions.length > 0 ? parameters.subscriptions : undefined; + if (parameters.subscribing) { + this.register(Object.assign(Object.assign({}, (parameters.timetoken ? { cursor: this.state.cursor } : {})), (subscriptions ? { subscriptions } : {}))); } - return { - payload: decryptedPayload, - error, - }; + else + this.unregister(subscriptions); } } - // endregion - // -------------------------------------------------------- - // -------------------- Fetch Messages -------------------- - // -------------------------------------------------------- - // region Fetch Messages /** - * PubNub-defined message type. + * {@link SubscriptionSet} state object. * - * Types of messages which can be retrieved with fetch messages REST API. + * State object used across multiple {@link SubscriptionSet} object clones. + * + * @internal */ - var PubNubMessageType; - (function (PubNubMessageType) { + class SubscriptionSetState extends SubscriptionBaseState { /** - * Regular message. + * Create a subscription state object. + * + * @param parameters - State configuration options + * @param parameters.client - PubNub client which will work with a subscription object. + * @param parameters.subscriptions - List of subscriptions managed by set. + * @param [parameters.options] - Subscription behavior options. */ - PubNubMessageType[PubNubMessageType["Message"] = -1] = "Message"; + constructor(parameters) { + const subscriptionInput = new SubscriptionInput({}); + parameters.subscriptions.forEach((subscription) => subscriptionInput.add(subscription.state.subscriptionInput)); + super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); + this.subscriptions = parameters.subscriptions; + } /** - * File message. + * Retrieve subscription type. + * + * There is two types: + * - Subscription + * - SubscriptionSet + * + * @returns One of subscription types. + * + * @internal */ - PubNubMessageType[PubNubMessageType["Files"] = 4] = "Files"; - })(PubNubMessageType || (PubNubMessageType = {})); - // endregion - - /** - * Fetch messages REST API module. - * - * @internal - */ - // -------------------------------------------------------- - // ---------------------- Defaults ------------------------ - // -------------------------------------------------------- - // region Defaults - /** - * Whether verbose logging enabled or not. - */ - const LOG_VERBOSITY = false; - /** - * Whether message type should be returned or not. - */ - const INCLUDE_MESSAGE_TYPE = true; - /** - * Whether timetokens should be returned as strings by default or not. - */ - const STRINGIFY_TIMETOKENS = false; - /** - * Whether message publisher `uuid` should be returned or not. - */ - const INCLUDE_UUID = true; - /** - * Default number of messages which can be returned for single channel, and it is maximum as well. - */ - const SINGLE_CHANNEL_MESSAGES_COUNT = 100; - /** - * Default number of messages which can be returned for multiple channels or when fetched - * message actions. - */ - const MULTIPLE_CHANNELS_MESSAGES_COUNT = 25; - // endregion + get subscriptionType() { + return 'SubscriptionSet'; + } + /** + * Add a single subscription object to the set. + * + * @param subscription - Another entity's subscription object, which should be added. + */ + addSubscription(subscription) { + if (this.subscriptions.includes(subscription)) + return; + subscription.state.addParentState(this); + this.subscriptions.push(subscription); + // Update subscription input. + this.subscriptionInput.add(subscription.state.subscriptionInput); + } + /** + * Remove a single subscription object from the set. + * + * @param subscription - Another entity's subscription object, which should be removed. + * @param clone - Whether a target subscription is a clone. + */ + removeSubscription(subscription, clone) { + const index = this.subscriptions.indexOf(subscription); + if (index === -1) + return; + this.subscriptions.splice(index, 1); + if (!clone) + subscription.state.removeParentState(this); + // Update subscription input. + this.subscriptionInput.remove(subscription.state.subscriptionInput); + } + /** + * Remove any registered subscription object. + */ + removeAllSubscriptions() { + this.subscriptions.forEach((subscription) => subscription.state.removeParentState(this)); + this.subscriptions.splice(0, this.subscriptions.length); + this.subscriptionInput.removeAll(); + } + } /** - * Fetch messages from channels request. + * Multiple entities subscription set object which can be used to receive and handle real-time + * updates. * - * @internal + * Subscription set object represents a collection of per-entity subscription objects and allows + * processing them at once for subscription loop and events handling. */ - class FetchMessagesRequest extends AbstractRequest { + class SubscriptionSet extends SubscriptionBase { + /** + * Create entities' subscription set object. + * + * Subscription set object represents a collection of per-entity subscription objects and allows + * processing them at once for subscription loop and events handling. + * + * @param parameters - Subscription set object configuration. + * + * @returns Ready to use entities' subscription set object. + * + * @internal + */ constructor(parameters) { - var _a, _b, _c, _d, _e; - super(); - this.parameters = parameters; - // Apply defaults. - const includeMessageActions = (_a = parameters.includeMessageActions) !== null && _a !== void 0 ? _a : false; - const defaultCount = parameters.channels.length > 1 || includeMessageActions - ? MULTIPLE_CHANNELS_MESSAGES_COUNT - : SINGLE_CHANNEL_MESSAGES_COUNT; - if (!parameters.count) - parameters.count = defaultCount; - else - parameters.count = Math.min(parameters.count, defaultCount); - if (parameters.includeUuid) - parameters.includeUUID = parameters.includeUuid; - else - (_b = parameters.includeUUID) !== null && _b !== void 0 ? _b : (parameters.includeUUID = INCLUDE_UUID); - (_c = parameters.stringifiedTimeToken) !== null && _c !== void 0 ? _c : (parameters.stringifiedTimeToken = STRINGIFY_TIMETOKENS); - (_d = parameters.includeMessageType) !== null && _d !== void 0 ? _d : (parameters.includeMessageType = INCLUDE_MESSAGE_TYPE); - (_e = parameters.logVerbosity) !== null && _e !== void 0 ? _e : (parameters.logVerbosity = LOG_VERBOSITY); - } - operation() { - return RequestOperation$1.PNFetchMessagesOperation; - } - validate() { - const { keySet: { subscribeKey }, channels, includeMessageActions, } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (!channels) - return 'Missing channels'; - if (includeMessageActions !== undefined && includeMessageActions && channels.length > 1) - return ('History can return actions data for a single channel only. Either pass a single channel ' + - 'or disable the includeMessageActions flag.'); - } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - var _a; - const serviceResponse = this.deserializeResponse(response); - const responseChannels = (_a = serviceResponse.channels) !== null && _a !== void 0 ? _a : {}; - const channels = {}; - Object.keys(responseChannels).forEach((channel) => { - // Map service response to expected data object type structure. - channels[channel] = responseChannels[channel].map((payload) => { - // `null` message type means regular message. - if (payload.message_type === null) - payload.message_type = PubNubMessageType.Message; - const processedPayload = this.processPayload(channel, payload); - const item = Object.assign(Object.assign({ channel, timetoken: payload.timetoken, message: processedPayload.payload, messageType: payload.message_type }, (payload.custom_message_type ? { customMessageType: payload.custom_message_type } : {})), { uuid: payload.uuid }); - if (payload.actions) { - const itemWithActions = item; - itemWithActions.actions = payload.actions; - // Backward compatibility for existing users. - // TODO: Remove in next release. - itemWithActions.data = payload.actions; - } - if (payload.meta) - item.meta = payload.meta; - if (processedPayload.error) - item.error = processedPayload.error; - return item; - }); - }); - if (serviceResponse.more) - return { channels, more: serviceResponse.more }; - return { channels }; - }); + let state; + if ('client' in parameters) { + let subscriptions = []; + if (!parameters.subscriptions && parameters.entities) { + parameters.entities.forEach((entity) => subscriptions.push(entity.subscription(parameters.options))); + } + else if (parameters.subscriptions) + subscriptions = parameters.subscriptions; + state = new SubscriptionSetState({ client: parameters.client, subscriptions, options: parameters.options }); + subscriptions.forEach((subscription) => subscription.state.addParentState(state)); + state.client.logger.debug('SubscriptionSet', () => ({ + messageType: 'object', + details: 'Create subscription set with parameters:', + message: Object.assign({ subscriptions: state.subscriptions }, (parameters.options ? parameters.options : {})), + })); + } + else { + state = parameters.state; + state.client.logger.debug('SubscriptionSet', 'Create subscription set clone'); + } + super(state); + this.state.storeClone(this.id, this); + // Update a parent sets list for original set subscriptions. + state.subscriptions.forEach((subscription) => subscription.addParentSet(this)); } - get path() { - const { keySet: { subscribeKey }, channels, includeMessageActions, } = this.parameters; - const endpoint = !includeMessageActions ? 'history' : 'history-with-actions'; - return `/v3/${endpoint}/sub-key/${subscribeKey}/channel/${encodeNames(channels)}`; + /** + * Get a {@link SubscriptionSet} object state. + * + * @returns: {@link SubscriptionSet} object state. + * + * @internal + */ + get state() { + return super.state; } - get queryParameters() { - const { start, end, count, includeCustomMessageType, includeMessageType, includeMeta, includeUUID, stringifiedTimeToken, } = this.parameters; - return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ max: count }, (start ? { start } : {})), (end ? { end } : {})), (stringifiedTimeToken ? { string_message_token: 'true' } : {})), (includeMeta !== undefined && includeMeta ? { include_meta: 'true' } : {})), (includeUUID ? { include_uuid: 'true' } : {})), (includeCustomMessageType !== undefined && includeCustomMessageType !== null - ? { include_custom_message_type: includeCustomMessageType ? 'true' : 'false' } - : {})), (includeMessageType ? { include_message_type: 'true' } : {})); + /** + * Get a list of entities' subscription objects registered in a subscription set. + * + * @returns Entities' subscription objects list. + */ + get subscriptions() { + return this.state.subscriptions.slice(0); } + // -------------------------------------------------------- + // -------------------- Event handler --------------------- + // -------------------------------------------------------- + // region Event handler /** - * Parse single channel data entry. + * Dispatch received a real-time update. * - * @param channel - Channel for which {@link payload} should be processed. - * @param payload - Source payload which should be processed and parsed to expected type. + * @param cursor - A time cursor for the next portion of events. + * @param event - A real-time event from multiplexed subscription. * - * @returns + * @return `true` if receiver has consumed event. + * + * @internal */ - processPayload(channel, payload) { - const { crypto, logVerbosity } = this.parameters; - if (!crypto || typeof payload.message !== 'string') - return { payload: payload.message }; - let decryptedPayload; - let error; - try { - const decryptedData = crypto.decrypt(payload.message); - decryptedPayload = - decryptedData instanceof ArrayBuffer - ? JSON.parse(FetchMessagesRequest.decoder.decode(decryptedData)) - : decryptedData; - } - catch (err) { - if (logVerbosity) - console.log(`decryption error`, err.message); - decryptedPayload = payload.message; - error = `Error while decrypting message content: ${err.message}`; + handleEvent(cursor, event) { + var _a; + // Check whether an event is not designated for this subscription set. + if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) + return; + // Check whether `event` can be processed or not. + if (!this.state._isSubscribed) { + this.state.client.logger.trace(this.subscriptionType, `Subscription set ${this.id} is not subscribed. Ignoring event.`); + return; } - if (!error && - decryptedPayload && - payload.message_type == PubNubMessageType.Files && - typeof decryptedPayload === 'object' && - this.isFileMessage(decryptedPayload)) { - const fileMessage = decryptedPayload; - return { - payload: { - message: fileMessage.message, - file: Object.assign(Object.assign({}, fileMessage.file), { url: this.parameters.getFileUrl({ channel, id: fileMessage.file.id, name: fileMessage.file.name }) }), - }, - error, - }; + super.handleEvent(cursor, event); + if (this.state.subscriptions.length > 0) { + this.state.client.logger.trace(this.subscriptionType, `Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`); } - return { payload: decryptedPayload, error }; + this.state.subscriptions.forEach((subscription) => subscription.handleEvent(cursor, event)); } + // endregion /** - * Check whether `payload` potentially represents file message. + User-provided subscription input associated with this {@link SubscriptionSet} object. * - * @param payload - Fetched message payload. + * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). * - * @returns `true` if payload can be {@link History#FileMessage|FileMessage}. + * @returns Subscription input object. + * + * @internal */ - isFileMessage(payload) { - return payload.file !== undefined; - } - } - - /** - * Get Message Actions REST API module. - * - * @internal - */ - // endregion - /** - * Fetch channel message actions request. - * - * @internal - */ - class GetMessageActionsRequest extends AbstractRequest { - constructor(parameters) { - super(); - this.parameters = parameters; + subscriptionInput(forUnsubscribe = false) { + let subscriptionInput = this.state.subscriptionInput; + this.state.subscriptions.forEach((subscription) => { + if (forUnsubscribe && subscription.state.entity.subscriptionsCount > 0) + subscriptionInput = subscriptionInput.without(subscription.state.subscriptionInput); + }); + return subscriptionInput; } - operation() { - return RequestOperation$1.PNGetMessageActionsOperation; + /** + * Make a bare copy of the {@link SubscriptionSet} object. + * + * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as + * the source object. + * + * @returns Bare copy of a {@link SubscriptionSet} object. + */ + cloneEmpty() { + return new SubscriptionSet({ state: this.state }); } - validate() { - if (!this.parameters.keySet.subscribeKey) - return 'Missing Subscribe Key'; - if (!this.parameters.channel) - return 'Missing message channel'; + /** + * Graceful {@link SubscriptionSet} destruction. + * + * This is an instance destructor, which will properly deinitialize it: + * - remove and unset all listeners, + * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). + * + * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. + */ + dispose() { + const isLastClone = this.state.isLastClone; + this.state.subscriptions.forEach((subscription) => { + subscription.removeParentSet(this); + if (isLastClone) + subscription.state.removeParentState(this.state); + }); + super.dispose(); } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - const serviceResponse = this.deserializeResponse(response); - let start = null; - let end = null; - if (serviceResponse.data.length > 0) { - start = serviceResponse.data[0].actionTimetoken; - end = serviceResponse.data[serviceResponse.data.length - 1].actionTimetoken; + /** + * Invalidate {@link SubscriptionSet} object. + * + * Clean up resources used by a subscription object. All {@link SubscriptionObject subscription} objects will be + * removed. + * + * **Important:** This method is used only when a global subscription set is used (backward compatibility). + * + * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. + * + * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. + * + * @internal + */ + invalidate(forDestroy = false) { + const subscriptions = forDestroy ? this.state.subscriptions.slice(0) : this.state.subscriptions; + subscriptions.forEach((subscription) => { + if (forDestroy) { + subscription.state.entity.decreaseSubscriptionCount(this.state.id); + subscription.removeParentSet(this); } - return { - data: serviceResponse.data, - more: serviceResponse.more, - start, - end, - }; + subscription.invalidate(forDestroy); }); + if (forDestroy) + this.state.removeAllSubscriptions(); + super.invalidate(); } - get path() { - const { keySet: { subscribeKey }, channel, } = this.parameters; - return `/v1/message-actions/${subscribeKey}/channel/${encodeString(channel)}`; - } - get queryParameters() { - const { limit, start, end } = this.parameters; - return Object.assign(Object.assign(Object.assign({}, (start ? { start } : {})), (end ? { end } : {})), (limit ? { limit } : {})); - } - } - - /** - * Add Message Action REST API module. - * - * @internal - */ - // endregion - /** - * Add Message Reaction request. - * - * @internal - */ - class AddMessageActionRequest extends AbstractRequest { - constructor(parameters) { - super({ method: TransportMethod.POST }); - this.parameters = parameters; + /** + * Add an entity's subscription to the subscription set. + * + * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * + * @param subscription - Another entity's subscription object, which should be added. + */ + addSubscription(subscription) { + this.addSubscriptions([subscription]); } - operation() { - return RequestOperation$1.PNAddMessageActionOperation; + /** + * Add an entity's subscriptions to the subscription set. + * + * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * + * @param subscriptions - List of entity's subscription objects, which should be added. + */ + addSubscriptions(subscriptions) { + const inactiveSubscriptions = []; + const activeSubscriptions = []; + this.state.client.logger.debug(this.subscriptionType, () => { + const ignoredSubscriptions = []; + const subscriptionsToAdd = []; + subscriptions.forEach((subscription) => { + if (!this.state.subscriptions.includes(subscription)) + subscriptionsToAdd.push(subscription); + else + ignoredSubscriptions.push(subscription); + }); + return { + messageType: 'object', + details: `Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length + subscriptionsToAdd.length}):`, + message: { addedSubscriptions: subscriptionsToAdd, ignoredSubscriptions }, + }; + }); + subscriptions + .filter((subscription) => !this.state.subscriptions.includes(subscription)) + .forEach((subscription) => { + if (subscription.state.isSubscribed) + activeSubscriptions.push(subscription); + else + inactiveSubscriptions.push(subscription); + subscription.addParentSet(this); + this.state.addSubscription(subscription); + }); + // Check whether there are any subscriptions for which the subscription loop should be changed or not. + if ((activeSubscriptions.length === 0 && inactiveSubscriptions.length === 0) || !this.state.isSubscribed) + return; + activeSubscriptions.forEach(({ state }) => state.entity.increaseSubscriptionCount(this.state.id)); + if (inactiveSubscriptions.length > 0) + this.updateSubscription({ subscribing: true, subscriptions: inactiveSubscriptions }); } - validate() { - const { keySet: { subscribeKey }, action, channel, messageTimetoken, } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (!channel) - return 'Missing message channel'; - if (!messageTimetoken) - return 'Missing message timetoken'; - if (!action) - return 'Missing Action'; - if (!action.value) - return 'Missing Action.value'; - if (!action.type) - return 'Missing Action.type'; - if (action.type.length > 15) - return 'Action.type value exceed maximum length of 15'; + /** + * Remove an entity's subscription object from the set. + * + * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * + * @param subscription - Another entity's subscription object, which should be removed. + */ + removeSubscription(subscription) { + this.removeSubscriptions([subscription]); } - parse(response) { - const _super = Object.create(null, { - parse: { get: () => super.parse } + /** + * Remove an entity's subscription objects from the set. + * + * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * + * @param subscriptions - List entity's subscription objects, which should be removed. + */ + removeSubscriptions(subscriptions) { + const activeSubscriptions = []; + this.state.client.logger.debug(this.subscriptionType, () => { + const ignoredSubscriptions = []; + const subscriptionsToRemove = []; + subscriptions.forEach((subscription) => { + if (this.state.subscriptions.includes(subscription)) + subscriptionsToRemove.push(subscription); + else + ignoredSubscriptions.push(subscription); + }); + return { + messageType: 'object', + details: `Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`, + message: { removedSubscriptions: subscriptionsToRemove, ignoredSubscriptions }, + }; }); - return __awaiter(this, void 0, void 0, function* () { - return _super.parse.call(this, response).then(({ data }) => ({ data })); + subscriptions + .filter((subscription) => this.state.subscriptions.includes(subscription)) + .forEach((subscription) => { + if (subscription.state.isSubscribed) + activeSubscriptions.push(subscription); + subscription.removeParentSet(this); + this.state.removeSubscription(subscription, subscription.parentSetsCount > 1); }); + // Check whether there are any subscriptions for which the subscription loop should be changed or not. + if (activeSubscriptions.length === 0 || !this.state.isSubscribed) + return; + this.updateSubscription({ subscribing: false, subscriptions: activeSubscriptions }); } - get path() { - const { keySet: { subscribeKey }, channel, messageTimetoken, } = this.parameters; - return `/v1/message-actions/${subscribeKey}/channel/${encodeString(channel)}/message/${messageTimetoken}`; + /** + * Merge with another {@link SubscriptionSet} object. + * + * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * + * @param subscriptionSet - Other entities' subscription set, which should be joined. + */ + addSubscriptionSet(subscriptionSet) { + this.addSubscriptions(subscriptionSet.subscriptions); } - get headers() { - var _a; - return Object.assign(Object.assign({}, ((_a = super.headers) !== null && _a !== void 0 ? _a : {})), { 'Content-Type': 'application/json' }); + /** + * Subtract another {@link SubscriptionSet} object. + * + * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * + * @param subscriptionSet - Other entities' subscription set, which should be subtracted. + */ + removeSubscriptionSet(subscriptionSet) { + this.removeSubscriptions(subscriptionSet.subscriptions); } - get body() { - return JSON.stringify(this.parameters.action); - } - } - - /** - * Remove Message Action REST API module. - * - * @internal - */ - // endregion - /** - * Remove specific message action request. - * - * @internal - */ - class RemoveMessageAction extends AbstractRequest { - constructor(parameters) { - super({ method: TransportMethod.DELETE }); - this.parameters = parameters; - } - operation() { - return RequestOperation$1.PNRemoveMessageActionOperation; - } - validate() { - const { keySet: { subscribeKey }, channel, messageTimetoken, actionTimetoken, } = this.parameters; - if (!subscribeKey) - return 'Missing Subscribe Key'; - if (!channel) - return 'Missing message action channel'; - if (!messageTimetoken) - return 'Missing message timetoken'; - if (!actionTimetoken) - return 'Missing action timetoken'; - } - parse(response) { - const _super = Object.create(null, { - parse: { get: () => super.parse } - }); - return __awaiter(this, void 0, void 0, function* () { - return _super.parse.call(this, response).then(({ data }) => ({ data })); - }); - } - get path() { - const { keySet: { subscribeKey }, channel, actionTimetoken, messageTimetoken, } = this.parameters; - return `/v1/message-actions/${subscribeKey}/channel/${encodeString(channel)}/message/${messageTimetoken}/action/${actionTimetoken}`; - } - } - - /** - * Publish File Message REST API module. - * - * @internal - */ - // -------------------------------------------------------- - // ----------------------- Defaults ----------------------- - // -------------------------------------------------------- - // region Defaults - /** - * Whether published file messages should be stored in the channel's history. - */ - const STORE_IN_HISTORY = true; - // endregion - /** - * Publish shared file information request. - * - * @internal - */ - class PublishFileMessageRequest extends AbstractRequest { - constructor(parameters) { + /** + * Register {@link SubscriptionSet} object for real-time events' retrieval. + * + * @param parameters - Object registration parameters. + * @param [parameters.cursor] - Subscription real-time events catch-up cursor. + * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial + * modification). + * + * @internal + */ + register(parameters) { var _a; - var _b; - super(); - this.parameters = parameters; - // Apply default request parameters. - (_a = (_b = this.parameters).storeInHistory) !== null && _a !== void 0 ? _a : (_b.storeInHistory = STORE_IN_HISTORY); - } - operation() { - return RequestOperation$1.PNPublishFileMessageOperation; - } - validate() { - const { channel, fileId, fileName } = this.parameters; - if (!channel) - return "channel can't be empty"; - if (!fileId) - return "file id can't be empty"; - if (!fileName) - return "file name can't be empty"; - } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - return { timetoken: this.deserializeResponse(response)[2] }; - }); - } - get path() { - const { message, channel, keySet: { publishKey, subscribeKey }, fileId, fileName, } = this.parameters; - const fileMessage = Object.assign({ file: { - name: fileName, - id: fileId, - } }, (message ? { message } : {})); - return `/v1/files/publish-file/${publishKey}/${subscribeKey}/0/${encodeString(channel)}/0/${encodeString(this.prepareMessagePayload(fileMessage))}`; - } - get queryParameters() { - const { customMessageType, storeInHistory, ttl, meta } = this.parameters; - return Object.assign(Object.assign(Object.assign({ store: storeInHistory ? '1' : '0' }, (customMessageType ? { custom_message_type: customMessageType } : {})), (ttl ? { ttl } : {})), (meta && typeof meta === 'object' ? { meta: JSON.stringify(meta) } : {})); + const subscriptions = ((_a = parameters.subscriptions) !== null && _a !== void 0 ? _a : this.state.subscriptions); + subscriptions.forEach(({ state }) => state.entity.increaseSubscriptionCount(this.state.id)); + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Register subscription for real-time events: ${this}`, + })); + this.state.client.registerEventHandleCapable(this, parameters.cursor, subscriptions); } /** - * Pre-process provided data. - * - * Data will be "normalized" and encrypted if `cryptoModule` has been provided. + * Unregister {@link SubscriptionSet} object from real-time events' retrieval. * - * @param payload - User-provided data which should be pre-processed before use. + * @param [subscriptions] - List of subscription objects which should be unregistered (in case of partial + * modification). * - * @returns Payload which can be used as part of request URL or body. + * @internal + */ + unregister(subscriptions) { + const activeSubscriptions = (subscriptions !== null && subscriptions !== void 0 ? subscriptions : this.state.subscriptions); + activeSubscriptions.forEach(({ state }) => state.entity.decreaseSubscriptionCount(this.state.id)); + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Unregister subscription from real-time events: ${this}`, + })); + this.state.client.unregisterEventHandleCapable(this, activeSubscriptions); + } + /** + * Stringify subscription object. * - * @throws {Error} in case if provided `payload` or results of `encryption` can't be stringified. + * @returns Serialized subscription object. */ - prepareMessagePayload(payload) { - const { crypto } = this.parameters; - if (!crypto) - return JSON.stringify(payload) || ''; - const encrypted = crypto.encrypt(JSON.stringify(payload)); - return JSON.stringify(typeof encrypted === 'string' ? encrypted : encode(encrypted)); + toString() { + const state = this.state; + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${state.isSubscribed}, subscriptions: [${state.subscriptions + .map((sub) => sub.toString()) + .join(', ')}] }`; } } /** - * File sharing REST API module. - * - * @internal - */ - // endregion - /** - * File download Url generation request. + * {@link Subscription} state object. * - * Local request which generates Url to download shared file from the specific channel. + * State object used across multiple {@link Subscription} object clones. * * @internal */ - class GetFileDownloadUrlRequest extends AbstractRequest { + class SubscriptionState extends SubscriptionBaseState { /** - * Construct file download Url generation request. + * Create a subscription state object. * - * @param parameters - Request configuration. + * @param parameters - State configuration options + * @param parameters.client - PubNub client which will work with a subscription object. + * @param parameters.entity - Entity for which a subscription object has been created. + * @param [parameters.options] - Subscription behavior options. */ constructor(parameters) { - super({ method: TransportMethod.LOCAL }); - this.parameters = parameters; - } - operation() { - return RequestOperation$1.PNGetFileUrlOperation; - } - validate() { - const { channel, id, name } = this.parameters; - if (!channel) - return "channel can't be empty"; - if (!id) - return "file id can't be empty"; - if (!name) - return "file name can't be empty"; - } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - return response.url; + var _a, _b; + const names = parameters.entity.subscriptionNames((_b = (_a = parameters.options) === null || _a === void 0 ? void 0 : _a.receivePresenceEvents) !== null && _b !== void 0 ? _b : false); + const subscriptionInput = new SubscriptionInput({ + [parameters.entity.subscriptionType == SubscriptionType.Channel ? 'channels' : 'channelGroups']: names, }); - } - get path() { - const { channel, id, name, keySet: { subscribeKey }, } = this.parameters; - return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files/${id}/${name}`; + super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); + this.entity = parameters.entity; } } - - /** - * Delete file REST API module. - * - * @internal - */ - // endregion /** - * Delete File request. - * - * @internal + * Single-entity subscription object which can be used to receive and handle real-time updates. */ - class DeleteFileRequest extends AbstractRequest { + class Subscription extends SubscriptionBase { + /** + * Create a subscribing capable object for entity. + * + * @param parameters - Subscription object configuration. + * + * @internal + */ constructor(parameters) { - super({ method: TransportMethod.DELETE }); - this.parameters = parameters; - } - operation() { - return RequestOperation$1.PNDeleteFileOperation; + if ('client' in parameters) { + parameters.client.logger.debug('Subscription', () => ({ + messageType: 'object', + details: 'Create subscription with parameters:', + message: Object.assign({ entity: parameters.entity }, (parameters.options ? parameters.options : {})), + })); + } + else + parameters.state.client.logger.debug('Subscription', 'Create subscription clone'); + super('state' in parameters ? parameters.state : new SubscriptionState(parameters)); + /** + * List of subscription {@link SubscriptionSet sets} which contains {@link Subscription subscription}. + * + * List if used to track usage of a specific {@link Subscription subscription} in other subscription + * {@link SubscriptionSet sets}. + * + * **Important:** Tracking is required to prevent cloned instance dispose if there are sets that still use it. + * + * @internal + */ + this.parents = []; + /** + * List of fingerprints from updates which has been handled already. + * + * **Important:** Tracking is required to avoid repetitive call of the subscription object's listener when the object + * is part of multiple subscribed sets. Handler will be called once, and then the fingerprint will be stored in this + * list to avoid another listener call for it. + * + * @internal + */ + this.handledUpdates = []; + this.state.storeClone(this.id, this); } - validate() { - const { channel, id, name } = this.parameters; - if (!channel) - return "channel can't be empty"; - if (!id) - return "file id can't be empty"; - if (!name) - return "file name can't be empty"; + /** + * Get a {@link Subscription} object state. + * + * @returns: {@link Subscription} object state. + * + * @internal + */ + get state() { + return super.state; } - get path() { - const { keySet: { subscribeKey }, id, channel, name, } = this.parameters; - return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files/${id}/${name}`; + /** + * Get number of {@link SubscriptionSet} which use this subscription object. + * + * @returns Number of {@link SubscriptionSet} which use this subscription object. + * + * @internal + */ + get parentSetsCount() { + return this.parents.length; + } + // -------------------------------------------------------- + // -------------------- Event handler --------------------- + // -------------------------------------------------------- + // region Event handler + /** + * Dispatch received a real-time update. + * + * @param cursor - A time cursor for the next portion of events. + * @param event - A real-time event from multiplexed subscription. + * + * @return `true` if receiver has consumed event. + * + * @internal + */ + handleEvent(cursor, event) { + var _a; + if (!this.state.isSubscribed) + return; + if (this.parentSetsCount > 0) { + // Creating from whole payload (not only for published messages). + const fingerprint = messageFingerprint(event.data); + if (this.handledUpdates.includes(fingerprint)) { + this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled. Ignoring.`); + return; + } + // Update a list of tracked messages and shrink it if too big. + this.handledUpdates.push(fingerprint); + if (this.handledUpdates.length > 10) + this.handledUpdates.shift(); + } + // Check whether an event is not designated for this subscription set. + if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) + return; + super.handleEvent(cursor, event); + } + // endregion + /** + * User-provided subscription input associated with this {@link Subscription} object. + * + * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). + * + * @returns Subscription input object. + * + * @internal + */ + subscriptionInput(forUnsubscribe = false) { + if (forUnsubscribe && this.state.entity.subscriptionsCount > 0) + return new SubscriptionInput({}); + return this.state.subscriptionInput; + } + /** + * Make a bare copy of the {@link Subscription} object. + * + * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as + * the source object. + * + * @returns Bare copy of a {@link Subscription} object. + */ + cloneEmpty() { + return new Subscription({ state: this.state }); + } + /** + * Graceful {@link Subscription} object destruction. + * + * This is an instance destructor, which will properly deinitialize it: + * - remove and unset all listeners, + * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). + * + * **Important:** {@link Subscription#dispose dispose} won't have any effect if a subscription object is part of + * {@link SubscriptionSet set}. To gracefully dispose an object, it should be removed from the set using + * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of + * {@link Subscription#dispose dispose} not required). + * + * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. + */ + dispose() { + if (this.parentSetsCount > 0) { + this.state.client.logger.debug(this.subscriptionType, () => ({ + messageType: 'text', + message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, + })); + return; + } + this.handledUpdates.splice(0, this.handledUpdates.length); + super.dispose(); + } + /** + * Invalidate subscription object. + * + * Clean up resources used by a subscription object. + * + * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. + * + * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. + * + * @internal + */ + invalidate(forDestroy = false) { + if (forDestroy) + this.state.entity.decreaseSubscriptionCount(this.state.id); + this.handledUpdates.splice(0, this.handledUpdates.length); + super.invalidate(forDestroy); + } + /** + * Add another {@link SubscriptionSet} into which subscription has been added. + * + * @param parent - {@link SubscriptionSet} which has been modified. + * + * @internal + */ + addParentSet(parent) { + if (!this.parents.includes(parent)) { + this.parents.push(parent); + this.state.client.logger.trace(this.subscriptionType, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); + } + } + /** + * Remove {@link SubscriptionSet} upon subscription removal from it. + * + * @param parent - {@link SubscriptionSet} which has been modified. + * + * @internal + */ + removeParentSet(parent) { + const parentIndex = this.parents.indexOf(parent); + if (parentIndex !== -1) { + this.parents.splice(parentIndex, 1); + this.state.client.logger.trace(this.subscriptionType, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); + } + if (this.parentSetsCount === 0) + this.handledUpdates.splice(0, this.handledUpdates.length); + } + /** + * Merge entities' subscription objects into {@link SubscriptionSet}. + * + * @param subscription - Another entity's subscription object to be merged with receiver. + * + * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. + */ + addSubscription(subscription) { + this.state.client.logger.debug(this.subscriptionType, () => ({ + messageType: 'text', + message: `Create set with subscription: ${subscription}`, + })); + const subscriptionSet = new SubscriptionSet({ + client: this.state.client, + subscriptions: [this, subscription], + options: this.state.options, + }); + // Check whether a source subscription is already subscribed or not. + if (!this.state.isSubscribed && !subscription.state.isSubscribed) + return subscriptionSet; + this.state.client.logger.trace(this.subscriptionType, 'Subscribe resulting set because the receiver is already subscribed.'); + // Subscribing resulting subscription set because source subscription was subscribed. + subscriptionSet.subscribe(); + return subscriptionSet; + } + /** + * Register {@link Subscription} object for real-time events' retrieval. + * + * **Note:** Superclass calls this method only in response to a {@link Subscription.subscribe subscribe} method call. + * + * @param parameters - Object registration parameters. + * @param [parameters.cursor] - Subscription real-time events catch-up cursor. + * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial + * modification). + * + * @internal + */ + register(parameters) { + this.state.entity.increaseSubscriptionCount(this.state.id); + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Register subscription for real-time events: ${this}`, + })); + this.state.client.registerEventHandleCapable(this, parameters.cursor); + } + /** + * Unregister {@link Subscription} object from real-time events' retrieval. + * + * **Note:** Superclass calls this method only in response to a {@link Subscription.unsubscribe unsubscribe} method + * call. + * + * @param [_subscriptions] - List of subscription objects which should be unregistered (in case of partial + * modification). + * + * @internal + */ + unregister(_subscriptions) { + this.state.entity.decreaseSubscriptionCount(this.state.id); + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Unregister subscription from real-time events: ${this}`, + })); + this.handledUpdates.splice(0, this.handledUpdates.length); + this.state.client.unregisterEventHandleCapable(this); + } + /** + * Stringify subscription object. + * + * @returns Serialized subscription object. + */ + toString() { + const state = this.state; + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity + .subscriptionNames(false) + .pop()}, clonesCount: ${Object.keys(state.clones).length}, isSubscribed: ${state.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${state.cursor ? state.cursor.timetoken : 'not set'}, referenceTimetoken: ${state.referenceTimetoken ? state.referenceTimetoken : 'not set'} }`; } } /** - * List Files REST API module. + * Get Presence State REST API module. * * @internal */ - // -------------------------------------------------------- - // ----------------------- Defaults ----------------------- - // -------------------------------------------------------- - // region Defaults - /** - * Number of files to return in response. - */ - const LIMIT$6 = 100; // endregion /** - * Files List request. + * Get `uuid` presence state request. * * @internal */ - class FilesListRequest extends AbstractRequest { + class GetPresenceStateRequest extends AbstractRequest { constructor(parameters) { - var _a; - var _b; + var _a, _b; + var _c, _d; super(); this.parameters = parameters; - // Apply default request parameters. - (_a = (_b = this.parameters).limit) !== null && _a !== void 0 ? _a : (_b.limit = LIMIT$6); + // Apply defaults. + (_a = (_c = this.parameters).channels) !== null && _a !== void 0 ? _a : (_c.channels = []); + (_b = (_d = this.parameters).channelGroups) !== null && _b !== void 0 ? _b : (_d.channelGroups = []); } operation() { - return RequestOperation$1.PNListFilesOperation; + return RequestOperation$1.PNGetStateOperation; } validate() { - if (!this.parameters.channel) - return "channel can't be empty"; - } - get path() { - const { keySet: { subscribeKey }, channel, } = this.parameters; - return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files`; + const { keySet: { subscribeKey }, channels, channelGroups, } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + const serviceResponse = this.deserializeResponse(response); + const { channels = [], channelGroups = [] } = this.parameters; + const state = { channels: {} }; + if (channels.length === 1 && channelGroups.length === 0) + state.channels[channels[0]] = serviceResponse.payload; + else + state.channels = serviceResponse.payload; + return state; + }); + } + get path() { + const { keySet: { subscribeKey }, uuid, channels, } = this.parameters; + return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}/uuid/${uuid}`; } get queryParameters() { - const { limit, next } = this.parameters; - return Object.assign({ limit: limit }, (next ? { next } : {})); + const { channelGroups } = this.parameters; + if (!channelGroups || channelGroups.length === 0) + return {}; + return { 'channel-group': channelGroups.join(',') }; } } /** - * Generate file upload URL REST API request. + * Set Presence State REST API module. * * @internal */ // endregion /** - * Generate File Upload Url request. + * Set `uuid` presence state request. * * @internal */ - class GenerateFileUploadUrlRequest extends AbstractRequest { + class SetPresenceStateRequest extends AbstractRequest { constructor(parameters) { - super({ method: TransportMethod.POST }); + super(); this.parameters = parameters; } operation() { - return RequestOperation$1.PNGenerateUploadUrlOperation; + return RequestOperation$1.PNSetStateOperation; } validate() { - if (!this.parameters.channel) - return "channel can't be empty"; - if (!this.parameters.name) - return "'name' can't be empty"; + const { keySet: { subscribeKey }, state, channels = [], channelGroups = [], } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (!state) + return 'Missing State'; + if ((channels === null || channels === void 0 ? void 0 : channels.length) === 0 && (channelGroups === null || channelGroups === void 0 ? void 0 : channelGroups.length) === 0) + return 'Please provide a list of channels and/or channel-groups'; } parse(response) { return __awaiter(this, void 0, void 0, function* () { - const serviceResponse = this.deserializeResponse(response); - return { - id: serviceResponse.data.id, - name: serviceResponse.data.name, - url: serviceResponse.file_upload_request.url, - formFields: serviceResponse.file_upload_request.form_fields, - }; + return { state: this.deserializeResponse(response).payload }; }); } get path() { - const { keySet: { subscribeKey }, channel, } = this.parameters; - return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/generate-upload-url`; - } - get headers() { - var _a; - return Object.assign(Object.assign({}, ((_a = super.headers) !== null && _a !== void 0 ? _a : {})), { 'Content-Type': 'application/json' }); + const { keySet: { subscribeKey }, uuid, channels, } = this.parameters; + return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}/uuid/${encodeString(uuid)}/data`; } - get body() { - return JSON.stringify({ name: this.parameters.name }); + get queryParameters() { + const { channelGroups, state } = this.parameters; + const query = { state: JSON.stringify(state) }; + if (channelGroups && channelGroups.length !== 0) + query['channel-group'] = channelGroups.join(','); + return query; } } /** - * Upload file REST API request. + * Announce heartbeat REST API module. * * @internal */ + // endregion /** - * File Upload request. + * Announce `uuid` presence request. * * @internal */ - class UploadFileRequest extends AbstractRequest { + class HeartbeatRequest extends AbstractRequest { constructor(parameters) { - super({ method: TransportMethod.POST }); + super({ cancellable: true }); this.parameters = parameters; - // Use file's actual mime type if available. - const mimeType = parameters.file.mimeType; - if (mimeType) { - parameters.formFields = parameters.formFields.map((entry) => { - if (entry.name === 'Content-Type') - return { name: entry.name, value: mimeType }; - return entry; - }); - } } operation() { - return RequestOperation$1.PNPublishFileOperation; + return RequestOperation$1.PNHeartbeatOperation; } validate() { - const { fileId, fileName, file, uploadUrl } = this.parameters; - if (!fileId) - return "Validation failed: file 'id' can't be empty"; - if (!fileName) - return "Validation failed: file 'name' can't be empty"; - if (!file) - return "Validation failed: 'file' can't be empty"; - if (!uploadUrl) - return "Validation failed: file upload 'url' can't be empty"; + const { keySet: { subscribeKey }, channels = [], channelGroups = [], } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (channels.length === 0 && channelGroups.length === 0) + return 'Please provide a list of channels and/or channel-groups'; } parse(response) { + const _super = Object.create(null, { + parse: { get: () => super.parse } + }); return __awaiter(this, void 0, void 0, function* () { - return { - status: response.status, - message: response.body ? UploadFileRequest.decoder.decode(response.body) : 'OK', - }; + return _super.parse.call(this, response).then((_) => ({})); }); } - request() { - return Object.assign(Object.assign({}, super.request()), { origin: new URL(this.parameters.uploadUrl).origin, timeout: 300 }); - } get path() { - const { pathname, search } = new URL(this.parameters.uploadUrl); - return `${pathname}${search}`; - } - get body() { - return this.parameters.file; + const { keySet: { subscribeKey }, channels, } = this.parameters; + return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}/heartbeat`; } - get formData() { - return this.parameters.formFields; + get queryParameters() { + const { channelGroups, state, heartbeat } = this.parameters; + const query = { heartbeat: `${heartbeat}` }; + if (channelGroups && channelGroups.length !== 0) + query['channel-group'] = channelGroups.join(','); + if (state) + query.state = JSON.stringify(state); + return query; } } /** - * Share File API module. + * Announce leave REST API module. * * @internal */ // endregion /** - * Send file composed request. + * Announce user leave request. * * @internal */ - class SendFileRequest { + class PresenceLeaveRequest extends AbstractRequest { constructor(parameters) { - var _a; + super(); this.parameters = parameters; - this.file = (_a = this.parameters.PubNubFile) === null || _a === void 0 ? void 0 : _a.create(parameters.file); - if (!this.file) - throw new Error('File upload error: unable to create File object.'); + if (this.parameters.channelGroups) + this.parameters.channelGroups = Array.from(new Set(this.parameters.channelGroups)); + if (this.parameters.channels) + this.parameters.channels = Array.from(new Set(this.parameters.channels)); } - /** - * Process user-input and upload file. - * - * @returns File upload request response. - */ - process() { + operation() { + return RequestOperation$1.PNUnsubscribeOperation; + } + validate() { + const { keySet: { subscribeKey }, channels = [], channelGroups = [], } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (channels.length === 0 && channelGroups.length === 0) + return 'At least one `channel` or `channel group` should be provided.'; + } + parse(response) { + const _super = Object.create(null, { + parse: { get: () => super.parse } + }); return __awaiter(this, void 0, void 0, function* () { - let fileName; - let fileId; - return this.generateFileUploadUrl() - .then((result) => { - fileName = result.name; - fileId = result.id; - return this.uploadFile(result); - }) - .then((result) => { - if (result.status !== 204) { - throw new PubNubError('Upload to bucket was unsuccessful', { - error: true, - statusCode: result.status, - category: StatusCategory$1.PNUnknownCategory, - operation: RequestOperation$1.PNPublishFileOperation, - errorData: { message: result.message }, - }); - } - }) - .then(() => this.publishFileMessage(fileId, fileName)) - .catch((error) => { - if (error instanceof PubNubError) - throw error; - const apiError = !(error instanceof PubNubAPIError) ? PubNubAPIError.create(error) : error; - throw new PubNubError('File upload error.', apiError.toStatus(RequestOperation$1.PNPublishFileOperation)); - }); + return _super.parse.call(this, response).then((_) => ({})); }); } - /** - * Generate pre-signed file upload Url. - * - * @returns File upload credentials. - */ - generateFileUploadUrl() { + get path() { + var _a; + const { keySet: { subscribeKey }, channels, } = this.parameters; + return `/v2/presence/sub-key/${subscribeKey}/channel/${encodeNames((_a = channels === null || channels === void 0 ? void 0 : channels.sort()) !== null && _a !== void 0 ? _a : [], ',')}/leave`; + } + get queryParameters() { + const { channelGroups } = this.parameters; + if (!channelGroups || channelGroups.length === 0) + return {}; + return { 'channel-group': channelGroups.sort().join(',') }; + } + } + + /** + * `uuid` presence REST API module. + * + * @internal + */ + // endregion + /** + * Get `uuid` presence request. + * + * @internal + */ + class WhereNowRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNWhereNowOperation; + } + validate() { + if (!this.parameters.keySet.subscribeKey) + return 'Missing Subscribe Key'; + } + parse(response) { return __awaiter(this, void 0, void 0, function* () { - const request = new GenerateFileUploadUrlRequest(Object.assign(Object.assign({}, this.parameters), { name: this.file.name, keySet: this.parameters.keySet })); - return this.parameters.sendRequest(request); + const serviceResponse = this.deserializeResponse(response); + if (!serviceResponse.payload) + return { channels: [] }; + return { channels: serviceResponse.payload.channels }; }); } - /** - * Prepare and upload {@link PubNub} File object to remote storage. - * - * @param uploadParameters - File upload request parameters. - * - * @returns - */ - uploadFile(uploadParameters) { - return __awaiter(this, void 0, void 0, function* () { - const { cipherKey, PubNubFile, crypto, cryptography } = this.parameters; - const { id, name, url, formFields } = uploadParameters; - // Encrypt file if possible. - if (this.parameters.PubNubFile.supportsEncryptFile) { - if (!cipherKey && crypto) - this.file = (yield crypto.encryptFile(this.file, PubNubFile)); - else if (cipherKey && cryptography) - this.file = (yield cryptography.encryptFile(cipherKey, this.file, PubNubFile)); - } - return this.parameters.sendRequest(new UploadFileRequest({ - fileId: id, - fileName: name, - file: this.file, - uploadUrl: url, - formFields, - })); - }); + get path() { + const { keySet: { subscribeKey }, uuid, } = this.parameters; + return `/v2/presence/sub-key/${subscribeKey}/uuid/${encodeString(uuid)}`; } - publishFileMessage(fileId, fileName) { + } + + /** + * Channels / channel groups presence REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Whether `uuid` should be included in response or not. + */ + const INCLUDE_UUID$1 = true; + /** + * Whether state associated with `uuid` should be included in response or not. + */ + const INCLUDE_STATE = false; + // endregion + /** + * Channel presence request. + * + * @internal + */ + class HereNowRequest extends AbstractRequest { + constructor(parameters) { + var _a, _b, _c; + var _d, _e, _f; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = (_d = this.parameters).queryParameters) !== null && _a !== void 0 ? _a : (_d.queryParameters = {}); + (_b = (_e = this.parameters).includeUUIDs) !== null && _b !== void 0 ? _b : (_e.includeUUIDs = INCLUDE_UUID$1); + (_c = (_f = this.parameters).includeState) !== null && _c !== void 0 ? _c : (_f.includeState = INCLUDE_STATE); + } + operation() { + const { channels = [], channelGroups = [] } = this.parameters; + return channels.length === 0 && channelGroups.length === 0 + ? RequestOperation$1.PNGlobalHereNowOperation + : RequestOperation$1.PNHereNowOperation; + } + validate() { + if (!this.parameters.keySet.subscribeKey) + return 'Missing Subscribe Key'; + } + parse(response) { return __awaiter(this, void 0, void 0, function* () { - var _a, _b, _c, _d; - let result = { timetoken: '0' }; - let retries = this.parameters.fileUploadPublishRetryLimit; - let publishError; - let wasSuccessful = false; - do { - try { - result = yield this.parameters.publishFile(Object.assign(Object.assign({}, this.parameters), { fileId, fileName })); - wasSuccessful = true; - } - catch (error) { - if (error instanceof PubNubError) - publishError = error; - retries -= 1; - } - } while (!wasSuccessful && retries > 0); - if (!wasSuccessful) { - throw new PubNubError('Publish failed. You may want to execute that operation manually using pubnub.publishFile', { - error: true, - category: (_b = (_a = publishError.status) === null || _a === void 0 ? void 0 : _a.category) !== null && _b !== void 0 ? _b : StatusCategory$1.PNUnknownCategory, - statusCode: (_d = (_c = publishError.status) === null || _c === void 0 ? void 0 : _c.statusCode) !== null && _d !== void 0 ? _d : 0, - channel: this.parameters.channel, - id: fileId, - name: fileName, - }); + var _a, _b; + const serviceResponse = this.deserializeResponse(response); + // Extract general presence information. + const totalChannels = 'occupancy' in serviceResponse ? 1 : serviceResponse.payload.total_channels; + const totalOccupancy = 'occupancy' in serviceResponse ? serviceResponse.occupancy : serviceResponse.payload.total_occupancy; + const channelsPresence = {}; + let channels = {}; + // Remap single channel presence to multiple channels presence response. + if ('occupancy' in serviceResponse) { + const channel = this.parameters.channels[0]; + channels[channel] = { uuids: (_a = serviceResponse.uuids) !== null && _a !== void 0 ? _a : [], occupancy: totalOccupancy }; } else - return { status: 200, timetoken: result.timetoken, id: fileId, name: fileName }; + channels = (_b = serviceResponse.payload.channels) !== null && _b !== void 0 ? _b : {}; + Object.keys(channels).forEach((channel) => { + const channelEntry = channels[channel]; + channelsPresence[channel] = { + occupants: this.parameters.includeUUIDs + ? channelEntry.uuids.map((uuid) => { + if (typeof uuid === 'string') + return { uuid, state: null }; + return uuid; + }) + : [], + name: channel, + occupancy: channelEntry.occupancy, + }; + }); + return { + totalChannels, + totalOccupancy, + channels: channelsPresence, + }; }); } + get path() { + const { keySet: { subscribeKey }, channels, channelGroups, } = this.parameters; + let path = `/v2/presence/sub-key/${subscribeKey}`; + if ((channels && channels.length > 0) || (channelGroups && channelGroups.length > 0)) + path += `/channel/${encodeNames(channels !== null && channels !== void 0 ? channels : [], ',')}`; + return path; + } + get queryParameters() { + const { channelGroups, includeUUIDs, includeState, queryParameters } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign({}, (!includeUUIDs ? { disable_uuids: '1' } : {})), ((includeState !== null && includeState !== void 0 ? includeState : false) ? { state: '1' } : {})), (channelGroups && channelGroups.length > 0 ? { 'channel-group': channelGroups.join(',') } : {})), queryParameters); + } } /** - * SubscriptionCapable entity type. + * Delete messages REST API module. * * @internal */ - var SubscriptionType; - (function (SubscriptionType) { - /** - * Channel identifier, which is part of the URI path. - */ - SubscriptionType[SubscriptionType["Channel"] = 0] = "Channel"; - /** - * Channel group identifiers, which is part of the query parameters. - */ - SubscriptionType[SubscriptionType["ChannelGroup"] = 1] = "ChannelGroup"; - })(SubscriptionType || (SubscriptionType = {})); - + // endregion /** - * User-provided channels and groups for subscription. - * - * Object contains information about channels and groups for which real-time updates should be retrieved from the - * PubNub network. + * Delete messages from channel history. * * @internal */ - class SubscriptionInput { - /** - * Create a subscription input object. - * - * @param channels - List of channels which will be used with subscribe REST API to receive real-time updates. - * @param channelGroups - List of channel groups which will be used with subscribe REST API to receive real-time - * updates. - */ - constructor({ channels, channelGroups }) { - /** - * Whether the user input is empty or not. - */ - this.isEmpty = true; - this._channelGroups = new Set((channelGroups !== null && channelGroups !== void 0 ? channelGroups : []).filter((value) => value.length > 0)); - this._channels = new Set((channels !== null && channels !== void 0 ? channels : []).filter((value) => value.length > 0)); - this.isEmpty = this._channels.size === 0 && this._channelGroups.size === 0; - } - /** - * Retrieve a list of user-provided channel names. - * - * @returns List of user-provided channel names. - */ - get channels() { - if (this.isEmpty) - return []; - return Array.from(this._channels); + class DeleteMessageRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; } - /** - * Retrieve a list of user-provided channel group names. - * - * @returns List of user-provided channel group names. - */ - get channelGroups() { - if (this.isEmpty) - return []; - return Array.from(this._channelGroups); + operation() { + return RequestOperation$1.PNDeleteMessagesOperation; } - /** - * Check if the given name is contained in the channel or channel group. - * - * @param name - Containing the name to be checked. - * - * @returns `true` if the name is found in the channel or channel group, `false` otherwise. - */ - contains(name) { - if (this.isEmpty) - return false; - return this._channels.has(name) || this._channelGroups.has(name); + validate() { + if (!this.parameters.keySet.subscribeKey) + return 'Missing Subscribe Key'; + if (!this.parameters.channel) + return 'Missing channel'; } - /** - * Create a new subscription input which will contain all channels and channel groups from both inputs. - * - * @param input - Another subscription input that should be used to aggregate data in new instance. - * - * @returns New subscription input instance with combined channels and channel groups. - */ - with(input) { - return new SubscriptionInput({ - channels: [...this._channels, ...input._channels], - channelGroups: [...this._channelGroups, ...input._channelGroups], + parse(response) { + const _super = Object.create(null, { + parse: { get: () => super.parse } }); - } - /** - * Create a new subscription input which will contain only channels and groups which not present in the input. - * - * @param input - Another subscription input which should be used to filter data in new instance. - * - * @returns New subscription input instance with filtered channels and channel groups. - */ - without(input) { - return new SubscriptionInput({ - channels: [...this._channels].filter((value) => !input._channels.has(value)), - channelGroups: [...this._channelGroups].filter((value) => !input._channelGroups.has(value)), + return __awaiter(this, void 0, void 0, function* () { + return _super.parse.call(this, response).then((_) => ({})); }); } - /** - * Add data from another subscription input to the receiver. - * - * @param input - Another subscription input whose data should be added to the receiver. - * - * @returns Receiver instance with updated channels and channel groups. - */ - add(input) { - if (input._channelGroups.size > 0) - this._channelGroups = new Set([...this._channelGroups, ...input._channelGroups]); - if (input._channels.size > 0) - this._channels = new Set([...this._channels, ...input._channels]); - this.isEmpty = this._channels.size === 0 && this._channelGroups.size === 0; - return this; + get path() { + const { keySet: { subscribeKey }, channel, } = this.parameters; + return `/v3/history/sub-key/${subscribeKey}/channel/${encodeString(channel)}`; } - /** - * Remove data from another subscription input from the receiver. - * - * @param input - Another subscription input whose data should be removed from the receiver. - * - * @returns Receiver instance with updated channels and channel groups. - */ - remove(input) { - if (input._channelGroups.size > 0) - this._channelGroups = new Set([...this._channelGroups].filter((value) => !input._channelGroups.has(value))); - if (input._channels.size > 0) - this._channels = new Set([...this._channels].filter((value) => !input._channels.has(value))); - return this; - } - /** - * Remove all data from subscription input. - * - * @returns Receiver instance with updated channels and channel groups. - */ - removeAll() { - this._channels.clear(); - this._channelGroups.clear(); - this.isEmpty = true; - return this; - } - /** - * Serialize a subscription input to string. - * - * @returns Printable string representation of a subscription input. - */ - toString() { - return `SubscriptionInput { channels: [${this.channels.join(', ')}], channelGroups: [${this.channelGroups.join(', ')}], is empty: ${this.isEmpty ? 'true' : 'false'}} }`; + get queryParameters() { + const { start, end } = this.parameters; + return Object.assign(Object.assign({}, (start ? { start } : {})), (end ? { end } : {})); } } - // endregion /** - * Subscription state object. + * Messages count REST API module. * - * State object used across multiple subscription object clones. + * @internal + */ + // endregion + /** + * Count messages request. * * @internal */ - class SubscriptionBaseState { - /** - * Create a base subscription state object. - * - * @param client - PubNub client which will work with a subscription object. - * @param subscriptionInput - User's input to be used with subscribe REST API. - * @param options - Subscription behavior options. - * @param referenceTimetoken - High-precision timetoken of the moment when subscription was created for entity. - */ - constructor(client, subscriptionInput, options, referenceTimetoken) { - /** - * Whether a subscribable object subscribed or not. - */ - this._isSubscribed = false; - /** - * The list of references to all {@link SubscriptionBase} clones created for this reference. - */ - this.clones = {}; - /** - * List of a parent subscription state objects list. - * - * List is used to track usage of a subscription object in other subscription object sets. - * - * **Important:** Tracking is required to prevent unexpected unsubscriptions if an object still has a parent. - */ - this.parents = []; - /** - * Unique subscription object identifier. - */ - this._id = uuidGenerator.createUUID(); - this.referenceTimetoken = referenceTimetoken; - this.subscriptionInput = subscriptionInput; - this.options = options; - this.client = client; - } - /** - * Get unique subscription object identifier. - * - * @returns Unique subscription object identifier. - */ - get id() { - return this._id; - } - /** - * Check whether a subscription object is the last clone or not. - * - * @returns `true` if a subscription object is the last clone. - */ - get isLastClone() { - return Object.keys(this.clones).length === 1; + class MessageCountRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; } - /** - * Get whether a subscribable object subscribed or not. - * - * **Warning:** This method shouldn't be overridden by {@link SubscriptionSet}. - * - * @returns Whether a subscribable object subscribed or not. - */ - get isSubscribed() { - if (this._isSubscribed) - return true; - // Checking whether any of "parents" is subscribed. - return this.parents.length > 0 && this.parents.some((state) => state.isSubscribed); + operation() { + return RequestOperation$1.PNMessageCounts; } - /** - * Update active subscription state. - * - * @param value - New subscription state. - */ - set isSubscribed(value) { - if (this.isSubscribed === value) - return; - this._isSubscribed = value; + validate() { + const { keySet: { subscribeKey }, channels, timetoken, channelTimetokens, } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (!channels) + return 'Missing channels'; + if (timetoken && channelTimetokens) + return '`timetoken` and `channelTimetokens` are incompatible together'; + if (!timetoken && !channelTimetokens) + return '`timetoken` or `channelTimetokens` need to be set'; + if (channelTimetokens && channelTimetokens.length > 1 && channelTimetokens.length !== channels.length) + return 'Length of `channelTimetokens` and `channels` do not match'; } - /** - * Add a parent subscription state object to mark the linkage. - * - * @param parent - Parent subscription state object. - * - * @internal - */ - addParentState(parent) { - if (!this.parents.includes(parent)) - this.parents.push(parent); + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { channels: this.deserializeResponse(response).channels }; + }); } - /** - * Remove a parent subscription state object. - * - * @param parent - Parent object for which linkage should be broken. - * - * @internal - */ - removeParentState(parent) { - const parentStateIndex = this.parents.indexOf(parent); - if (parentStateIndex !== -1) - this.parents.splice(parentStateIndex, 1); + get path() { + return `/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${encodeNames(this.parameters.channels)}`; } - /** - * Store a clone of a {@link SubscriptionBase} instance with a given instance ID. - * - * @param id - The instance ID to associate with clone. - * @param instance - Reference to the subscription instance to store as a clone. - */ - storeClone(id, instance) { - if (!this.clones[id]) - this.clones[id] = instance; + get queryParameters() { + let { channelTimetokens } = this.parameters; + if (this.parameters.timetoken) + channelTimetokens = [this.parameters.timetoken]; + return Object.assign(Object.assign({}, (channelTimetokens.length === 1 ? { timetoken: channelTimetokens[0] } : {})), (channelTimetokens.length > 1 ? { channelsTimetoken: channelTimetokens.join(',') } : {})); } } + /** - * Base subscribe object. + * Get history REST API module. * - * Implementation of base functionality used by {@link SubscriptionObject Subscription} and {@link SubscriptionSet}. + * @internal */ - class SubscriptionBase { - /** - * Create a subscription object from the state. - * - * @param state - Subscription state object. - * - * @internal - */ - constructor(state) { - /** - * Unique subscription object identifier. - * - * @internal - */ - this.id = uuidGenerator.createUUID(); - /** - * Event emitter, which will notify listeners about updates received for channels / groups. - * - * @internal - */ - this.eventDispatcher = new EventDispatcher(); - this._state = state; + // -------------------------------------------------------- + // ---------------------- Defaults ------------------------ + // -------------------------------------------------------- + // region Defaults + /** + * Whether verbose logging enabled or not. + */ + const LOG_VERBOSITY$1 = false; + /** + * Whether associated message metadata should be returned or not. + */ + const INCLUDE_METADATA = false; + /** + * Whether timetokens should be returned as strings by default or not. + */ + const STRINGIFY_TIMETOKENS$1 = false; + /** + * Default and maximum number of messages which should be returned. + */ + const MESSAGES_COUNT = 100; + // endregion + /** + * Get single channel messages request. + * + * @internal + */ + class GetHistoryRequest extends AbstractRequest { + constructor(parameters) { + var _a, _b, _c; + super(); + this.parameters = parameters; + // Apply defaults. + if (parameters.count) + parameters.count = Math.min(parameters.count, MESSAGES_COUNT); + else + parameters.count = MESSAGES_COUNT; + (_a = parameters.stringifiedTimeToken) !== null && _a !== void 0 ? _a : (parameters.stringifiedTimeToken = STRINGIFY_TIMETOKENS$1); + (_b = parameters.includeMeta) !== null && _b !== void 0 ? _b : (parameters.includeMeta = INCLUDE_METADATA); + (_c = parameters.logVerbosity) !== null && _c !== void 0 ? _c : (parameters.logVerbosity = LOG_VERBOSITY$1); } - /** - * Subscription state. - * - * @returns Subscription state object. - * - * @internal - */ - get state() { - return this._state; + operation() { + return RequestOperation$1.PNHistoryOperation; } - /** - * Get a list of channels which is used for subscription. - * - * @returns List of channel names. - */ - get channels() { - return this.state.subscriptionInput.channels.slice(0); - } - /** - * Get a list of channel groups which is used for subscription. - * - * @returns List of channel group names. - */ - get channelGroups() { - return this.state.subscriptionInput.channelGroups.slice(0); - } - // -------------------------------------------------------- - // -------------------- Event emitter --------------------- - // -------------------------------------------------------- - // region Event emitter - /** - * Set a new message handler. - * - * @param listener - Listener function, which will be called each time when a new message - * is received from the real-time network. - */ - set onMessage(listener) { - this.eventDispatcher.onMessage = listener; + validate() { + if (!this.parameters.keySet.subscribeKey) + return 'Missing Subscribe Key'; + if (!this.parameters.channel) + return 'Missing channel'; } - /** - * Set a new presence events handler. - * - * @param listener - Listener function, which will be called each time when a new - * presence event is received from the real-time network. - */ - set onPresence(listener) { - this.eventDispatcher.onPresence = listener; + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + const serviceResponse = this.deserializeResponse(response); + const messages = serviceResponse[0]; + const startTimeToken = serviceResponse[1]; + const endTimeToken = serviceResponse[2]; + // Handle malformed get history response. + if (!Array.isArray(messages)) + return { messages: [], startTimeToken, endTimeToken }; + return { + messages: messages.map((payload) => { + const processedPayload = this.processPayload(payload.message); + const item = { + entry: processedPayload.payload, + timetoken: payload.timetoken, + }; + if (processedPayload.error) + item.error = processedPayload.error; + if (payload.meta) + item.meta = payload.meta; + return item; + }), + startTimeToken, + endTimeToken, + }; + }); } - /** - * Set a new signal handler. - * - * @param listener - Listener function, which will be called each time when a new signal - * is received from the real-time network. - */ - set onSignal(listener) { - this.eventDispatcher.onSignal = listener; + get path() { + const { keySet: { subscribeKey }, channel, } = this.parameters; + return `/v2/history/sub-key/${subscribeKey}/channel/${encodeString(channel)}`; } - /** - * Set a new app context event handler. - * - * @param listener - Listener function, which will be called each time when a new - * app context event is received from the real-time network. - */ - set onObjects(listener) { - this.eventDispatcher.onObjects = listener; + get queryParameters() { + const { start, end, reverse, count, stringifiedTimeToken, includeMeta } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ count: count, include_token: 'true' }, (start ? { start } : {})), (end ? { end } : {})), (stringifiedTimeToken ? { string_message_token: 'true' } : {})), (reverse !== undefined && reverse !== null ? { reverse: reverse.toString() } : {})), (includeMeta ? { include_meta: 'true' } : {})); } - /** - * Set a new message reaction event handler. - * - * @param listener - Listener function, which will be called each time when a - * new message reaction event is received from the real-time network. - */ - set onMessageAction(listener) { - this.eventDispatcher.onMessageAction = listener; + processPayload(payload) { + const { crypto, logVerbosity } = this.parameters; + if (!crypto || typeof payload !== 'string') + return { payload }; + let decryptedPayload; + let error; + try { + const decryptedData = crypto.decrypt(payload); + decryptedPayload = + decryptedData instanceof ArrayBuffer + ? JSON.parse(GetHistoryRequest.decoder.decode(decryptedData)) + : decryptedData; + } + catch (err) { + if (logVerbosity) + console.log(`decryption error`, err.message); + decryptedPayload = payload; + error = `Error while decrypting message content: ${err.message}`; + } + return { + payload: decryptedPayload, + error, + }; } + } + + // endregion + // -------------------------------------------------------- + // -------------------- Fetch Messages -------------------- + // -------------------------------------------------------- + // region Fetch Messages + /** + * PubNub-defined message type. + * + * Types of messages which can be retrieved with fetch messages REST API. + */ + var PubNubMessageType; + (function (PubNubMessageType) { /** - * Set a new file handler. - * - * @param listener - Listener function, which will be called each time when a new file - * is received from the real-time network. + * Regular message. */ - set onFile(listener) { - this.eventDispatcher.onFile = listener; - } + PubNubMessageType[PubNubMessageType["Message"] = -1] = "Message"; /** - * Set events handler. - * - * @param listener - Events listener configuration object, which lets specify handlers for multiple - * types of events. + * File message. */ - addListener(listener) { - this.eventDispatcher.addListener(listener); + PubNubMessageType[PubNubMessageType["Files"] = 4] = "Files"; + })(PubNubMessageType || (PubNubMessageType = {})); + // endregion + + /** + * Fetch messages REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ---------------------- Defaults ------------------------ + // -------------------------------------------------------- + // region Defaults + /** + * Whether verbose logging enabled or not. + */ + const LOG_VERBOSITY = false; + /** + * Whether message type should be returned or not. + */ + const INCLUDE_MESSAGE_TYPE = true; + /** + * Whether timetokens should be returned as strings by default or not. + */ + const STRINGIFY_TIMETOKENS = false; + /** + * Whether message publisher `uuid` should be returned or not. + */ + const INCLUDE_UUID = true; + /** + * Default number of messages which can be returned for single channel, and it is maximum as well. + */ + const SINGLE_CHANNEL_MESSAGES_COUNT = 100; + /** + * Default number of messages which can be returned for multiple channels or when fetched + * message actions. + */ + const MULTIPLE_CHANNELS_MESSAGES_COUNT = 25; + // endregion + /** + * Fetch messages from channels request. + * + * @internal + */ + class FetchMessagesRequest extends AbstractRequest { + constructor(parameters) { + var _a, _b, _c, _d, _e; + super(); + this.parameters = parameters; + // Apply defaults. + const includeMessageActions = (_a = parameters.includeMessageActions) !== null && _a !== void 0 ? _a : false; + const defaultCount = parameters.channels.length > 1 || includeMessageActions + ? MULTIPLE_CHANNELS_MESSAGES_COUNT + : SINGLE_CHANNEL_MESSAGES_COUNT; + if (!parameters.count) + parameters.count = defaultCount; + else + parameters.count = Math.min(parameters.count, defaultCount); + if (parameters.includeUuid) + parameters.includeUUID = parameters.includeUuid; + else + (_b = parameters.includeUUID) !== null && _b !== void 0 ? _b : (parameters.includeUUID = INCLUDE_UUID); + (_c = parameters.stringifiedTimeToken) !== null && _c !== void 0 ? _c : (parameters.stringifiedTimeToken = STRINGIFY_TIMETOKENS); + (_d = parameters.includeMessageType) !== null && _d !== void 0 ? _d : (parameters.includeMessageType = INCLUDE_MESSAGE_TYPE); + (_e = parameters.logVerbosity) !== null && _e !== void 0 ? _e : (parameters.logVerbosity = LOG_VERBOSITY); } - /** - * Remove events handler. - * - * @param listener - Event listener configuration, which should be removed from the list of notified - * listeners. **Important:** Should be the same object which has been passed to the {@link addListener}. - */ - removeListener(listener) { - this.eventDispatcher.removeListener(listener); + operation() { + return RequestOperation$1.PNFetchMessagesOperation; } - /** - * Remove all events listeners. - */ - removeAllListeners() { - this.eventDispatcher.removeAllListeners(); + validate() { + const { keySet: { subscribeKey }, channels, includeMessageActions, } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (!channels) + return 'Missing channels'; + if (includeMessageActions !== undefined && includeMessageActions && channels.length > 1) + return ('History can return actions data for a single channel only. Either pass a single channel ' + + 'or disable the includeMessageActions flag.'); } - /** - * Dispatch received a real-time update. - * - * @param cursor - A time cursor for the next portion of events. - * @param event - A real-time event from multiplexed subscription. - * - * @return `true` if receiver has consumed event. - * - * @internal - */ - handleEvent(cursor, event) { - var _a; - if (!this.state.cursor || cursor > this.state.cursor) - this.state.cursor = cursor; - // Check whether this is an old `old` event and it should be ignored or not. - if (this.state.referenceTimetoken && event.data.timetoken < this.state.referenceTimetoken) { - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Event timetoken (${event.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`, - })); - return; - } - // Don't pass events which are filtered out by the user-provided function. - if (((_a = this.state.options) === null || _a === void 0 ? void 0 : _a.filter) && !this.state.options.filter(event)) { - this.state.client.logger.trace(this.constructor.name, `Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`); - return; - } - const clones = Object.values(this.state.clones); - if (clones.length > 0) { - this.state.client.logger.trace(this.constructor.name, `Notify ${this.id} subscription object clones (count: ${clones.length}) about received event.`); - } - clones.forEach((subscription) => subscription.eventDispatcher.handleEvent(event)); + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + var _a; + const serviceResponse = this.deserializeResponse(response); + const responseChannels = (_a = serviceResponse.channels) !== null && _a !== void 0 ? _a : {}; + const channels = {}; + Object.keys(responseChannels).forEach((channel) => { + // Map service response to expected data object type structure. + channels[channel] = responseChannels[channel].map((payload) => { + // `null` message type means regular message. + if (payload.message_type === null) + payload.message_type = PubNubMessageType.Message; + const processedPayload = this.processPayload(channel, payload); + const item = Object.assign(Object.assign({ channel, timetoken: payload.timetoken, message: processedPayload.payload, messageType: payload.message_type }, (payload.custom_message_type ? { customMessageType: payload.custom_message_type } : {})), { uuid: payload.uuid }); + if (payload.actions) { + const itemWithActions = item; + itemWithActions.actions = payload.actions; + // Backward compatibility for existing users. + // TODO: Remove in next release. + itemWithActions.data = payload.actions; + } + if (payload.meta) + item.meta = payload.meta; + if (processedPayload.error) + item.error = processedPayload.error; + return item; + }); + }); + if (serviceResponse.more) + return { channels, more: serviceResponse.more }; + return { channels }; + }); } - /** - * Graceful object destruction. - * - * This is an instance destructor, which will properly deinitialize it: - * - remove and unset all listeners, - * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). - * - * **Important:** {@link SubscriptionBase#dispose dispose} won't have any effect if a subscription object is part of - * set. To gracefully dispose an object, it should be removed from the set using - * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of - * {@link SubscriptionBase#dispose dispose} not required. - * - * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. - */ - dispose() { - const keys = Object.keys(this.state.clones); - if (keys.length > 1) { - this.state.client.logger.debug(this.constructor.name, `Remove subscription object clone on dispose: ${this.id}`); - delete this.state.clones[this.id]; - } - else if (keys.length === 1 && this.state.clones[this.id]) { - this.state.client.logger.debug(this.constructor.name, `Unsubscribe subscription object on dispose: ${this.id}`); - this.unsubscribe(); - } + get path() { + const { keySet: { subscribeKey }, channels, includeMessageActions, } = this.parameters; + const endpoint = !includeMessageActions ? 'history' : 'history-with-actions'; + return `/v3/${endpoint}/sub-key/${subscribeKey}/channel/${encodeNames(channels)}`; + } + get queryParameters() { + const { start, end, count, includeCustomMessageType, includeMessageType, includeMeta, includeUUID, stringifiedTimeToken, } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ max: count }, (start ? { start } : {})), (end ? { end } : {})), (stringifiedTimeToken ? { string_message_token: 'true' } : {})), (includeMeta !== undefined && includeMeta ? { include_meta: 'true' } : {})), (includeUUID ? { include_uuid: 'true' } : {})), (includeCustomMessageType !== undefined && includeCustomMessageType !== null + ? { include_custom_message_type: includeCustomMessageType ? 'true' : 'false' } + : {})), (includeMessageType ? { include_message_type: 'true' } : {})); } /** - * Invalidate subscription object. - * - * Clean up resources used by a subscription object. - * - * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. + * Parse single channel data entry. * - * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. + * @param channel - Channel for which {@link payload} should be processed. + * @param payload - Source payload which should be processed and parsed to expected type. * - * @internal + * @returns */ - invalidate(forDestroy = false) { - this.state._isSubscribed = false; - if (forDestroy) { - delete this.state.clones[this.id]; - if (Object.keys(this.state.clones).length === 0) { - this.state.client.logger.trace(this.constructor.name, 'Last clone removed. Reset shared subscription state.'); - this.state.subscriptionInput.removeAll(); - this.state.parents = []; - } + processPayload(channel, payload) { + const { crypto, logVerbosity } = this.parameters; + if (!crypto || typeof payload.message !== 'string') + return { payload: payload.message }; + let decryptedPayload; + let error; + try { + const decryptedData = crypto.decrypt(payload.message); + decryptedPayload = + decryptedData instanceof ArrayBuffer + ? JSON.parse(FetchMessagesRequest.decoder.decode(decryptedData)) + : decryptedData; } - } - /** - * Start receiving real-time updates. - * - * @param parameters - Additional subscription configuration options which should be used - * for request. - */ - subscribe(parameters) { - if (this.state.isSubscribed) { - this.state.client.logger.trace(this.constructor.name, 'Already subscribed. Ignoring subscribe request.'); - return; + catch (err) { + if (logVerbosity) + console.log(`decryption error`, err.message); + decryptedPayload = payload.message; + error = `Error while decrypting message content: ${err.message}`; } - this.state.client.logger.debug(this.constructor.name, () => { - if (!parameters) - return { messageType: 'text', message: 'Subscribe' }; - return { messageType: 'object', message: parameters, details: 'Subscribe with parameters:' }; - }); - this.state.isSubscribed = true; - this.updateSubscription({ subscribing: true, timetoken: parameters === null || parameters === void 0 ? void 0 : parameters.timetoken }); - } - /** - * Stop real-time events processing. - * - * **Important:** {@link SubscriptionBase#unsubscribe unsubscribe} won't have any effect if a subscription object - * is part of active (subscribed) set. To unsubscribe an object, it should be removed from the set using - * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of - * {@link SubscriptionBase#unsubscribe unsubscribe} not required. - * - * **Note:** Unsubscribed instance won't call the dispatcher to deliver updates to the listeners. - */ - unsubscribe() { - // Check whether an instance-level subscription flag not set or parent has active subscription. - if (!this.state._isSubscribed || this.state.isSubscribed) { - // Warn if a user tries to unsubscribe using specific subscription which subscribed as part of a subscription set. - if (!this.state._isSubscribed && this.state.parents.length > 0 && this.state.isSubscribed) { - this.state.client.logger.warn(this.constructor.name, () => ({ - messageType: 'object', - details: 'Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:', - message: this.state.parents.filter((subscriptionSet) => subscriptionSet.isSubscribed), - })); - return; - } - else if (!this.state._isSubscribed) { - this.state.client.logger.trace(this.constructor.name, 'Not subscribed. Ignoring unsubscribe request.'); - return; - } + if (!error && + decryptedPayload && + payload.message_type == PubNubMessageType.Files && + typeof decryptedPayload === 'object' && + this.isFileMessage(decryptedPayload)) { + const fileMessage = decryptedPayload; + return { + payload: { + message: fileMessage.message, + file: Object.assign(Object.assign({}, fileMessage.file), { url: this.parameters.getFileUrl({ channel, id: fileMessage.file.id, name: fileMessage.file.name }) }), + }, + error, + }; } - this.state.client.logger.debug(this.constructor.name, 'Unsubscribe'); - this.state.isSubscribed = true; - delete this.state.cursor; - this.updateSubscription({ subscribing: false }); + return { payload: decryptedPayload, error }; } /** - * Update channels and groups used by subscription loop. + * Check whether `payload` potentially represents file message. * - * @param parameters - Subscription loop update parameters. - * @param parameters.subscribing - Whether subscription updates as part of subscription or unsubscription. - * @param [parameters.timetoken] - Subscription catch-up timetoken. - * @param [parameters.subscriptions] - List of subscriptions which should be used to modify a subscription loop - * object. + * @param payload - Fetched message payload. * - * @internal + * @returns `true` if payload can be {@link History#FileMessage|FileMessage}. */ - updateSubscription(parameters) { - var _a, _b; - if (parameters === null || parameters === void 0 ? void 0 : parameters.timetoken) { - if (((_a = this.state.cursor) === null || _a === void 0 ? void 0 : _a.timetoken) && ((_b = this.state.cursor) === null || _b === void 0 ? void 0 : _b.timetoken) !== '0') { - if (parameters.timetoken !== '0' && parameters.timetoken > this.state.cursor.timetoken) - this.state.cursor.timetoken = parameters.timetoken; - } - else - this.state.cursor = { timetoken: parameters.timetoken }; - } - const subscriptions = parameters.subscriptions && parameters.subscriptions.length > 0 ? parameters.subscriptions : undefined; - if (parameters.subscribing) { - this.register(Object.assign(Object.assign({}, (parameters.timetoken ? { cursor: this.state.cursor } : {})), (subscriptions ? { subscriptions } : {}))); - } - else - this.unregister(subscriptions); + isFileMessage(payload) { + return payload.file !== undefined; } } /** - * {@link SubscriptionSet} state object. + * Get Message Actions REST API module. * - * State object used across multiple {@link SubscriptionSet} object clones. + * @internal + */ + // endregion + /** + * Fetch channel message actions request. * * @internal */ - class SubscriptionSetState extends SubscriptionBaseState { - /** - * Create a subscription state object. - * - * @param parameters - State configuration options - * @param parameters.client - PubNub client which will work with a subscription object. - * @param parameters.subscriptions - List of subscriptions managed by set. - * @param [parameters.options] - Subscription behavior options. - */ + class GetMessageActionsRequest extends AbstractRequest { constructor(parameters) { - const subscriptionInput = new SubscriptionInput({}); - parameters.subscriptions.forEach((subscription) => subscriptionInput.add(subscription.state.subscriptionInput)); - super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); - this.subscriptions = parameters.subscriptions; + super(); + this.parameters = parameters; } - /** - * Add a single subscription object to the set. - * - * @param subscription - Another entity's subscription object, which should be added. - */ - addSubscription(subscription) { - if (this.subscriptions.includes(subscription)) - return; - subscription.state.addParentState(this); - this.subscriptions.push(subscription); - // Update subscription input. - this.subscriptionInput.add(subscription.state.subscriptionInput); + operation() { + return RequestOperation$1.PNGetMessageActionsOperation; } - /** - * Remove a single subscription object from the set. - * - * @param subscription - Another entity's subscription object, which should be removed. - * @param clone - Whether a target subscription is a clone. - */ - removeSubscription(subscription, clone) { - const index = this.subscriptions.indexOf(subscription); - if (index === -1) - return; - this.subscriptions.splice(index, 1); - if (!clone) - subscription.state.removeParentState(this); - // Update subscription input. - this.subscriptionInput.remove(subscription.state.subscriptionInput); + validate() { + if (!this.parameters.keySet.subscribeKey) + return 'Missing Subscribe Key'; + if (!this.parameters.channel) + return 'Missing message channel'; } - /** - * Remove any registered subscription object. - */ - removeAllSubscriptions() { - this.subscriptions.forEach((subscription) => subscription.state.removeParentState(this)); - this.subscriptions.splice(0, this.subscriptions.length); - this.subscriptionInput.removeAll(); + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + const serviceResponse = this.deserializeResponse(response); + let start = null; + let end = null; + if (serviceResponse.data.length > 0) { + start = serviceResponse.data[0].actionTimetoken; + end = serviceResponse.data[serviceResponse.data.length - 1].actionTimetoken; + } + return { + data: serviceResponse.data, + more: serviceResponse.more, + start, + end, + }; + }); + } + get path() { + const { keySet: { subscribeKey }, channel, } = this.parameters; + return `/v1/message-actions/${subscribeKey}/channel/${encodeString(channel)}`; + } + get queryParameters() { + const { limit, start, end } = this.parameters; + return Object.assign(Object.assign(Object.assign({}, (start ? { start } : {})), (end ? { end } : {})), (limit ? { limit } : {})); } } + /** - * Multiple entities subscription set object which can be used to receive and handle real-time - * updates. + * Add Message Action REST API module. * - * Subscription set object represents a collection of per-entity subscription objects and allows - * processing them at once for subscription loop and events handling. + * @internal */ - class SubscriptionSet extends SubscriptionBase { - /** - * Create entities' subscription set object. - * - * Subscription set object represents a collection of per-entity subscription objects and allows - * processing them at once for subscription loop and events handling. - * - * @param parameters - Subscription set object configuration. - * - * @returns Ready to use entities' subscription set object. - * - * @internal - */ + // endregion + /** + * Add Message Reaction request. + * + * @internal + */ + class AddMessageActionRequest extends AbstractRequest { constructor(parameters) { - let state; - if ('client' in parameters) { - let subscriptions = []; - if (!parameters.subscriptions && parameters.entities) { - parameters.entities.forEach((entity) => subscriptions.push(entity.subscription(parameters.options))); - } - else if (parameters.subscriptions) - subscriptions = parameters.subscriptions; - state = new SubscriptionSetState({ client: parameters.client, subscriptions, options: parameters.options }); - subscriptions.forEach((subscription) => subscription.state.addParentState(state)); - state.client.logger.debug('SubscriptionSet', () => ({ - messageType: 'object', - details: 'Create subscription set with parameters:', - message: Object.assign({ subscriptions: state.subscriptions }, (parameters.options ? parameters.options : {})), - })); - } - else { - state = parameters.state; - state.client.logger.debug('SubscriptionSet', 'Create subscription set clone'); - } - super(state); - this.state.storeClone(this.id, this); - // Update a parent sets list for original set subscriptions. - state.subscriptions.forEach((subscription) => subscription.addParentSet(this)); + super({ method: TransportMethod.POST }); + this.parameters = parameters; } - /** - * Get a {@link SubscriptionSet} object state. - * - * @returns: {@link SubscriptionSet} object state. - * - * @internal - */ - get state() { - return super.state; + operation() { + return RequestOperation$1.PNAddMessageActionOperation; } - /** - * Get a list of entities' subscription objects registered in a subscription set. - * - * @returns Entities' subscription objects list. - */ - get subscriptions() { - return this.state.subscriptions.slice(0); + validate() { + const { keySet: { subscribeKey }, action, channel, messageTimetoken, } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (!channel) + return 'Missing message channel'; + if (!messageTimetoken) + return 'Missing message timetoken'; + if (!action) + return 'Missing Action'; + if (!action.value) + return 'Missing Action.value'; + if (!action.type) + return 'Missing Action.type'; + if (action.type.length > 15) + return 'Action.type value exceed maximum length of 15'; } - // -------------------------------------------------------- - // -------------------- Event handler --------------------- - // -------------------------------------------------------- - // region Event handler - /** - * Dispatch received a real-time update. - * - * @param cursor - A time cursor for the next portion of events. - * @param event - A real-time event from multiplexed subscription. - * - * @return `true` if receiver has consumed event. - * - * @internal - */ - handleEvent(cursor, event) { + parse(response) { + const _super = Object.create(null, { + parse: { get: () => super.parse } + }); + return __awaiter(this, void 0, void 0, function* () { + return _super.parse.call(this, response).then(({ data }) => ({ data })); + }); + } + get path() { + const { keySet: { subscribeKey }, channel, messageTimetoken, } = this.parameters; + return `/v1/message-actions/${subscribeKey}/channel/${encodeString(channel)}/message/${messageTimetoken}`; + } + get headers() { var _a; - // Check whether an event is not designated for this subscription set. - if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) - return; - // Check whether `event` can be processed or not. - if (!this.state._isSubscribed) { - this.state.client.logger.trace(this.constructor.name, `Subscription set ${this.id} is not subscribed. Ignoring event.`); - return; - } - super.handleEvent(cursor, event); - if (this.state.subscriptions.length > 0) { - this.state.client.logger.trace(this.constructor.name, `Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`); - } - this.state.subscriptions.forEach((subscription) => subscription.handleEvent(cursor, event)); + return Object.assign(Object.assign({}, ((_a = super.headers) !== null && _a !== void 0 ? _a : {})), { 'Content-Type': 'application/json' }); } - // endregion - /** - User-provided subscription input associated with this {@link SubscriptionSet} object. - * - * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). - * - * @returns Subscription input object. - * - * @internal - */ - subscriptionInput(forUnsubscribe = false) { - let subscriptionInput = this.state.subscriptionInput; - this.state.subscriptions.forEach((subscription) => { - if (forUnsubscribe && subscription.state.entity.subscriptionsCount > 0) - subscriptionInput = subscriptionInput.without(subscription.state.subscriptionInput); - }); - return subscriptionInput; + get body() { + return JSON.stringify(this.parameters.action); } - /** - * Make a bare copy of the {@link SubscriptionSet} object. - * - * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as - * the source object. - * - * @returns Bare copy of a {@link SubscriptionSet} object. - */ - cloneEmpty() { - return new SubscriptionSet({ state: this.state }); + } + + /** + * Remove Message Action REST API module. + * + * @internal + */ + // endregion + /** + * Remove specific message action request. + * + * @internal + */ + class RemoveMessageAction extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; } - /** - * Graceful {@link SubscriptionSet} destruction. - * - * This is an instance destructor, which will properly deinitialize it: - * - remove and unset all listeners, - * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). - * - * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. - */ - dispose() { - const isLastClone = this.state.isLastClone; - this.state.subscriptions.forEach((subscription) => { - subscription.removeParentSet(this); - if (isLastClone) - subscription.state.removeParentState(this.state); - }); - super.dispose(); + operation() { + return RequestOperation$1.PNRemoveMessageActionOperation; } - /** - * Invalidate {@link SubscriptionSet} object. - * - * Clean up resources used by a subscription object. All {@link SubscriptionObject subscription} objects will be - * removed. - * - * **Important:** This method is used only when a global subscription set is used (backward compatibility). - * - * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. - * - * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. - * - * @internal - */ - invalidate(forDestroy = false) { - const subscriptions = forDestroy ? this.state.subscriptions.slice(0) : this.state.subscriptions; - subscriptions.forEach((subscription) => { - if (forDestroy) { - subscription.state.entity.decreaseSubscriptionCount(this.state.id); - subscription.removeParentSet(this); - } - subscription.invalidate(forDestroy); + validate() { + const { keySet: { subscribeKey }, channel, messageTimetoken, actionTimetoken, } = this.parameters; + if (!subscribeKey) + return 'Missing Subscribe Key'; + if (!channel) + return 'Missing message action channel'; + if (!messageTimetoken) + return 'Missing message timetoken'; + if (!actionTimetoken) + return 'Missing action timetoken'; + } + parse(response) { + const _super = Object.create(null, { + parse: { get: () => super.parse } + }); + return __awaiter(this, void 0, void 0, function* () { + return _super.parse.call(this, response).then(({ data }) => ({ data })); }); - if (forDestroy) - this.state.removeAllSubscriptions(); - super.invalidate(); } - /** - * Add an entity's subscription to the subscription set. - * - * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. - * - * @param subscription - Another entity's subscription object, which should be added. - */ - addSubscription(subscription) { - this.addSubscriptions([subscription]); + get path() { + const { keySet: { subscribeKey }, channel, actionTimetoken, messageTimetoken, } = this.parameters; + return `/v1/message-actions/${subscribeKey}/channel/${encodeString(channel)}/message/${messageTimetoken}/action/${actionTimetoken}`; } - /** - * Add an entity's subscriptions to the subscription set. - * - * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. - * - * @param subscriptions - List of entity's subscription objects, which should be added. - */ - addSubscriptions(subscriptions) { - const inactiveSubscriptions = []; - const activeSubscriptions = []; - this.state.client.logger.debug(this.constructor.name, () => { - const ignoredSubscriptions = []; - const subscriptionsToAdd = []; - subscriptions.forEach((subscription) => { - if (!this.state.subscriptions.includes(subscription)) - subscriptionsToAdd.push(subscription); - else - ignoredSubscriptions.push(subscription); - }); - return { - messageType: 'object', - details: `Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length + subscriptionsToAdd.length}):`, - message: { addedSubscriptions: subscriptionsToAdd, ignoredSubscriptions }, - }; - }); - subscriptions - .filter((subscription) => !this.state.subscriptions.includes(subscription)) - .forEach((subscription) => { - if (subscription.state.isSubscribed) - activeSubscriptions.push(subscription); - else - inactiveSubscriptions.push(subscription); - subscription.addParentSet(this); - this.state.addSubscription(subscription); + } + + /** + * Publish File Message REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Whether published file messages should be stored in the channel's history. + */ + const STORE_IN_HISTORY = true; + // endregion + /** + * Publish shared file information request. + * + * @internal + */ + class PublishFileMessageRequest extends AbstractRequest { + constructor(parameters) { + var _a; + var _b; + super(); + this.parameters = parameters; + // Apply default request parameters. + (_a = (_b = this.parameters).storeInHistory) !== null && _a !== void 0 ? _a : (_b.storeInHistory = STORE_IN_HISTORY); + } + operation() { + return RequestOperation$1.PNPublishFileMessageOperation; + } + validate() { + const { channel, fileId, fileName } = this.parameters; + if (!channel) + return "channel can't be empty"; + if (!fileId) + return "file id can't be empty"; + if (!fileName) + return "file name can't be empty"; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { timetoken: this.deserializeResponse(response)[2] }; }); - // Check whether there are any subscriptions for which the subscription loop should be changed or not. - if ((activeSubscriptions.length === 0 && inactiveSubscriptions.length === 0) || !this.state.isSubscribed) - return; - activeSubscriptions.forEach(({ state }) => state.entity.increaseSubscriptionCount(this.state.id)); - if (inactiveSubscriptions.length > 0) - this.updateSubscription({ subscribing: true, subscriptions: inactiveSubscriptions }); } - /** - * Remove an entity's subscription object from the set. - * - * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. - * - * @param subscription - Another entity's subscription object, which should be removed. - */ - removeSubscription(subscription) { - this.removeSubscriptions([subscription]); + get path() { + const { message, channel, keySet: { publishKey, subscribeKey }, fileId, fileName, } = this.parameters; + const fileMessage = Object.assign({ file: { + name: fileName, + id: fileId, + } }, (message ? { message } : {})); + return `/v1/files/publish-file/${publishKey}/${subscribeKey}/0/${encodeString(channel)}/0/${encodeString(this.prepareMessagePayload(fileMessage))}`; } - /** - * Remove an entity's subscription objects from the set. - * - * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. - * - * @param subscriptions - List entity's subscription objects, which should be removed. - */ - removeSubscriptions(subscriptions) { - const activeSubscriptions = []; - this.state.client.logger.debug(this.constructor.name, () => { - const ignoredSubscriptions = []; - const subscriptionsToRemove = []; - subscriptions.forEach((subscription) => { - if (this.state.subscriptions.includes(subscription)) - subscriptionsToRemove.push(subscription); - else - ignoredSubscriptions.push(subscription); - }); - return { - messageType: 'object', - details: `Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`, - message: { removedSubscriptions: subscriptionsToRemove, ignoredSubscriptions }, - }; - }); - subscriptions - .filter((subscription) => this.state.subscriptions.includes(subscription)) - .forEach((subscription) => { - if (subscription.state.isSubscribed) - activeSubscriptions.push(subscription); - subscription.removeParentSet(this); - this.state.removeSubscription(subscription, subscription.parentSetsCount > 1); - }); - // Check whether there are any subscriptions for which the subscription loop should be changed or not. - if (activeSubscriptions.length === 0 || !this.state.isSubscribed) - return; - this.updateSubscription({ subscribing: false, subscriptions: activeSubscriptions }); + get queryParameters() { + const { customMessageType, storeInHistory, ttl, meta } = this.parameters; + return Object.assign(Object.assign(Object.assign({ store: storeInHistory ? '1' : '0' }, (customMessageType ? { custom_message_type: customMessageType } : {})), (ttl ? { ttl } : {})), (meta && typeof meta === 'object' ? { meta: JSON.stringify(meta) } : {})); } /** - * Merge with another {@link SubscriptionSet} object. + * Pre-process provided data. * - * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * Data will be "normalized" and encrypted if `cryptoModule` has been provided. * - * @param subscriptionSet - Other entities' subscription set, which should be joined. - */ - addSubscriptionSet(subscriptionSet) { - this.addSubscriptions(subscriptionSet.subscriptions); - } - /** - * Subtract another {@link SubscriptionSet} object. + * @param payload - User-provided data which should be pre-processed before use. * - * **Important:** Changes will be effective immediately if {@link SubscriptionSet} already subscribed. + * @returns Payload which can be used as part of request URL or body. * - * @param subscriptionSet - Other entities' subscription set, which should be subtracted. + * @throws {Error} in case if provided `payload` or results of `encryption` can't be stringified. */ - removeSubscriptionSet(subscriptionSet) { - this.removeSubscriptions(subscriptionSet.subscriptions); + prepareMessagePayload(payload) { + const { crypto } = this.parameters; + if (!crypto) + return JSON.stringify(payload) || ''; + const encrypted = crypto.encrypt(JSON.stringify(payload)); + return JSON.stringify(typeof encrypted === 'string' ? encrypted : encode(encrypted)); } + } + + /** + * File sharing REST API module. + * + * @internal + */ + // endregion + /** + * File download Url generation request. + * + * Local request which generates Url to download shared file from the specific channel. + * + * @internal + */ + class GetFileDownloadUrlRequest extends AbstractRequest { /** - * Register {@link SubscriptionSet} object for real-time events' retrieval. - * - * @param parameters - Object registration parameters. - * @param [parameters.cursor] - Subscription real-time events catch-up cursor. - * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial - * modification). + * Construct file download Url generation request. * - * @internal + * @param parameters - Request configuration. */ - register(parameters) { + constructor(parameters) { + super({ method: TransportMethod.LOCAL }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGetFileUrlOperation; + } + validate() { + const { channel, id, name } = this.parameters; + if (!channel) + return "channel can't be empty"; + if (!id) + return "file id can't be empty"; + if (!name) + return "file name can't be empty"; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return response.url; + }); + } + get path() { + const { channel, id, name, keySet: { subscribeKey }, } = this.parameters; + return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files/${id}/${name}`; + } + } + + /** + * Delete file REST API module. + * + * @internal + */ + // endregion + /** + * Delete File request. + * + * @internal + */ + class DeleteFileRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNDeleteFileOperation; + } + validate() { + const { channel, id, name } = this.parameters; + if (!channel) + return "channel can't be empty"; + if (!id) + return "file id can't be empty"; + if (!name) + return "file name can't be empty"; + } + get path() { + const { keySet: { subscribeKey }, id, channel, name, } = this.parameters; + return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files/${id}/${name}`; + } + } + + /** + * List Files REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Number of files to return in response. + */ + const LIMIT$6 = 100; + // endregion + /** + * Files List request. + * + * @internal + */ + class FilesListRequest extends AbstractRequest { + constructor(parameters) { var _a; - const subscriptions = ((_a = parameters.subscriptions) !== null && _a !== void 0 ? _a : this.state.subscriptions); - subscriptions.forEach(({ state }) => state.entity.increaseSubscriptionCount(this.state.id)); - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Register subscription for real-time events: ${this}`, - })); - this.state.client.registerEventHandleCapable(this, parameters.cursor, subscriptions); + var _b; + super(); + this.parameters = parameters; + // Apply default request parameters. + (_a = (_b = this.parameters).limit) !== null && _a !== void 0 ? _a : (_b.limit = LIMIT$6); + } + operation() { + return RequestOperation$1.PNListFilesOperation; + } + validate() { + if (!this.parameters.channel) + return "channel can't be empty"; + } + get path() { + const { keySet: { subscribeKey }, channel, } = this.parameters; + return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files`; + } + get queryParameters() { + const { limit, next } = this.parameters; + return Object.assign({ limit: limit }, (next ? { next } : {})); + } + } + + /** + * Generate file upload URL REST API request. + * + * @internal + */ + // endregion + /** + * Generate File Upload Url request. + * + * @internal + */ + class GenerateFileUploadUrlRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGenerateUploadUrlOperation; + } + validate() { + if (!this.parameters.channel) + return "channel can't be empty"; + if (!this.parameters.name) + return "'name' can't be empty"; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + const serviceResponse = this.deserializeResponse(response); + return { + id: serviceResponse.data.id, + name: serviceResponse.data.name, + url: serviceResponse.file_upload_request.url, + formFields: serviceResponse.file_upload_request.form_fields, + }; + }); } - /** - * Unregister {@link SubscriptionSet} object from real-time events' retrieval. - * - * @param [subscriptions] - List of subscription objects which should be unregistered (in case of partial - * modification). - * - * @internal - */ - unregister(subscriptions) { - const activeSubscriptions = (subscriptions !== null && subscriptions !== void 0 ? subscriptions : this.state.subscriptions); - activeSubscriptions.forEach(({ state }) => state.entity.decreaseSubscriptionCount(this.state.id)); - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Unregister subscription from real-time events: ${this}`, - })); - this.state.client.unregisterEventHandleCapable(this, activeSubscriptions); + get path() { + const { keySet: { subscribeKey }, channel, } = this.parameters; + return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/generate-upload-url`; } - /** - * Stringify subscription object. - * - * @returns Serialized subscription object. - */ - toString() { - const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${state.isSubscribed}, subscriptions: [${state.subscriptions - .map((sub) => sub.toString()) - .join(', ')}] }`; + get headers() { + var _a; + return Object.assign(Object.assign({}, ((_a = super.headers) !== null && _a !== void 0 ? _a : {})), { 'Content-Type': 'application/json' }); + } + get body() { + return JSON.stringify({ name: this.parameters.name }); } } /** - * {@link Subscription} state object. - * - * State object used across multiple {@link Subscription} object clones. + * Upload file REST API request. * * @internal */ - class SubscriptionState extends SubscriptionBaseState { - /** - * Create a subscription state object. - * - * @param parameters - State configuration options - * @param parameters.client - PubNub client which will work with a subscription object. - * @param parameters.entity - Entity for which a subscription object has been created. - * @param [parameters.options] - Subscription behavior options. - */ - constructor(parameters) { - var _a, _b; - const names = parameters.entity.subscriptionNames((_b = (_a = parameters.options) === null || _a === void 0 ? void 0 : _a.receivePresenceEvents) !== null && _b !== void 0 ? _b : false); - const subscriptionInput = new SubscriptionInput({ - [parameters.entity.subscriptionType == SubscriptionType.Channel ? 'channels' : 'channelGroups']: names, - }); - super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); - this.entity = parameters.entity; - } - } /** - * Single-entity subscription object which can be used to receive and handle real-time updates. + * File Upload request. + * + * @internal */ - class Subscription extends SubscriptionBase { - /** - * Create a subscribing capable object for entity. - * - * @param parameters - Subscription object configuration. - * - * @internal - */ + class UploadFileRequest extends AbstractRequest { constructor(parameters) { - if ('client' in parameters) { - parameters.client.logger.debug('Subscription', () => ({ - messageType: 'object', - details: 'Create subscription with parameters:', - message: Object.assign({ entity: parameters.entity }, (parameters.options ? parameters.options : {})), - })); + super({ method: TransportMethod.POST }); + this.parameters = parameters; + // Use file's actual mime type if available. + const mimeType = parameters.file.mimeType; + if (mimeType) { + parameters.formFields = parameters.formFields.map((entry) => { + if (entry.name === 'Content-Type') + return { name: entry.name, value: mimeType }; + return entry; + }); } - else - parameters.state.client.logger.debug('Subscription', 'Create subscription clone'); - super('state' in parameters ? parameters.state : new SubscriptionState(parameters)); - /** - * List of subscription {@link SubscriptionSet sets} which contains {@link Subscription subscription}. - * - * List if used to track usage of a specific {@link Subscription subscription} in other subscription - * {@link SubscriptionSet sets}. - * - * **Important:** Tracking is required to prevent cloned instance dispose if there are sets that still use it. - * - * @internal - */ - this.parents = []; - /** - * List of fingerprints from updates which has been handled already. - * - * **Important:** Tracking is required to avoid repetitive call of the subscription object's listener when the object - * is part of multiple subscribed sets. Handler will be called once, and then the fingerprint will be stored in this - * list to avoid another listener call for it. - * - * @internal - */ - this.handledUpdates = []; - this.state.storeClone(this.id, this); - } - /** - * Get a {@link Subscription} object state. - * - * @returns: {@link Subscription} object state. - * - * @internal - */ - get state() { - return super.state; } - /** - * Get number of {@link SubscriptionSet} which use this subscription object. - * - * @returns Number of {@link SubscriptionSet} which use this subscription object. - * - * @internal - */ - get parentSetsCount() { - return this.parents.length; + operation() { + return RequestOperation$1.PNPublishFileOperation; } - // -------------------------------------------------------- - // -------------------- Event handler --------------------- - // -------------------------------------------------------- - // region Event handler - /** - * Dispatch received a real-time update. - * - * @param cursor - A time cursor for the next portion of events. - * @param event - A real-time event from multiplexed subscription. - * - * @return `true` if receiver has consumed event. - * - * @internal - */ - handleEvent(cursor, event) { - var _a; - if (!this.state.isSubscribed) - return; - if (this.parentSetsCount > 0) { - // Creating from whole payload (not only for published messages). - const fingerprint = messageFingerprint(event.data); - if (this.handledUpdates.includes(fingerprint)) { - this.state.client.logger.trace(this.constructor.name, `Message (${fingerprint}) already handled. Ignoring.`); - return; - } - // Update a list of tracked messages and shrink it if too big. - this.handledUpdates.push(fingerprint); - if (this.handledUpdates.length > 10) - this.handledUpdates.shift(); - } - // Check whether an event is not designated for this subscription set. - if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) - return; - super.handleEvent(cursor, event); + validate() { + const { fileId, fileName, file, uploadUrl } = this.parameters; + if (!fileId) + return "Validation failed: file 'id' can't be empty"; + if (!fileName) + return "Validation failed: file 'name' can't be empty"; + if (!file) + return "Validation failed: 'file' can't be empty"; + if (!uploadUrl) + return "Validation failed: file upload 'url' can't be empty"; } - // endregion - /** - * User-provided subscription input associated with this {@link Subscription} object. - * - * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). - * - * @returns Subscription input object. - * - * @internal - */ - subscriptionInput(forUnsubscribe = false) { - if (forUnsubscribe && this.state.entity.subscriptionsCount > 0) - return new SubscriptionInput({}); - return this.state.subscriptionInput; + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { + status: response.status, + message: response.body ? UploadFileRequest.decoder.decode(response.body) : 'OK', + }; + }); } - /** - * Make a bare copy of the {@link Subscription} object. - * - * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as - * the source object. - * - * @returns Bare copy of a {@link Subscription} object. - */ - cloneEmpty() { - return new Subscription({ state: this.state }); + request() { + return Object.assign(Object.assign({}, super.request()), { origin: new URL(this.parameters.uploadUrl).origin, timeout: 300 }); } - /** - * Graceful {@link Subscription} object destruction. - * - * This is an instance destructor, which will properly deinitialize it: - * - remove and unset all listeners, - * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). - * - * **Important:** {@link Subscription#dispose dispose} won't have any effect if a subscription object is part of - * {@link SubscriptionSet set}. To gracefully dispose an object, it should be removed from the set using - * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of - * {@link Subscription#dispose dispose} not required). - * - * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. - */ - dispose() { - if (this.parentSetsCount > 0) { - this.state.client.logger.debug(this.constructor.name, () => ({ - messageType: 'text', - message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, - })); - return; - } - this.handledUpdates.splice(0, this.handledUpdates.length); - super.dispose(); + get path() { + const { pathname, search } = new URL(this.parameters.uploadUrl); + return `${pathname}${search}`; } - /** - * Invalidate subscription object. - * - * Clean up resources used by a subscription object. - * - * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. - * - * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. - * - * @internal - */ - invalidate(forDestroy = false) { - if (forDestroy) - this.state.entity.decreaseSubscriptionCount(this.state.id); - this.handledUpdates.splice(0, this.handledUpdates.length); - super.invalidate(forDestroy); + get body() { + return this.parameters.file; } - /** - * Add another {@link SubscriptionSet} into which subscription has been added. - * - * @param parent - {@link SubscriptionSet} which has been modified. - * - * @internal - */ - addParentSet(parent) { - if (!this.parents.includes(parent)) { - this.parents.push(parent); - this.state.client.logger.trace(this.constructor.name, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); - } + get formData() { + return this.parameters.formFields; } - /** - * Remove {@link SubscriptionSet} upon subscription removal from it. - * - * @param parent - {@link SubscriptionSet} which has been modified. - * - * @internal - */ - removeParentSet(parent) { - const parentIndex = this.parents.indexOf(parent); - if (parentIndex !== -1) { - this.parents.splice(parentIndex, 1); - this.state.client.logger.trace(this.constructor.name, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); - } - if (this.parentSetsCount === 0) - this.handledUpdates.splice(0, this.handledUpdates.length); + } + + /** + * Share File API module. + * + * @internal + */ + // endregion + /** + * Send file composed request. + * + * @internal + */ + class SendFileRequest { + constructor(parameters) { + var _a; + this.parameters = parameters; + this.file = (_a = this.parameters.PubNubFile) === null || _a === void 0 ? void 0 : _a.create(parameters.file); + if (!this.file) + throw new Error('File upload error: unable to create File object.'); } /** - * Merge entities' subscription objects into {@link SubscriptionSet}. - * - * @param subscription - Another entity's subscription object to be merged with receiver. + * Process user-input and upload file. * - * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. + * @returns File upload request response. */ - addSubscription(subscription) { - this.state.client.logger.debug(this.constructor.name, () => ({ - messageType: 'text', - message: `Create set with subscription: ${subscription}`, - })); - const subscriptionSet = new SubscriptionSet({ - client: this.state.client, - subscriptions: [this, subscription], - options: this.state.options, + process() { + return __awaiter(this, void 0, void 0, function* () { + let fileName; + let fileId; + return this.generateFileUploadUrl() + .then((result) => { + fileName = result.name; + fileId = result.id; + return this.uploadFile(result); + }) + .then((result) => { + if (result.status !== 204) { + throw new PubNubError('Upload to bucket was unsuccessful', { + error: true, + statusCode: result.status, + category: StatusCategory$1.PNUnknownCategory, + operation: RequestOperation$1.PNPublishFileOperation, + errorData: { message: result.message }, + }); + } + }) + .then(() => this.publishFileMessage(fileId, fileName)) + .catch((error) => { + if (error instanceof PubNubError) + throw error; + const apiError = !(error instanceof PubNubAPIError) ? PubNubAPIError.create(error) : error; + throw new PubNubError('File upload error.', apiError.toStatus(RequestOperation$1.PNPublishFileOperation)); + }); }); - // Check whether a source subscription is already subscribed or not. - if (!this.state.isSubscribed && !subscription.state.isSubscribed) - return subscriptionSet; - this.state.client.logger.trace(this.constructor.name, 'Subscribe resulting set because the receiver is already subscribed.'); - // Subscribing resulting subscription set because source subscription was subscribed. - subscriptionSet.subscribe(); - return subscriptionSet; } /** - * Register {@link Subscription} object for real-time events' retrieval. - * - * **Note:** Superclass calls this method only in response to a {@link Subscription.subscribe subscribe} method call. - * - * @param parameters - Object registration parameters. - * @param [parameters.cursor] - Subscription real-time events catch-up cursor. - * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial - * modification). + * Generate pre-signed file upload Url. * - * @internal + * @returns File upload credentials. */ - register(parameters) { - this.state.entity.increaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Register subscription for real-time events: ${this}`, - })); - this.state.client.registerEventHandleCapable(this, parameters.cursor); + generateFileUploadUrl() { + return __awaiter(this, void 0, void 0, function* () { + const request = new GenerateFileUploadUrlRequest(Object.assign(Object.assign({}, this.parameters), { name: this.file.name, keySet: this.parameters.keySet })); + return this.parameters.sendRequest(request); + }); } /** - * Unregister {@link Subscription} object from real-time events' retrieval. - * - * **Note:** Superclass calls this method only in response to a {@link Subscription.unsubscribe unsubscribe} method - * call. + * Prepare and upload {@link PubNub} File object to remote storage. * - * @param [_subscriptions] - List of subscription objects which should be unregistered (in case of partial - * modification). + * @param uploadParameters - File upload request parameters. * - * @internal + * @returns */ - unregister(_subscriptions) { - this.state.entity.decreaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Unregister subscription from real-time events: ${this}`, - })); - this.handledUpdates.splice(0, this.handledUpdates.length); - this.state.client.unregisterEventHandleCapable(this); + uploadFile(uploadParameters) { + return __awaiter(this, void 0, void 0, function* () { + const { cipherKey, PubNubFile, crypto, cryptography } = this.parameters; + const { id, name, url, formFields } = uploadParameters; + // Encrypt file if possible. + if (this.parameters.PubNubFile.supportsEncryptFile) { + if (!cipherKey && crypto) + this.file = (yield crypto.encryptFile(this.file, PubNubFile)); + else if (cipherKey && cryptography) + this.file = (yield cryptography.encryptFile(cipherKey, this.file, PubNubFile)); + } + return this.parameters.sendRequest(new UploadFileRequest({ + fileId: id, + fileName: name, + file: this.file, + uploadUrl: url, + formFields, + })); + }); } - /** - * Stringify subscription object. - * - * @returns Serialized subscription object. - */ - toString() { - const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity - .subscriptionNames(false) - .pop()}, clonesCount: ${Object.keys(state.clones).length}, isSubscribed: ${state.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${state.cursor ? state.cursor.timetoken : 'not set'}, referenceTimetoken: ${state.referenceTimetoken ? state.referenceTimetoken : 'not set'} }`; + publishFileMessage(fileId, fileName) { + return __awaiter(this, void 0, void 0, function* () { + var _a, _b, _c, _d; + let result = { timetoken: '0' }; + let retries = this.parameters.fileUploadPublishRetryLimit; + let publishError; + let wasSuccessful = false; + do { + try { + result = yield this.parameters.publishFile(Object.assign(Object.assign({}, this.parameters), { fileId, fileName })); + wasSuccessful = true; + } + catch (error) { + if (error instanceof PubNubError) + publishError = error; + retries -= 1; + } + } while (!wasSuccessful && retries > 0); + if (!wasSuccessful) { + throw new PubNubError('Publish failed. You may want to execute that operation manually using pubnub.publishFile', { + error: true, + category: (_b = (_a = publishError.status) === null || _a === void 0 ? void 0 : _a.category) !== null && _b !== void 0 ? _b : StatusCategory$1.PNUnknownCategory, + statusCode: (_d = (_c = publishError.status) === null || _c === void 0 ? void 0 : _c.statusCode) !== null && _d !== void 0 ? _d : 0, + channel: this.parameters.channel, + id: fileId, + name: fileName, + }); + } + else + return { status: 200, timetoken: result.timetoken, id: fileId, name: fileName }; + }); } } @@ -12191,6 +12237,22 @@ this.client = client; this._nameOrId = nameOrId; } + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'Channel'; + } /** * Type of subscription entity. * @@ -12285,7 +12347,7 @@ * @returns Serialized entity object. */ toString() { - return `${this.constructor.name} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`; + return `${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`; } } @@ -12293,6 +12355,22 @@ * First-class objects which provides access to the channel app context object-specific APIs. */ class ChannelMetadata extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'ChannelMetadata'; + } /** * Get unique channel metadata object identifier. * @@ -12322,6 +12400,22 @@ * First-class objects which provides access to the channel group-specific APIs. */ class ChannelGroup extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'ChannelGroups'; + } /** * Get a unique channel group name. * @@ -12348,6 +12442,22 @@ * First-class objects which provides access to the user app context object-specific APIs. */ class UserMetadata extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'UserMetadata'; + } /** * Get unique user metadata object identifier. * @@ -12377,6 +12487,22 @@ * First-class objects which provides access to the channel-specific APIs. */ class Channel extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'Channel'; + } /** * Get a unique channel name. * @@ -13558,6 +13684,13 @@ if (!this.parameters.data) return 'Data cannot be empty'; } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json' }); + } get path() { const { keySet: { subscribeKey }, channel, } = this.parameters; return `/v2/objects/${subscribeKey}/channels/${encodeString(channel)}`; @@ -14972,19 +15105,29 @@ }, delay: (amount) => new Promise((resolve) => setTimeout(resolve, amount)), join: (parameters) => { + var _a, _b; this.logger.trace('EventEngine', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Join with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('EventEngine', "Ignoring 'join' announcement request."); + return; + } this.join(parameters); }, leave: (parameters) => { + var _a, _b; this.logger.trace('EventEngine', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Leave with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('EventEngine', "Ignoring 'leave' announcement request."); + return; + } this.leave(parameters); }, leaveAll: (parameters) => { @@ -15788,6 +15931,44 @@ } if (subscriptionInput.isEmpty) return; + else { + const _channelGroupsInUse = []; + const _channelsInUse = []; + Object.values(this.eventHandleCapable).forEach((_subscription) => { + const _subscriptionInput = _subscription.subscriptionInput(false); + const _subscriptionChannelGroups = _subscriptionInput.channelGroups; + const _subscriptionChannels = _subscriptionInput.channels; + _channelGroupsInUse.push(...subscriptionInput.channelGroups.filter((channel) => _subscriptionChannelGroups.includes(channel))); + _channelsInUse.push(...subscriptionInput.channels.filter((channel) => _subscriptionChannels.includes(channel))); + }); + if (_channelsInUse.length > 0 || _channelGroupsInUse.length > 0) { + this.logger.trace('PubNub', () => { + const _entitiesInUse = []; + const addEntityIfInUse = (entity) => { + const namesOrIds = entity.subscriptionNames(true); + const checkList = entity.subscriptionType === SubscriptionType.Channel ? _channelsInUse : _channelGroupsInUse; + if (namesOrIds.some((id) => checkList.includes(id))) + _entitiesInUse.push(entity); + }; + Object.values(this.eventHandleCapable).forEach((_subscription) => { + if (_subscription instanceof SubscriptionSet) { + _subscription.subscriptions.forEach((_subscriptionInSet) => { + addEntityIfInUse(_subscriptionInSet.state.entity); + }); + } + else if (_subscription instanceof Subscription) + addEntityIfInUse(_subscription.state.entity); + }); + let details = 'Some entities still in use:'; + if (_channelsInUse.length + _channelGroupsInUse.length === subscriptionInput.length) + details = "Can't unregister event handle capable because entities still in use:"; + return { messageType: 'object', message: { entities: _entitiesInUse }, details }; + }); + subscriptionInput.remove(new SubscriptionInput({ channels: _channelsInUse, channelGroups: _channelGroupsInUse })); + if (subscriptionInput.isEmpty) + return; + } + } const parameters = {}; parameters.channels = subscriptionInput.channels; parameters.channelGroups = subscriptionInput.channelGroups; @@ -16463,6 +16644,7 @@ */ heartbeat(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { + var _a; { this.logger.trace('PubNub', () => ({ messageType: 'object', @@ -16498,13 +16680,20 @@ return; this.logger.trace('PubNub', 'Heartbeat success.'); }; + const abortUnsubscribe = (_a = parameters.abortSignal) === null || _a === void 0 ? void 0 : _a.subscribe((err) => { + request.abort('Cancel long-poll subscribe request'); + }); if (callback) return this.sendRequest(request, (status, response) => { logResponse(response); + if (abortUnsubscribe) + abortUnsubscribe(); callback(status, response); }); return this.sendRequest(request).then((response) => { logResponse(response); + if (abortUnsubscribe) + abortUnsubscribe(); return response; }); } @@ -16520,12 +16709,17 @@ * @param parameters - List of channels and groups where `join` event should be sent. */ join(parameters) { + var _a, _b; { this.logger.trace('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Join with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('PubNub', "Ignoring 'join' announcement request."); + return; + } if (this.presenceEventEngine) this.presenceEventEngine.join(parameters); else { @@ -16566,15 +16760,19 @@ * @param parameters - List of channels and groups where `leave` event should be sent. */ leave(parameters) { - var _a; + var _a, _b, _c; { this.logger.trace('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Leave with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('PubNub', "Ignoring 'leave' announcement request."); + return; + } if (this.presenceEventEngine) - (_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leave(parameters); + (_c = this.presenceEventEngine) === null || _c === void 0 ? void 0 : _c.leave(parameters); else this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { }); } diff --git a/dist/web/pubnub.min.js b/dist/web/pubnub.min.js index 42be16df3..7d94be1ac 100644 --- a/dist/web/pubnub.min.js +++ b/dist/web/pubnub.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),h(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function m(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var y=function e(){var r,d,y=l(),f=y>>5,v=31&y;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)w+=d,S.push(u(d));var O=new Uint8Array(w),k=0;for(r=0;r=0;)m(C,d);else m(C,d);return String.fromCharCode.apply(null,C);case 4:var P;if(d<0)for(P=[];!p();)P.push(e());else for(P=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==i?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==i&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,m,y,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),h=l,l=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),m=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=m.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=S,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],l=(o=e[i+1],e[i+2]),h=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],m=e[i+8],y=e[i+9],f=e[i+10],v=e[i+11],S=e[i+12],w=e[i+13],O=e[i+14],k=e[i+15],C=t(C=a[0],E=a[1],j=a[2],P=a[3],c,7,u[0]),P=t(P,C,E,j,o,12,u[1]),j=t(j,P,C,E,l,17,u[2]),E=t(E,j,P,C,h,22,u[3]);C=t(C,E,j,P,d,7,u[4]),P=t(P,C,E,j,p,12,u[5]),j=t(j,P,C,E,g,17,u[6]),E=t(E,j,P,C,b,22,u[7]),C=t(C,E,j,P,m,7,u[8]),P=t(P,C,E,j,y,12,u[9]),j=t(j,P,C,E,f,17,u[10]),E=t(E,j,P,C,v,22,u[11]),C=t(C,E,j,P,S,7,u[12]),P=t(P,C,E,j,w,12,u[13]),j=t(j,P,C,E,O,17,u[14]),C=s(C,E=t(E,j,P,C,k,22,u[15]),j,P,o,5,u[16]),P=s(P,C,E,j,g,9,u[17]),j=s(j,P,C,E,v,14,u[18]),E=s(E,j,P,C,c,20,u[19]),C=s(C,E,j,P,p,5,u[20]),P=s(P,C,E,j,f,9,u[21]),j=s(j,P,C,E,k,14,u[22]),E=s(E,j,P,C,d,20,u[23]),C=s(C,E,j,P,y,5,u[24]),P=s(P,C,E,j,O,9,u[25]),j=s(j,P,C,E,h,14,u[26]),E=s(E,j,P,C,m,20,u[27]),C=s(C,E,j,P,w,5,u[28]),P=s(P,C,E,j,l,9,u[29]),j=s(j,P,C,E,b,14,u[30]),C=n(C,E=s(E,j,P,C,S,20,u[31]),j,P,p,4,u[32]),P=n(P,C,E,j,m,11,u[33]),j=n(j,P,C,E,v,16,u[34]),E=n(E,j,P,C,O,23,u[35]),C=n(C,E,j,P,o,4,u[36]),P=n(P,C,E,j,d,11,u[37]),j=n(j,P,C,E,b,16,u[38]),E=n(E,j,P,C,f,23,u[39]),C=n(C,E,j,P,w,4,u[40]),P=n(P,C,E,j,c,11,u[41]),j=n(j,P,C,E,h,16,u[42]),E=n(E,j,P,C,g,23,u[43]),C=n(C,E,j,P,y,4,u[44]),P=n(P,C,E,j,S,11,u[45]),j=n(j,P,C,E,k,16,u[46]),C=r(C,E=n(E,j,P,C,l,23,u[47]),j,P,c,6,u[48]),P=r(P,C,E,j,b,10,u[49]),j=r(j,P,C,E,O,15,u[50]),E=r(E,j,P,C,p,21,u[51]),C=r(C,E,j,P,S,6,u[52]),P=r(P,C,E,j,h,10,u[53]),j=r(j,P,C,E,f,15,u[54]),E=r(E,j,P,C,o,21,u[55]),C=r(C,E,j,P,m,6,u[56]),P=r(P,C,E,j,k,10,u[57]),j=r(j,P,C,E,g,15,u[58]),E=r(E,j,P,C,w,21,u[59]),C=r(C,E,j,P,d,6,u[60]),P=r(P,C,E,j,v,10,u[61]),j=r(j,P,C,E,l,15,u[62]),E=r(E,j,P,C,y,21,u[63]);a[0]=a[0]+C|0,a[1]=a[1]+E|0,a[2]=a[2]+j|0,a[3]=a[3]+P|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,l.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,m=0;for(g=0;256>g;g++){var y=(y=m^m<<1^m<<2^m<<3^m<<4)>>>8^255&y^99;n[b]=y,r[y]=b;var f=p[b],v=p[f],w=p[v],O=257*p[y]^16843008*y;i[b]=O<<24|O>>>8,a[b]=O<<16|O>>>16,o[b]=O<<8|O>>>24,c[b]=O,O=16843009*w^65537*v^257*f^16843008*b,u[y]=O<<24|O>>>8,l[y]=O<<16|O>>>16,h[y]=O<<8|O>>>24,d[y]=O,b?(b=f^p[p[p[w^f]]],m^=p[p[m]]):b=m=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[l>>>16&255]^i[h>>>8&255]^a[255&d]^s[p++],m=n[l>>>24]^r[h>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],y=n[h>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[l>>>8&255]^a[255&h]^s[p++],u=b,l=m,h=y}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],m=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],y=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=m,e[t+2]=y,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var w=t(S);class O{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=w,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:O.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return O.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(O.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=O.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e})))}get logger(){return this._logger}HMACSHA256(e){return w.HmacSHA256(e,this.configuration.secretKey).toString(w.enc.Base64)}SHA256(e){return w.SHA256(e).toString(w.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn(this.constructor.name,"'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn(this.constructor.name,"'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug(this.constructor.name,(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Encrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=w.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(w.enc.Base64)}const a=this.getIV(s);return w.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(w.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug(this.constructor.name,(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Decrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=k(t.slice(0,16)),n=k(t.slice(16));try{const e=w.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(w.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error(this.constructor.name,(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=w.enc.Base64.parse(e),n=w.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(w.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error(this.constructor.name,(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?w.enc.Base64.parse(e):"hex"===t.keyEncoding?w.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?w.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?w.mode.ECB:w.mode.CBC}getIV(e){return"cbc"===e.mode?w.enc.Utf8.parse(this.iv):null}getRandomIV(){return w.lib.WordArray.random(16)}}class P{encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=P.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return P.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(P.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(P.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=P.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return P.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",P.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=P.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}P.IV_LENGTH=16,P.encoder=new TextEncoder,P.decoder=new TextDecoder;class j{constructor(e){this.config=e,this.cryptor=new C(Object.assign({},e)),this.fileCryptor=new P}set logger(e){this.cryptor.logger=e}encrypt(e){const t="string"==typeof e?e:j.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){const e=Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]);return`${this.constructor.name} { ${e.join(", ")} }`}}j.encoder=new TextEncoder,j.decoder=new TextDecoder;class E extends a{set logger(e){if(this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER)this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===E.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new j(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new O({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new O({cipherKey:e.cipherKey}),cryptors:[new j(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(E.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=N.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=N.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===N.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof T)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=N.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}E.LEGACY_IDENTIFIER="";class N{static from(e,t){if(e!==N.LEGACY_IDENTIFIER)return new T(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==N.SENTINEL))return E.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>N.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+N.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new T(this.decoder.decode(n),a)}}N.SENTINEL="PNED",N.LEGACY_IDENTIFIER="",N.IDENTIFIER_LENGTH=4,N.VERSION=1,N.MAX_VERSION=1,N.decoder=new TextDecoder;class T{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return N.VERSION}get length(){return N.SENTINEL.length+1+N.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(N.SENTINEL)),e+=N.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=N.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}T.IDENTIFIER_LENGTH=4,T.SENTINEL="PNED";class _ extends Error{static create(e,t){return _.isErrorObject(e)?_.createFromError(e):_.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new _(s,t,0);if(e instanceof _)return e;if(_.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new _(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":400===i?(n=h.PNBadRequestCategory,r="Bad request"):403===i&&(n=h.PNAccessDeniedCategory,r="Access denied"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);"object"==typeof e&&(Array.isArray(e)?"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]):("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e?(s=e,i=e.status):s=e,"error"in e&&e.error instanceof Error&&(s=e.error)))}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new _(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,_.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}class I{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug(this.constructor.name,"Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.token=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error(this.constructor.name,(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogVerbosity:this.configuration.workerLogVerbosity},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e)}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",t.message);else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t})}else if("request-process-success"===t.type||"request-process-error"===t.type){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);if("request-process-success"===t.type)e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body});else{let e=h.PNUnknownCategory,n="Unknown error";if(t.error)"NETWORK_ISSUE"===t.error.type?e=h.PNNetworkIssuesCategory:"TIMEOUT"===t.error.type?e=h.PNTimeoutCategory:"ABORTED"===t.error.type&&(e=h.PNCancelledCategory),n=`${t.error.message} (${t.identifier})`;else if(t.response)return s(_.create({url:t.url,headers:t.response.headers,body:t.response.body,status:t.response.status},t.response.body));s(new _(n,e,0,new Error(n)))}}}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;const s=e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0;if(s)return this.accessTokensMap[s]?this.accessTokensMap[s]:this.stringifyAccessToken(s).then((([e,t])=>{if(e&&t)return(this.accessTokensMap={[s]:{token:t,expiration:e.timestamp*e.ttl*60}})[s]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}}function M(e){const t=e=>"object"==typeof e&&null!==e&&e.constructor===Object,s=e=>"number"==typeof e&&isFinite(e);if(!t(e))return e;const n={};return Object.keys(e).forEach((r=>{const i=(e=>"string"==typeof e||e instanceof String)(r);let a=r;const o=e[r];if(i&&r.indexOf(",")>=0){a=r.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(s(r)||i&&!isNaN(Number(r)))&&(a=String.fromCharCode(s(r)?r:parseInt(r,10)));n[a]=t(o)?M(o):o})),n}const A=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,l,h,p,g,b,m,y;const f=Object.assign({},e);if(null!==(t=f.logVerbosity)&&void 0!==t||(f.logVerbosity=!1),null!==(s=f.ssl)&&void 0!==s||(f.ssl=!0),null!==(n=f.transactionalRequestTimeout)&&void 0!==n||(f.transactionalRequestTimeout=15),null!==(r=f.subscribeRequestTimeout)&&void 0!==r||(f.subscribeRequestTimeout=310),null!==(i=f.fileRequestTimeout)&&void 0!==i||(f.fileRequestTimeout=300),null!==(a=f.restore)&&void 0!==a||(f.restore=!1),null!==(o=f.useInstanceId)&&void 0!==o||(f.useInstanceId=!1),null!==(c=f.suppressLeaveEvents)&&void 0!==c||(f.suppressLeaveEvents=!1),null!==(u=f.requestMessageCountThreshold)&&void 0!==u||(f.requestMessageCountThreshold=100),null!==(l=f.autoNetworkDetection)&&void 0!==l||(f.autoNetworkDetection=!1),null!==(h=f.enableEventEngine)&&void 0!==h||(f.enableEventEngine=!1),null!==(p=f.maintainPresenceState)&&void 0!==p||(f.maintainPresenceState=!0),null!==(g=f.useSmartHeartbeat)&&void 0!==g||(f.useSmartHeartbeat=!1),null!==(b=f.keepAlive)&&void 0!==b||(f.keepAlive=!1),f.userId&&f.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(m=f.userId)&&void 0!==m||(f.userId=f.uuid),!f.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=f.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");f.origin||(f.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const v={subscribeKey:f.subscribeKey,publishKey:f.publishKey,secretKey:f.secretKey};void 0!==f.presenceTimeout&&(f.presenceTimeout>320?(f.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):f.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete f.presenceTimeout)),void 0!==f.presenceTimeout?f.heartbeatInterval=f.presenceTimeout/2-1:f.presenceTimeout=300;let S=!1,w=!0,O=5,k=!1,C=100,P=!0;return void 0!==f.dedupeOnSubscribe&&"boolean"==typeof f.dedupeOnSubscribe&&(k=f.dedupeOnSubscribe),void 0!==f.maximumCacheSize&&"number"==typeof f.maximumCacheSize&&(C=f.maximumCacheSize),void 0!==f.useRequestId&&"boolean"==typeof f.useRequestId&&(P=f.useRequestId),void 0!==f.announceSuccessfulHeartbeats&&"boolean"==typeof f.announceSuccessfulHeartbeats&&(S=f.announceSuccessfulHeartbeats),void 0!==f.announceFailedHeartbeats&&"boolean"==typeof f.announceFailedHeartbeats&&(w=f.announceFailedHeartbeats),void 0!==f.fileUploadPublishRetryLimit&&"number"==typeof f.fileUploadPublishRetryLimit&&(O=f.fileUploadPublishRetryLimit),Object.assign(Object.assign({},f),{keySet:v,dedupeOnSubscribe:k,maximumCacheSize:C,useRequestId:P,announceSuccessfulHeartbeats:S,announceFailedHeartbeats:w,fileUploadPublishRetryLimit:O})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var U;!function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(U||(U={}));class ${static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return R(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry");if(this.maximumRetry>10)throw new Error("Maximum retry for linear retry policy can not be more than 10")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return R(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry");if(this.maximumDelay>150)throw new Error("Maximum delay can not be set more than 150 seconds for retry");if(this.maximumRetry>6)throw new Error("Maximum retry for exponential retry policy can not be more than 6")}}}}const R=(e,t,s,n,r,i)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!F(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),F=(e,t)=>!!(t&&t.length>0)&&t.includes(D(e)),D=e=>{let t=U.Unknown;return e.path.startsWith("/v2/subscribe")?t=U.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=U.MessageSend:e.path.startsWith("/v2/presence")?t=U.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=U.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=U.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=U.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=U.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=U.Files),t};var x={exports:{}}; -/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(x,x.exports);var G,q=t(x.exports),K={createUUID:()=>q.uuid?q.uuid():q()};!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(G||(G={}));class L{constructor(e,t,s){this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(G.Trace,e,t)}debug(e,t){this.log(G.Debug,e,t)}info(e,t){this.log(G.Info,e,t)}warn(e,t){this.log(G.Warn,e,t)}error(e,t){this.log(G.Error,e,t)}log(e,t,s){if(ee[n](r)))}}const H=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),B=(e,t)=>{const s=e.map((e=>H(e)));return s.length?s.join(","):null!=t?t:""},W=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},z=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),V=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${H(e)}`)).join("&"):`${t}=${H(s)}`})).join("&"),J=(e,t)=>{if("0"===t||"0"===e)return;const s=Q(`${Date.now()}0000`,t,!1);return Q(e,s,!0)},X=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=Q(e,t,!1);return Q(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},Q=(e,t,s)=>{t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0&&(o>0?(o-=1,c+=1e7):o<0&&(c*=-1)),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},Y=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};class Z{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}log(e){const t=G[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==G.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?V(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===G.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,r=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),a=i?"...":s?"[]":t(h,n+1,r);o.push(`${u}${d}:${i||r||s?" ":"\n"}${a}`)}else o.push(`${u}${d}: ${h}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${Z.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(Z.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}Z.decoder=new TextDecoder;const ee=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=$.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[U.MessageSend,U.Presence,U.Files,U.MessageStorage,U.ChannelGroups,U.DevicePushNotifications,U.AppContext,U.MessageReactions]}));const a=`pn-${K.createUUID()}`;e.logVerbosity?e.logLevel=G.Debug:void 0===e.logLevel&&(e.logLevel=G.None);const o=new L(se(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new Z]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate(),null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),e.useRandomIVs&&o.warn("Configuration","'useRandomIVs' is deprecated. Use 'cryptoModule' instead."),e.origin=te(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const c=e.cryptoModule;c&&delete e.cryptoModule;const u=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"9.6.1"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),u.setCipherKey(e.cipherKey)):c&&(u._cryptoModule=c),u},te=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},se=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class ne{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=r.length>0,d=i.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var re,ie;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(re||(re={}));class ae{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?re.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===re.POST||t===re.PATCH){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=ae.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace(this.constructor.name,(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${H(e)}`)).join("&"):`${t}=${H(s)}`})).join("&")}}ae.textDecoder=new TextDecoder("utf-8");class oe{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new ae(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[l,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==h.PNCancelledCategory,l=!s||s.status>=400;let d=-1;i&&l&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn(this.constructor.name,`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class ce{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug(this.constructor.name,`Create with configuration:\n - transport: ${t}`),"fetch"!==t||window&&window.fetch||(e.warn(this.constructor.name,`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(ce.originalFetch=fetch.bind(window),this.isFetchMonkeyPatched()&&(ce.originalFetch=ce.getOriginalFetch(),e.warn(this.constructor.name,"Native Web Fetch API 'fetch' function monkey patched."),this.isFetchMonkeyPatched(ce.originalFetch)?e.warn(this.constructor.name,"Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation"):e.info(this.constructor.name,"Use native Web Fetch API 'fetch' implementation from iframe as APM workaround.")))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace(this.constructor.name,`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug(this.constructor.name,(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug(this.constructor.name,(()=>({messageType:"network-response",message:a}))),n>=400)throw _.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn(this.constructor.name,(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug(this.constructor.name,(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn(this.constructor.name,(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn(this.constructor.name,(()=>({messageType:"network-request",message:e,details:_.create(n).message,failed:!0}))),_.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([ce.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(_.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn(this.constructor.name,(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error(this.constructor.name,(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?ce.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace(this.constructor.name,(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${V(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}ce.encoder=new TextEncoder,ce.decoder=new TextDecoder;class ue{constructor(e){this.params=e,this.requestIdentifier=K.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:re.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===re.POST||a.method===re.PATCH){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=ue.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw _.create(e);return n}}ue.decoder=new TextDecoder,function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(ie||(ie={}));var le=ie;var he;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(he||(he={}));class de extends ue{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return le.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=ue.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;return null!=t||(t=e.c.endsWith("-pnpres")?he.Presence:he.Message),t!=he.Signal&&"string"==typeof e.d?t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}:t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:t===he.Presence?{type:he.Presence,data:this.presenceEventFromEnvelope(e)}:t==he.Signal?{type:he.Signal,data:this.signalFromEnvelope(e)}:t===he.AppContext?{type:he.AppContext,data:this.appContextFromEnvelope(e)}:t===he.MessageAction?{type:he.MessageAction,data:this.messageActionFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(pe.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class pe extends de{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${B(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i}=this.parameters,a={};return e&&e.length>0&&(a["channel-group"]=e.sort().join(",")),t&&t.length>0&&(a["filter-expr"]=t),s&&(a.heartbeat=s),n&&Object.keys(n).length>0&&(a.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(a.tt=r):void 0!==r&&r>0&&(a.tt=r),i&&(a.tr=i),a}}class ge{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===he.Message)this.announce("message",e.data);else if(e.type===he.Signal)this.announce("signal",e.data);else if(e.type===he.Presence)this.announce("presence",e.data);else if(e.type===he.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:l}=o,h=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===he.MessageAction?this.announce("messageAction",e.data):e.type===he.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class be{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class me{constructor(e){this.config=e,e.logger().debug(this.constructor.name,(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size||(!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:this.currentTimetoken,lastTimetoken:this.lastTimetoken}))}))),0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0))}unsubscribeAll(e=!1){this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=X(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug(this.constructor.name,(()=>({messageType:"object",message:s.map((e=>{const t=e.type===he.Message||e.type===he.Signal?Y(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn(this.constructor.name,(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class fe{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class ve extends fe{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class Se extends fe{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this._body=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.notification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.payload.notification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.payload.notification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={}}toObject(){let e=Object.assign({},this.payload.data),t=null;const s={};if(Object.keys(this.payload).length>2){const t=r(this.payload,["notification","data"]);e=Object.assign(Object.assign({},e),t)}return this._isSilent?e.notification=this.payload.notification:t=this.payload.notification,Object.keys(e).length&&(s.data=e),t&&Object.keys(t).length&&(s.notification=t),Object.keys(s).length?s:null}}class we{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ve(this._payload.apns,e,t),this.fcm=new Se(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_gcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Oe{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class ke{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class Ce extends Oe{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new ke(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error(this.constructor.name,"Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace(this.constructor.name,(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace(this.constructor.name,(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace(this.constructor.name,`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace(this.constructor.name,(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace(this.constructor.name,(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}else this.logger.warn(this.constructor.name,`No transition from '${this._currentState.label}' found for event: ${e.type}`)}}class Pe{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace(this.constructor.name,`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error(this.constructor.name,`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace(this.constructor.name,(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function je(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ee(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Ne(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Te extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class _e extends Oe{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Te}abort(){this._aborted=!0,this.notify(new Te)}}class Ie{constructor(e,t){this.payload=e,this.dependencies=t}}class Me extends Ie{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new _e}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const Ae=e=>(t,s)=>new Me(t,s,e),Ue=Ne("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),$e=Ee("LEAVE",((e,t)=>({channels:e,groups:t}))),Re=Ee("EMIT_STATUS",(e=>e)),Fe=Ne("WAIT",(()=>({}))),De=je("RECONNECT",(()=>({}))),xe=je("DISCONNECT",((e=!1)=>({isOffline:e}))),Ge=je("JOINED",((e,t)=>({channels:e,groups:t}))),qe=je("LEFT",((e,t)=>({channels:e,groups:t}))),Ke=je("LEFT_ALL",((e=!1)=>({isOffline:e}))),Le=je("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),He=je("HEARTBEAT_FAILURE",(e=>e)),Be=je("TIMES_UP",(()=>({})));class We extends Pe{constructor(e,t){super(t,t.config.logger()),this.on(Ue.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){try{yield n(Object.assign(Object.assign({channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(Le(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(He(t))}}}))))),this.on($e.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(Fe.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Be())}))))),this.on(Re.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:le.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const ze=new ke("HEARTBEAT_STOPPED");ze.on(Ge.type,((e,t)=>ze.with({channels:[...e.channels,...t.payload.channels],groups:[...e.groups,...t.payload.groups]}))),ze.on(qe.type,((e,t)=>ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),ze.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),ze.on(Ke.type,((e,t)=>Qe.with(void 0)));const Ve=new ke("HEARTBEAT_COOLDOWN");Ve.onEnter((()=>Fe())),Ve.onExit((()=>Fe.cancel)),Ve.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Ve.on(Ge.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels],groups:[...e.groups,...t.payload.groups]}))),Ve.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Ve.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Ve.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Je=new ke("HEARTBEAT_FAILED");Je.on(Ge.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels],groups:[...e.groups,...t.payload.groups]}))),Je.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Je.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Je.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Je.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Xe=new ke("HEARTBEATING");Xe.onEnter((e=>Ue(e.channels,e.groups))),Xe.onExit((()=>Ue.cancel)),Xe.on(Le.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[Re(Object.assign({},t.payload))]))),Xe.on(Ge.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels],groups:[...e.groups,...t.payload.groups]}))),Xe.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Xe.on(He.type,((e,t)=>Je.with(Object.assign({},e),[...t.payload.status?[Re(Object.assign({},t.payload.status))]:[]]))),Xe.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Xe.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Qe=new ke("HEARTBEAT_INACTIVE");Qe.on(Ge.type,((e,t)=>Xe.with({channels:t.payload.channels,groups:t.payload.groups})));class Ye{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ce(e.config.logger()),this.dispatcher=new We(this.engine,e),e.config.logger().debug(this.constructor.name,"Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Qe,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],this.engine.transition(Ge(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(qe(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.engine.transition(Ke(e))}reconnect(){this.engine.transition(De())}disconnect(e=!1){this.engine.transition(xe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const Ze=Ne("HANDSHAKE",((e,t)=>({channels:e,groups:t}))),et=Ne("RECEIVE_MESSAGES",((e,t,s)=>({channels:e,groups:t,cursor:s}))),tt=Ee("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),st=Ee("EMIT_STATUS",(e=>e)),nt=je("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),rt=je("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),it=je("HANDSHAKE_SUCCESS",(e=>e)),at=je("HANDSHAKE_FAILURE",(e=>e)),ot=je("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),ct=je("RECEIVE_FAILURE",(e=>e)),ut=je("DISCONNECT",((e=!1)=>({isOffline:e}))),lt=je("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),ht=je("UNSUBSCRIBE_ALL",(()=>({}))),dt=new ke("UNSUBSCRIBED");dt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups}))),dt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region}})));const pt=new ke("HANDSHAKE_STOPPED");pt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),pt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),pt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),pt.on(ht.type,(e=>dt.with()));const gt=new ke("HANDSHAKE_FAILED");gt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),gt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),gt.on(rt.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0}})})),gt.on(ht.type,(e=>dt.with()));const bt=new ke("HANDSHAKING");bt.onEnter((e=>Ze(e.channels,e.groups))),bt.onExit((()=>Ze.cancel)),bt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),bt.on(it.type,((e,{payload:t})=>{var s,n,r,i,a;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:X(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[st({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),bt.on(at.type,((e,t)=>{var s;return gt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),bt.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return gt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return pt.with(Object.assign({},e))})),bt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0}})})),bt.on(ht.type,(e=>dt.with()));const mt=new ke("RECEIVE_STOPPED");mt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),mt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),mt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),mt.on(ht.type,(()=>dt.with(void 0)));const yt=new ke("RECEIVE_FAILED");yt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),yt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),yt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),yt.on(ht.type,(e=>dt.with(void 0)));const ft=new ke("RECEIVING");ft.onEnter((e=>et(e.channels,e.groups,e.cursor))),ft.onExit((()=>et.cancel)),ft.on(ot.type,((e,{payload:t})=>ft.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:X(t.cursor.timetoken)},[tt(e.cursor,t.events)]))),ft.on(nt.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation).status)||void 0===s?void 0:s.category),dt.with(void 0,[st(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory},e?{error:e}:{}))])}return ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),ft.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0,[st({category:h.PNDisconnectedCategory})]):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:X(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken)},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),ft.on(ct.type,((e,{payload:t})=>{var s;return yt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),ft.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return yt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return mt.with(Object.assign({},e),[st({category:h.PNDisconnectedCategory})])})),ft.on(ht.type,(e=>dt.with(void 0,[st({category:h.PNDisconnectedCategory})])));class vt extends Pe{constructor(e,t){super(t,t.config.logger()),this.on(Ze.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}));return e.transition(it(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(at(t))}}}))))),this.on(et.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression});e.transition(ot(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(ct(t))}}}))))),this.on(tt.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(st.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class St{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ce(e.config.logger()),this.dispatcher=new vt(this.engine,e),e.config.logger().debug(this.constructor.name,"Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(dt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===ft.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return J(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s?this.engine.transition(rt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s)):this.engine.transition(nt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])))),this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=W(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=W(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=z(this.channels,e),i=z(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(nt(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(nt(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(lt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ut(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class wt extends ue{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?re.POST:re.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return le.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${H(t)}/0${this.parameters.sendByPost?"":`/${H(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Ot extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${H(s)}/0/${H(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class kt extends de{operation(){return le.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${B(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n}=this.parameters,r={ee:""};return e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(r.tt=s):s&&s>0&&(r.tt=s),n&&(r.tr=n),r}}class Ct extends de{operation(){return le.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${B(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s}=this.parameters,n={ee:""};return e&&e.length>0&&(n["channel-group"]=e.sort().join(",")),t&&t.length>0&&(n["filter-expr"]=t),s&&Object.keys(s).length>0&&(n.state=JSON.stringify(s)),n}}class Pt extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return le.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${B(null!=s?s:[],",")}/uuid/${t}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class jt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?t?0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing State":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${B(null!=s?s:[],",")}/uuid/${H(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class Et extends ue{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return le.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${B(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),t&&(n.state=JSON.stringify(t)),n}}class Nt extends ue{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return le.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${B(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class Tt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${H(t)}`}}class _t extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=(r=this.parameters).queryParameters)&&void 0!==t||(r.queryParameters={}),null!==(s=(i=this.parameters).includeUUIDs)&&void 0!==s||(i.includeUUIDs=true),null!==(n=(a=this.parameters).includeState)&&void 0!==n||(a.includeState=false)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?le.PNGlobalHereNowOperation:le.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy}})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${B(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,queryParameters:n}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign({},t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),n)}}class It extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${H(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class Mt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${B(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class At extends ue{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return le.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${H(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(At.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Ut;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Ut||(Ut={}));class $t extends ue{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return le.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Ut.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${B(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse($t.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Ut.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Rt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${H(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Ft extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${H(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Dt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${H(t)}/message/${n}/action/${s}`}}class xt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return le.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${H(t)}/0/${H(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Gt extends ue{constructor(e){super({method:re.LOCAL}),this.parameters=e}operation(){return le.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${H(e)}/files/${t}/${s}`}}class qt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${H(s)}/files/${t}/${n}`}}class Kt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return le.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${H(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Lt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${H(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class Ht extends ue{constructor(e){super({method:re.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return le.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?Ht.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class Bt{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:le.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof _?e:_.create(e);throw new d("File upload error.",t.toStatus(le.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new Lt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new Ht({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}var Wt;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(Wt||(Wt={}));class zt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new zt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new zt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Vt{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=K.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Jt{constructor(e){this.id=K.createUUID(),this.eventDispatcher=new ge,this._state=e}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.constructor.name,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.constructor.name,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.constructor.name,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.constructor.name,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.constructor.name,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.constructor.name,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.constructor.name,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.constructor.name,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.constructor.name,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.constructor.name,"Unsubscribe"),this.state.isSubscribed=!0,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Xt extends Vt{constructor(e){const t=new zt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class Qt extends Jt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Xt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.constructor.name,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.constructor.name,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new Qt({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.constructor.name,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.constructor.name,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.constructor.name,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.constructor.name,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.constructor.name} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class Yt extends Vt{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new zt({[e.entity.subscriptionType==Wt.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Zt extends Jt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new Yt(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s;if(this.state.isSubscribed){if(this.parentSetsCount>0){const e=Y(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.constructor.name,`Message (${e}) already handled. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new zt({}):this.state.subscriptionInput}cloneEmpty(){return new Zt({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.constructor.name,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.constructor.name,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.constructor.name,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.constructor.name,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new Qt({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.constructor.name,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.constructor.name,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.constructor.name,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.constructor.name} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class es{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get subscriptionType(){return Wt.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Zt({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.constructor.name} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ts extends es{get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class ss extends es{get name(){return this._nameOrId}get subscriptionType(){return Wt.ChannelGroup}}class ns extends es{get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class rs extends es{get name(){return this._nameOrId}}class is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${H(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class as extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${H(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class os extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${H(t)}`}}class cs extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${H(t)}/remove`}}class us extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ls{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.info("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new us({keySet:this.keySet}),s=e=>{e&&this.logger.info("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new as(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new is(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class hs extends ue{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: gcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class ds extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return le.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ps extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return le.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class gs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return le.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return le.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ms{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new ds(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ys extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return le.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class fs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${H(t)}`}}class vs extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,m,y,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(m=e.include).customChannelFields)&&void 0!==o||(m.customChannelFields=false),null!==(c=(y=e.include).channelStatusField)&&void 0!==c||(y.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${H(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,m,y,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(m=e.include).customChannelFields)&&void 0!==o||(m.customChannelFields=false),null!==(c=(y=e.include).channelStatusField)&&void 0!==c||(y.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${H(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ws extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return le.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Os extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${H(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class ks extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${H(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Cs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${H(t)}`}}class Ps extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,m,y,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(m=e.include).customUUIDFields)&&void 0!==o||(m.customUUIDFields=false),null!==(c=(y=e.include).UUIDStatusField)&&void 0!==c||(y.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${H(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class js extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,m,y,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(m=e.include).customUUIDFields)&&void 0!==o||(m.customUUIDFields=false),null!==(c=(y=e.include).UUIDStatusField)&&void 0!==c||(y.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${H(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Es extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${H(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ns extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${H(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ts{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ws(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Es(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ns(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.'`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Cs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ys(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.'`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new ks(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new vs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class _s extends ue{constructor(){super()}operation(){return le.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class Is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${H(t)}/files/${s}/${n}`}}class Ms{static notificationPayload(e,t){return new we(e,t)}static generateUUID(){return K.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")}))),this._objects=new Ts(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ls(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new ms(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ge,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new Ye({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new St({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),this.join(e)},leave:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===he.Message||e.type===he.Signal?Y(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new ye(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub",`Set auth key: ${e}`),this._configuration.setAuthKey(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}getUserId(){return this._configuration.userId}setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub",`Set cipher key: ${e}`),this.cipherKey=e}set heartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e)}setHeartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new rs(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new ss(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ts(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new ns(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new Qt({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===le.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===le.PNSubscribeOperation||i===le.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Ms.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof _?e:_.create(e);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,"REST API request processing error, check status for details")}))),t(s.toStatus(i),null);const n=s.toPubNubError(i,"REST API request processing error, check status for details");throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:n}))),n}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Ot(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new zt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];let n;if(this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"}))),t&&0!==t.length||delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new zt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof Qt?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(r):this.eventEngine&&this.eventEngine.unsubscribe(r)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{const s=new pe(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:le.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new Nt({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub","Disconnect (while offline? "+(e?"yes":"no")),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{const t=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{const t=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Rt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Ft(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Dt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new $t(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new It(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new Mt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new At(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new _t(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new Tt({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new Pt(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state)))}o="withHeartbeat"in e&&e.withHeartbeat?new Et(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new jt(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof Et?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&this.subscriptionManager.setState(e),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length){const e={error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const r=new Et(Object.assign(Object.assign({},e),{channels:s,channelGroups:n,keySet:this._configuration.keySet})),i=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}}))}join(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.presenceEventEngine?null===(t=this.presenceEventEngine)||void 0===t||t.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e)}setToken(e){this.token=e}parseToken(e){return this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:le.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof _&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${H(t)}`)).join("&"):`${e}=${H(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new Is(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new _s,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Ms.decoder=new TextDecoder,Ms.OPERATIONS=le,Ms.CATEGORIES=h,Ms.Endpoint=U,Ms.ExponentialRetryPolicy=$.ExponentialRetryPolicy,Ms.LinearRetryPolicy=$.LinearRetryPolicy,Ms.NoneRetryPolicy=$.None,Ms.LogLevel=G;class As{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Us extends Ms{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=A(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=ee(i,(e=>{if(e.cipherKey){return new E({default:new j(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new O({cipherKey:e.cipherKey})]})}}));let u,l,h;a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new ne(new As((e=>M(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new C({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()})),h=new P;let d=new ce(a.logger(),i.transport);if(r.subscriptionWorkerUrl){const e=new I({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogVerbosity:i.subscriptionWorkerLogVerbosity,tokenManager:u,transport:d,logger:a.logger()});d=e,window.onpagehide=t=>{t.persisted||e.terminate()}}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const p=new oe({clientConfiguration:a,tokenManager:u,transport:d});super({configuration:a,transport:p,cryptography:h,tokenManager:u,crypto:l}),(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Us.CryptoModule=E,Us})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),h(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function y(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var m=function e(){var r,d,m=l(),f=m>>5,v=31&m;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)w+=d,S.push(u(d));var O=new Uint8Array(w),k=0;for(r=0;r=0;)y(C,d);else y(C,d);return String.fromCharCode.apply(null,C);case 4:var j;if(d<0)for(j=[];!p();)j.push(e());else for(j=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==i?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==i&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,y,m,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),h=l,l=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),y=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=y.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=S,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],l=(o=e[i+1],e[i+2]),h=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],y=e[i+8],m=e[i+9],f=e[i+10],v=e[i+11],S=e[i+12],w=e[i+13],O=e[i+14],k=e[i+15],C=t(C=a[0],E=a[1],P=a[2],j=a[3],c,7,u[0]),j=t(j,C,E,P,o,12,u[1]),P=t(P,j,C,E,l,17,u[2]),E=t(E,P,j,C,h,22,u[3]);C=t(C,E,P,j,d,7,u[4]),j=t(j,C,E,P,p,12,u[5]),P=t(P,j,C,E,g,17,u[6]),E=t(E,P,j,C,b,22,u[7]),C=t(C,E,P,j,y,7,u[8]),j=t(j,C,E,P,m,12,u[9]),P=t(P,j,C,E,f,17,u[10]),E=t(E,P,j,C,v,22,u[11]),C=t(C,E,P,j,S,7,u[12]),j=t(j,C,E,P,w,12,u[13]),P=t(P,j,C,E,O,17,u[14]),C=s(C,E=t(E,P,j,C,k,22,u[15]),P,j,o,5,u[16]),j=s(j,C,E,P,g,9,u[17]),P=s(P,j,C,E,v,14,u[18]),E=s(E,P,j,C,c,20,u[19]),C=s(C,E,P,j,p,5,u[20]),j=s(j,C,E,P,f,9,u[21]),P=s(P,j,C,E,k,14,u[22]),E=s(E,P,j,C,d,20,u[23]),C=s(C,E,P,j,m,5,u[24]),j=s(j,C,E,P,O,9,u[25]),P=s(P,j,C,E,h,14,u[26]),E=s(E,P,j,C,y,20,u[27]),C=s(C,E,P,j,w,5,u[28]),j=s(j,C,E,P,l,9,u[29]),P=s(P,j,C,E,b,14,u[30]),C=n(C,E=s(E,P,j,C,S,20,u[31]),P,j,p,4,u[32]),j=n(j,C,E,P,y,11,u[33]),P=n(P,j,C,E,v,16,u[34]),E=n(E,P,j,C,O,23,u[35]),C=n(C,E,P,j,o,4,u[36]),j=n(j,C,E,P,d,11,u[37]),P=n(P,j,C,E,b,16,u[38]),E=n(E,P,j,C,f,23,u[39]),C=n(C,E,P,j,w,4,u[40]),j=n(j,C,E,P,c,11,u[41]),P=n(P,j,C,E,h,16,u[42]),E=n(E,P,j,C,g,23,u[43]),C=n(C,E,P,j,m,4,u[44]),j=n(j,C,E,P,S,11,u[45]),P=n(P,j,C,E,k,16,u[46]),C=r(C,E=n(E,P,j,C,l,23,u[47]),P,j,c,6,u[48]),j=r(j,C,E,P,b,10,u[49]),P=r(P,j,C,E,O,15,u[50]),E=r(E,P,j,C,p,21,u[51]),C=r(C,E,P,j,S,6,u[52]),j=r(j,C,E,P,h,10,u[53]),P=r(P,j,C,E,f,15,u[54]),E=r(E,P,j,C,o,21,u[55]),C=r(C,E,P,j,y,6,u[56]),j=r(j,C,E,P,k,10,u[57]),P=r(P,j,C,E,g,15,u[58]),E=r(E,P,j,C,w,21,u[59]),C=r(C,E,P,j,d,6,u[60]),j=r(j,C,E,P,v,10,u[61]),P=r(P,j,C,E,l,15,u[62]),E=r(E,P,j,C,m,21,u[63]);a[0]=a[0]+C|0,a[1]=a[1]+E|0,a[2]=a[2]+P|0,a[3]=a[3]+j|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,l.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,y=0;for(g=0;256>g;g++){var m=(m=y^y<<1^y<<2^y<<3^y<<4)>>>8^255&m^99;n[b]=m,r[m]=b;var f=p[b],v=p[f],w=p[v],O=257*p[m]^16843008*m;i[b]=O<<24|O>>>8,a[b]=O<<16|O>>>16,o[b]=O<<8|O>>>24,c[b]=O,O=16843009*w^65537*v^257*f^16843008*b,u[m]=O<<24|O>>>8,l[m]=O<<16|O>>>16,h[m]=O<<8|O>>>24,d[m]=O,b?(b=f^p[p[p[w^f]]],y^=p[p[y]]):b=y=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[l>>>16&255]^i[h>>>8&255]^a[255&d]^s[p++],y=n[l>>>24]^r[h>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],m=n[h>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[l>>>8&255]^a[255&h]^s[p++],u=b,l=y,h=m}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],y=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],m=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=y,e[t+2]=m,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var w=t(S);class O{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=w,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:O.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return O.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(O.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=O.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e})))}get logger(){return this._logger}HMACSHA256(e){return w.HmacSHA256(e,this.configuration.secretKey).toString(w.enc.Base64)}SHA256(e){return w.SHA256(e).toString(w.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Encrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=w.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(w.enc.Base64)}const a=this.getIV(s);return w.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(w.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Decrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=k(t.slice(0,16)),n=k(t.slice(16));try{const e=w.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(w.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=w.enc.Base64.parse(e),n=w.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(w.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?w.enc.Base64.parse(e):"hex"===t.keyEncoding?w.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?w.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?w.mode.ECB:w.mode.CBC}getIV(e){return"cbc"===e.mode?w.enc.Utf8.parse(this.iv):null}getRandomIV(){return w.lib.WordArray.random(16)}}class j{encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=j.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return j.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(j.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(j.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=j.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return j.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",j.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=j.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}j.IV_LENGTH=16,j.encoder=new TextEncoder,j.decoder=new TextDecoder;class P{constructor(e){this.config=e,this.cryptor=new C(Object.assign({},e)),this.fileCryptor=new j}set logger(e){this.cryptor.logger=e}encrypt(e){const t="string"==typeof e?e:P.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`AesCbcCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}P.encoder=new TextEncoder,P.decoder=new TextDecoder;class E extends a{set logger(e){if(this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER)this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===E.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new P(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new O({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new O({cipherKey:e.cipherKey}),cryptors:[new P(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(E.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=N.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=N.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===N.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof T)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=N.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}E.LEGACY_IDENTIFIER="";class N{static from(e,t){if(e!==N.LEGACY_IDENTIFIER)return new T(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==N.SENTINEL))return E.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>N.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+N.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new T(this.decoder.decode(n),a)}}N.SENTINEL="PNED",N.LEGACY_IDENTIFIER="",N.IDENTIFIER_LENGTH=4,N.VERSION=1,N.MAX_VERSION=1,N.decoder=new TextDecoder;class T{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return N.VERSION}get length(){return N.SENTINEL.length+1+N.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(N.SENTINEL)),e+=N.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=N.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}T.IDENTIFIER_LENGTH=4,T.SENTINEL="PNED";class _ extends Error{static create(e,t){return _.isErrorObject(e)?_.createFromError(e):_.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new _(s,t,0);if(e instanceof _)return e;if(_.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new _(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":400===i?(n=h.PNBadRequestCategory,r="Bad request"):403===i&&(n=h.PNAccessDeniedCategory,r="Access denied"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);"object"==typeof e&&(Array.isArray(e)?"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]):("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e?(s=e,i=e.status):s=e,"error"in e&&e.error instanceof Error&&(s=e.error)))}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new _(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,_.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}class I{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.token=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogVerbosity:this.configuration.workerLogVerbosity},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e)}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",t.message);else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t})}else if("request-process-success"===t.type||"request-process-error"===t.type){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);if("request-process-success"===t.type)e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body});else{let e=h.PNUnknownCategory,n="Unknown error";if(t.error)"NETWORK_ISSUE"===t.error.type?e=h.PNNetworkIssuesCategory:"TIMEOUT"===t.error.type?e=h.PNTimeoutCategory:"ABORTED"===t.error.type&&(e=h.PNCancelledCategory),n=`${t.error.message} (${t.identifier})`;else if(t.response)return s(_.create({url:t.url,headers:t.response.headers,body:t.response.body,status:t.response.status},t.response.body));s(new _(n,e,0,new Error(n)))}}}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;const s=e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0;if(s)return this.accessTokensMap[s]?this.accessTokensMap[s]:this.stringifyAccessToken(s).then((([e,t])=>{if(e&&t)return(this.accessTokensMap={[s]:{token:t,expiration:e.timestamp*e.ttl*60}})[s]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}}function M(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const r={};return Object.keys(e).forEach((i=>{const a=(e=>"string"==typeof e||e instanceof String)(i);let o=i;const c=e[i];if(t<2)if(a&&i.indexOf(",")>=0){o=i.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(i)||a&&!isNaN(Number(i)))&&(o=String.fromCharCode(n(i)?i:parseInt(i,10)));r[o]=s(c)?M(c,t+1):c})),r}const A=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,l,h,p,g,b,y;const m=Object.assign({},e);if(null!==(t=m.ssl)&&void 0!==t||(m.ssl=!0),null!==(s=m.transactionalRequestTimeout)&&void 0!==s||(m.transactionalRequestTimeout=15),null!==(n=m.subscribeRequestTimeout)&&void 0!==n||(m.subscribeRequestTimeout=310),null!==(r=m.fileRequestTimeout)&&void 0!==r||(m.fileRequestTimeout=300),null!==(i=m.restore)&&void 0!==i||(m.restore=!1),null!==(a=m.useInstanceId)&&void 0!==a||(m.useInstanceId=!1),null!==(o=m.suppressLeaveEvents)&&void 0!==o||(m.suppressLeaveEvents=!1),null!==(c=m.requestMessageCountThreshold)&&void 0!==c||(m.requestMessageCountThreshold=100),null!==(u=m.autoNetworkDetection)&&void 0!==u||(m.autoNetworkDetection=!1),null!==(l=m.enableEventEngine)&&void 0!==l||(m.enableEventEngine=!1),null!==(h=m.maintainPresenceState)&&void 0!==h||(m.maintainPresenceState=!0),null!==(p=m.useSmartHeartbeat)&&void 0!==p||(m.useSmartHeartbeat=!1),null!==(g=m.keepAlive)&&void 0!==g||(m.keepAlive=!1),m.userId&&m.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=m.userId)&&void 0!==b||(m.userId=m.uuid),!m.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=m.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");m.origin||(m.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:m.subscribeKey,publishKey:m.publishKey,secretKey:m.secretKey};void 0!==m.presenceTimeout&&(m.presenceTimeout>320?(m.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):m.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete m.presenceTimeout)),void 0!==m.presenceTimeout?m.heartbeatInterval=m.presenceTimeout/2-1:m.presenceTimeout=300;let v=!1,S=!0,w=5,O=!1,k=100,C=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(O=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(C=m.useRequestId),void 0!==m.announceSuccessfulHeartbeats&&"boolean"==typeof m.announceSuccessfulHeartbeats&&(v=m.announceSuccessfulHeartbeats),void 0!==m.announceFailedHeartbeats&&"boolean"==typeof m.announceFailedHeartbeats&&(S=m.announceFailedHeartbeats),void 0!==m.fileUploadPublishRetryLimit&&"number"==typeof m.fileUploadPublishRetryLimit&&(w=m.fileUploadPublishRetryLimit),Object.assign(Object.assign({},m),{keySet:f,dedupeOnSubscribe:O,maximumCacheSize:k,useRequestId:C,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:S,fileUploadPublishRetryLimit:w})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var U;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(U||(U={}));const $=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),R=(e,t)=>{const s=e.map((e=>$(e)));return s.length?s.join(","):null!=t?t:""},F=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},D=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),x=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&"),q=(e,t)=>{if("0"===t||"0"===e)return;const s=K(`${Date.now()}0000`,t,!1);return K(e,s,!0)},G=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=K(e,t,!1);return K(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},K=(e,t,s)=>{t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0&&(o>0?(o-=1,c+=1e7):o<0&&(c*=-1)),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},L=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};class H{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}log(e){const t=U[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==U.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?x(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===U.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,r=!(e||h instanceof String||0!==Object.keys(h).length),a=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),c=i?"...":s?"[]":r?"{}":t(h,n+1,a);o.push(`${u}${d}:${i||a||s||r?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${h}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${H.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(H.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}var B;H.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(B||(B={}));class W{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return z(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry");if(this.maximumRetry>10)throw new Error("Maximum retry for linear retry policy can not be more than 10")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return z(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry");if(this.maximumDelay>150)throw new Error("Maximum delay can not be set more than 150 seconds for retry");if(this.maximumRetry>6)throw new Error("Maximum retry for exponential retry policy can not be more than 6")}}}}const z=(e,t,s,n,r,i)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!V(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),V=(e,t)=>!!(t&&t.length>0)&&t.includes(J(e)),J=e=>{let t=B.Unknown;return e.path.startsWith("/v2/subscribe")?t=B.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=B.MessageSend:e.path.startsWith("/v2/presence")?t=B.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=B.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=B.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=B.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=B.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=B.Files),t};class X{constructor(e,t,s){this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(U.Trace,e,t)}debug(e,t){this.log(U.Debug,e,t)}info(e,t){this.log(U.Info,e,t)}warn(e,t){this.log(U.Warn,e,t)}error(e,t){this.log(U.Error,e,t)}log(e,t,s){if(ee[n](r)))}}var Q={exports:{}}; +/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(Q,Q.exports);var Y=t(Q.exports),Z={createUUID:()=>Y.uuid?Y.uuid():Y()};const ee=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=W.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[B.MessageSend,B.Presence,B.Files,B.MessageStorage,B.ChannelGroups,B.DevicePushNotifications,B.AppContext,B.MessageReactions]}));const a=`pn-${Z.createUUID()}`;e.logVerbosity?e.logLevel=U.Debug:void 0===e.logLevel&&(e.logLevel=U.None);const o=new X(se(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new H]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate(),null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),e.useRandomIVs&&o.warn("Configuration","'useRandomIVs' is deprecated. Use 'cryptoModule' instead."),e.origin=te(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const c=e.cryptoModule;c&&delete e.cryptoModule;const u=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"9.6.1"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),u.setCipherKey(e.cipherKey)):c&&(u._cryptoModule=c),u},te=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},se=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class ne{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=r.length>0,d=i.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var re,ie;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(re||(re={}));class ae{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?re.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===re.POST||t===re.PATCH){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=ae.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&")}}ae.textDecoder=new TextDecoder("utf-8");class oe{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new ae(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[l,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==h.PNCancelledCategory,l=!s||s.status>=400;let d=-1;i&&l&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class ce{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"!==t||window&&window.fetch||(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(ce.originalFetch=fetch.bind(window),this.isFetchMonkeyPatched()&&(ce.originalFetch=ce.getOriginalFetch(),e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."),this.isFetchMonkeyPatched(ce.originalFetch)?e.warn("WebTransport","Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation"):e.info("WebTransport","Use native Web Fetch API 'fetch' implementation from iframe as APM workaround.")))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw _.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:_.create(n).message,failed:!0}))),_.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([ce.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(_.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?ce.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${x(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}ce.encoder=new TextEncoder,ce.decoder=new TextDecoder;class ue{constructor(e){this.params=e,this.requestIdentifier=Z.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:re.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===re.POST||a.method===re.PATCH){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=ue.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw _.create(e);return n}}ue.decoder=new TextDecoder,function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(ie||(ie={}));var le=ie;var he;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(he||(he={}));class de extends ue{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return le.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=ue.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;return null!=t||(t=e.c.endsWith("-pnpres")?he.Presence:he.Message),t!=he.Signal&&"string"==typeof e.d?t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}:t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:t===he.Presence?{type:he.Presence,data:this.presenceEventFromEnvelope(e)}:t==he.Signal?{type:he.Signal,data:this.signalFromEnvelope(e)}:t===he.AppContext?{type:he.AppContext,data:this.appContextFromEnvelope(e)}:t===he.MessageAction?{type:he.MessageAction,data:this.messageActionFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(pe.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class pe extends de{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${R(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i}=this.parameters,a={};return e&&e.length>0&&(a["channel-group"]=e.sort().join(",")),t&&t.length>0&&(a["filter-expr"]=t),s&&(a.heartbeat=s),n&&Object.keys(n).length>0&&(a.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(a.tt=r):void 0!==r&&r>0&&(a.tt=r),i&&(a.tr=i),a}}class ge{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===he.Message)this.announce("message",e.data);else if(e.type===he.Signal)this.announce("signal",e.data);else if(e.type===he.Presence)this.announce("presence",e.data);else if(e.type===he.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:l}=o,h=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===he.MessageAction?this.announce("messageAction",e.data):e.type===he.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class be{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class ye{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size||(!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:this.currentTimetoken,lastTimetoken:this.lastTimetoken}))}))),0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0))}unsubscribeAll(e=!1){this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=G(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>{const t=e.type===he.Message||e.type===he.Signal?L(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class fe{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class ve extends fe{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class Se extends fe{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this._body=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.notification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.payload.notification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.payload.notification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={}}toObject(){let e=Object.assign({},this.payload.data),t=null;const s={};if(Object.keys(this.payload).length>2){const t=r(this.payload,["notification","data"]);e=Object.assign(Object.assign({},e),t)}return this._isSilent?e.notification=this.payload.notification:t=this.payload.notification,Object.keys(e).length&&(s.data=e),t&&Object.keys(t).length&&(s.notification=t),Object.keys(s).length?s:null}}class we{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ve(this._payload.apns,e,t),this.fcm=new Se(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_gcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Oe{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class ke{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class Ce extends Oe{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new ke(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class je{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function Pe(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ee(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Ne(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Te extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class _e extends Oe{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Te}abort(){this._aborted=!0,this.notify(new Te)}}class Ie{constructor(e,t){this.payload=e,this.dependencies=t}}class Me extends Ie{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new _e}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const Ae=e=>(t,s)=>new Me(t,s,e),Ue=Ne("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),$e=Ee("LEAVE",((e,t)=>({channels:e,groups:t}))),Re=Ee("EMIT_STATUS",(e=>e)),Fe=Ne("WAIT",(()=>({}))),De=Pe("RECONNECT",(()=>({}))),xe=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),qe=Pe("JOINED",((e,t)=>({channels:e,groups:t}))),Ge=Pe("LEFT",((e,t)=>({channels:e,groups:t}))),Ke=Pe("LEFT_ALL",((e=!1)=>({isOffline:e}))),Le=Pe("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),He=Pe("HEARTBEAT_FAILURE",(e=>e)),Be=Pe("TIMES_UP",(()=>({})));class We extends je{constructor(e,t){super(t,t.config.logger()),this.on(Ue.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(Le(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(He(t))}}}))))),this.on($e.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(Fe.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Be())}))))),this.on(Re.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:le.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const ze=new ke("HEARTBEAT_STOPPED");ze.on(qe.type,((e,t)=>ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),ze.on(Ge.type,((e,t)=>ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),ze.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),ze.on(Ke.type,((e,t)=>Qe.with(void 0)));const Ve=new ke("HEARTBEAT_COOLDOWN");Ve.onEnter((()=>Fe())),Ve.onExit((()=>Fe.cancel)),Ve.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Ve.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ve.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Ve.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Ve.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Je=new ke("HEARTBEAT_FAILED");Je.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Je.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Je.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Je.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Je.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Xe=new ke("HEARTBEATING");Xe.onEnter((e=>Ue(e.channels,e.groups))),Xe.onExit((()=>Ue.cancel)),Xe.on(Le.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[Re(Object.assign({},t.payload))]))),Xe.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Xe.on(He.type,((e,t)=>Je.with(Object.assign({},e),[...t.payload.status?[Re(Object.assign({},t.payload.status))]:[]]))),Xe.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Xe.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Qe=new ke("HEARTBEAT_INACTIVE");Qe.on(qe.type,((e,t)=>Xe.with({channels:t.payload.channels,groups:t.payload.groups})));class Ye{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ce(e.config.logger()),this.dispatcher=new We(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Qe,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(qe(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(Ge(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.engine.transition(Ke(e))}reconnect(){this.engine.transition(De())}disconnect(e=!1){this.engine.transition(xe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const Ze=Ne("HANDSHAKE",((e,t)=>({channels:e,groups:t}))),et=Ne("RECEIVE_MESSAGES",((e,t,s)=>({channels:e,groups:t,cursor:s}))),tt=Ee("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),st=Ee("EMIT_STATUS",(e=>e)),nt=Pe("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),rt=Pe("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),it=Pe("HANDSHAKE_SUCCESS",(e=>e)),at=Pe("HANDSHAKE_FAILURE",(e=>e)),ot=Pe("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),ct=Pe("RECEIVE_FAILURE",(e=>e)),ut=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),lt=Pe("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),ht=Pe("UNSUBSCRIBE_ALL",(()=>({}))),dt=new ke("UNSUBSCRIBED");dt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups}))),dt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region}})));const pt=new ke("HANDSHAKE_STOPPED");pt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),pt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),pt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),pt.on(ht.type,(e=>dt.with()));const gt=new ke("HANDSHAKE_FAILED");gt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),gt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),gt.on(rt.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0}})})),gt.on(ht.type,(e=>dt.with()));const bt=new ke("HANDSHAKING");bt.onEnter((e=>Ze(e.channels,e.groups))),bt.onExit((()=>Ze.cancel)),bt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),bt.on(it.type,((e,{payload:t})=>{var s,n,r,i,a;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:G(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[st({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),bt.on(at.type,((e,t)=>{var s;return gt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),bt.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return gt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return pt.with(Object.assign({},e))})),bt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0}})})),bt.on(ht.type,(e=>dt.with()));const yt=new ke("RECEIVE_STOPPED");yt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),yt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),yt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),yt.on(ht.type,(()=>dt.with(void 0)));const mt=new ke("RECEIVE_FAILED");mt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),mt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),mt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),mt.on(ht.type,(e=>dt.with(void 0)));const ft=new ke("RECEIVING");ft.onEnter((e=>et(e.channels,e.groups,e.cursor))),ft.onExit((()=>et.cancel)),ft.on(ot.type,((e,{payload:t})=>ft.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:G(t.cursor.timetoken)},[tt(e.cursor,t.events)]))),ft.on(nt.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation).status)||void 0===s?void 0:s.category),dt.with(void 0,[st(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory},e?{error:e}:{}))])}return ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),ft.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0,[st({category:h.PNDisconnectedCategory})]):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:G(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken)},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),ft.on(ct.type,((e,{payload:t})=>{var s;return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),ft.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return yt.with(Object.assign({},e),[st({category:h.PNDisconnectedCategory})])})),ft.on(ht.type,(e=>dt.with(void 0,[st({category:h.PNDisconnectedCategory})])));class vt extends je{constructor(e,t){super(t,t.config.logger()),this.on(Ze.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}));return e.transition(it(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(at(t))}}}))))),this.on(et.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression});e.transition(ot(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(ct(t))}}}))))),this.on(tt.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(st.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class St{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ce(e.config.logger()),this.dispatcher=new vt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(dt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===ft.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return q(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s?this.engine.transition(rt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s)):this.engine.transition(nt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])))),this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=F(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=F(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=D(this.channels,e),i=D(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(nt(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(nt(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(lt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ut(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class wt extends ue{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?re.POST:re.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return le.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${$(t)}/0${this.parameters.sendByPost?"":`/${$(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Ot extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${$(s)}/0/${$(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class kt extends de{operation(){return le.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${R(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n}=this.parameters,r={ee:""};return e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(r.tt=s):s&&s>0&&(r.tt=s),n&&(r.tr=n),r}}class Ct extends de{operation(){return le.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${R(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s}=this.parameters,n={ee:""};return e&&e.length>0&&(n["channel-group"]=e.sort().join(",")),t&&t.length>0&&(n["filter-expr"]=t),s&&Object.keys(s).length>0&&(n.state=JSON.stringify(s)),n}}var jt;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(jt||(jt={}));class Pt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new Pt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new Pt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Et{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=Z.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Nt{constructor(e){this.id=Z.createUUID(),this.eventDispatcher=new ge,this._state=e}get subscriptionType(){return"Subscription"}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Tt extends Et{constructor(e){const t=new Pt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}get subscriptionType(){return"SubscriptionSet"}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class _t extends Nt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Tt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new _t({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class It extends Et{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new Pt({[e.entity.subscriptionType==jt.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Mt extends Nt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new It(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s;if(this.state.isSubscribed){if(this.parentSetsCount>0){const e=L(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Message (${e}) already handled. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new Pt({}):this.state.subscriptionInput}cloneEmpty(){return new Mt({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new _t({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class At extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return le.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=s?s:[],",")}/uuid/${t}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Ut extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?t?0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing State":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=s?s:[],",")}/uuid/${$(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class $t extends ue{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return le.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),t&&(n.state=JSON.stringify(t)),n}}class Rt extends ue{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return le.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${R(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class Ft extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${$(t)}`}}class Dt extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=(r=this.parameters).queryParameters)&&void 0!==t||(r.queryParameters={}),null!==(s=(i=this.parameters).includeUUIDs)&&void 0!==s||(i.includeUUIDs=true),null!==(n=(a=this.parameters).includeState)&&void 0!==n||(a.includeState=false)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?le.PNGlobalHereNowOperation:le.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy}})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${R(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,queryParameters:n}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign({},t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),n)}}class xt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class qt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${R(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class Gt extends ue{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return le.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(Gt.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Kt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Kt||(Kt={}));class Lt extends ue{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return le.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Kt.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${R(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse(Lt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Kt.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Ht extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Bt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Wt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${n}/action/${s}`}}class zt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return le.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${$(t)}/0/${$(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Vt extends ue{constructor(e){super({method:re.LOCAL}),this.parameters=e}operation(){return le.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${$(e)}/files/${t}/${s}`}}class Jt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(s)}/files/${t}/${n}`}}class Xt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return le.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Qt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class Yt extends ue{constructor(e){super({method:re.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return le.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?Yt.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class Zt{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:le.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof _?e:_.create(e);throw new d("File upload error.",t.toStatus(le.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new Qt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new Yt({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}class es{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return jt.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Mt({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ts extends es{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class ss extends es{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return jt.ChannelGroup}}class ns extends es{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class rs extends es{get entityType(){return"Channel"}get name(){return this._nameOrId}}class is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class as extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class os extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}}class cs extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}/remove`}}class us extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ls{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.info("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new us({keySet:this.keySet}),s=e=>{e&&this.logger.info("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new as(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new is(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class hs extends ue{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: gcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class ds extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return le.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ps extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return le.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class gs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return le.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return le.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ys{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new ds(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ms extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return le.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class fs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}}class vs extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ws extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return le.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Os extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class ks extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Cs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}}class js extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ps extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Es extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ns extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ts{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ws(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Es(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ns(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.'`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Cs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ms(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.'`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new ks(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new vs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class _s extends ue{constructor(){super()}operation(){return le.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class Is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files/${s}/${n}`}}class Ms{static notificationPayload(e,t){return new we(e,t)}static generateUUID(){return Z.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")}))),this._objects=new Ts(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ls(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new ys(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ge,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new Ye({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new St({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===he.Message||e.type===he.Signal?L(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new me(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub",`Set auth key: ${e}`),this._configuration.setAuthKey(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}getUserId(){return this._configuration.userId}setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub",`Set cipher key: ${e}`),this.cipherKey=e}set heartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e)}setHeartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new rs(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new ss(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ts(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new ns(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new _t({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===le.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===le.PNSubscribeOperation||i===le.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Ms.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof _?e:_.create(e);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,"REST API request processing error, check status for details")}))),t(s.toStatus(i),null);const n=s.toPubNubError(i,"REST API request processing error, check status for details");throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:n}))),n}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Ot(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new Pt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];let n;if(this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"}))),t&&0!==t.length||delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new Pt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof _t?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const r=s.subscriptionInput(!1),i=r.channelGroups,a=r.channels;e.push(...n.channelGroups.filter((e=>i.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],r=n=>{const r=n.subscriptionNames(!0),i=n.subscriptionType===jt.Channel?t:e;r.some((e=>i.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof _t?e.subscriptions.forEach((e=>{r(e.state.entity)})):e instanceof Mt&&r(e.state.entity)}));let i="Some entities still in use:";return t.length+e.length===n.length&&(i="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:i}})),n.remove(new Pt({channels:t,channelGroups:e})),n.isEmpty))return}const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(r):this.eventEngine&&this.eventEngine.unsubscribe(r)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{const s=new pe(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:le.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new Rt({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub","Disconnect (while offline? "+(e?"yes":"no")),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{const t=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{const t=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Ht(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Lt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Dt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new Ft({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new At(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state)))}o="withHeartbeat"in e&&e.withHeartbeat?new $t(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new Ut(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof $t?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&this.subscriptionManager.setState(e),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:r}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(r&&(r=r.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=r?r:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const i=new $t(Object.assign(Object.assign({},e),{channels:n,channelGroups:r,keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{i.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(i,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(i).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e)}setToken(e){this.token=e}parseToken(e){return this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new Zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:le.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof _&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${$(t)}`)).join("&"):`${e}=${$(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new Is(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new _s,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Ms.decoder=new TextDecoder,Ms.OPERATIONS=le,Ms.CATEGORIES=h,Ms.Endpoint=B,Ms.ExponentialRetryPolicy=W.ExponentialRetryPolicy,Ms.LinearRetryPolicy=W.LinearRetryPolicy,Ms.NoneRetryPolicy=W.None,Ms.LogLevel=U;class As{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Us extends Ms{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=A(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=ee(i,(e=>{if(e.cipherKey){return new E({default:new P(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new O({cipherKey:e.cipherKey})]})}}));let u,l,h;a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new ne(new As((e=>M(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new C({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()})),h=new j;let d=new ce(a.logger(),i.transport);if(r.subscriptionWorkerUrl){const e=new I({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogVerbosity:i.subscriptionWorkerLogVerbosity,tokenManager:u,transport:d,logger:a.logger()});d=e,window.onpagehide=t=>{t.persisted||e.terminate()}}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const p=new oe({clientConfiguration:a,tokenManager:u,transport:d});super({configuration:a,transport:p,cryptography:h,tokenManager:u,crypto:l}),(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Us.CryptoModule=E,Us})); diff --git a/dist/web/pubnub.worker.js b/dist/web/pubnub.worker.js index e989805e5..6e5e8148d 100644 --- a/dist/web/pubnub.worker.js +++ b/dist/web/pubnub.worker.js @@ -465,6 +465,11 @@ if (hbRequestsBySubscriptionKey[heartbeatRequestKey] && hbRequestsBySubscriptionKey[heartbeatRequestKey].clientIdentifier === client.clientIdentifier) delete hbRequestsBySubscriptionKey[heartbeatRequestKey].clientIdentifier; + if (heartbeat.timer) { + clearInterval(heartbeat.timer); + delete heartbeat.heartbeatEvent; + delete heartbeat.timer; + } } } if (!request) { @@ -1242,6 +1247,7 @@ * Use information from request to populate list of channels and other useful information. * * @param event - Send request. + * @returns `true` if channels / groups list has been changed. May return `undefined` because `client` is missing. */ const updateClientSubscribeStateIfRequired = (event) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; @@ -1249,6 +1255,7 @@ const query = event.request.queryParameters; const { clientIdentifier } = event; const client = pubNubClients[clientIdentifier]; + let changed = false; // This should never happen. if (!client) return; @@ -1256,6 +1263,7 @@ const state = ((_b = query.state) !== null && _b !== void 0 ? _b : ''); let subscription = client.subscription; if (!subscription) { + changed = true; subscription = { path: '', channelGroupQuery: '', @@ -1294,11 +1302,17 @@ } if (subscription.path !== event.request.path) { subscription.path = event.request.path; - subscription.channels = channelsFromRequest(event.request); + const _channelsFromRequest = channelsFromRequest(event.request); + if (!changed) + changed = includesStrings(subscription.channels, _channelsFromRequest); + subscription.channels = _channelsFromRequest; } if (subscription.channelGroupQuery !== channelGroupQuery) { subscription.channelGroupQuery = channelGroupQuery; - subscription.channelGroups = channelGroupsFromRequest(event.request); + const _channelGroupsFromRequest = channelGroupsFromRequest(event.request); + if (!changed) + changed = includesStrings(subscription.channelGroups, _channelGroupsFromRequest); + subscription.channelGroups = _channelGroupsFromRequest; } let { authKey } = client; const { userId } = client; @@ -1326,7 +1340,8 @@ */ const updateClientHeartbeatState = (event) => { var _a, _b; - const client = pubNubClients[event.clientIdentifier]; + const { clientIdentifier } = event; + const client = pubNubClients[clientIdentifier]; const { request } = event; // This should never happen. if (!client) @@ -1335,6 +1350,16 @@ channels: [], channelGroups: [], })); + _clientHeartbeat.heartbeatEvent = Object.assign({}, event); + if (!_clientHeartbeat.timer) { + _clientHeartbeat.timer = setInterval(() => { + const client = pubNubClients[clientIdentifier]; + // This should never happen. + if (!client || !client.heartbeat || !client.heartbeat.heartbeatEvent) + return; + handleHeartbeatRequestEvent(client.heartbeat.heartbeatEvent); + }, client.heartbeatInterval * 1000); + } // Update presence heartbeat information about client. _clientHeartbeat.channelGroups = channelGroupsFromRequest(request).filter((group) => !group.endsWith('-pnpres')); _clientHeartbeat.channels = channelsFromRequest(request).filter((channel) => !channel.endsWith('-pnpres')); @@ -1396,6 +1421,9 @@ if (serviceRequestId) cancelRequest(serviceRequestId); } + // Make sure to stop heartbeat timer. + if (invalidatedClient.heartbeat && invalidatedClient.heartbeat.timer) + clearInterval(invalidatedClient.heartbeat.timer); if (serviceHeartbeatRequests[subscriptionKey]) { const hbRequestsBySubscriptionKey = ((_a = serviceHeartbeatRequests[subscriptionKey]) !== null && _a !== void 0 ? _a : (serviceHeartbeatRequests[subscriptionKey] = {})); const heartbeatRequestKey = `${invalidatedClient.userId}_${(_b = clientAggregateAuthKey(invalidatedClient)) !== null && _b !== void 0 ? _b : ''}`; diff --git a/dist/web/pubnub.worker.min.js b/dist/web/pubnub.worker.min.js index cf3ae976a..ba51eb803 100644 --- a/dist/web/pubnub.worker.min.js +++ b/dist/web/pubnub.worker.min.js @@ -1,2 +1,2 @@ !function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";function e(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function c(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,c)}l((r=r.apply(e,t||[])).next())}))}var t;"function"==typeof SuppressedError&&SuppressedError,function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(t||(t={}));"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var r,i,s={exports:{}}; -/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */r=s,function(e){var t="0.1.0",n={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function r(){var e,t,n="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(n+="-"),n+=(12===e?4:16===e?3&t|8:t).toString(16);return n}function i(e,t){var r=n[t||"all"];return r&&r.test(e)||!1}r.isUUID=i,r.VERSION=t,e.uuid=r,e.isUUID=i}(i=s.exports),null!==r&&(r.exports=i.uuid);var o=n(s.exports),c={createUUID:()=>o.uuid?o.uuid():o()};const l=new Map,u={},a=c.createUUID(),d=new Map,f={},h={},p={},b={},g={},v={};self.onconnect=e=>{ie("New PubNub Client connected to the Subscription Shared Worker."),e.ports.forEach((e=>{e.start(),e.onmessage=t=>{if(!J(t))return;const n=t.data;if("client-register"===n.type)n.port=e,x(n),ie(`Client '${n.clientIdentifier}' registered with '${a}' shared worker`);else if("client-unregister"===n.type)F(n);else if("client-pong"===n.type)M(n);else if("send-request"===n.type)if(n.request.path.startsWith("/v2/subscribe")){U(n);const e=f[n.clientIdentifier];if(e){const t=re(e);let r=[];if(l.has(t)&&(r=l.get(t)[0]),r.push([e,n]),!l.has(t)){const e=setTimeout((()=>{y(r,n),l.delete(t)}),50);l.set(t,[r,e])}}}else n.request.path.endsWith("/heartbeat")?(D(n),m(n)):$(n);else"cancel-request"===n.type&&k(n)},e.postMessage({type:"shared-worker-connected"})}))};const y=(e,t)=>{const n=K(t),r=f[t.clientIdentifier];r&&(e=e.filter((e=>e[0].clientIdentifier!==r.clientIdentifier)),I(r,t,n,!0),e.forEach((([e,t])=>I(e,t,n,!1))))},I=(e,t,n,r)=>{var i;let s=!1;if(r||"string"==typeof n||(n=n.identifier),e.subscription&&(s="0"===e.subscription.timetoken),"string"==typeof n){const r=v[n];if(e){if(e.subscription&&(e.subscription.timetoken=r.timetoken,e.subscription.region=r.region,e.subscription.serviceRequestId=n),!s)return;const o=(new TextEncoder).encode(`{"t":{"t":"${r.timetoken}","r":${null!==(i=r.region)&&void 0!==i?i:"0"}},"m":[]}`),c=new Headers({"Content-Type":'text/javascript; charset="UTF-8"',"Content-Length":`${o.length}`}),l=new Response(o,{status:200,headers:c}),u=W([l,o]);u.url=`${t.request.origin}${t.request.path}`,u.clientIdentifier=t.clientIdentifier,u.identifier=t.request.identifier,R(e,u)}return}t.request.cancellable&&d.set(n.identifier,new AbortController);const o=v[n.identifier],{timetokenOverride:c,regionOverride:l}=o;j(n,(()=>E(n.identifier)),((e,r)=>{A(e,r,t.request),S(e,n.identifier)}),((e,r)=>{A(e,null,t.request,L(r)),S(e,n.identifier)}),(e=>{let t=e;return s&&c&&"0"!==c&&(t=q(t,c,l)),t})),ie(`'${Object.keys(v).length}' subscription request currently active.`)},q=(e,t,n)=>{if(void 0===t||"0"===t||e[0].status>=400)return e;let r;const i=e[0];let s=i,o=e[1];try{r=JSON.parse((new TextDecoder).decode(o))}catch(t){return ie(`Subscribe response parse error: ${t}`),e}r.t.t=t,n&&(r.t.r=parseInt(n,10));try{if(o=(new TextEncoder).encode(JSON.stringify(r)).buffer,o.byteLength){const e=new Headers(i.headers);e.set("Content-Length",`${o.byteLength}`),s=new Response(o,{status:i.status,statusText:i.statusText,headers:e})}}catch(t){return ie(`Subscribe serialization error: ${t}`),e}return o.byteLength>0?[s,o]:e},m=e=>{var t;const n=f[e.clientIdentifier],r=G(e);if(!n)return;const i=`${n.userId}_${null!==(t=te(n))&&void 0!==t?t:""}`,s=p[n.subscriptionKey],o=(null!=s?s:{})[i];if(!r){let t,r;if(ie(`Previous heartbeat request has been sent less than ${n.heartbeatInterval} seconds ago. Skipping...`,n),o&&o.response&&([t,r]=o.response),!t){r=(new TextEncoder).encode('{ "status": 200, "message": "OK", "service": "Presence" }').buffer;const e=new Headers({"Content-Type":'text/javascript; charset="UTF-8"',"Content-Length":`${r.byteLength}`});t=new Response(r,{status:200,headers:e})}const i=W([t,r]);return i.url=`${e.request.origin}${e.request.path}`,i.clientIdentifier=e.clientIdentifier,i.identifier=e.request.identifier,void R(n,i)}j(r,(()=>[n]),((t,n)=>{o&&(o.response=n),A(t,n,e.request)}),((t,n)=>{A(t,null,e.request,L(n))})),ie("Started heartbeat request.",n)},$=(e,t,n)=>{var r,i,s;const o=null!=t?t:f[e.clientIdentifier],c=C(e,t);if(!o)return;const{subscription:l,heartbeat:u}=o,a=null!=n?n:null==l?void 0:l.serviceRequestId;if(l&&0===l.channels.length&&0===l.channelGroups.length&&(l.channelGroupQuery="",l.path="",l.previousTimetoken="0",l.timetoken="0",delete l.region,delete l.serviceRequestId,delete l.request),p[o.subscriptionKey]&&u&&0===u.channels.length&&0===u.channelGroups.length){const e=null!==(r=p[s=o.subscriptionKey])&&void 0!==r?r:p[s]={},t=`${o.userId}_${null!==(i=te(o))&&void 0!==i?i:""}`;e[t]&&e[t].clientIdentifier===o.clientIdentifier&&delete e[t].clientIdentifier}if(!c){const t=(new TextEncoder).encode('{"status": 200, "action": "leave", "message": "OK", "service":"Presence"}'),n=new Headers({"Content-Type":'text/javascript; charset="UTF-8"',"Content-Length":`${t.length}`}),r=new Response(t,{status:200,headers:n}),i=W([r,t]);return i.url=`${e.request.origin}${e.request.path}`,i.clientIdentifier=e.clientIdentifier,i.identifier=e.request.identifier,void R(o,i)}if(j(c,(()=>[o]),((t,n)=>{A(t,n,e.request)}),((t,n)=>{A(t,null,e.request,L(n))})),ie("Started leave request.",o),void 0===a)return;const d=E(a);d.forEach((e=>{e&&e.subscription&&delete e.subscription.serviceRequestId})),O(a),w(d)},k=e=>{const t=f[e.clientIdentifier];if(!t||!t.subscription)return;const n=t.subscription.serviceRequestId;t&&n&&(delete t.subscription.serviceRequestId,t.subscription.request&&t.subscription.request.identifier===e.identifier&&delete t.subscription.request,O(n))},w=e=>{let t,n;for(const r of e)if(r.subscription&&r.subscription.request){n=r.subscription.request,t=r;break}if(!n||!t)return;const r={type:"send-request",clientIdentifier:t.clientIdentifier,subscriptionKey:t.subscriptionKey,request:n};y([[t,r]],r)},j=(t,n,r,i,s)=>{e(void 0,void 0,void 0,(function*(){var e;Promise.race([fetch(T(t),{signal:null===(e=d.get(t.identifier))||void 0===e?void 0:e.signal,keepalive:!0}),P(t.identifier,t.timeout)]).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>s?s(e):e)).then((e=>{const t=n();0!==t.length&&r(t,e)})).catch((e=>{const t=n();if(0===t.length)return;let r=e;if("string"==typeof e){const t=e.toLowerCase();r=new Error(e),!t.includes("timeout")&&t.includes("cancel")&&(r.name="AbortError")}i(t,r)}))}))},O=e=>{if(0===E(e).length){const t=d.get(e);d.delete(e),delete v[e],t&&t.abort("Cancel request")}},P=(e,t)=>new Promise(((n,r)=>{const i=setTimeout((()=>{d.delete(e),clearTimeout(i),r(new Error("Request timeout"))}),1e3*t)})),E=e=>Object.values(f).filter((t=>void 0!==t&&void 0!==t.subscription&&t.subscription.serviceRequestId===e)),S=(e,t)=>{delete v[t],e.forEach((e=>{e.subscription&&(delete e.subscription.request,delete e.subscription.serviceRequestId)}))},T=e=>{let t;const n=e.queryParameters;let r=e.path;if(e.headers){t={};for(const[n,r]of Object.entries(e.headers))t[n]=r}return n&&0!==Object.keys(n).length&&(r=`${r}?${oe(n)}`),new Request(`${e.origin}${r}`,{method:e.method,headers:t,redirect:"follow"})},K=e=>{var t,n,r,i,s;const o=f[e.clientIdentifier],l=o.subscription,u=Q(l.timetoken,e),a=c.createUUID(),d=Object.assign({},e.request);let h,p;if(u.length>1){const s=H(u,e);if(s){const e=v[s],{channels:n,channelGroups:r}=null!==(t=o.subscription)&&void 0!==t?t:{channels:[],channelGroups:[]};if((!(n.length>0)||Z(e.channels,n))&&(!(r.length>0)||Z(e.channelGroups,r)))return s}const c=(null!==(n=b[o.subscriptionKey])&&void 0!==n?n:{})[o.userId],f={},g=new Set(l.channelGroups),y=new Set(l.channels);c&&l.objectsWithState.length&&l.objectsWithState.forEach((e=>{const t=c[e];t&&(f[e]=t)}));for(const e of u){const{subscription:t}=e;if(!t)continue;1!==u.length&&e.clientIdentifier===o.clientIdentifier||!t.timetoken||(h=t.timetoken,p=t.region),t.channelGroups.forEach(g.add,g),t.channels.forEach(y.add,y);const n=t.serviceRequestId;t.serviceRequestId=a,n&&v[n]&&O(n),c&&t.objectsWithState.forEach((e=>{const t=c[e];t&&!f[e]&&(f[e]=t)}))}const I=null!==(r=v[a])&&void 0!==r?r:v[a]={requestId:a,timetoken:null!==(i=d.queryParameters.tt)&&void 0!==i?i:"0",channelGroups:[],channels:[]};if(y.size){I.channels=Array.from(y).sort();const e=d.path.split("/");e[4]=I.channels.join(","),d.path=e.join("/")}if(g.size&&(I.channelGroups=Array.from(g).sort(),d.queryParameters["channel-group"]=I.channelGroups.join(",")),Object.keys(f).length&&(d.queryParameters.state=JSON.stringify(f)),d.queryParameters&&d.queryParameters.auth){const e=ne(u);e&&(d.queryParameters.auth=e)}}else v[a]={requestId:a,timetoken:null!==(s=d.queryParameters.tt)&&void 0!==s?s:"0",channelGroups:l.channelGroups,channels:l.channels};v[a]&&(d.queryParameters&&void 0!==d.queryParameters.tt&&void 0!==d.queryParameters.tr&&(v[a].region=d.queryParameters.tr),v[a].timetokenOverride=h,v[a].regionOverride=p),l.serviceRequestId=a,d.identifier=a;const g=u.reduce(((e,{clientIdentifier:t})=>(e.push(t),e)),[]).join(", ");if(g.length>0)for(const e of u)se(v[a],`Started aggregated request for clients: ${g}`,e);return d},G=e=>{var t,n,r,i,s;const o=f[e.clientIdentifier],c=B(e),l=Object.assign({},e.request);if(!o||!o.heartbeat)return;const u=null!==(t=p[s=o.subscriptionKey])&&void 0!==t?t:p[s]={},a=`${o.userId}_${null!==(n=te(o))&&void 0!==n?n:""}`,d=[...o.heartbeat.channelGroups],h=[...o.heartbeat.channels];let b,g,v=!1;if(u[a]){const{channels:e,channelGroups:t,response:n}=u[a];b=null!==(i=o.heartbeat.presenceState)&&void 0!==i?i:{},g=Z(e,h)&&Z(t,d),n&&(v=n[0].status>=400)}else u[a]={channels:h,channelGroups:d,clientIdentifier:o.clientIdentifier,timestamp:Date.now()},b=null!==(r=o.heartbeat.presenceState)&&void 0!==r?r:{},g=!1;let y=o.heartbeatInterval;for(const e of c)e.heartbeatInterval&&(y=Math.min(y,e.heartbeatInterval));if(g&&u[a].clientIdentifier){const e=u[a].timestamp+1e3*y,t=Date.now();if(!v&&t.05*y*1e3)return}delete u[a].response,u[a].clientIdentifier=o.clientIdentifier;for(const t of c){const{heartbeat:n}=t;void 0!==n&&t.clientIdentifier!==e.clientIdentifier&&(n.presenceState&&(b=Object.assign(Object.assign({},b),n.presenceState)),d.push(...n.channelGroups.filter((e=>!d.includes(e)))),h.push(...n.channels.filter((e=>!h.includes(e)))))}u[a].channels=h,u[a].channelGroups=d,u[a].timestamp=Date.now();for(const e in Object.keys(b))h.includes(e)||d.includes(e)||delete b[e];if(0!==h.length||0!==d.length){if(h.length||d.length){const e=l.path.split("/");e[6]=h.length?h.join(","):",",l.path=e.join("/")}if(d.length&&(l.queryParameters["channel-group"]=d.join(",")),Object.keys(b).length?l.queryParameters.state=JSON.stringify(b):delete l.queryParameters.state,c.length>1&&l.queryParameters&&l.queryParameters.auth){const e=ne(c);e&&(l.queryParameters.auth=e)}return l}},C=(e,t)=>{var n;const r=null!=t?t:f[e.clientIdentifier],i=z(e,t);let s=Y(e.request),o=X(e.request);const c=Object.assign({},e.request);if(r&&r.subscription){const{subscription:e}=r;o.length&&(e.channels=e.channels.filter((e=>!o.includes(e)))),s.length&&(e.channelGroups=e.channelGroups.filter((e=>!s.includes(e))))}if(r&&r.heartbeat){const{heartbeat:e}=r;o.length&&(e.channels=e.channels.filter((e=>!o.includes(e)))),s.length&&(e.channelGroups=e.channelGroups.filter((e=>!s.includes(e))))}for(const t of i){const n=t.subscription;void 0!==n&&(t.clientIdentifier!==e.clientIdentifier&&(o.length&&(o=o.filter((e=>!e.endsWith("-pnpres")&&!n.channels.includes(e)))),s.length&&(s=s.filter((e=>!e.endsWith("-pnpres")&&!n.channelGroups.includes(e))))))}if(o.length&&(o=o.filter((e=>!e.endsWith("-pnpres")))),s.length&&(s=s.filter((e=>!e.endsWith("-pnpres")))),0!==o.length||0!==s.length){if(r&&p[r.subscriptionKey]&&(o.length||s.length)){const e=p[r.subscriptionKey],t=`${r.userId}_${null!==(n=te(r))&&void 0!==n?n:""}`;if(e[t]){let{channels:n,channelGroups:r}=e[t];s.length&&(r=r.filter((e=>!o.includes(e)))),o.length&&(n=n.filter((e=>!o.includes(e)))),e[t].channelGroups=r,e[t].channels=n}}if(o.length){const e=c.path.split("/");e[6]=o.join(","),c.path=e.join("/")}if(s.length&&(c.queryParameters["channel-group"]=s.join(",")),i.length>1&&c.queryParameters&&c.queryParameters.auth){const e=ne(i);e&&(c.queryParameters.auth=e)}return c}if(r&&r.workerLogVerbosity){const e=i.reduce(((e,{clientIdentifier:t})=>(e.push(t),e)),[]).join(", ");ie(`Specified channels and groups still in use by other clients: ${e}. Ignoring leave request.`,r)}},R=(e,t)=>{var n;const r=(null!==(n=g[e.subscriptionKey])&&void 0!==n?n:{})[e.clientIdentifier];if(!r)return!1;try{return r.postMessage(t),!0}catch(t){e.workerLogVerbosity&&console.error(`[SharedWorker] Unable send message using message port: ${t}`)}return!1},A=(e,t,n,r)=>{var i,s;if(0===e.length)return;if(!r&&!t)return;const o=e.some((e=>e&&e.workerLogVerbosity)),c=null!==(i=g[e[0].subscriptionKey])&&void 0!==i?i:{},l=n&&n.path.startsWith("/v2/subscribe");if(!r&&t&&(r=t[0].status>=400?L(void 0,t):W(t)),o&&n&&!n.path.endsWith("/heartbeat")){const t=`Notify clients about ${l?"subscribe":"leave"} request completion: ${e.reduce(((e,{clientIdentifier:t})=>(e.push(t),e)),[]).join(", ")}`;for(const n of e)ie(t,n)}for(const t of e){if(l&&!t.subscription){if(o){const n=`${t.clientIdentifier} doesn't have active subscription. Don't notify about completion.`;for(const t of e)ie(n,t)}continue}const i=c[t.clientIdentifier],{request:u}=null!==(s=t.subscription)&&void 0!==s?s:{};let a=null!=u?u:n;if(l||(a=n),i&&a){const e=Object.assign(Object.assign({},r),{clientIdentifier:t.clientIdentifier,identifier:a.identifier,url:`${a.origin}${a.path}`});R(t,e)}else if(!i&&o){const n=`${t.clientIdentifier} doesn't have Shared Worker's communication channel. Don't notify about completion.`;for(const r of e)r.clientIdentifier!==t.clientIdentifier&&ie(n,r)}}},W=e=>{var t;const[n,r]=e,i=r.byteLength>0?r:void 0,s=parseInt(null!==(t=n.headers.get("Content-Length"))&&void 0!==t?t:"0",10),o=n.headers.get("Content-Type"),c={};return n.headers.forEach(((e,t)=>c[t]=e.toLowerCase())),{type:"request-process-success",clientIdentifier:"",identifier:"",url:"",response:{contentLength:s,contentType:o,headers:c,status:n.status,body:i}}},L=(e,t)=>{if(t)return Object.assign(Object.assign({},W(t)),{type:"request-process-error"});let n="NETWORK_ISSUE",r="Unknown error",i="Error";e&&e instanceof Error&&(r=e.message,i=e.name);const s=r.toLowerCase();return s.includes("timeout")?n="TIMEOUT":("AbortError"===i||s.includes("aborted")||s.includes("cancel"))&&(r="Request aborted",n="ABORTED"),{type:"request-process-error",clientIdentifier:"",identifier:"",url:"",error:{name:i,type:n,message:r}}},x=e=>{var t,n,r,i,s;const{clientIdentifier:o}=e;if(f[o])return;const c=f[o]={clientIdentifier:o,subscriptionKey:e.subscriptionKey,userId:e.userId,heartbeatInterval:e.heartbeatInterval,newlyRegistered:!0,offlineClientsCheckInterval:e.workerOfflineClientsCheckInterval,unsubscribeOfflineClients:e.workerUnsubscribeOfflineClients,workerLogVerbosity:e.workerLogVerbosity},l=null!==(t=h[i=e.subscriptionKey])&&void 0!==t?t:h[i]=[];l.every((e=>e.clientIdentifier!==o))&&l.push(c),(null!==(n=g[s=e.subscriptionKey])&&void 0!==n?n:g[s]={})[o]=e.port;const a=`Registered PubNub client with '${o}' identifier. '${l.length}' clients currently active.`;for(const e of l)ie(a,e);if(!u[e.subscriptionKey]&&(null!==(r=h[e.subscriptionKey])&&void 0!==r?r:[]).length>0){const{subscriptionKey:t}=e,n=e.workerOfflineClientsCheckInterval;for(const e of l)ie(`Setup PubNub client ping event ${n} seconds`,e);u[t]=setTimeout((()=>ee(t)),500*n-1)}},F=e=>{_(e.subscriptionKey,e.clientIdentifier)},U=e=>{var t,n,r,i,s,o,c,l,u,a,d,h,p,g,v,y,I,q,m,$;const k=e.request.queryParameters,{clientIdentifier:w}=e,j=f[w];if(!j)return;const O=null!==(t=k["channel-group"])&&void 0!==t?t:"",P=null!==(n=k.state)&&void 0!==n?n:"";let E=j.subscription;if(E){if(P.length>0){const e=JSON.parse(P),t=null!==(o=(y=null!==(s=b[v=j.subscriptionKey])&&void 0!==s?s:b[v]={})[I=j.userId])&&void 0!==o?o:y[I]={};Object.entries(e).forEach((([e,n])=>t[e]=n));for(const n of E.objectsWithState)e[n]||delete t[n];E.objectsWithState=Object.keys(e)}else if(E.objectsWithState.length){const e=null!==(l=(m=null!==(c=b[q=j.subscriptionKey])&&void 0!==c?c:b[q]={})[$=j.userId])&&void 0!==l?l:m[$]={};for(const t of E.objectsWithState)delete e[t];E.objectsWithState=[]}}else{if(E={path:"",channelGroupQuery:"",channels:[],channelGroups:[],previousTimetoken:"0",timetoken:"0",objectsWithState:[]},P.length>0){const e=JSON.parse(P),t=null!==(i=(p=null!==(r=b[h=j.subscriptionKey])&&void 0!==r?r:b[h]={})[g=j.userId])&&void 0!==i?i:p[g]={};Object.entries(e).forEach((([e,n])=>t[e]=n)),E.objectsWithState=Object.keys(e)}j.subscription=E}E.path!==e.request.path&&(E.path=e.request.path,E.channels=X(e.request)),E.channelGroupQuery!==O&&(E.channelGroupQuery=O,E.channelGroups=Y(e.request));let{authKey:S}=j;const{userId:T}=j;E.request=e.request,E.filterExpression=null!==(u=k["filter-expr"])&&void 0!==u?u:"",E.timetoken=null!==(a=k.tt)&&void 0!==a?a:"0",void 0!==k.tr&&(E.region=k.tr),j.authKey=null!==(d=k.auth)&&void 0!==d?d:"",j.origin=e.request.origin,j.userId=k.uuid,j.pnsdk=k.pnsdk,j.accessToken=e.token,j.newlyRegistered&&!S&&j.authKey&&(S=j.authKey),j.newlyRegistered=!1,N(j,T,S)},D=e=>{var t,n;const r=f[e.clientIdentifier],{request:i}=e;if(!r)return;const s=null!==(t=r.heartbeat)&&void 0!==t?t:r.heartbeat={channels:[],channelGroups:[]};s.channelGroups=Y(i).filter((e=>!e.endsWith("-pnpres"))),s.channels=X(i).filter((e=>!e.endsWith("-pnpres")));const o=null!==(n=i.queryParameters.state)&&void 0!==n?n:"";if(o.length>0){const e=JSON.parse(o);for(const t of Object.keys(e))s.channels.includes(t)||s.channelGroups.includes(t)||delete e[t];s.presenceState=e}},N=(e,t,n)=>{var r,i,s;if(!e||t===e.userId&&(null!=n?n:"")===(null!==(r=e.authKey)&&void 0!==r?r:""))return;const o=null!==(i=p[e.subscriptionKey])&&void 0!==i?i:{},c=`${t}_${null!==(s=te(e))&&void 0!==s?s:""}`;void 0!==o[c]&&delete o[c]},M=e=>{const t=f[e.clientIdentifier];t&&(t.lastPongEvent=(new Date).getTime()/1e3)},_=(e,t)=>{var n,r,i;const s=f[t];delete f[t];let o,c=h[e];if(s){if(s.subscription&&(o=s.subscription.serviceRequestId,delete s.subscription.serviceRequestId,o&&O(o)),p[e]){const t=null!==(n=p[e])&&void 0!==n?n:p[e]={},i=`${s.userId}_${null!==(r=te(s))&&void 0!==r?r:""}`;t[i]&&t[i].clientIdentifier===s.clientIdentifier&&delete t[i].clientIdentifier}s.unsubscribeOfflineClients&&V(s,o)}if(c)if(c=c.filter((e=>e.clientIdentifier!==t)),c.length>0?h[e]=c:(delete h[e],delete p[e]),0===c.length&&delete b[e],c.length>0){const n=g[e];n&&(delete n[t],0===Object.keys(n).length&&delete g[e])}else delete g[e];const l=`Invalidate '${t}' client. '${(null!==(i=h[e])&&void 0!==i?i:[]).length}' clients currently active.`;if(c)for(const e of c)ie(l,e);else ie(l)},V=(e,n)=>{if(!e.subscription)return;const{channels:r,channelGroups:i}=e.subscription,s=(null!=i?i:[]).filter((e=>!e.endsWith("-pnpres"))).map((e=>ce(e))).sort(),o=(null!=r?r:[]).filter((e=>!e.endsWith("-pnpres"))).map((e=>ce(e))).sort();if(0===o.length&&0===s.length)return;const l=s.length>0?s.join(","):void 0,u=0===o.length?",":o.join(","),a=Object.assign(Object.assign({instanceid:e.clientIdentifier,uuid:e.userId,requestid:c.createUUID()},e.authKey?{auth:e.authKey}:{}),l?{"channel-group":l}:{}),d={type:"send-request",clientIdentifier:e.clientIdentifier,subscriptionKey:e.subscriptionKey,request:{origin:e.origin,path:`/v2/presence/sub-key/${e.subscriptionKey}/channel/${u}/leave`,queryParameters:a,method:t.GET,headers:{},timeout:10,cancellable:!1,compressible:!1,identifier:a.requestid}};$(d,e,n)},J=e=>{const{clientIdentifier:t,subscriptionKey:n}=e.data;return!(!t||"string"!=typeof t)&&!(!n||"string"!=typeof n)},H=(e,t)=>{var n;const r=null!==(n=t.request.queryParameters["channel-group"])&&void 0!==n?n:"",i=t.request.path;let s,o;for(const n of e){const{subscription:e}=n;if(!e||!e.serviceRequestId)continue;const c=f[t.clientIdentifier],l=e.serviceRequestId;if(e.path===i&&e.channelGroupQuery===r)return ie(`Found identical request started by '${n.clientIdentifier}' client. \nWaiting for existing '${l}' request completion.`,c),e.serviceRequestId;{const r=v[e.serviceRequestId];if(s||(s=Y(t.request)),o||(o=X(t.request)),o.length&&!Z(r.channels,o))continue;if(s.length&&!Z(r.channelGroups,s))continue;return se(r,`'${t.request.identifier}' request channels and groups are subset of ongoing '${l}' request \nwhich has started by '${n.clientIdentifier}' client. Waiting for existing '${l}' request completion.`,c),e.serviceRequestId}}},Q=(e,t)=>{var n,r;const i=f[t.clientIdentifier];if(!i)return[];const s=t.request.queryParameters,o=te(i),c=null!==(n=s["filter-expr"])&&void 0!==n?n:"",l=s.uuid;return(null!==(r=h[t.subscriptionKey])&&void 0!==r?r:[]).filter((t=>t.userId===l&&te(t)===o&&t.subscription&&(0!==t.subscription.channels.length||0!==t.subscription.channelGroups.length)&&t.subscription.filterExpression===c&&("0"===e||"0"===t.subscription.timetoken||t.subscription.timetoken===e)))},B=e=>z(e),z=(e,t)=>{var n;const r=null!=t?t:f[e.clientIdentifier];if(!r)return[];const i=e.request.queryParameters,s=te(r),o=i.uuid;return(null!==(n=h[e.subscriptionKey])&&void 0!==n?n:[]).filter((e=>e.userId===o&&te(e)===s))},X=e=>{const t=e.path.split("/")[e.path.startsWith("/v2/subscribe/")?4:6];return","===t?[]:t.split(",").filter((e=>e.length>0))},Y=e=>{var t;const n=null!==(t=e.queryParameters["channel-group"])&&void 0!==t?t:"";return 0===n.length?[]:n.split(",").filter((e=>e.length>0))},Z=(e,t)=>{const n=new Set(e);return t.every(n.has,n)},ee=e=>{const t={type:"shared-worker-ping"},n=Object.values(f).filter((t=>t&&t.subscriptionKey===e));if(n.forEach((e=>{let r=!1;if(e&&e.lastPingRequest){const t=e.offlineClientsCheckInterval;if(!e.lastPongEvent||Math.abs(e.lastPongEvent-e.lastPingRequest)>.5*t){r=!0;for(const t of n)ie(`'${e.clientIdentifier}' client is inactive. Invalidating...`,t);_(e.subscriptionKey,e.clientIdentifier)}}e&&!r&&(e.lastPingRequest=(new Date).getTime()/1e3,R(e,t))})),n&&n.length>0&&n[0]){const t=n[0].offlineClientsCheckInterval;u[e]=setTimeout((()=>ee(e)),500*t-1)}},te=e=>{var t;return e.accessToken&&null!==(t=e.accessToken.token)&&void 0!==t?t:e.authKey},ne=e=>{const t=e.filter((e=>!!e.accessToken)).sort(((e,t)=>e.accessToken.expiration-t.accessToken.expiration)).pop();return t?t.authKey:void 0},re=e=>{const t=te(e);let n=`${e.userId}-${e.subscriptionKey}${t?`-${t}`:""}`;return e.subscription&&e.subscription.filterExpression&&(n+=`-${e.subscription.filterExpression}`),n},ie=(e,t)=>{const n=(t?[t]:Object.values(f)).filter((e=>e&&e.workerLogVerbosity)),r={type:"shared-worker-console-log",message:e};n.forEach((e=>{e&&R(e,r)}))},se=(e,t,n)=>{const r=(n?[n]:Object.values(f)).filter((e=>e&&e.workerLogVerbosity)),i={type:"shared-worker-console-dir",message:t,data:e};r.forEach((e=>{e&&R(e,i)}))},oe=e=>Object.keys(e).map((t=>{const n=e[t];return Array.isArray(n)?n.map((e=>`${t}=${ce(e)}`)).join("&"):`${t}=${ce(n)}`})).join("&"),ce=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`))})); +/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */r=s,function(e){var t="0.1.0",n={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function r(){var e,t,n="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(n+="-"),n+=(12===e?4:16===e?3&t|8:t).toString(16);return n}function i(e,t){var r=n[t||"all"];return r&&r.test(e)||!1}r.isUUID=i,r.VERSION=t,e.uuid=r,e.isUUID=i}(i=s.exports),null!==r&&(r.exports=i.uuid);var o=n(s.exports),c={createUUID:()=>o.uuid?o.uuid():o()};const l=new Map,u={},a=c.createUUID(),d=new Map,h={},f={},p={},b={},g={},v={};self.onconnect=e=>{ie("New PubNub Client connected to the Subscription Shared Worker."),e.ports.forEach((e=>{e.start(),e.onmessage=t=>{if(!J(t))return;const n=t.data;if("client-register"===n.type)n.port=e,x(n),ie(`Client '${n.clientIdentifier}' registered with '${a}' shared worker`);else if("client-unregister"===n.type)F(n);else if("client-pong"===n.type)M(n);else if("send-request"===n.type)if(n.request.path.startsWith("/v2/subscribe")){U(n);const e=h[n.clientIdentifier];if(e){const t=re(e);let r=[];if(l.has(t)&&(r=l.get(t)[0]),r.push([e,n]),!l.has(t)){const e=setTimeout((()=>{y(r,n),l.delete(t)}),50);l.set(t,[r,e])}}}else n.request.path.endsWith("/heartbeat")?(D(n),m(n)):$(n);else"cancel-request"===n.type&&k(n)},e.postMessage({type:"shared-worker-connected"})}))};const y=(e,t)=>{const n=K(t),r=h[t.clientIdentifier];r&&(e=e.filter((e=>e[0].clientIdentifier!==r.clientIdentifier)),I(r,t,n,!0),e.forEach((([e,t])=>I(e,t,n,!1))))},I=(e,t,n,r)=>{var i;let s=!1;if(r||"string"==typeof n||(n=n.identifier),e.subscription&&(s="0"===e.subscription.timetoken),"string"==typeof n){const r=v[n];if(e){if(e.subscription&&(e.subscription.timetoken=r.timetoken,e.subscription.region=r.region,e.subscription.serviceRequestId=n),!s)return;const o=(new TextEncoder).encode(`{"t":{"t":"${r.timetoken}","r":${null!==(i=r.region)&&void 0!==i?i:"0"}},"m":[]}`),c=new Headers({"Content-Type":'text/javascript; charset="UTF-8"',"Content-Length":`${o.length}`}),l=new Response(o,{status:200,headers:c}),u=W([l,o]);u.url=`${t.request.origin}${t.request.path}`,u.clientIdentifier=t.clientIdentifier,u.identifier=t.request.identifier,R(e,u)}return}t.request.cancellable&&d.set(n.identifier,new AbortController);const o=v[n.identifier],{timetokenOverride:c,regionOverride:l}=o;j(n,(()=>P(n.identifier)),((e,r)=>{A(e,r,t.request),S(e,n.identifier)}),((e,r)=>{A(e,null,t.request,L(r)),S(e,n.identifier)}),(e=>{let t=e;return s&&c&&"0"!==c&&(t=q(t,c,l)),t})),ie(`'${Object.keys(v).length}' subscription request currently active.`)},q=(e,t,n)=>{if(void 0===t||"0"===t||e[0].status>=400)return e;let r;const i=e[0];let s=i,o=e[1];try{r=JSON.parse((new TextDecoder).decode(o))}catch(t){return ie(`Subscribe response parse error: ${t}`),e}r.t.t=t,n&&(r.t.r=parseInt(n,10));try{if(o=(new TextEncoder).encode(JSON.stringify(r)).buffer,o.byteLength){const e=new Headers(i.headers);e.set("Content-Length",`${o.byteLength}`),s=new Response(o,{status:i.status,statusText:i.statusText,headers:e})}}catch(t){return ie(`Subscribe serialization error: ${t}`),e}return o.byteLength>0?[s,o]:e},m=e=>{var t;const n=h[e.clientIdentifier],r=G(e);if(!n)return;const i=`${n.userId}_${null!==(t=te(n))&&void 0!==t?t:""}`,s=p[n.subscriptionKey],o=(null!=s?s:{})[i];if(!r){let t,r;if(ie(`Previous heartbeat request has been sent less than ${n.heartbeatInterval} seconds ago. Skipping...`,n),o&&o.response&&([t,r]=o.response),!t){r=(new TextEncoder).encode('{ "status": 200, "message": "OK", "service": "Presence" }').buffer;const e=new Headers({"Content-Type":'text/javascript; charset="UTF-8"',"Content-Length":`${r.byteLength}`});t=new Response(r,{status:200,headers:e})}const i=W([t,r]);return i.url=`${e.request.origin}${e.request.path}`,i.clientIdentifier=e.clientIdentifier,i.identifier=e.request.identifier,void R(n,i)}j(r,(()=>[n]),((t,n)=>{o&&(o.response=n),A(t,n,e.request)}),((t,n)=>{A(t,null,e.request,L(n))})),ie("Started heartbeat request.",n)},$=(e,t,n)=>{var r,i,s;const o=null!=t?t:h[e.clientIdentifier],c=C(e,t);if(!o)return;const{subscription:l,heartbeat:u}=o,a=null!=n?n:null==l?void 0:l.serviceRequestId;if(l&&0===l.channels.length&&0===l.channelGroups.length&&(l.channelGroupQuery="",l.path="",l.previousTimetoken="0",l.timetoken="0",delete l.region,delete l.serviceRequestId,delete l.request),p[o.subscriptionKey]&&u&&0===u.channels.length&&0===u.channelGroups.length){const e=null!==(r=p[s=o.subscriptionKey])&&void 0!==r?r:p[s]={},t=`${o.userId}_${null!==(i=te(o))&&void 0!==i?i:""}`;e[t]&&e[t].clientIdentifier===o.clientIdentifier&&delete e[t].clientIdentifier,u.timer&&(clearInterval(u.timer),delete u.heartbeatEvent,delete u.timer)}if(!c){const t=(new TextEncoder).encode('{"status": 200, "action": "leave", "message": "OK", "service":"Presence"}'),n=new Headers({"Content-Type":'text/javascript; charset="UTF-8"',"Content-Length":`${t.length}`}),r=new Response(t,{status:200,headers:n}),i=W([r,t]);return i.url=`${e.request.origin}${e.request.path}`,i.clientIdentifier=e.clientIdentifier,i.identifier=e.request.identifier,void R(o,i)}if(j(c,(()=>[o]),((t,n)=>{A(t,n,e.request)}),((t,n)=>{A(t,null,e.request,L(n))})),ie("Started leave request.",o),void 0===a)return;const d=P(a);d.forEach((e=>{e&&e.subscription&&delete e.subscription.serviceRequestId})),O(a),w(d)},k=e=>{const t=h[e.clientIdentifier];if(!t||!t.subscription)return;const n=t.subscription.serviceRequestId;t&&n&&(delete t.subscription.serviceRequestId,t.subscription.request&&t.subscription.request.identifier===e.identifier&&delete t.subscription.request,O(n))},w=e=>{let t,n;for(const r of e)if(r.subscription&&r.subscription.request){n=r.subscription.request,t=r;break}if(!n||!t)return;const r={type:"send-request",clientIdentifier:t.clientIdentifier,subscriptionKey:t.subscriptionKey,request:n};y([[t,r]],r)},j=(t,n,r,i,s)=>{e(void 0,void 0,void 0,(function*(){var e;Promise.race([fetch(T(t),{signal:null===(e=d.get(t.identifier))||void 0===e?void 0:e.signal,keepalive:!0}),E(t.identifier,t.timeout)]).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>s?s(e):e)).then((e=>{const t=n();0!==t.length&&r(t,e)})).catch((e=>{const t=n();if(0===t.length)return;let r=e;if("string"==typeof e){const t=e.toLowerCase();r=new Error(e),!t.includes("timeout")&&t.includes("cancel")&&(r.name="AbortError")}i(t,r)}))}))},O=e=>{if(0===P(e).length){const t=d.get(e);d.delete(e),delete v[e],t&&t.abort("Cancel request")}},E=(e,t)=>new Promise(((n,r)=>{const i=setTimeout((()=>{d.delete(e),clearTimeout(i),r(new Error("Request timeout"))}),1e3*t)})),P=e=>Object.values(h).filter((t=>void 0!==t&&void 0!==t.subscription&&t.subscription.serviceRequestId===e)),S=(e,t)=>{delete v[t],e.forEach((e=>{e.subscription&&(delete e.subscription.request,delete e.subscription.serviceRequestId)}))},T=e=>{let t;const n=e.queryParameters;let r=e.path;if(e.headers){t={};for(const[n,r]of Object.entries(e.headers))t[n]=r}return n&&0!==Object.keys(n).length&&(r=`${r}?${oe(n)}`),new Request(`${e.origin}${r}`,{method:e.method,headers:t,redirect:"follow"})},K=e=>{var t,n,r,i,s;const o=h[e.clientIdentifier],l=o.subscription,u=Q(l.timetoken,e),a=c.createUUID(),d=Object.assign({},e.request);let f,p;if(u.length>1){const s=H(u,e);if(s){const e=v[s],{channels:n,channelGroups:r}=null!==(t=o.subscription)&&void 0!==t?t:{channels:[],channelGroups:[]};if((!(n.length>0)||Z(e.channels,n))&&(!(r.length>0)||Z(e.channelGroups,r)))return s}const c=(null!==(n=b[o.subscriptionKey])&&void 0!==n?n:{})[o.userId],h={},g=new Set(l.channelGroups),y=new Set(l.channels);c&&l.objectsWithState.length&&l.objectsWithState.forEach((e=>{const t=c[e];t&&(h[e]=t)}));for(const e of u){const{subscription:t}=e;if(!t)continue;1!==u.length&&e.clientIdentifier===o.clientIdentifier||!t.timetoken||(f=t.timetoken,p=t.region),t.channelGroups.forEach(g.add,g),t.channels.forEach(y.add,y);const n=t.serviceRequestId;t.serviceRequestId=a,n&&v[n]&&O(n),c&&t.objectsWithState.forEach((e=>{const t=c[e];t&&!h[e]&&(h[e]=t)}))}const I=null!==(r=v[a])&&void 0!==r?r:v[a]={requestId:a,timetoken:null!==(i=d.queryParameters.tt)&&void 0!==i?i:"0",channelGroups:[],channels:[]};if(y.size){I.channels=Array.from(y).sort();const e=d.path.split("/");e[4]=I.channels.join(","),d.path=e.join("/")}if(g.size&&(I.channelGroups=Array.from(g).sort(),d.queryParameters["channel-group"]=I.channelGroups.join(",")),Object.keys(h).length&&(d.queryParameters.state=JSON.stringify(h)),d.queryParameters&&d.queryParameters.auth){const e=ne(u);e&&(d.queryParameters.auth=e)}}else v[a]={requestId:a,timetoken:null!==(s=d.queryParameters.tt)&&void 0!==s?s:"0",channelGroups:l.channelGroups,channels:l.channels};v[a]&&(d.queryParameters&&void 0!==d.queryParameters.tt&&void 0!==d.queryParameters.tr&&(v[a].region=d.queryParameters.tr),v[a].timetokenOverride=f,v[a].regionOverride=p),l.serviceRequestId=a,d.identifier=a;const g=u.reduce(((e,{clientIdentifier:t})=>(e.push(t),e)),[]).join(", ");if(g.length>0)for(const e of u)se(v[a],`Started aggregated request for clients: ${g}`,e);return d},G=e=>{var t,n,r,i,s;const o=h[e.clientIdentifier],c=B(e),l=Object.assign({},e.request);if(!o||!o.heartbeat)return;const u=null!==(t=p[s=o.subscriptionKey])&&void 0!==t?t:p[s]={},a=`${o.userId}_${null!==(n=te(o))&&void 0!==n?n:""}`,d=[...o.heartbeat.channelGroups],f=[...o.heartbeat.channels];let b,g,v=!1;if(u[a]){const{channels:e,channelGroups:t,response:n}=u[a];b=null!==(i=o.heartbeat.presenceState)&&void 0!==i?i:{},g=Z(e,f)&&Z(t,d),n&&(v=n[0].status>=400)}else u[a]={channels:f,channelGroups:d,clientIdentifier:o.clientIdentifier,timestamp:Date.now()},b=null!==(r=o.heartbeat.presenceState)&&void 0!==r?r:{},g=!1;let y=o.heartbeatInterval;for(const e of c)e.heartbeatInterval&&(y=Math.min(y,e.heartbeatInterval));if(g&&u[a].clientIdentifier){const e=u[a].timestamp+1e3*y,t=Date.now();if(!v&&t.05*y*1e3)return}delete u[a].response,u[a].clientIdentifier=o.clientIdentifier;for(const t of c){const{heartbeat:n}=t;void 0!==n&&t.clientIdentifier!==e.clientIdentifier&&(n.presenceState&&(b=Object.assign(Object.assign({},b),n.presenceState)),d.push(...n.channelGroups.filter((e=>!d.includes(e)))),f.push(...n.channels.filter((e=>!f.includes(e)))))}u[a].channels=f,u[a].channelGroups=d,u[a].timestamp=Date.now();for(const e in Object.keys(b))f.includes(e)||d.includes(e)||delete b[e];if(0!==f.length||0!==d.length){if(f.length||d.length){const e=l.path.split("/");e[6]=f.length?f.join(","):",",l.path=e.join("/")}if(d.length&&(l.queryParameters["channel-group"]=d.join(",")),Object.keys(b).length?l.queryParameters.state=JSON.stringify(b):delete l.queryParameters.state,c.length>1&&l.queryParameters&&l.queryParameters.auth){const e=ne(c);e&&(l.queryParameters.auth=e)}return l}},C=(e,t)=>{var n;const r=null!=t?t:h[e.clientIdentifier],i=z(e,t);let s=Y(e.request),o=X(e.request);const c=Object.assign({},e.request);if(r&&r.subscription){const{subscription:e}=r;o.length&&(e.channels=e.channels.filter((e=>!o.includes(e)))),s.length&&(e.channelGroups=e.channelGroups.filter((e=>!s.includes(e))))}if(r&&r.heartbeat){const{heartbeat:e}=r;o.length&&(e.channels=e.channels.filter((e=>!o.includes(e)))),s.length&&(e.channelGroups=e.channelGroups.filter((e=>!s.includes(e))))}for(const t of i){const n=t.subscription;void 0!==n&&(t.clientIdentifier!==e.clientIdentifier&&(o.length&&(o=o.filter((e=>!e.endsWith("-pnpres")&&!n.channels.includes(e)))),s.length&&(s=s.filter((e=>!e.endsWith("-pnpres")&&!n.channelGroups.includes(e))))))}if(o.length&&(o=o.filter((e=>!e.endsWith("-pnpres")))),s.length&&(s=s.filter((e=>!e.endsWith("-pnpres")))),0!==o.length||0!==s.length){if(r&&p[r.subscriptionKey]&&(o.length||s.length)){const e=p[r.subscriptionKey],t=`${r.userId}_${null!==(n=te(r))&&void 0!==n?n:""}`;if(e[t]){let{channels:n,channelGroups:r}=e[t];s.length&&(r=r.filter((e=>!o.includes(e)))),o.length&&(n=n.filter((e=>!o.includes(e)))),e[t].channelGroups=r,e[t].channels=n}}if(o.length){const e=c.path.split("/");e[6]=o.join(","),c.path=e.join("/")}if(s.length&&(c.queryParameters["channel-group"]=s.join(",")),i.length>1&&c.queryParameters&&c.queryParameters.auth){const e=ne(i);e&&(c.queryParameters.auth=e)}return c}if(r&&r.workerLogVerbosity){const e=i.reduce(((e,{clientIdentifier:t})=>(e.push(t),e)),[]).join(", ");ie(`Specified channels and groups still in use by other clients: ${e}. Ignoring leave request.`,r)}},R=(e,t)=>{var n;const r=(null!==(n=g[e.subscriptionKey])&&void 0!==n?n:{})[e.clientIdentifier];if(!r)return!1;try{return r.postMessage(t),!0}catch(t){e.workerLogVerbosity&&console.error(`[SharedWorker] Unable send message using message port: ${t}`)}return!1},A=(e,t,n,r)=>{var i,s;if(0===e.length)return;if(!r&&!t)return;const o=e.some((e=>e&&e.workerLogVerbosity)),c=null!==(i=g[e[0].subscriptionKey])&&void 0!==i?i:{},l=n&&n.path.startsWith("/v2/subscribe");if(!r&&t&&(r=t[0].status>=400?L(void 0,t):W(t)),o&&n&&!n.path.endsWith("/heartbeat")){const t=`Notify clients about ${l?"subscribe":"leave"} request completion: ${e.reduce(((e,{clientIdentifier:t})=>(e.push(t),e)),[]).join(", ")}`;for(const n of e)ie(t,n)}for(const t of e){if(l&&!t.subscription){if(o){const n=`${t.clientIdentifier} doesn't have active subscription. Don't notify about completion.`;for(const t of e)ie(n,t)}continue}const i=c[t.clientIdentifier],{request:u}=null!==(s=t.subscription)&&void 0!==s?s:{};let a=null!=u?u:n;if(l||(a=n),i&&a){const e=Object.assign(Object.assign({},r),{clientIdentifier:t.clientIdentifier,identifier:a.identifier,url:`${a.origin}${a.path}`});R(t,e)}else if(!i&&o){const n=`${t.clientIdentifier} doesn't have Shared Worker's communication channel. Don't notify about completion.`;for(const r of e)r.clientIdentifier!==t.clientIdentifier&&ie(n,r)}}},W=e=>{var t;const[n,r]=e,i=r.byteLength>0?r:void 0,s=parseInt(null!==(t=n.headers.get("Content-Length"))&&void 0!==t?t:"0",10),o=n.headers.get("Content-Type"),c={};return n.headers.forEach(((e,t)=>c[t]=e.toLowerCase())),{type:"request-process-success",clientIdentifier:"",identifier:"",url:"",response:{contentLength:s,contentType:o,headers:c,status:n.status,body:i}}},L=(e,t)=>{if(t)return Object.assign(Object.assign({},W(t)),{type:"request-process-error"});let n="NETWORK_ISSUE",r="Unknown error",i="Error";e&&e instanceof Error&&(r=e.message,i=e.name);const s=r.toLowerCase();return s.includes("timeout")?n="TIMEOUT":("AbortError"===i||s.includes("aborted")||s.includes("cancel"))&&(r="Request aborted",n="ABORTED"),{type:"request-process-error",clientIdentifier:"",identifier:"",url:"",error:{name:i,type:n,message:r}}},x=e=>{var t,n,r,i,s;const{clientIdentifier:o}=e;if(h[o])return;const c=h[o]={clientIdentifier:o,subscriptionKey:e.subscriptionKey,userId:e.userId,heartbeatInterval:e.heartbeatInterval,newlyRegistered:!0,offlineClientsCheckInterval:e.workerOfflineClientsCheckInterval,unsubscribeOfflineClients:e.workerUnsubscribeOfflineClients,workerLogVerbosity:e.workerLogVerbosity},l=null!==(t=f[i=e.subscriptionKey])&&void 0!==t?t:f[i]=[];l.every((e=>e.clientIdentifier!==o))&&l.push(c),(null!==(n=g[s=e.subscriptionKey])&&void 0!==n?n:g[s]={})[o]=e.port;const a=`Registered PubNub client with '${o}' identifier. '${l.length}' clients currently active.`;for(const e of l)ie(a,e);if(!u[e.subscriptionKey]&&(null!==(r=f[e.subscriptionKey])&&void 0!==r?r:[]).length>0){const{subscriptionKey:t}=e,n=e.workerOfflineClientsCheckInterval;for(const e of l)ie(`Setup PubNub client ping event ${n} seconds`,e);u[t]=setTimeout((()=>ee(t)),500*n-1)}},F=e=>{_(e.subscriptionKey,e.clientIdentifier)},U=e=>{var t,n,r,i,s,o,c,l,u,a,d,f,p,g,v,y,I,q,m,$;const k=e.request.queryParameters,{clientIdentifier:w}=e,j=h[w];let O=!1;if(!j)return;const E=null!==(t=k["channel-group"])&&void 0!==t?t:"",P=null!==(n=k.state)&&void 0!==n?n:"";let S=j.subscription;if(S){if(P.length>0){const e=JSON.parse(P),t=null!==(o=(y=null!==(s=b[v=j.subscriptionKey])&&void 0!==s?s:b[v]={})[I=j.userId])&&void 0!==o?o:y[I]={};Object.entries(e).forEach((([e,n])=>t[e]=n));for(const n of S.objectsWithState)e[n]||delete t[n];S.objectsWithState=Object.keys(e)}else if(S.objectsWithState.length){const e=null!==(l=(m=null!==(c=b[q=j.subscriptionKey])&&void 0!==c?c:b[q]={})[$=j.userId])&&void 0!==l?l:m[$]={};for(const t of S.objectsWithState)delete e[t];S.objectsWithState=[]}}else{if(O=!0,S={path:"",channelGroupQuery:"",channels:[],channelGroups:[],previousTimetoken:"0",timetoken:"0",objectsWithState:[]},P.length>0){const e=JSON.parse(P),t=null!==(i=(p=null!==(r=b[f=j.subscriptionKey])&&void 0!==r?r:b[f]={})[g=j.userId])&&void 0!==i?i:p[g]={};Object.entries(e).forEach((([e,n])=>t[e]=n)),S.objectsWithState=Object.keys(e)}j.subscription=S}if(S.path!==e.request.path){S.path=e.request.path;const t=X(e.request);O||(O=Z(S.channels,t)),S.channels=t}if(S.channelGroupQuery!==E){S.channelGroupQuery=E;const t=Y(e.request);O||(O=Z(S.channelGroups,t)),S.channelGroups=t}let{authKey:T}=j;const{userId:K}=j;S.request=e.request,S.filterExpression=null!==(u=k["filter-expr"])&&void 0!==u?u:"",S.timetoken=null!==(a=k.tt)&&void 0!==a?a:"0",void 0!==k.tr&&(S.region=k.tr),j.authKey=null!==(d=k.auth)&&void 0!==d?d:"",j.origin=e.request.origin,j.userId=k.uuid,j.pnsdk=k.pnsdk,j.accessToken=e.token,j.newlyRegistered&&!T&&j.authKey&&(T=j.authKey),j.newlyRegistered=!1,N(j,K,T)},D=e=>{var t,n;const{clientIdentifier:r}=e,i=h[r],{request:s}=e;if(!i)return;const o=null!==(t=i.heartbeat)&&void 0!==t?t:i.heartbeat={channels:[],channelGroups:[]};o.heartbeatEvent=Object.assign({},e),o.timer||(o.timer=setInterval((()=>{const e=h[r];e&&e.heartbeat&&e.heartbeat.heartbeatEvent&&m(e.heartbeat.heartbeatEvent)}),1e3*i.heartbeatInterval)),o.channelGroups=Y(s).filter((e=>!e.endsWith("-pnpres"))),o.channels=X(s).filter((e=>!e.endsWith("-pnpres")));const c=null!==(n=s.queryParameters.state)&&void 0!==n?n:"";if(c.length>0){const e=JSON.parse(c);for(const t of Object.keys(e))o.channels.includes(t)||o.channelGroups.includes(t)||delete e[t];o.presenceState=e}},N=(e,t,n)=>{var r,i,s;if(!e||t===e.userId&&(null!=n?n:"")===(null!==(r=e.authKey)&&void 0!==r?r:""))return;const o=null!==(i=p[e.subscriptionKey])&&void 0!==i?i:{},c=`${t}_${null!==(s=te(e))&&void 0!==s?s:""}`;void 0!==o[c]&&delete o[c]},M=e=>{const t=h[e.clientIdentifier];t&&(t.lastPongEvent=(new Date).getTime()/1e3)},_=(e,t)=>{var n,r,i;const s=h[t];delete h[t];let o,c=f[e];if(s){if(s.subscription&&(o=s.subscription.serviceRequestId,delete s.subscription.serviceRequestId,o&&O(o)),s.heartbeat&&s.heartbeat.timer&&clearInterval(s.heartbeat.timer),p[e]){const t=null!==(n=p[e])&&void 0!==n?n:p[e]={},i=`${s.userId}_${null!==(r=te(s))&&void 0!==r?r:""}`;t[i]&&t[i].clientIdentifier===s.clientIdentifier&&delete t[i].clientIdentifier}s.unsubscribeOfflineClients&&V(s,o)}if(c)if(c=c.filter((e=>e.clientIdentifier!==t)),c.length>0?f[e]=c:(delete f[e],delete p[e]),0===c.length&&delete b[e],c.length>0){const n=g[e];n&&(delete n[t],0===Object.keys(n).length&&delete g[e])}else delete g[e];const l=`Invalidate '${t}' client. '${(null!==(i=f[e])&&void 0!==i?i:[]).length}' clients currently active.`;if(c)for(const e of c)ie(l,e);else ie(l)},V=(e,n)=>{if(!e.subscription)return;const{channels:r,channelGroups:i}=e.subscription,s=(null!=i?i:[]).filter((e=>!e.endsWith("-pnpres"))).map((e=>ce(e))).sort(),o=(null!=r?r:[]).filter((e=>!e.endsWith("-pnpres"))).map((e=>ce(e))).sort();if(0===o.length&&0===s.length)return;const l=s.length>0?s.join(","):void 0,u=0===o.length?",":o.join(","),a=Object.assign(Object.assign({instanceid:e.clientIdentifier,uuid:e.userId,requestid:c.createUUID()},e.authKey?{auth:e.authKey}:{}),l?{"channel-group":l}:{}),d={type:"send-request",clientIdentifier:e.clientIdentifier,subscriptionKey:e.subscriptionKey,request:{origin:e.origin,path:`/v2/presence/sub-key/${e.subscriptionKey}/channel/${u}/leave`,queryParameters:a,method:t.GET,headers:{},timeout:10,cancellable:!1,compressible:!1,identifier:a.requestid}};$(d,e,n)},J=e=>{const{clientIdentifier:t,subscriptionKey:n}=e.data;return!(!t||"string"!=typeof t)&&!(!n||"string"!=typeof n)},H=(e,t)=>{var n;const r=null!==(n=t.request.queryParameters["channel-group"])&&void 0!==n?n:"",i=t.request.path;let s,o;for(const n of e){const{subscription:e}=n;if(!e||!e.serviceRequestId)continue;const c=h[t.clientIdentifier],l=e.serviceRequestId;if(e.path===i&&e.channelGroupQuery===r)return ie(`Found identical request started by '${n.clientIdentifier}' client. \nWaiting for existing '${l}' request completion.`,c),e.serviceRequestId;{const r=v[e.serviceRequestId];if(s||(s=Y(t.request)),o||(o=X(t.request)),o.length&&!Z(r.channels,o))continue;if(s.length&&!Z(r.channelGroups,s))continue;return se(r,`'${t.request.identifier}' request channels and groups are subset of ongoing '${l}' request \nwhich has started by '${n.clientIdentifier}' client. Waiting for existing '${l}' request completion.`,c),e.serviceRequestId}}},Q=(e,t)=>{var n,r;const i=h[t.clientIdentifier];if(!i)return[];const s=t.request.queryParameters,o=te(i),c=null!==(n=s["filter-expr"])&&void 0!==n?n:"",l=s.uuid;return(null!==(r=f[t.subscriptionKey])&&void 0!==r?r:[]).filter((t=>t.userId===l&&te(t)===o&&t.subscription&&(0!==t.subscription.channels.length||0!==t.subscription.channelGroups.length)&&t.subscription.filterExpression===c&&("0"===e||"0"===t.subscription.timetoken||t.subscription.timetoken===e)))},B=e=>z(e),z=(e,t)=>{var n;const r=null!=t?t:h[e.clientIdentifier];if(!r)return[];const i=e.request.queryParameters,s=te(r),o=i.uuid;return(null!==(n=f[e.subscriptionKey])&&void 0!==n?n:[]).filter((e=>e.userId===o&&te(e)===s))},X=e=>{const t=e.path.split("/")[e.path.startsWith("/v2/subscribe/")?4:6];return","===t?[]:t.split(",").filter((e=>e.length>0))},Y=e=>{var t;const n=null!==(t=e.queryParameters["channel-group"])&&void 0!==t?t:"";return 0===n.length?[]:n.split(",").filter((e=>e.length>0))},Z=(e,t)=>{const n=new Set(e);return t.every(n.has,n)},ee=e=>{const t={type:"shared-worker-ping"},n=Object.values(h).filter((t=>t&&t.subscriptionKey===e));if(n.forEach((e=>{let r=!1;if(e&&e.lastPingRequest){const t=e.offlineClientsCheckInterval;if(!e.lastPongEvent||Math.abs(e.lastPongEvent-e.lastPingRequest)>.5*t){r=!0;for(const t of n)ie(`'${e.clientIdentifier}' client is inactive. Invalidating...`,t);_(e.subscriptionKey,e.clientIdentifier)}}e&&!r&&(e.lastPingRequest=(new Date).getTime()/1e3,R(e,t))})),n&&n.length>0&&n[0]){const t=n[0].offlineClientsCheckInterval;u[e]=setTimeout((()=>ee(e)),500*t-1)}},te=e=>{var t;return e.accessToken&&null!==(t=e.accessToken.token)&&void 0!==t?t:e.authKey},ne=e=>{const t=e.filter((e=>!!e.accessToken)).sort(((e,t)=>e.accessToken.expiration-t.accessToken.expiration)).pop();return t?t.authKey:void 0},re=e=>{const t=te(e);let n=`${e.userId}-${e.subscriptionKey}${t?`-${t}`:""}`;return e.subscription&&e.subscription.filterExpression&&(n+=`-${e.subscription.filterExpression}`),n},ie=(e,t)=>{const n=(t?[t]:Object.values(h)).filter((e=>e&&e.workerLogVerbosity)),r={type:"shared-worker-console-log",message:e};n.forEach((e=>{e&&R(e,r)}))},se=(e,t,n)=>{const r=(n?[n]:Object.values(h)).filter((e=>e&&e.workerLogVerbosity)),i={type:"shared-worker-console-dir",message:t,data:e};r.forEach((e=>{e&&R(e,i)}))},oe=e=>Object.keys(e).map((t=>{const n=e[t];return Array.isArray(n)?n.map((e=>`${t}=${ce(e)}`)).join("&"):`${t}=${ce(n)}`})).join("&"),ce=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`))})); diff --git a/lib/core/components/configuration.js b/lib/core/components/configuration.js index fa22fb4da..d55de913e 100644 --- a/lib/core/components/configuration.js +++ b/lib/core/components/configuration.js @@ -9,11 +9,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeConfiguration = void 0; +const console_logger_1 = require("../../loggers/console-logger"); const retry_policy_1 = require("./retry-policy"); -const uuid_1 = __importDefault(require("./uuid")); const logger_1 = require("../interfaces/logger"); const logger_manager_1 = require("./logger-manager"); -const console_logger_1 = require("../../loggers/console-logger"); +const uuid_1 = __importDefault(require("./uuid")); // -------------------------------------------------------- // ----------------------- Defaults ----------------------- // -------------------------------------------------------- diff --git a/lib/core/components/cryptography/index.js b/lib/core/components/cryptography/index.js index 6388b0cb0..3e1cd3be5 100644 --- a/lib/core/components/cryptography/index.js +++ b/lib/core/components/cryptography/index.js @@ -123,7 +123,7 @@ class default_1 { encrypt(data, customCipherKey, options) { if (this.configuration.customEncrypt) { if (this.logger) - this.logger.warn(this.constructor.name, "'customEncrypt' is deprecated. Consult docs for better alternative."); + this.logger.warn('Crypto', "'customEncrypt' is deprecated. Consult docs for better alternative."); return this.configuration.customEncrypt(data); } return this.pnEncrypt(data, customCipherKey, options); @@ -140,7 +140,7 @@ class default_1 { decrypt(data, customCipherKey, options) { if (this.configuration.customDecrypt) { if (this.logger) - this.logger.warn(this.constructor.name, "'customDecrypt' is deprecated. Consult docs for better alternative."); + this.logger.warn('Crypto', "'customDecrypt' is deprecated. Consult docs for better alternative."); return this.configuration.customDecrypt(data); } return this.pnDecrypt(data, customCipherKey, options); @@ -159,7 +159,7 @@ class default_1 { if (!decidedCipherKey) return data; if (this.logger) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('Crypto', () => ({ messageType: 'object', message: Object.assign({ data, cipherKey: decidedCipherKey }, (options !== null && options !== void 0 ? options : {})), details: 'Encrypt with parameters:', @@ -196,7 +196,7 @@ class default_1 { if (!decidedCipherKey) return data; if (this.logger) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('Crypto', () => ({ messageType: 'object', message: Object.assign({ data, cipherKey: decidedCipherKey }, (options !== null && options !== void 0 ? options : {})), details: 'Decrypt with parameters:', @@ -218,7 +218,7 @@ class default_1 { } catch (e) { if (this.logger) - this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e })); + this.logger.error('Crypto', () => ({ messageType: 'error', message: e })); return null; } } @@ -233,7 +233,7 @@ class default_1 { } catch (e) { if (this.logger) - this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e })); + this.logger.error('Crypto', () => ({ messageType: 'error', message: e })); return null; } } diff --git a/lib/core/components/deduping_manager.js b/lib/core/components/deduping_manager.js index e1bf249e7..8da9afa9d 100644 --- a/lib/core/components/deduping_manager.js +++ b/lib/core/components/deduping_manager.js @@ -19,7 +19,7 @@ class DedupingManager { */ constructor(config) { this.config = config; - config.logger().debug(this.constructor.name, () => ({ + config.logger().debug('DedupingManager', () => ({ messageType: 'object', message: { maximumCacheSize: config.maximumCacheSize }, details: 'Create with configuration:', diff --git a/lib/core/components/stringify_buffer_keys.js b/lib/core/components/stringify_buffer_keys.js index 4aa394b29..3cfdc806f 100644 --- a/lib/core/components/stringify_buffer_keys.js +++ b/lib/core/components/stringify_buffer_keys.js @@ -10,12 +10,13 @@ exports.stringifyBufferKeys = stringifyBufferKeys; * Re-map CBOR object keys from potentially C buffer strings to actual strings. * * @param obj CBOR which should be remapped to stringified keys. + * @param nestingLevel PAM token structure nesting level. * * @returns Dictionary with stringified keys. * * @internal */ -function stringifyBufferKeys(obj) { +function stringifyBufferKeys(obj, nestingLevel = 0) { const isObject = (value) => typeof value === 'object' && value !== null && value.constructor === Object; const isString = (value) => typeof value === 'string' || value instanceof String; const isNumber = (value) => typeof value === 'number' && isFinite(value); @@ -26,16 +27,18 @@ function stringifyBufferKeys(obj) { const keyIsString = isString(key); let stringifiedKey = key; const value = obj[key]; - if (keyIsString && key.indexOf(',') >= 0) { - const bytes = key.split(',').map(Number); - stringifiedKey = bytes.reduce((string, byte) => { - return string + String.fromCharCode(byte); - }, ''); + if (nestingLevel < 2) { + if (keyIsString && key.indexOf(',') >= 0) { + const bytes = key.split(',').map(Number); + stringifiedKey = bytes.reduce((string, byte) => { + return string + String.fromCharCode(byte); + }, ''); + } + else if (isNumber(key) || (keyIsString && !isNaN(Number(key)))) { + stringifiedKey = String.fromCharCode(isNumber(key) ? key : parseInt(key, 10)); + } } - else if (isNumber(key) || (keyIsString && !isNaN(Number(key)))) { - stringifiedKey = String.fromCharCode(isNumber(key) ? key : parseInt(key, 10)); - } - normalizedObject[stringifiedKey] = isObject(value) ? stringifyBufferKeys(value) : value; + normalizedObject[stringifiedKey] = isObject(value) ? stringifyBufferKeys(value, nestingLevel + 1) : value; }); return normalizedObject; } diff --git a/lib/core/components/subscription-manager.js b/lib/core/components/subscription-manager.js index d584bde69..5f4a943db 100644 --- a/lib/core/components/subscription-manager.js +++ b/lib/core/components/subscription-manager.js @@ -38,7 +38,7 @@ class SubscriptionManager { this.subscribeCall = subscribeCall; this.heartbeatCall = heartbeatCall; this.leaveCall = leaveCall; - configuration.logger().trace(this.constructor.name, 'Create manager.'); + configuration.logger().trace('SubscriptionManager', 'Create manager.'); this.reconnectionManager = new reconnection_manager_1.ReconnectionManager(time); this.dedupingManager = new deduping_manager_1.DedupingManager(this.configuration); this.heartbeatChannelGroups = {}; @@ -320,7 +320,7 @@ class SubscriptionManager { timetoken: this.currentTimetoken, region: this.region ? this.region : undefined, }; - this.configuration.logger().debug(this.constructor.name, () => { + this.configuration.logger().debug('SubscriptionManager', () => { const hashedEvents = messages.map((event) => { const pn_mfp = event.type === subscribe_1.PubNubEventType.Message || event.type === subscribe_1.PubNubEventType.Signal ? (0, utils_1.messageFingerprint)(event.data.message) @@ -332,7 +332,7 @@ class SubscriptionManager { messages.forEach((message) => { if (dedupeOnSubscribe && 'message' in message.data && 'timetoken' in message.data) { if (this.dedupingManager.isDuplicate(message.data)) { - this.configuration.logger().warn(this.constructor.name, () => ({ + this.configuration.logger().warn('SubscriptionManager', () => ({ messageType: 'object', message: message.data, details: 'Duplicate message detected (skipped):', diff --git a/lib/core/endpoints/objects/channel/set.js b/lib/core/endpoints/objects/channel/set.js index c6497fa6f..5bff4b4e3 100644 --- a/lib/core/endpoints/objects/channel/set.js +++ b/lib/core/endpoints/objects/channel/set.js @@ -46,6 +46,13 @@ class SetChannelMetadataRequest extends request_1.AbstractRequest { if (!this.parameters.data) return 'Data cannot be empty'; } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json' }); + } get path() { const { keySet: { subscribeKey }, channel, } = this.parameters; return `/v2/objects/${subscribeKey}/channels/${(0, utils_1.encodeString)(channel)}`; diff --git a/lib/core/interfaces/configuration.js b/lib/core/interfaces/configuration.js index 89739eeb3..5884bed4f 100644 --- a/lib/core/interfaces/configuration.js +++ b/lib/core/interfaces/configuration.js @@ -50,10 +50,6 @@ const USE_SMART_HEARTBEAT = false; * Whether PubNub client should try to utilize existing TCP connection for new requests or not. */ const KEEP_ALIVE = false; -/** - * Whether verbose logging should be enabled or not. - */ -const USE_VERBOSE_LOGGING = false; /** * Whether leave events should be suppressed or not. */ @@ -102,29 +98,28 @@ const PRESENCE_TIMEOUT_MAXIMUM = 320; * @internal */ const setDefaults = (configuration) => { - var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r; + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; // Copy configuration. const configurationCopy = Object.assign({}, configuration); - (_a = configurationCopy.logVerbosity) !== null && _a !== void 0 ? _a : (configurationCopy.logVerbosity = USE_VERBOSE_LOGGING); - (_b = configurationCopy.ssl) !== null && _b !== void 0 ? _b : (configurationCopy.ssl = USE_SSL); - (_c = configurationCopy.transactionalRequestTimeout) !== null && _c !== void 0 ? _c : (configurationCopy.transactionalRequestTimeout = TRANSACTIONAL_REQUEST_TIMEOUT); - (_d = configurationCopy.subscribeRequestTimeout) !== null && _d !== void 0 ? _d : (configurationCopy.subscribeRequestTimeout = SUBSCRIBE_REQUEST_TIMEOUT); - (_e = configurationCopy.fileRequestTimeout) !== null && _e !== void 0 ? _e : (configurationCopy.fileRequestTimeout = FILE_REQUEST_TIMEOUT); - (_f = configurationCopy.restore) !== null && _f !== void 0 ? _f : (configurationCopy.restore = RESTORE); - (_g = configurationCopy.useInstanceId) !== null && _g !== void 0 ? _g : (configurationCopy.useInstanceId = USE_INSTANCE_ID); - (_h = configurationCopy.suppressLeaveEvents) !== null && _h !== void 0 ? _h : (configurationCopy.suppressLeaveEvents = SUPPRESS_LEAVE_EVENTS); - (_j = configurationCopy.requestMessageCountThreshold) !== null && _j !== void 0 ? _j : (configurationCopy.requestMessageCountThreshold = DEDUPE_CACHE_SIZE); - (_k = configurationCopy.autoNetworkDetection) !== null && _k !== void 0 ? _k : (configurationCopy.autoNetworkDetection = AUTO_NETWORK_DETECTION); - (_l = configurationCopy.enableEventEngine) !== null && _l !== void 0 ? _l : (configurationCopy.enableEventEngine = ENABLE_EVENT_ENGINE); - (_m = configurationCopy.maintainPresenceState) !== null && _m !== void 0 ? _m : (configurationCopy.maintainPresenceState = MAINTAIN_PRESENCE_STATE); - (_o = configurationCopy.useSmartHeartbeat) !== null && _o !== void 0 ? _o : (configurationCopy.useSmartHeartbeat = USE_SMART_HEARTBEAT); - (_p = configurationCopy.keepAlive) !== null && _p !== void 0 ? _p : (configurationCopy.keepAlive = KEEP_ALIVE); + (_a = configurationCopy.ssl) !== null && _a !== void 0 ? _a : (configurationCopy.ssl = USE_SSL); + (_b = configurationCopy.transactionalRequestTimeout) !== null && _b !== void 0 ? _b : (configurationCopy.transactionalRequestTimeout = TRANSACTIONAL_REQUEST_TIMEOUT); + (_c = configurationCopy.subscribeRequestTimeout) !== null && _c !== void 0 ? _c : (configurationCopy.subscribeRequestTimeout = SUBSCRIBE_REQUEST_TIMEOUT); + (_d = configurationCopy.fileRequestTimeout) !== null && _d !== void 0 ? _d : (configurationCopy.fileRequestTimeout = FILE_REQUEST_TIMEOUT); + (_e = configurationCopy.restore) !== null && _e !== void 0 ? _e : (configurationCopy.restore = RESTORE); + (_f = configurationCopy.useInstanceId) !== null && _f !== void 0 ? _f : (configurationCopy.useInstanceId = USE_INSTANCE_ID); + (_g = configurationCopy.suppressLeaveEvents) !== null && _g !== void 0 ? _g : (configurationCopy.suppressLeaveEvents = SUPPRESS_LEAVE_EVENTS); + (_h = configurationCopy.requestMessageCountThreshold) !== null && _h !== void 0 ? _h : (configurationCopy.requestMessageCountThreshold = DEDUPE_CACHE_SIZE); + (_j = configurationCopy.autoNetworkDetection) !== null && _j !== void 0 ? _j : (configurationCopy.autoNetworkDetection = AUTO_NETWORK_DETECTION); + (_k = configurationCopy.enableEventEngine) !== null && _k !== void 0 ? _k : (configurationCopy.enableEventEngine = ENABLE_EVENT_ENGINE); + (_l = configurationCopy.maintainPresenceState) !== null && _l !== void 0 ? _l : (configurationCopy.maintainPresenceState = MAINTAIN_PRESENCE_STATE); + (_m = configurationCopy.useSmartHeartbeat) !== null && _m !== void 0 ? _m : (configurationCopy.useSmartHeartbeat = USE_SMART_HEARTBEAT); + (_o = configurationCopy.keepAlive) !== null && _o !== void 0 ? _o : (configurationCopy.keepAlive = KEEP_ALIVE); if (configurationCopy.userId && configurationCopy.uuid) throw new pubnub_error_1.PubNubError("PubNub client configuration error: use only 'userId'"); - (_q = configurationCopy.userId) !== null && _q !== void 0 ? _q : (configurationCopy.userId = configurationCopy.uuid); + (_p = configurationCopy.userId) !== null && _p !== void 0 ? _p : (configurationCopy.userId = configurationCopy.uuid); if (!configurationCopy.userId) throw new pubnub_error_1.PubNubError("PubNub client configuration error: 'userId' not set"); - else if (((_r = configurationCopy.userId) === null || _r === void 0 ? void 0 : _r.trim().length) === 0) + else if (((_q = configurationCopy.userId) === null || _q === void 0 ? void 0 : _q.trim().length) === 0) throw new pubnub_error_1.PubNubError("PubNub client configuration error: 'userId' is empty"); // Generate default origin subdomains. if (!configurationCopy.origin) diff --git a/lib/core/interfaces/crypto-module.js b/lib/core/interfaces/crypto-module.js index f3622e3d7..ee85d77b5 100644 --- a/lib/core/interfaces/crypto-module.js +++ b/lib/core/interfaces/crypto-module.js @@ -71,7 +71,7 @@ class AbstractCryptoModule { * @returns Serialized crypto module information. */ toString() { - return `${this.constructor.name} { default: ${this.defaultCryptor.toString()}, cryptors: [${this.cryptors.map((c) => c.toString()).join(', ')}]}`; + return `AbstractCryptoModule { default: ${this.defaultCryptor.toString()}, cryptors: [${this.cryptors.map((c) => c.toString()).join(', ')}]}`; } } exports.AbstractCryptoModule = AbstractCryptoModule; diff --git a/lib/core/pubnub-common.js b/lib/core/pubnub-common.js index faa5e5a4b..fa1529751 100644 --- a/lib/core/pubnub-common.js +++ b/lib/core/pubnub-common.js @@ -76,6 +76,7 @@ const Signal = __importStar(require("./endpoints/signal")); const subscribe_1 = require("./endpoints/subscribe"); const receiveMessages_1 = require("./endpoints/subscriptionUtils/receiveMessages"); const handshake_1 = require("./endpoints/subscriptionUtils/handshake"); +const subscription_1 = require("../entities/subscription"); // endregion // region Presence const get_state_1 = require("./endpoints/presence/get_state"); @@ -108,6 +109,9 @@ const revoke_token_1 = require("./endpoints/access_manager/revoke_token"); const grant_token_1 = require("./endpoints/access_manager/grant_token"); const grant_1 = require("./endpoints/access_manager/grant"); const audit_1 = require("./endpoints/access_manager/audit"); +// endregion +// region Entities +const subscription_capable_1 = require("../entities/interfaces/subscription-capable"); const channel_metadata_1 = require("../entities/channel-metadata"); const subscription_set_1 = require("../entities/subscription-set"); const channel_group_1 = require("../entities/channel-group"); @@ -124,7 +128,7 @@ const pubnub_objects_1 = __importDefault(require("./pubnub-objects")); // region Time const Time = __importStar(require("./endpoints/time")); const download_file_1 = require("./endpoints/file_upload/download_file"); -const subscription_1 = require("./types/api/subscription"); +const subscription_2 = require("./types/api/subscription"); const logger_1 = require("./interfaces/logger"); const utils_1 = require("./utils"); const categories_2 = __importDefault(require("./constants/categories")); @@ -264,19 +268,29 @@ class PubNubCore { }, delay: (amount) => new Promise((resolve) => setTimeout(resolve, amount)), join: (parameters) => { + var _a, _b; this.logger.trace('EventEngine', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Join with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('EventEngine', "Ignoring 'join' announcement request."); + return; + } this.join(parameters); }, leave: (parameters) => { + var _a, _b; this.logger.trace('EventEngine', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Leave with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('EventEngine', "Ignoring 'leave' announcement request."); + return; + } this.leave(parameters); }, leaveAll: (parameters) => { @@ -1027,7 +1041,7 @@ class PubNubCore { if (!subscriptions || subscriptions.length === 0) subscriptionInput = subscription.subscriptionInput(false); else { - subscriptionInput = new subscription_1.SubscriptionInput({}); + subscriptionInput = new subscription_2.SubscriptionInput({}); subscriptions.forEach((subscription) => subscriptionInput.add(subscription.subscriptionInput(false))); } const parameters = {}; @@ -1068,7 +1082,7 @@ class PubNubCore { inUseSubscriptions.push(subscription); } else { - subscriptionInput = new subscription_1.SubscriptionInput({}); + subscriptionInput = new subscription_2.SubscriptionInput({}); subscriptions.forEach((subscription) => { const input = subscription.subscriptionInput(true); if (input.isEmpty) @@ -1094,6 +1108,44 @@ class PubNubCore { } if (subscriptionInput.isEmpty) return; + else { + const _channelGroupsInUse = []; + const _channelsInUse = []; + Object.values(this.eventHandleCapable).forEach((_subscription) => { + const _subscriptionInput = _subscription.subscriptionInput(false); + const _subscriptionChannelGroups = _subscriptionInput.channelGroups; + const _subscriptionChannels = _subscriptionInput.channels; + _channelGroupsInUse.push(...subscriptionInput.channelGroups.filter((channel) => _subscriptionChannelGroups.includes(channel))); + _channelsInUse.push(...subscriptionInput.channels.filter((channel) => _subscriptionChannels.includes(channel))); + }); + if (_channelsInUse.length > 0 || _channelGroupsInUse.length > 0) { + this.logger.trace('PubNub', () => { + const _entitiesInUse = []; + const addEntityIfInUse = (entity) => { + const namesOrIds = entity.subscriptionNames(true); + const checkList = entity.subscriptionType === subscription_capable_1.SubscriptionType.Channel ? _channelsInUse : _channelGroupsInUse; + if (namesOrIds.some((id) => checkList.includes(id))) + _entitiesInUse.push(entity); + }; + Object.values(this.eventHandleCapable).forEach((_subscription) => { + if (_subscription instanceof subscription_set_1.SubscriptionSet) { + _subscription.subscriptions.forEach((_subscriptionInSet) => { + addEntityIfInUse(_subscriptionInSet.state.entity); + }); + } + else if (_subscription instanceof subscription_1.Subscription) + addEntityIfInUse(_subscription.state.entity); + }); + let details = 'Some entities still in use:'; + if (_channelsInUse.length + _channelGroupsInUse.length === subscriptionInput.length) + details = "Can't unregister event handle capable because entities still in use:"; + return { messageType: 'object', message: { entities: _entitiesInUse }, details }; + }); + subscriptionInput.remove(new subscription_2.SubscriptionInput({ channels: _channelsInUse, channelGroups: _channelGroupsInUse })); + if (subscriptionInput.isEmpty) + return; + } + } const parameters = {}; parameters.channels = subscriptionInput.channels; parameters.channelGroups = subscriptionInput.channelGroups; @@ -1811,6 +1863,7 @@ class PubNubCore { */ heartbeat(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { + var _a; if (process.env.PRESENCE_MODULE !== 'disabled') { this.logger.trace('PubNub', () => ({ messageType: 'object', @@ -1846,13 +1899,20 @@ class PubNubCore { return; this.logger.trace('PubNub', 'Heartbeat success.'); }; + const abortUnsubscribe = (_a = parameters.abortSignal) === null || _a === void 0 ? void 0 : _a.subscribe((err) => { + request.abort('Cancel long-poll subscribe request'); + }); if (callback) return this.sendRequest(request, (status, response) => { logResponse(response); + if (abortUnsubscribe) + abortUnsubscribe(); callback(status, response); }); return this.sendRequest(request).then((response) => { logResponse(response); + if (abortUnsubscribe) + abortUnsubscribe(); return response; }); } @@ -1870,12 +1930,17 @@ class PubNubCore { * @param parameters - List of channels and groups where `join` event should be sent. */ join(parameters) { + var _a, _b; if (process.env.PRESENCE_MODULE !== 'disabled') { this.logger.trace('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Join with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('PubNub', "Ignoring 'join' announcement request."); + return; + } if (this.presenceEventEngine) this.presenceEventEngine.join(parameters); else { @@ -1920,15 +1985,19 @@ class PubNubCore { * @param parameters - List of channels and groups where `leave` event should be sent. */ leave(parameters) { - var _a; + var _a, _b, _c; if (process.env.PRESENCE_MODULE !== 'disabled') { this.logger.trace('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Leave with parameters:', })); + if (parameters && ((_a = parameters.channels) !== null && _a !== void 0 ? _a : []).length === 0 && ((_b = parameters.groups) !== null && _b !== void 0 ? _b : []).length === 0) { + this.logger.trace('PubNub', "Ignoring 'leave' announcement request."); + return; + } if (this.presenceEventEngine) - (_a = this.presenceEventEngine) === null || _a === void 0 ? void 0 : _a.leave(parameters); + (_c = this.presenceEventEngine) === null || _c === void 0 ? void 0 : _c.leave(parameters); else this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => { }); } diff --git a/lib/core/types/api/subscription.js b/lib/core/types/api/subscription.js index abd9c86c9..6ff071020 100644 --- a/lib/core/types/api/subscription.js +++ b/lib/core/types/api/subscription.js @@ -26,6 +26,16 @@ class SubscriptionInput { this._channels = new Set((channels !== null && channels !== void 0 ? channels : []).filter((value) => value.length > 0)); this.isEmpty = this._channels.size === 0 && this._channelGroups.size === 0; } + /** + * Retrieve total length of subscription input. + * + * @returns Number of channels and groups in subscription input. + */ + get length() { + if (this.isEmpty) + return 0; + return this._channels.size + this._channelGroups.size; + } /** * Retrieve a list of user-provided channel names. * diff --git a/lib/crypto/modules/NodeCryptoModule/aesCbcCryptor.js b/lib/crypto/modules/NodeCryptoModule/aesCbcCryptor.js index 50f9519ea..2ad7886a4 100644 --- a/lib/crypto/modules/NodeCryptoModule/aesCbcCryptor.js +++ b/lib/crypto/modules/NodeCryptoModule/aesCbcCryptor.js @@ -146,7 +146,7 @@ class AesCbcCryptor { * @returns Serialized cryptor information. */ toString() { - return `${this.constructor.name} { cipherKey: ${this.cipherKey} }`; + return `AesCbcCryptor { cipherKey: ${this.cipherKey} }`; } } /** diff --git a/lib/crypto/modules/NodeCryptoModule/legacyCryptor.js b/lib/crypto/modules/NodeCryptoModule/legacyCryptor.js index 65537d64f..43c286fae 100644 --- a/lib/crypto/modules/NodeCryptoModule/legacyCryptor.js +++ b/lib/crypto/modules/NodeCryptoModule/legacyCryptor.js @@ -96,7 +96,7 @@ class LegacyCryptor { acc.push(`${key}: ${typeof value === 'function' ? '' : value}`); return acc; }, []); - return `${this.constructor.name} { ${configurationEntries.join(', ')} }`; + return `LegacyCryptor { ${configurationEntries.join(', ')} }`; } } exports.default = LegacyCryptor; diff --git a/lib/entities/channel-group.js b/lib/entities/channel-group.js index d42c4f1ac..784bb5212 100644 --- a/lib/entities/channel-group.js +++ b/lib/entities/channel-group.js @@ -7,6 +7,22 @@ const entity_1 = require("./entity"); * First-class objects which provides access to the channel group-specific APIs. */ class ChannelGroup extends entity_1.Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'ChannelGroups'; + } /** * Get a unique channel group name. * diff --git a/lib/entities/channel-metadata.js b/lib/entities/channel-metadata.js index cd298a094..2b5eaa203 100644 --- a/lib/entities/channel-metadata.js +++ b/lib/entities/channel-metadata.js @@ -6,6 +6,22 @@ const entity_1 = require("./entity"); * First-class objects which provides access to the channel app context object-specific APIs. */ class ChannelMetadata extends entity_1.Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'ChannelMetadata'; + } /** * Get unique channel metadata object identifier. * diff --git a/lib/entities/channel.js b/lib/entities/channel.js index f71ab290d..61452410e 100644 --- a/lib/entities/channel.js +++ b/lib/entities/channel.js @@ -6,6 +6,22 @@ const entity_1 = require("./entity"); * First-class objects which provides access to the channel-specific APIs. */ class Channel extends entity_1.Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'Channel'; + } /** * Get a unique channel name. * diff --git a/lib/entities/entity.js b/lib/entities/entity.js index 1d5298dd5..7060dc96e 100644 --- a/lib/entities/entity.js +++ b/lib/entities/entity.js @@ -25,6 +25,22 @@ class Entity { this.client = client; this._nameOrId = nameOrId; } + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'Channel'; + } /** * Type of subscription entity. * @@ -133,7 +149,7 @@ class Entity { * @returns Serialized entity object. */ toString() { - return `${this.constructor.name} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`; + return `${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`; } } exports.Entity = Entity; diff --git a/lib/entities/subscription-base.js b/lib/entities/subscription-base.js index 89425c583..0a6c2a2e8 100644 --- a/lib/entities/subscription-base.js +++ b/lib/entities/subscription-base.js @@ -150,6 +150,20 @@ class SubscriptionBase { this.eventDispatcher = new event_dispatcher_1.EventDispatcher(); this._state = state; } + /** + * Retrieve subscription type. + * + * There is two types: + * - Subscription + * - SubscriptionSet + * + * @returns One of subscription types. + * + * @internal + */ + get subscriptionType() { + return 'Subscription'; + } /** * Subscription state. * @@ -274,7 +288,7 @@ class SubscriptionBase { this.state.cursor = cursor; // Check whether this is an old `old` event and it should be ignored or not. if (this.state.referenceTimetoken && event.data.timetoken < this.state.referenceTimetoken) { - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Event timetoken (${event.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`, })); @@ -282,12 +296,12 @@ class SubscriptionBase { } // Don't pass events which are filtered out by the user-provided function. if (((_a = this.state.options) === null || _a === void 0 ? void 0 : _a.filter) && !this.state.options.filter(event)) { - this.state.client.logger.trace(this.constructor.name, `Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`); + this.state.client.logger.trace(this.subscriptionType, `Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`); return; } const clones = Object.values(this.state.clones); if (clones.length > 0) { - this.state.client.logger.trace(this.constructor.name, `Notify ${this.id} subscription object clones (count: ${clones.length}) about received event.`); + this.state.client.logger.trace(this.subscriptionType, `Notify ${this.id} subscription object clones (count: ${clones.length}) about received event.`); } clones.forEach((subscription) => subscription.eventDispatcher.handleEvent(event)); } @@ -308,11 +322,11 @@ class SubscriptionBase { dispose() { const keys = Object.keys(this.state.clones); if (keys.length > 1) { - this.state.client.logger.debug(this.constructor.name, `Remove subscription object clone on dispose: ${this.id}`); + this.state.client.logger.debug(this.subscriptionType, `Remove subscription object clone on dispose: ${this.id}`); delete this.state.clones[this.id]; } else if (keys.length === 1 && this.state.clones[this.id]) { - this.state.client.logger.debug(this.constructor.name, `Unsubscribe subscription object on dispose: ${this.id}`); + this.state.client.logger.debug(this.subscriptionType, `Unsubscribe subscription object on dispose: ${this.id}`); this.unsubscribe(); } } @@ -332,7 +346,7 @@ class SubscriptionBase { if (forDestroy) { delete this.state.clones[this.id]; if (Object.keys(this.state.clones).length === 0) { - this.state.client.logger.trace(this.constructor.name, 'Last clone removed. Reset shared subscription state.'); + this.state.client.logger.trace(this.subscriptionType, 'Last clone removed. Reset shared subscription state.'); this.state.subscriptionInput.removeAll(); this.state.parents = []; } @@ -346,10 +360,10 @@ class SubscriptionBase { */ subscribe(parameters) { if (this.state.isSubscribed) { - this.state.client.logger.trace(this.constructor.name, 'Already subscribed. Ignoring subscribe request.'); + this.state.client.logger.trace(this.subscriptionType, 'Already subscribed. Ignoring subscribe request.'); return; } - this.state.client.logger.debug(this.constructor.name, () => { + this.state.client.logger.debug(this.subscriptionType, () => { if (!parameters) return { messageType: 'text', message: 'Subscribe' }; return { messageType: 'object', message: parameters, details: 'Subscribe with parameters:' }; @@ -372,7 +386,7 @@ class SubscriptionBase { if (!this.state._isSubscribed || this.state.isSubscribed) { // Warn if a user tries to unsubscribe using specific subscription which subscribed as part of a subscription set. if (!this.state._isSubscribed && this.state.parents.length > 0 && this.state.isSubscribed) { - this.state.client.logger.warn(this.constructor.name, () => ({ + this.state.client.logger.warn(this.subscriptionType, () => ({ messageType: 'object', details: 'Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:', message: this.state.parents.filter((subscriptionSet) => subscriptionSet.isSubscribed), @@ -380,12 +394,12 @@ class SubscriptionBase { return; } else if (!this.state._isSubscribed) { - this.state.client.logger.trace(this.constructor.name, 'Not subscribed. Ignoring unsubscribe request.'); + this.state.client.logger.trace(this.subscriptionType, 'Not subscribed. Ignoring unsubscribe request.'); return; } } - this.state.client.logger.debug(this.constructor.name, 'Unsubscribe'); - this.state.isSubscribed = true; + this.state.client.logger.debug(this.subscriptionType, 'Unsubscribe'); + this.state.isSubscribed = false; delete this.state.cursor; this.updateSubscription({ subscribing: false }); } diff --git a/lib/entities/subscription-set.js b/lib/entities/subscription-set.js index 975fc84e5..b55f8c66e 100644 --- a/lib/entities/subscription-set.js +++ b/lib/entities/subscription-set.js @@ -58,6 +58,20 @@ class SubscriptionSetState extends subscription_base_1.SubscriptionBaseState { super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); this.subscriptions = parameters.subscriptions; } + /** + * Retrieve subscription type. + * + * There is two types: + * - Subscription + * - SubscriptionSet + * + * @returns One of subscription types. + * + * @internal + */ + get subscriptionType() { + return 'SubscriptionSet'; + } /** * Add a single subscription object to the set. * @@ -181,12 +195,12 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase { return; // Check whether `event` can be processed or not. if (!this.state._isSubscribed) { - this.state.client.logger.trace(this.constructor.name, `Subscription set ${this.id} is not subscribed. Ignoring event.`); + this.state.client.logger.trace(this.subscriptionType, `Subscription set ${this.id} is not subscribed. Ignoring event.`); return; } super.handleEvent(cursor, event); if (this.state.subscriptions.length > 0) { - this.state.client.logger.trace(this.constructor.name, `Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`); + this.state.client.logger.trace(this.subscriptionType, `Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`); } this.state.subscriptions.forEach((subscription) => subscription.handleEvent(cursor, event)); } @@ -284,7 +298,7 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase { addSubscriptions(subscriptions) { const inactiveSubscriptions = []; const activeSubscriptions = []; - this.state.client.logger.debug(this.constructor.name, () => { + this.state.client.logger.debug(this.subscriptionType, () => { const ignoredSubscriptions = []; const subscriptionsToAdd = []; subscriptions.forEach((subscription) => { @@ -335,7 +349,7 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase { */ removeSubscriptions(subscriptions) { const activeSubscriptions = []; - this.state.client.logger.debug(this.constructor.name, () => { + this.state.client.logger.debug(this.subscriptionType, () => { const ignoredSubscriptions = []; const subscriptionsToRemove = []; subscriptions.forEach((subscription) => { @@ -397,7 +411,7 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase { var _a; const subscriptions = ((_a = parameters.subscriptions) !== null && _a !== void 0 ? _a : this.state.subscriptions); subscriptions.forEach(({ state }) => state.entity.increaseSubscriptionCount(this.state.id)); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Register subscription for real-time events: ${this}`, })); @@ -414,7 +428,7 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase { unregister(subscriptions) { const activeSubscriptions = (subscriptions !== null && subscriptions !== void 0 ? subscriptions : this.state.subscriptions); activeSubscriptions.forEach(({ state }) => state.entity.decreaseSubscriptionCount(this.state.id)); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Unregister subscription from real-time events: ${this}`, })); @@ -427,7 +441,7 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase { */ toString() { const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${state.isSubscribed}, subscriptions: [${state.subscriptions + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${state.isSubscribed}, subscriptions: [${state.subscriptions .map((sub) => sub.toString()) .join(', ')}] }`; } diff --git a/lib/entities/subscription.js b/lib/entities/subscription.js index eaf71b3ba..d57260421 100644 --- a/lib/entities/subscription.js +++ b/lib/entities/subscription.js @@ -119,7 +119,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { // Creating from whole payload (not only for published messages). const fingerprint = (0, utils_1.messageFingerprint)(event.data); if (this.handledUpdates.includes(fingerprint)) { - this.state.client.logger.trace(this.constructor.name, `Message (${fingerprint}) already handled. Ignoring.`); + this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled. Ignoring.`); return; } // Update a list of tracked messages and shrink it if too big. @@ -174,7 +174,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { */ dispose() { if (this.parentSetsCount > 0) { - this.state.client.logger.debug(this.constructor.name, () => ({ + this.state.client.logger.debug(this.subscriptionType, () => ({ messageType: 'text', message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, })); @@ -210,7 +210,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { addParentSet(parent) { if (!this.parents.includes(parent)) { this.parents.push(parent); - this.state.client.logger.trace(this.constructor.name, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); + this.state.client.logger.trace(this.subscriptionType, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); } } /** @@ -224,7 +224,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { const parentIndex = this.parents.indexOf(parent); if (parentIndex !== -1) { this.parents.splice(parentIndex, 1); - this.state.client.logger.trace(this.constructor.name, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); + this.state.client.logger.trace(this.subscriptionType, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); } if (this.parentSetsCount === 0) this.handledUpdates.splice(0, this.handledUpdates.length); @@ -237,7 +237,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. */ addSubscription(subscription) { - this.state.client.logger.debug(this.constructor.name, () => ({ + this.state.client.logger.debug(this.subscriptionType, () => ({ messageType: 'text', message: `Create set with subscription: ${subscription}`, })); @@ -249,7 +249,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { // Check whether a source subscription is already subscribed or not. if (!this.state.isSubscribed && !subscription.state.isSubscribed) return subscriptionSet; - this.state.client.logger.trace(this.constructor.name, 'Subscribe resulting set because the receiver is already subscribed.'); + this.state.client.logger.trace(this.subscriptionType, 'Subscribe resulting set because the receiver is already subscribed.'); // Subscribing resulting subscription set because source subscription was subscribed. subscriptionSet.subscribe(); return subscriptionSet; @@ -268,7 +268,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { */ register(parameters) { this.state.entity.increaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Register subscription for real-time events: ${this}`, })); @@ -287,7 +287,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { */ unregister(_subscriptions) { this.state.entity.decreaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Unregister subscription from real-time events: ${this}`, })); @@ -301,7 +301,7 @@ class Subscription extends subscription_base_1.SubscriptionBase { */ toString() { const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity .subscriptionNames(false) .pop()}, clonesCount: ${Object.keys(state.clones).length}, isSubscribed: ${state.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${state.cursor ? state.cursor.timetoken : 'not set'}, referenceTimetoken: ${state.referenceTimetoken ? state.referenceTimetoken : 'not set'} }`; } diff --git a/lib/entities/user-metadata.js b/lib/entities/user-metadata.js index 634cffbb1..d5b9cc9c6 100644 --- a/lib/entities/user-metadata.js +++ b/lib/entities/user-metadata.js @@ -6,6 +6,22 @@ const entity_1 = require("./entity"); * First-class objects which provides access to the user app context object-specific APIs. */ class UserMetadata extends entity_1.Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'UserMetadata'; + } /** * Get unique user metadata object identifier. * diff --git a/lib/event-engine/core/dispatcher.js b/lib/event-engine/core/dispatcher.js index 002f2054d..7959fb4ac 100644 --- a/lib/event-engine/core/dispatcher.js +++ b/lib/event-engine/core/dispatcher.js @@ -24,7 +24,7 @@ class Dispatcher { this.handlers.set(type, handlerCreator); } dispatch(invocation) { - this.logger.trace(this.constructor.name, `Process invocation: ${invocation.type}`); + this.logger.trace('Dispatcher', `Process invocation: ${invocation.type}`); if (invocation.type === 'CANCEL') { if (this.instances.has(invocation.payload)) { const instance = this.instances.get(invocation.payload); @@ -35,11 +35,11 @@ class Dispatcher { } const handlerCreator = this.handlers.get(invocation.type); if (!handlerCreator) { - this.logger.error(this.constructor.name, `Unhandled invocation '${invocation.type}'`); + this.logger.error('Dispatcher', `Unhandled invocation '${invocation.type}'`); throw new Error(`Unhandled invocation '${invocation.type}'`); } const instance = handlerCreator(invocation.payload, this.dependencies); - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Dispatcher', () => ({ messageType: 'object', details: 'Call invocation handler with parameters:', message: invocation.payload, diff --git a/lib/event-engine/core/engine.js b/lib/event-engine/core/engine.js index bda704b40..8b9eff705 100644 --- a/lib/event-engine/core/engine.js +++ b/lib/event-engine/core/engine.js @@ -41,11 +41,11 @@ class Engine extends subject_1.Subject { } transition(event) { if (!this._currentState) { - this.logger.error(this.constructor.name, 'Finite state machine is not started'); + this.logger.error('Engine', 'Finite state machine is not started'); throw new Error('Start the engine first'); } if (this._inTransition) { - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', message: event, details: 'Event engine in transition. Enqueue received event:', @@ -55,7 +55,7 @@ class Engine extends subject_1.Subject { } else this._inTransition = true; - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', message: event, details: 'Event engine received event:', @@ -67,14 +67,14 @@ class Engine extends subject_1.Subject { const transition = this._currentState.transition(this._currentContext, event); if (transition) { const [newState, newContext, effects] = transition; - this.logger.trace(this.constructor.name, `Exiting state: ${this._currentState.label}`); + this.logger.trace('Engine', `Exiting state: ${this._currentState.label}`); for (const effect of this._currentState.exitEffects) { this.notify({ type: 'invocationDispatched', invocation: effect(this._currentContext), }); } - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', details: `Entering '${newState.label}' state with context:`, message: newContext, @@ -103,22 +103,22 @@ class Engine extends subject_1.Subject { invocation: effect(this._currentContext), }); } - this._inTransition = false; - // Check whether a pending task should be dequeued. - if (this._pendingEvents.length > 0) { - const nextEvent = this._pendingEvents.shift(); - if (nextEvent) { - this.logger.trace(this.constructor.name, () => ({ - messageType: 'object', - message: nextEvent, - details: 'De-queueing pending event:', - })); - this.transition(nextEvent); - } - } } else - this.logger.warn(this.constructor.name, `No transition from '${this._currentState.label}' found for event: ${event.type}`); + this.logger.warn('Engine', `No transition from '${this._currentState.label}' found for event: ${event.type}`); + this._inTransition = false; + // Check whether a pending task should be dequeued. + if (this._pendingEvents.length > 0) { + const nextEvent = this._pendingEvents.shift(); + if (nextEvent) { + this.logger.trace('Engine', () => ({ + messageType: 'object', + message: nextEvent, + details: 'De-queueing pending event:', + })); + this.transition(nextEvent); + } + } } } exports.Engine = Engine; diff --git a/lib/event-engine/core/handler.js b/lib/event-engine/core/handler.js index ef513bd1e..5a4baee8d 100644 --- a/lib/event-engine/core/handler.js +++ b/lib/event-engine/core/handler.js @@ -36,7 +36,6 @@ class AsyncHandler extends Handler { } start() { this.asyncFunction(this.payload, this.abortSignal, this.dependencies).catch((error) => { - // console.log('Unhandled error:', error); // swallow the error }); } diff --git a/lib/event-engine/index.js b/lib/event-engine/index.js index ee41182c4..a44f3be4b 100644 --- a/lib/event-engine/index.js +++ b/lib/event-engine/index.js @@ -61,7 +61,7 @@ class EventEngine { this.dependencies = dependencies; this.engine = new core_1.Engine(dependencies.config.logger()); this.dispatcher = new dispatcher_1.EventEngineDispatcher(this.engine, dependencies); - dependencies.config.logger().debug(this.constructor.name, 'Create subscribe event engine.'); + dependencies.config.logger().debug('EventEngine', 'Create subscribe event engine.'); this._unsubscribeEngine = this.engine.subscribe((change) => { if (change.type === 'invocationDispatched') { this.dispatcher.dispatch(change.invocation); diff --git a/lib/event-engine/presence/dispatcher.js b/lib/event-engine/presence/dispatcher.js index c14ebbe88..f70ca3a0a 100644 --- a/lib/event-engine/presence/dispatcher.js +++ b/lib/event-engine/presence/dispatcher.js @@ -67,9 +67,10 @@ const events = __importStar(require("./events")); class PresenceEventEngineDispatcher extends core_1.Dispatcher { constructor(engine, dependencies) { super(dependencies, dependencies.config.logger()); - this.on(effects.heartbeat.type, (0, core_1.asyncHandler)((payload_1, _1, _a) => __awaiter(this, [payload_1, _1, _a], void 0, function* (payload, _, { heartbeat, presenceState, config }) { + this.on(effects.heartbeat.type, (0, core_1.asyncHandler)((payload_1, abortSignal_1, _a) => __awaiter(this, [payload_1, abortSignal_1, _a], void 0, function* (payload, abortSignal, { heartbeat, presenceState, config }) { + abortSignal.throwIfAborted(); try { - const result = yield heartbeat(Object.assign(Object.assign({ channels: payload.channels, channelGroups: payload.groups }, (config.maintainPresenceState && { state: presenceState })), { heartbeat: config.presenceTimeout })); + const result = yield heartbeat(Object.assign(Object.assign({ abortSignal: abortSignal, channels: payload.channels, channelGroups: payload.groups }, (config.maintainPresenceState && { state: presenceState })), { heartbeat: config.presenceTimeout })); engine.transition(events.heartbeatSuccess(200)); } catch (e) { diff --git a/lib/event-engine/presence/presence.js b/lib/event-engine/presence/presence.js index 2d8381043..311b6b704 100644 --- a/lib/event-engine/presence/presence.js +++ b/lib/event-engine/presence/presence.js @@ -58,7 +58,7 @@ class PresenceEventEngine { this.groups = []; this.engine = new core_1.Engine(dependencies.config.logger()); this.dispatcher = new dispatcher_1.PresenceEventEngineDispatcher(this.engine, dependencies); - dependencies.config.logger().debug(this.constructor.name, 'Create presence event engine.'); + dependencies.config.logger().debug('PresenceEventEngine', 'Create presence event engine.'); this._unsubscribeEngine = this.engine.subscribe((change) => { if (change.type === 'invocationDispatched') { this.dispatcher.dispatch(change.invocation); @@ -67,8 +67,11 @@ class PresenceEventEngine { this.engine.start(heartbeat_inactive_1.HeartbeatInactiveState, undefined); } join({ channels, groups }) { - this.channels = [...this.channels, ...(channels !== null && channels !== void 0 ? channels : [])]; - this.groups = [...this.groups, ...(groups !== null && groups !== void 0 ? groups : [])]; + this.channels = [...this.channels, ...(channels !== null && channels !== void 0 ? channels : []).filter((channel) => !this.channels.includes(channel))]; + this.groups = [...this.groups, ...(groups !== null && groups !== void 0 ? groups : []).filter((group) => !this.groups.includes(group))]; + // Don't make any transitions if there is no channels and groups. + if (this.channels.length === 0 && this.groups.length === 0) + return; this.engine.transition(events.joined(this.channels.slice(0), this.groups.slice(0))); } leave({ channels, groups }) { diff --git a/lib/event-engine/presence/states/heartbeat_cooldown.js b/lib/event-engine/presence/states/heartbeat_cooldown.js index 2b7b1e236..70fd2a65b 100644 --- a/lib/event-engine/presence/states/heartbeat_cooldown.js +++ b/lib/event-engine/presence/states/heartbeat_cooldown.js @@ -27,8 +27,8 @@ exports.HeartbeatCooldownState.on(events_1.timesUp.type, (context, _) => heartbe groups: context.groups, })); exports.HeartbeatCooldownState.on(events_1.joined.type, (context, event) => heartbeating_1.HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); exports.HeartbeatCooldownState.on(events_1.left.type, (context, event) => heartbeating_1.HeartbeatingState.with({ channels: context.channels.filter((channel) => !event.payload.channels.includes(channel)), diff --git a/lib/event-engine/presence/states/heartbeat_failed.js b/lib/event-engine/presence/states/heartbeat_failed.js index da519c0e6..7716b528e 100644 --- a/lib/event-engine/presence/states/heartbeat_failed.js +++ b/lib/event-engine/presence/states/heartbeat_failed.js @@ -22,8 +22,8 @@ const heartbeat_inactive_1 = require("./heartbeat_inactive"); */ exports.HeartbeatFailedState = new state_1.State('HEARTBEAT_FAILED'); exports.HeartbeatFailedState.on(events_1.joined.type, (context, event) => heartbeating_1.HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); exports.HeartbeatFailedState.on(events_1.left.type, (context, event) => heartbeating_1.HeartbeatingState.with({ channels: context.channels.filter((channel) => !event.payload.channels.includes(channel)), diff --git a/lib/event-engine/presence/states/heartbeat_stopped.js b/lib/event-engine/presence/states/heartbeat_stopped.js index 96f501270..69922bc3a 100644 --- a/lib/event-engine/presence/states/heartbeat_stopped.js +++ b/lib/event-engine/presence/states/heartbeat_stopped.js @@ -20,8 +20,8 @@ const heartbeating_1 = require("./heartbeating"); */ exports.HeartbeatStoppedState = new state_1.State('HEARTBEAT_STOPPED'); exports.HeartbeatStoppedState.on(events_1.joined.type, (context, event) => exports.HeartbeatStoppedState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); exports.HeartbeatStoppedState.on(events_1.left.type, (context, event) => exports.HeartbeatStoppedState.with({ channels: context.channels.filter((channel) => !event.payload.channels.includes(channel)), diff --git a/lib/event-engine/presence/states/heartbeating.js b/lib/event-engine/presence/states/heartbeating.js index 41e24a523..290bd38a8 100644 --- a/lib/event-engine/presence/states/heartbeating.js +++ b/lib/event-engine/presence/states/heartbeating.js @@ -27,8 +27,8 @@ exports.HeartbeatingState.on(events_1.heartbeatSuccess.type, (context, event) => (0, effects_1.emitStatus)(Object.assign({}, event.payload)), ])); exports.HeartbeatingState.on(events_1.joined.type, (context, event) => exports.HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], })); exports.HeartbeatingState.on(events_1.left.type, (context, event) => { return exports.HeartbeatingState.with({ diff --git a/lib/loggers/console-logger.js b/lib/loggers/console-logger.js index 221366415..2b947a87f 100644 --- a/lib/loggers/console-logger.js +++ b/lib/loggers/console-logger.js @@ -180,9 +180,16 @@ class ConsoleLogger { else if (typeof raw === 'object') { const isArray = Array.isArray(raw); const isEmptyArray = isArray && raw.length === 0; + const isEmptyObject = !isArray && !(raw instanceof String) && Object.keys(raw).length === 0; const hasToString = !isArray && typeof raw.toString === 'function' && raw.toString().indexOf('[object') !== 0; - const entry = maxIndentReached ? '...' : isEmptyArray ? '[]' : stringify(raw, level + 1, hasToString); - lines.push(`${indent}${paddedKey}:${maxIndentReached || hasToString || isEmptyArray ? ' ' : '\n'}${entry}`); + const entry = maxIndentReached + ? '...' + : isEmptyArray + ? '[]' + : isEmptyObject + ? '{}' + : stringify(raw, level + 1, hasToString); + lines.push(`${indent}${paddedKey}:${maxIndentReached || hasToString || isEmptyArray || isEmptyObject ? ' ' : '\n'}${entry}`); } else lines.push(`${indent}${paddedKey}: ${raw}`); @@ -240,7 +247,7 @@ class ConsoleLogger { if (typeof body === 'string') { stringifiedBody = ` ${body}`; } - else if (body instanceof ArrayBuffer) { + else if (body instanceof ArrayBuffer || Object.prototype.toString.call(body) === '[object ArrayBuffer]') { if (contentType && (contentType.indexOf('javascript') !== -1 || contentType.indexOf('json') !== -1)) stringifiedBody = ` ${ConsoleLogger.decoder.decode(body)}`; else diff --git a/lib/transport/middleware.js b/lib/transport/middleware.js index 2822d5843..2e3ac80f1 100644 --- a/lib/transport/middleware.js +++ b/lib/transport/middleware.js @@ -45,7 +45,7 @@ class RequestSignature { if (payload) signatureInput += payload; } - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('RequestSignature', () => ({ messageType: 'text', message: `Request signature input:\n${signatureInput}`, })); @@ -133,7 +133,7 @@ class PubNubMiddleware { delay = retryPolicy.getDelay(attempt, res); if (delay > 0) { attempt++; - this.logger.warn(this.constructor.name, `HTTP request retry #${attempt} in ${delay}ms.`); + this.logger.warn('PubNubMiddleware', `HTTP request retry #${attempt} in ${delay}ms.`); retryTimeout = setTimeout(() => trySendRequest(), delay); } else { diff --git a/lib/transport/node-transport.js b/lib/transport/node-transport.js index aeeacb2a4..9704f86e7 100644 --- a/lib/transport/node-transport.js +++ b/lib/transport/node-transport.js @@ -81,7 +81,7 @@ class NodeTransport { this.logger = logger; this.keepAlive = keepAlive; this.keepAliveSettings = keepAliveSettings; - logger.debug(this.constructor.name, () => ({ + logger.debug('NodeTransport', () => ({ messageType: 'object', message: { keepAlive, keepAliveSettings }, details: 'Create with configuration:', @@ -96,9 +96,9 @@ class NodeTransport { */ setProxy(configuration) { if (configuration) - this.logger.debug(this.constructor.name, 'Proxy configuration has been set.'); + this.logger.debug('NodeTransport', 'Proxy configuration has been set.'); else - this.logger.debug(this.constructor.name, 'Proxy configuration has been removed.'); + this.logger.debug('NodeTransport', 'Proxy configuration has been removed.'); this.proxyConfiguration = configuration; } makeSendable(req) { @@ -112,14 +112,14 @@ class NodeTransport { abort: (reason) => { if (!abortController || abortController.signal.aborted) return; - this.logger.trace(this.constructor.name, `On-demand request aborting: ${reason}`); + this.logger.trace('NodeTransport', `On-demand request aborting: ${reason}`); abortController === null || abortController === void 0 ? void 0 : abortController.abort(reason); }, }; } return [ this.requestFromTransportRequest(req).then((request) => { - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('NodeTransport', () => ({ messageType: 'network-request', message: req })); return (0, node_fetch_1.default)(request, { signal: abortController === null || abortController === void 0 ? void 0 : abortController.signal, timeout: req.timeout * 1000, @@ -137,7 +137,7 @@ class NodeTransport { headers, body: responseBody, }; - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('NodeTransport', () => ({ messageType: 'network-response', message: transportResponse, })); @@ -149,7 +149,7 @@ class NodeTransport { const errorMessage = (typeof error === 'string' ? error : error.message).toLowerCase(); let fetchError = typeof error === 'string' ? new Error(error) : error; if (errorMessage.includes('timeout')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('NodeTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', @@ -157,7 +157,7 @@ class NodeTransport { })); } else if (errorMessage.includes('cancel') || errorMessage.includes('abort')) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('NodeTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -166,7 +166,7 @@ class NodeTransport { fetchError = new node_fetch_1.AbortError('Aborted'); } else if (errorMessage.includes('network')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('NodeTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', @@ -174,7 +174,7 @@ class NodeTransport { })); } else { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('NodeTransport', () => ({ messageType: 'network-request', message: req, details: pubnub_api_error_1.PubNubAPIError.create(fetchError).message, @@ -227,7 +227,7 @@ class NodeTransport { // Compressing body (if required). body = req.compressible ? zlib.deflateSync(req.body) : req.body; if (req.compressible) { - this.logger.trace(this.constructor.name, () => { + this.logger.trace('NodeTransport', () => { const compressedSize = body.byteLength; const ratio = (compressedSize / initialBodySize).toFixed(2); return { diff --git a/lib/transport/react-native-transport.js b/lib/transport/react-native-transport.js index 0dc9428db..36129d156 100644 --- a/lib/transport/react-native-transport.js +++ b/lib/transport/react-native-transport.js @@ -35,7 +35,7 @@ class ReactNativeTransport { constructor(logger, keepAlive = false) { this.logger = logger; this.keepAlive = keepAlive; - logger.debug(this.constructor.name, `Create with configuration:\n - keep-alive: ${keepAlive}`); + logger.debug('ReactNativeTransport', `Create with configuration:\n - keep-alive: ${keepAlive}`); } makeSendable(req) { const abortController = new AbortController(); @@ -44,14 +44,14 @@ class ReactNativeTransport { abortController, abort: (reason) => { if (!abortController.signal.aborted) { - this.logger.trace(this.constructor.name, `On-demand request aborting: ${reason}`); + this.logger.trace('ReactNativeTransport', `On-demand request aborting: ${reason}`); abortController.abort(reason); } }, }; return [ this.requestFromTransportRequest(req).then((request) => { - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('ReactNativeTransport', () => ({ messageType: 'network-request', message: req })); /** * Setup request timeout promise. * @@ -91,7 +91,7 @@ class ReactNativeTransport { headers, body: responseBody, }; - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('ReactNativeTransport', () => ({ messageType: 'network-response', message: transportResponse, })); @@ -103,7 +103,7 @@ class ReactNativeTransport { const errorMessage = (typeof error === 'string' ? error : error.message).toLowerCase(); let fetchError = typeof error === 'string' ? new Error(error) : error; if (errorMessage.includes('timeout')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', @@ -111,7 +111,7 @@ class ReactNativeTransport { })); } else if (errorMessage.includes('cancel') || errorMessage.includes('abort')) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -121,7 +121,7 @@ class ReactNativeTransport { fetchError.name = 'AbortError'; } else if (errorMessage.includes('network')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', @@ -129,7 +129,7 @@ class ReactNativeTransport { })); } else { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: pubnub_api_error_1.PubNubAPIError.create(fetchError).message, @@ -186,7 +186,7 @@ class ReactNativeTransport { const bodyArrayBuffer = typeof req.body === 'string' ? ReactNativeTransport.encoder.encode(req.body) : new Uint8Array(req.body); const initialBodySize = bodyArrayBuffer.byteLength; body = (0, fflate_1.gzipSync)(bodyArrayBuffer); - this.logger.trace(this.constructor.name, () => { + this.logger.trace('ReactNativeTransport', () => { const compressedSize = body.byteLength; const ratio = (compressedSize / initialBodySize).toFixed(2); return { diff --git a/package-lock.json b/package-lock.json index bd1ff6ead..fe7643706 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,22 @@ { "name": "pubnub", - "version": "9.4.0", + "version": "9.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pubnub", - "version": "9.4.0", + "version": "9.6.1", "license": "SEE LICENSE IN LICENSE", "dependencies": { + "@jsonjoy.com/json-pack": "^1.2.0", + "@levischuck/tiny-cbor": "^0.3.1", "agentkeepalive": "^3.5.2", "buffer": "^6.0.3", "cbor-js": "^0.1.0", "cbor-sync": "^1.0.4", + "cbor-x": "^1.6.0", + "cborg": "^4.2.12", "fflate": "^0.8.2", "form-data": "^4.0.0", "lil-uuid": "^0.1.1", @@ -2196,6 +2200,84 @@ "node": ">=6.9.0" } }, + "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3499,6 +3581,66 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", + "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", + "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@levischuck/tiny-cbor": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.3.1.tgz", + "integrity": "sha512-0mqIFNx1SJBfpjuarq6cGPr1KLasCAfk93MT/rs4sfceffNZP+w7Rx3dqS7OonfmnFOZhaSNPtwUJGHV/8WmlQ==", + "license": "MIT" + }, "node_modules/@mswjs/interceptors": { "version": "0.38.3", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.38.3.tgz", @@ -5854,6 +5996,28 @@ "upper-case-first": "^2.0.2" } }, + "node_modules/cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.1.1" + }, + "bin": { + "download-cbor-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + } + }, "node_modules/cbor-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cbor-js/-/cbor-js-0.1.0.tgz", @@ -5866,6 +6030,24 @@ "integrity": "sha512-GWlXN4wiz0vdWWXBU71Dvc1q3aBo0HytqwAZnXF1wOwjqNnDWA1vZ1gDMFLlqohak31VQzmhiYfiCX5QSSfagA==", "license": "MIT" }, + "node_modules/cbor-x": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "license": "MIT", + "optionalDependencies": { + "cbor-extract": "^2.2.0" + } + }, + "node_modules/cborg": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.2.12.tgz", + "integrity": "sha512-z126yLoavS75cdTuiKu61RC3Y3trqtDAgQRa5Q0dpHn1RmqhIedptWXKnk0lQ5yo/GmcV9myvIkzFgZ8GnqSog==", + "license": "Apache-2.0", + "bin": { + "cborg": "lib/bin.js" + } + }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", @@ -6564,6 +6746,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", @@ -8064,6 +8256,15 @@ "ms": "^2.0.0" } }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -10438,6 +10639,21 @@ "node": ">= 6.13.0" } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -13191,6 +13407,18 @@ "node": ">=0.8" } }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "license": "Unlicense", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, "node_modules/throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", diff --git a/package.json b/package.json index ad23b8291..ce5966b47 100644 --- a/package.json +++ b/package.json @@ -54,10 +54,14 @@ "messaging" ], "dependencies": { + "@jsonjoy.com/json-pack": "^1.2.0", + "@levischuck/tiny-cbor": "^0.3.1", "agentkeepalive": "^3.5.2", "buffer": "^6.0.3", "cbor-js": "^0.1.0", "cbor-sync": "^1.0.4", + "cbor-x": "^1.6.0", + "cborg": "^4.2.12", "fflate": "^0.8.2", "form-data": "^4.0.0", "lil-uuid": "^0.1.1", diff --git a/src/core/components/configuration.ts b/src/core/components/configuration.ts index f939810a0..47e663cfa 100644 --- a/src/core/components/configuration.ts +++ b/src/core/components/configuration.ts @@ -7,12 +7,12 @@ import { ExtendedConfiguration, PlatformConfiguration, PrivateClientConfiguration } from '../interfaces/configuration'; import { CryptorConfiguration, ICryptoModule } from '../interfaces/crypto-module'; import { PubNubFileConstructor, PubNubFileInterface } from '../types/file'; +import { ConsoleLogger } from '../../loggers/console-logger'; import { Endpoint, RetryPolicy } from './retry-policy'; -import { Payload } from '../types/api'; -import uuidGenerator from './uuid'; import { LogLevel } from '../interfaces/logger'; import { LoggerManager } from './logger-manager'; -import { ConsoleLogger } from '../../loggers/console-logger'; +import { Payload } from '../types/api'; +import uuidGenerator from './uuid'; // -------------------------------------------------------- // ----------------------- Defaults ----------------------- diff --git a/src/core/components/cryptography/index.ts b/src/core/components/cryptography/index.ts index 4fae151ec..75bd4fa30 100644 --- a/src/core/components/cryptography/index.ts +++ b/src/core/components/cryptography/index.ts @@ -157,7 +157,7 @@ export default class { public encrypt(data: string | Payload, customCipherKey?: string, options?: CryptoConfiguration) { if (this.configuration.customEncrypt) { if (this.logger) - this.logger.warn(this.constructor.name, "'customEncrypt' is deprecated. Consult docs for better alternative."); + this.logger.warn('Crypto', "'customEncrypt' is deprecated. Consult docs for better alternative."); return this.configuration.customEncrypt(data); } @@ -177,7 +177,7 @@ export default class { public decrypt(data: string, customCipherKey?: string, options?: CryptoConfiguration) { if (this.configuration.customDecrypt) { if (this.logger) - this.logger.warn(this.constructor.name, "'customDecrypt' is deprecated. Consult docs for better alternative."); + this.logger.warn('Crypto', "'customDecrypt' is deprecated. Consult docs for better alternative."); return this.configuration.customDecrypt(data); } @@ -199,7 +199,7 @@ export default class { if (!decidedCipherKey) return data; if (this.logger) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('Crypto', () => ({ messageType: 'object', message: { data, cipherKey: decidedCipherKey, ...(options ?? {}) }, details: 'Encrypt with parameters:', @@ -242,7 +242,7 @@ export default class { if (!decidedCipherKey) return data; if (this.logger) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('Crypto', () => ({ messageType: 'object', message: { data, cipherKey: decidedCipherKey, ...(options ?? {}) }, details: 'Decrypt with parameters:', @@ -267,7 +267,7 @@ export default class { ); return JSON.parse(plainJSON); } catch (e) { - if (this.logger) this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e })); + if (this.logger) this.logger.error('Crypto', () => ({ messageType: 'error', message: e })); return null; } @@ -280,7 +280,7 @@ export default class { const plainJSON = CryptoJS.AES.decrypt({ ciphertext }, cipherKey, { iv, mode }).toString(CryptoJS.enc.Utf8); return JSON.parse(plainJSON); } catch (e) { - if (this.logger) this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: e })); + if (this.logger) this.logger.error('Crypto', () => ({ messageType: 'error', message: e })); return null; } diff --git a/src/core/components/deduping_manager.ts b/src/core/components/deduping_manager.ts index 43b3a5ef7..6d1dd762d 100644 --- a/src/core/components/deduping_manager.ts +++ b/src/core/components/deduping_manager.ts @@ -34,7 +34,7 @@ export class DedupingManager { * @param config - PubNub client configuration object. */ constructor(private readonly config: PrivateClientConfiguration) { - config.logger().debug(this.constructor.name, () => ({ + config.logger().debug('DedupingManager', () => ({ messageType: 'object', message: { maximumCacheSize: config.maximumCacheSize }, details: 'Create with configuration:', diff --git a/src/core/components/stringify_buffer_keys.ts b/src/core/components/stringify_buffer_keys.ts index 32f49216e..90368ebab 100644 --- a/src/core/components/stringify_buffer_keys.ts +++ b/src/core/components/stringify_buffer_keys.ts @@ -8,12 +8,13 @@ * Re-map CBOR object keys from potentially C buffer strings to actual strings. * * @param obj CBOR which should be remapped to stringified keys. + * @param nestingLevel PAM token structure nesting level. * * @returns Dictionary with stringified keys. * * @internal */ -export function stringifyBufferKeys(obj: unknown): Record { +export function stringifyBufferKeys(obj: unknown, nestingLevel: number = 0): Record { const isObject = (value: unknown): value is Record => typeof value === 'object' && value !== null && value.constructor === Object; const isString = (value: unknown): value is string => typeof value === 'string' || value instanceof String; @@ -28,17 +29,19 @@ export function stringifyBufferKeys(obj: unknown): Record { let stringifiedKey = key; const value = obj[key]; - if (keyIsString && key.indexOf(',') >= 0) { - const bytes = key.split(',').map(Number); + if (nestingLevel < 2) { + if (keyIsString && key.indexOf(',') >= 0) { + const bytes = key.split(',').map(Number); - stringifiedKey = bytes.reduce((string, byte) => { - return string + String.fromCharCode(byte); - }, ''); - } else if (isNumber(key) || (keyIsString && !isNaN(Number(key)))) { - stringifiedKey = String.fromCharCode(isNumber(key) ? key : parseInt(key, 10)); + stringifiedKey = bytes.reduce((string, byte) => { + return string + String.fromCharCode(byte); + }, ''); + } else if (isNumber(key) || (keyIsString && !isNaN(Number(key)))) { + stringifiedKey = String.fromCharCode(isNumber(key) ? key : parseInt(key, 10)); + } } - normalizedObject[stringifiedKey] = isObject(value) ? stringifyBufferKeys(value) : value; + normalizedObject[stringifiedKey] = isObject(value) ? stringifyBufferKeys(value, nestingLevel + 1) : value; }); return normalizedObject; diff --git a/src/core/components/subscription-manager.ts b/src/core/components/subscription-manager.ts index e8876e7dd..fff153956 100644 --- a/src/core/components/subscription-manager.ts +++ b/src/core/components/subscription-manager.ts @@ -150,7 +150,7 @@ export class SubscriptionManager { private readonly leaveCall: (parameters: Presence.PresenceLeaveParameters, callback: StatusCallback) => void, time: typeof PubNubCore.prototype.time, ) { - configuration.logger().trace(this.constructor.name, 'Create manager.'); + configuration.logger().trace('SubscriptionManager', 'Create manager.'); this.reconnectionManager = new ReconnectionManager(time); this.dedupingManager = new DedupingManager(this.configuration); @@ -500,7 +500,7 @@ export class SubscriptionManager { region: this.region ? this.region : undefined, }; - this.configuration.logger().debug(this.constructor.name, () => { + this.configuration.logger().debug('SubscriptionManager', () => { const hashedEvents = messages.map((event) => { const pn_mfp = event.type === PubNubEventType.Message || event.type === PubNubEventType.Signal @@ -514,7 +514,7 @@ export class SubscriptionManager { messages.forEach((message) => { if (dedupeOnSubscribe && 'message' in message.data && 'timetoken' in message.data) { if (this.dedupingManager.isDuplicate(message.data)) { - this.configuration.logger().warn(this.constructor.name, () => ({ + this.configuration.logger().warn('SubscriptionManager', () => ({ messageType: 'object', message: message.data, details: 'Duplicate message detected (skipped):', diff --git a/src/core/endpoints/objects/channel/set.ts b/src/core/endpoints/objects/channel/set.ts index b803d0c47..085973592 100644 --- a/src/core/endpoints/objects/channel/set.ts +++ b/src/core/endpoints/objects/channel/set.ts @@ -64,6 +64,13 @@ export class SetChannelMetadataRequest< if (!this.parameters.data) return 'Data cannot be empty'; } + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return { ...headers, 'Content-Type': 'application/json' }; + } + protected get path(): string { const { keySet: { subscribeKey }, diff --git a/src/core/interfaces/configuration.ts b/src/core/interfaces/configuration.ts index 3fe0a3c12..a77e1ca42 100644 --- a/src/core/interfaces/configuration.ts +++ b/src/core/interfaces/configuration.ts @@ -66,11 +66,6 @@ const USE_SMART_HEARTBEAT = false; */ const KEEP_ALIVE = false; -/** - * Whether verbose logging should be enabled or not. - */ -const USE_VERBOSE_LOGGING = false; - /** * Whether leave events should be suppressed or not. */ @@ -771,7 +766,6 @@ export interface PrivateClientConfiguration export const setDefaults = (configuration: UserConfiguration): ExtendedConfiguration => { // Copy configuration. const configurationCopy = { ...configuration }; - configurationCopy.logVerbosity ??= USE_VERBOSE_LOGGING; configurationCopy.ssl ??= USE_SSL; configurationCopy.transactionalRequestTimeout ??= TRANSACTIONAL_REQUEST_TIMEOUT; configurationCopy.subscribeRequestTimeout ??= SUBSCRIBE_REQUEST_TIMEOUT; diff --git a/src/core/interfaces/crypto-module.ts b/src/core/interfaces/crypto-module.ts index a26a33137..ee6a37a0e 100644 --- a/src/core/interfaces/crypto-module.ts +++ b/src/core/interfaces/crypto-module.ts @@ -280,7 +280,7 @@ export abstract class AbstractCryptoModule implements ICryptoModule { * @returns Serialized crypto module information. */ toString() { - return `${this.constructor.name} { default: ${( + return `AbstractCryptoModule { default: ${( this.defaultCryptor as object ).toString()}, cryptors: [${this.cryptors.map((c) => (c as object).toString()).join(', ')}]}`; } diff --git a/src/core/pubnub-common.ts b/src/core/pubnub-common.ts index 78d2c4019..5537872a4 100644 --- a/src/core/pubnub-common.ts +++ b/src/core/pubnub-common.ts @@ -91,7 +91,11 @@ import { AuditRequest } from './endpoints/access_manager/audit'; import * as PAM from './types/api/access-manager'; // endregion // region Entities -import { SubscriptionCapable, SubscriptionOptions } from '../entities/interfaces/subscription-capable'; +import { + SubscriptionCapable, + SubscriptionOptions, + SubscriptionType, +} from '../entities/interfaces/subscription-capable'; import { EventEmitCapable } from '../entities/interfaces/event-emit-capable'; import { EntityInterface } from '../entities/interfaces/entity-interface'; import { SubscriptionBase } from '../entities/subscription-base'; @@ -487,6 +491,11 @@ export class PubNubCore< details: 'Join with parameters:', })); + if (parameters && (parameters.channels ?? []).length === 0 && (parameters.groups ?? []).length === 0) { + this.logger.trace('EventEngine', "Ignoring 'join' announcement request."); + return; + } + this.join(parameters); }, leave: (parameters) => { @@ -496,6 +505,11 @@ export class PubNubCore< details: 'Leave with parameters:', })); + if (parameters && (parameters.channels ?? []).length === 0 && (parameters.groups ?? []).length === 0) { + this.logger.trace('EventEngine', "Ignoring 'leave' announcement request."); + return; + } + this.leave(parameters); }, leaveAll: (parameters) => { @@ -1515,6 +1529,55 @@ export class PubNubCore< } if (subscriptionInput.isEmpty) return; + else { + const _channelGroupsInUse: string[] = []; + const _channelsInUse: string[] = []; + + Object.values(this.eventHandleCapable).forEach((_subscription) => { + const _subscriptionInput = _subscription.subscriptionInput(false); + const _subscriptionChannelGroups = _subscriptionInput.channelGroups; + const _subscriptionChannels = _subscriptionInput.channels; + _channelGroupsInUse.push( + ...subscriptionInput.channelGroups.filter((channel) => _subscriptionChannelGroups.includes(channel)), + ); + _channelsInUse.push( + ...subscriptionInput.channels.filter((channel) => _subscriptionChannels.includes(channel)), + ); + }); + + if (_channelsInUse.length > 0 || _channelGroupsInUse.length > 0) { + this.logger.trace('PubNub', () => { + const _entitiesInUse: Entity[] = []; + const addEntityIfInUse = (entity: Entity) => { + const namesOrIds = entity.subscriptionNames(true); + const checkList = + entity.subscriptionType === SubscriptionType.Channel ? _channelsInUse : _channelGroupsInUse; + if (namesOrIds.some((id) => checkList.includes(id))) _entitiesInUse.push(entity); + }; + + Object.values(this.eventHandleCapable).forEach((_subscription) => { + if (_subscription instanceof SubscriptionSet) { + _subscription.subscriptions.forEach((_subscriptionInSet) => { + addEntityIfInUse(_subscriptionInSet.state.entity as Entity); + }); + } else if (_subscription instanceof SubscriptionObject) + addEntityIfInUse(_subscription.state.entity as Entity); + }); + + let details = 'Some entities still in use:'; + if (_channelsInUse.length + _channelGroupsInUse.length === subscriptionInput.length) + details = "Can't unregister event handle capable because entities still in use:"; + + return { messageType: 'object', message: { entities: _entitiesInUse }, details }; + }); + + subscriptionInput.remove( + new SubscriptionInput({ channels: _channelsInUse, channelGroups: _channelGroupsInUse }), + ); + + if (subscriptionInput.isEmpty) return; + } + } const parameters: Presence.PresenceLeaveParameters = {}; parameters.channels = subscriptionInput.channels; @@ -2589,7 +2652,7 @@ export class PubNubCore< * @param callback - Request completion handler callback. */ private async heartbeat( - parameters: Presence.PresenceHeartbeatParameters, + parameters: Presence.CancelablePresenceHeartbeatParameters, callback?: ResultCallback, ) { if (process.env.PRESENCE_MODULE !== 'disabled') { @@ -2629,20 +2692,27 @@ export class PubNubCore< channelGroups, keySet: this._configuration.keySet, }); + const logResponse = (response: Presence.PresenceHeartbeatResponse | null) => { if (!response) return; this.logger.trace('PubNub', 'Heartbeat success.'); }; + const abortUnsubscribe = parameters.abortSignal?.subscribe((err) => { + request.abort('Cancel long-poll subscribe request'); + }); + if (callback) return this.sendRequest(request, (status, response) => { logResponse(response); + if (abortUnsubscribe) abortUnsubscribe(); callback(status, response); }); return this.sendRequest(request).then((response) => { logResponse(response); + if (abortUnsubscribe) abortUnsubscribe(); return response; }); } else throw new Error('Announce UUID Presence error: presence module disabled'); @@ -2665,6 +2735,11 @@ export class PubNubCore< details: 'Join with parameters:', })); + if (parameters && (parameters.channels ?? []).length === 0 && (parameters.groups ?? []).length === 0) { + this.logger.trace('PubNub', "Ignoring 'join' announcement request."); + return; + } + if (this.presenceEventEngine) this.presenceEventEngine.join(parameters); else { this.heartbeat( @@ -2729,6 +2804,11 @@ export class PubNubCore< details: 'Leave with parameters:', })); + if (parameters && (parameters.channels ?? []).length === 0 && (parameters.groups ?? []).length === 0) { + this.logger.trace('PubNub', "Ignoring 'leave' announcement request."); + return; + } + if (this.presenceEventEngine) this.presenceEventEngine?.leave(parameters); else this.makeUnsubscribe({ channels: parameters.channels, channelGroups: parameters.groups }, () => {}); } else throw new Error('Announce UUID Leave error: presence module disabled'); diff --git a/src/core/types/api/presence.ts b/src/core/types/api/presence.ts index 16d9e2f33..05bfdb503 100644 --- a/src/core/types/api/presence.ts +++ b/src/core/types/api/presence.ts @@ -1,3 +1,4 @@ +import { AbortSignal } from '../../components/abort_signal'; import { Payload } from './index'; // region Get Presence State @@ -93,6 +94,18 @@ export type SetPresenceStateResponse = { // endregion // region Heartbeat announce +/** + * Cancelable heartbeat request parameters. + * + * @internal + */ +export type CancelablePresenceHeartbeatParameters = PresenceHeartbeatParameters & { + /** + * Request termination signal. + */ + abortSignal?: AbortSignal; +}; + /** * Announce heartbeat parameters. */ diff --git a/src/core/types/api/subscription.ts b/src/core/types/api/subscription.ts index fd32edfa2..5f45072e8 100644 --- a/src/core/types/api/subscription.ts +++ b/src/core/types/api/subscription.ts @@ -81,6 +81,16 @@ export class SubscriptionInput { this.isEmpty = this._channels.size === 0 && this._channelGroups.size === 0; } + /** + * Retrieve total length of subscription input. + * + * @returns Number of channels and groups in subscription input. + */ + get length(): number { + if (this.isEmpty) return 0; + return this._channels.size + this._channelGroups.size; + } + /** * Retrieve a list of user-provided channel names. * diff --git a/src/crypto/modules/NodeCryptoModule/aesCbcCryptor.ts b/src/crypto/modules/NodeCryptoModule/aesCbcCryptor.ts index 82c07bc22..620474c97 100644 --- a/src/crypto/modules/NodeCryptoModule/aesCbcCryptor.ts +++ b/src/crypto/modules/NodeCryptoModule/aesCbcCryptor.ts @@ -171,6 +171,6 @@ export default class AesCbcCryptor implements ICryptor { * @returns Serialized cryptor information. */ toString() { - return `${this.constructor.name} { cipherKey: ${this.cipherKey} }`; + return `AesCbcCryptor { cipherKey: ${this.cipherKey} }`; } } diff --git a/src/crypto/modules/NodeCryptoModule/legacyCryptor.ts b/src/crypto/modules/NodeCryptoModule/legacyCryptor.ts index d58e52d8b..4a2e2015e 100644 --- a/src/crypto/modules/NodeCryptoModule/legacyCryptor.ts +++ b/src/crypto/modules/NodeCryptoModule/legacyCryptor.ts @@ -111,6 +111,6 @@ export default class LegacyCryptor implements ILegacyCryptor { acc.push(`${key}: ${typeof value === 'function' ? '' : value}`); return acc; }, [] as string[]); - return `${this.constructor.name} { ${configurationEntries.join(', ')} }`; + return `LegacyCryptor { ${configurationEntries.join(', ')} }`; } } diff --git a/src/crypto/modules/WebCryptoModule/aesCbcCryptor.ts b/src/crypto/modules/WebCryptoModule/aesCbcCryptor.ts index c904dc4f3..a392893ce 100644 --- a/src/crypto/modules/WebCryptoModule/aesCbcCryptor.ts +++ b/src/crypto/modules/WebCryptoModule/aesCbcCryptor.ts @@ -166,6 +166,6 @@ export default class AesCbcCryptor implements ICryptor { * @returns Serialized cryptor information. */ toString() { - return `${this.constructor.name} { cipherKey: ${this.cipherKey} }`; + return `AesCbcCryptor { cipherKey: ${this.cipherKey} }`; } } diff --git a/src/crypto/modules/WebCryptoModule/legacyCryptor.ts b/src/crypto/modules/WebCryptoModule/legacyCryptor.ts index cf8174114..94bfcae80 100644 --- a/src/crypto/modules/WebCryptoModule/legacyCryptor.ts +++ b/src/crypto/modules/WebCryptoModule/legacyCryptor.ts @@ -12,6 +12,7 @@ import { PubNubError } from '../../../errors/pubnub-error'; import { ILegacyCryptor } from './ILegacyCryptor'; import { EncryptedDataType } from './ICryptor'; import FileCryptor from '../web'; +import AesCbcCryptor from './aesCbcCryptor'; /** * Legacy cryptor. @@ -117,6 +118,6 @@ export default class LegacyCryptor implements ILegacyCryptor { acc.push(`${key}: ${typeof value === 'function' ? '' : value}`); return acc; }, [] as string[]); - return `${this.constructor.name} { ${configurationEntries.join(', ')} }`; + return `AesCbcCryptor { ${configurationEntries.join(', ')} }`; } } diff --git a/src/entities/channel-group.ts b/src/entities/channel-group.ts index 4a5d782f4..d6ddf942a 100644 --- a/src/entities/channel-group.ts +++ b/src/entities/channel-group.ts @@ -5,6 +5,23 @@ import { Entity } from './entity'; * First-class objects which provides access to the channel group-specific APIs. */ export class ChannelGroup extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + override get entityType(): 'Channel' | 'ChannelGroups' | 'ChannelMetadata' | 'UserMetadata' { + return 'ChannelGroups'; + } + /** * Get a unique channel group name. * diff --git a/src/entities/channel-metadata.ts b/src/entities/channel-metadata.ts index 611ca97b0..cfa120788 100644 --- a/src/entities/channel-metadata.ts +++ b/src/entities/channel-metadata.ts @@ -4,6 +4,23 @@ import { Entity } from './entity'; * First-class objects which provides access to the channel app context object-specific APIs. */ export class ChannelMetadata extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + override get entityType(): 'Channel' | 'ChannelGroups' | 'ChannelMetadata' | 'UserMetadata' { + return 'ChannelMetadata'; + } + /** * Get unique channel metadata object identifier. * diff --git a/src/entities/channel.ts b/src/entities/channel.ts index 624f68e6d..f992cf20c 100644 --- a/src/entities/channel.ts +++ b/src/entities/channel.ts @@ -4,6 +4,23 @@ import { Entity } from './entity'; * First-class objects which provides access to the channel-specific APIs. */ export class Channel extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + override get entityType(): 'Channel' | 'ChannelGroups' | 'ChannelMetadata' | 'UserMetadata' { + return 'Channel'; + } + /** * Get a unique channel name. * diff --git a/src/entities/entity.ts b/src/entities/entity.ts index 35ef2a44b..814febb11 100644 --- a/src/entities/entity.ts +++ b/src/entities/entity.ts @@ -43,6 +43,23 @@ export abstract class Entity implements EntityInterface, SubscriptionCapable { this._nameOrId = nameOrId; } + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType(): 'Channel' | 'ChannelGroups' | 'ChannelMetadata' | 'UserMetadata' { + return 'Channel'; + } + /** * Type of subscription entity. * @@ -143,6 +160,6 @@ export abstract class Entity implements EntityInterface, SubscriptionCapable { * @returns Serialized entity object. */ toString(): string { - return `${this.constructor.name} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`; + return `${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`; } } diff --git a/src/entities/interfaces/entity-interface.ts b/src/entities/interfaces/entity-interface.ts index 8c41893dd..f39209645 100644 --- a/src/entities/interfaces/entity-interface.ts +++ b/src/entities/interfaces/entity-interface.ts @@ -13,4 +13,19 @@ export interface EntityInterface extends SubscriptionCapable { * @internal */ client: PubNub; + + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + entityType: 'Channel' | 'ChannelGroups' | 'ChannelMetadata' | 'UserMetadata'; } diff --git a/src/entities/subscription-base.ts b/src/entities/subscription-base.ts index 675983420..58845e739 100644 --- a/src/entities/subscription-base.ts +++ b/src/entities/subscription-base.ts @@ -201,6 +201,21 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC this._state = state; } + /** + * Retrieve subscription type. + * + * There is two types: + * - Subscription + * - SubscriptionSet + * + * @returns One of subscription types. + * + * @internal + */ + get subscriptionType(): 'Subscription' | 'SubscriptionSet' { + return 'Subscription'; + } + /** * Subscription state. * @@ -354,7 +369,7 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC // Check whether this is an old `old` event and it should be ignored or not. if (this.state.referenceTimetoken && event.data.timetoken < this.state.referenceTimetoken) { - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Event timetoken (${event.data.timetoken}) is older than reference timetoken (${ this.state.referenceTimetoken @@ -367,7 +382,7 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC // Don't pass events which are filtered out by the user-provided function. if (this.state.options?.filter && !this.state.options.filter(event)) { this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, `Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`, ); @@ -377,7 +392,7 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC const clones = Object.values(this.state.clones); if (clones.length > 0) { this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, `Notify ${this.id} subscription object clones (count: ${clones.length}) about received event.`, ); } @@ -414,10 +429,10 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC const keys = Object.keys(this.state.clones); if (keys.length > 1) { - this.state.client.logger.debug(this.constructor.name, `Remove subscription object clone on dispose: ${this.id}`); + this.state.client.logger.debug(this.subscriptionType, `Remove subscription object clone on dispose: ${this.id}`); delete this.state.clones[this.id]; } else if (keys.length === 1 && this.state.clones[this.id]) { - this.state.client.logger.debug(this.constructor.name, `Unsubscribe subscription object on dispose: ${this.id}`); + this.state.client.logger.debug(this.subscriptionType, `Unsubscribe subscription object on dispose: ${this.id}`); this.unsubscribe(); } } @@ -440,7 +455,7 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC delete this.state.clones[this.id]; if (Object.keys(this.state.clones).length === 0) { - this.state.client.logger.trace(this.constructor.name, 'Last clone removed. Reset shared subscription state.'); + this.state.client.logger.trace(this.subscriptionType, 'Last clone removed. Reset shared subscription state.'); this.state.subscriptionInput.removeAll(); this.state.parents = []; } @@ -455,11 +470,11 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC */ subscribe(parameters?: { timetoken?: string }) { if (this.state.isSubscribed) { - this.state.client.logger.trace(this.constructor.name, 'Already subscribed. Ignoring subscribe request.'); + this.state.client.logger.trace(this.subscriptionType, 'Already subscribed. Ignoring subscribe request.'); return; } - this.state.client.logger.debug(this.constructor.name, () => { + this.state.client.logger.debug(this.subscriptionType, () => { if (!parameters) return { messageType: 'text', message: 'Subscribe' }; return { messageType: 'object', message: parameters, details: 'Subscribe with parameters:' }; }); @@ -483,21 +498,21 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC if (!this.state._isSubscribed || this.state.isSubscribed) { // Warn if a user tries to unsubscribe using specific subscription which subscribed as part of a subscription set. if (!this.state._isSubscribed && this.state.parents.length > 0 && this.state.isSubscribed) { - this.state.client.logger.warn(this.constructor.name, () => ({ + this.state.client.logger.warn(this.subscriptionType, () => ({ messageType: 'object', details: 'Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:', message: this.state.parents.filter((subscriptionSet) => subscriptionSet.isSubscribed), })); return; } else if (!this.state._isSubscribed) { - this.state.client.logger.trace(this.constructor.name, 'Not subscribed. Ignoring unsubscribe request.'); + this.state.client.logger.trace(this.subscriptionType, 'Not subscribed. Ignoring unsubscribe request.'); return; } } - this.state.client.logger.debug(this.constructor.name, 'Unsubscribe'); + this.state.client.logger.debug(this.subscriptionType, 'Unsubscribe'); - this.state.isSubscribed = true; + this.state.isSubscribed = false; delete this.state.cursor; this.updateSubscription({ subscribing: false }); diff --git a/src/entities/subscription-set.ts b/src/entities/subscription-set.ts index 299166f1b..88a6f7f76 100644 --- a/src/entities/subscription-set.ts +++ b/src/entities/subscription-set.ts @@ -39,6 +39,21 @@ class SubscriptionSetState extends SubscriptionBaseState { this.subscriptions = parameters.subscriptions; } + /** + * Retrieve subscription type. + * + * There is two types: + * - Subscription + * - SubscriptionSet + * + * @returns One of subscription types. + * + * @internal + */ + get subscriptionType(): 'Subscription' | 'SubscriptionSet' { + return 'SubscriptionSet'; + } + /** * Add a single subscription object to the set. * @@ -188,7 +203,7 @@ export class SubscriptionSet extends SubscriptionBase { // Check whether `event` can be processed or not. if (!this.state._isSubscribed) { this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, `Subscription set ${this.id} is not subscribed. Ignoring event.`, ); return; @@ -197,7 +212,7 @@ export class SubscriptionSet extends SubscriptionBase { if (this.state.subscriptions.length > 0) { this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, `Notify ${this.id} subscription set subscriptions (count: ${ this.state.subscriptions.length }) about received event.`, @@ -312,7 +327,7 @@ export class SubscriptionSet extends SubscriptionBase { const inactiveSubscriptions: SubscriptionObject[] = []; const activeSubscriptions: SubscriptionObject[] = []; - this.state.client.logger.debug(this.constructor.name, () => { + this.state.client.logger.debug(this.subscriptionType, () => { const ignoredSubscriptions: SubscriptionObject[] = []; const subscriptionsToAdd: SubscriptionObject[] = []; @@ -369,7 +384,7 @@ export class SubscriptionSet extends SubscriptionBase { removeSubscriptions(subscriptions: SubscriptionObject[]) { const activeSubscriptions: SubscriptionObject[] = []; - this.state.client.logger.debug(this.constructor.name, () => { + this.state.client.logger.debug(this.subscriptionType, () => { const ignoredSubscriptions: SubscriptionObject[] = []; const subscriptionsToRemove: SubscriptionObject[] = []; @@ -437,7 +452,7 @@ export class SubscriptionSet extends SubscriptionBase { this.state.subscriptions) as SubscriptionObject[]; subscriptions.forEach(({ state }) => state.entity.increaseSubscriptionCount(this.state.id)); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Register subscription for real-time events: ${this}`, })); @@ -458,7 +473,7 @@ export class SubscriptionSet extends SubscriptionBase { this.state.subscriptions) as SubscriptionObject[]; activeSubscriptions.forEach(({ state }) => state.entity.decreaseSubscriptionCount(this.state.id)); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Unregister subscription from real-time events: ${this}`, })); @@ -474,7 +489,7 @@ export class SubscriptionSet extends SubscriptionBase { toString(): string { const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, clonesCount: ${ + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, clonesCount: ${ Object.keys(this.state.clones).length }, isSubscribed: ${state.isSubscribed}, subscriptions: [${state.subscriptions .map((sub) => sub.toString()) diff --git a/src/entities/subscription.ts b/src/entities/subscription.ts index d227c11b5..9072916c7 100644 --- a/src/entities/subscription.ts +++ b/src/entities/subscription.ts @@ -145,7 +145,7 @@ export class Subscription extends SubscriptionBase { // Creating from whole payload (not only for published messages). const fingerprint = messageFingerprint(event.data); if (this.handledUpdates.includes(fingerprint)) { - this.state.client.logger.trace(this.constructor.name, `Message (${fingerprint}) already handled. Ignoring.`); + this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled. Ignoring.`); return; } @@ -204,7 +204,7 @@ export class Subscription extends SubscriptionBase { */ dispose(): void { if (this.parentSetsCount > 0) { - this.state.client.logger.debug(this.constructor.name, () => ({ + this.state.client.logger.debug(this.subscriptionType, () => ({ messageType: 'text', message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, })); @@ -245,7 +245,7 @@ export class Subscription extends SubscriptionBase { this.parents.push(parent); this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${ this.parentSetsCount }`, @@ -266,7 +266,7 @@ export class Subscription extends SubscriptionBase { this.parents.splice(parentIndex, 1); this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${ this.parentSetsCount }`, @@ -284,7 +284,7 @@ export class Subscription extends SubscriptionBase { * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. */ addSubscription(subscription: Subscription): SubscriptionSet { - this.state.client.logger.debug(this.constructor.name, () => ({ + this.state.client.logger.debug(this.subscriptionType, () => ({ messageType: 'text', message: `Create set with subscription: ${subscription}`, })); @@ -299,7 +299,7 @@ export class Subscription extends SubscriptionBase { if (!this.state.isSubscribed && !subscription.state.isSubscribed) return subscriptionSet; this.state.client.logger.trace( - this.constructor.name, + this.subscriptionType, 'Subscribe resulting set because the receiver is already subscribed.', ); @@ -324,7 +324,7 @@ export class Subscription extends SubscriptionBase { protected register(parameters: { cursor?: SubscriptionCursor; subscriptions?: EventHandleCapable[] }): void { this.state.entity.increaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Register subscription for real-time events: ${this}`, })); @@ -346,7 +346,7 @@ export class Subscription extends SubscriptionBase { protected unregister(_subscriptions?: Subscription[]) { this.state.entity.decreaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ + this.state.client.logger.trace(this.subscriptionType, () => ({ messageType: 'text', message: `Unregister subscription from real-time events: ${this}`, })); @@ -363,7 +363,7 @@ export class Subscription extends SubscriptionBase { toString(): string { const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity .subscriptionNames(false) .pop()}, clonesCount: ${ Object.keys(state.clones).length diff --git a/src/entities/user-metadata.ts b/src/entities/user-metadata.ts index d7a0f2911..b269a42f6 100644 --- a/src/entities/user-metadata.ts +++ b/src/entities/user-metadata.ts @@ -4,6 +4,23 @@ import { Entity } from './entity'; * First-class objects which provides access to the user app context object-specific APIs. */ export class UserMetadata extends Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + override get entityType(): 'Channel' | 'ChannelGroups' | 'ChannelMetadata' | 'UserMetadata' { + return 'UserMetadata'; + } + /** * Get unique user metadata object identifier. * diff --git a/src/event-engine/core/dispatcher.ts b/src/event-engine/core/dispatcher.ts index cdcab594c..f134a0943 100644 --- a/src/event-engine/core/dispatcher.ts +++ b/src/event-engine/core/dispatcher.ts @@ -45,7 +45,7 @@ export class Dispatcher< } dispatch(invocation: Invocation): void { - this.logger.trace(this.constructor.name, `Process invocation: ${invocation.type}`); + this.logger.trace('Dispatcher', `Process invocation: ${invocation.type}`); if (invocation.type === 'CANCEL') { if (this.instances.has(invocation.payload)) { @@ -62,13 +62,13 @@ export class Dispatcher< const handlerCreator = this.handlers.get(invocation.type); if (!handlerCreator) { - this.logger.error(this.constructor.name, `Unhandled invocation '${invocation.type}'`); + this.logger.error('Dispatcher', `Unhandled invocation '${invocation.type}'`); throw new Error(`Unhandled invocation '${invocation.type}'`); } const instance = handlerCreator(invocation.payload, this.dependencies); - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Dispatcher', () => ({ messageType: 'object', details: 'Call invocation handler with parameters:', message: invocation.payload, diff --git a/src/event-engine/core/engine.ts b/src/event-engine/core/engine.ts index 65e005f92..9014695e3 100644 --- a/src/event-engine/core/engine.ts +++ b/src/event-engine/core/engine.ts @@ -54,12 +54,12 @@ export class Engine exten transition(event: Event) { if (!this._currentState) { - this.logger.error(this.constructor.name, 'Finite state machine is not started'); + this.logger.error('Engine', 'Finite state machine is not started'); throw new Error('Start the engine first'); } if (this._inTransition) { - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', message: event, details: 'Event engine in transition. Enqueue received event:', @@ -69,7 +69,7 @@ export class Engine exten return; } else this._inTransition = true; - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', message: event, details: 'Event engine received event:', @@ -85,7 +85,7 @@ export class Engine exten if (transition) { const [newState, newContext, effects] = transition; - this.logger.trace(this.constructor.name, `Exiting state: ${this._currentState.label}`); + this.logger.trace('Engine', `Exiting state: ${this._currentState.label}`); for (const effect of this._currentState.exitEffects) { this.notify({ @@ -94,7 +94,7 @@ export class Engine exten }); } - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('Engine', () => ({ messageType: 'object', details: `Entering '${newState.label}' state with context:`, message: newContext, @@ -127,27 +127,23 @@ export class Engine exten invocation: effect(this._currentContext), }); } + } else + this.logger.warn('Engine', `No transition from '${this._currentState.label}' found for event: ${event.type}`); + this._inTransition = false; - this._inTransition = false; - - // Check whether a pending task should be dequeued. - if (this._pendingEvents.length > 0) { - const nextEvent = this._pendingEvents.shift(); + // Check whether a pending task should be dequeued. + if (this._pendingEvents.length > 0) { + const nextEvent = this._pendingEvents.shift(); - if (nextEvent) { - this.logger.trace(this.constructor.name, () => ({ - messageType: 'object', - message: nextEvent, - details: 'De-queueing pending event:', - })); + if (nextEvent) { + this.logger.trace('Engine', () => ({ + messageType: 'object', + message: nextEvent, + details: 'De-queueing pending event:', + })); - this.transition(nextEvent); - } + this.transition(nextEvent); } - } else - this.logger.warn( - this.constructor.name, - `No transition from '${this._currentState.label}' found for event: ${event.type}`, - ); + } } } diff --git a/src/event-engine/core/handler.ts b/src/event-engine/core/handler.ts index aa93e16da..bfd3f7b2c 100644 --- a/src/event-engine/core/handler.ts +++ b/src/event-engine/core/handler.ts @@ -54,7 +54,6 @@ class AsyncHandler extends Handler start() { this.asyncFunction(this.payload, this.abortSignal, this.dependencies).catch((error) => { - // console.log('Unhandled error:', error); // swallow the error }); } diff --git a/src/event-engine/index.ts b/src/event-engine/index.ts index a3db3c007..7b8ab4bcf 100644 --- a/src/event-engine/index.ts +++ b/src/event-engine/index.ts @@ -37,7 +37,7 @@ export class EventEngine { this.engine = new Engine(dependencies.config.logger()); this.dispatcher = new EventEngineDispatcher(this.engine, dependencies); - dependencies.config.logger().debug(this.constructor.name, 'Create subscribe event engine.'); + dependencies.config.logger().debug('EventEngine', 'Create subscribe event engine.'); this._unsubscribeEngine = this.engine.subscribe((change) => { if (change.type === 'invocationDispatched') { diff --git a/src/event-engine/presence/dispatcher.ts b/src/event-engine/presence/dispatcher.ts index 08db3a676..5af978b3b 100644 --- a/src/event-engine/presence/dispatcher.ts +++ b/src/event-engine/presence/dispatcher.ts @@ -21,7 +21,7 @@ import * as events from './events'; */ export type Dependencies = { heartbeat: ( - parameters: Presence.PresenceHeartbeatParameters, + parameters: Presence.CancelablePresenceHeartbeatParameters, callback?: ResultCallback, ) => Promise; leave: (parameters: Presence.PresenceLeaveParameters) => void; @@ -47,9 +47,12 @@ export class PresenceEventEngineDispatcher extends Dispatcher { + asyncHandler(async (payload, abortSignal, { heartbeat, presenceState, config }) => { + abortSignal.throwIfAborted(); + try { const result = await heartbeat({ + abortSignal: abortSignal, channels: payload.channels, channelGroups: payload.groups, ...(config.maintainPresenceState && { state: presenceState }), diff --git a/src/event-engine/presence/presence.ts b/src/event-engine/presence/presence.ts index 650563914..7dcf1f228 100644 --- a/src/event-engine/presence/presence.ts +++ b/src/event-engine/presence/presence.ts @@ -29,7 +29,7 @@ export class PresenceEventEngine { this.engine = new Engine(dependencies.config.logger()); this.dispatcher = new PresenceEventEngineDispatcher(this.engine, dependencies); - dependencies.config.logger().debug(this.constructor.name, 'Create presence event engine.'); + dependencies.config.logger().debug('PresenceEventEngine', 'Create presence event engine.'); this._unsubscribeEngine = this.engine.subscribe((change) => { if (change.type === 'invocationDispatched') { @@ -43,8 +43,11 @@ export class PresenceEventEngine { groups: string[] = []; join({ channels, groups }: { channels?: string[]; groups?: string[] }) { - this.channels = [...this.channels, ...(channels ?? [])]; - this.groups = [...this.groups, ...(groups ?? [])]; + this.channels = [...this.channels, ...(channels ?? []).filter((channel) => !this.channels.includes(channel))]; + this.groups = [...this.groups, ...(groups ?? []).filter((group) => !this.groups.includes(group))]; + + // Don't make any transitions if there is no channels and groups. + if (this.channels.length === 0 && this.groups.length === 0) return; this.engine.transition(events.joined(this.channels.slice(0), this.groups.slice(0))); } diff --git a/src/event-engine/presence/states/heartbeat_cooldown.ts b/src/event-engine/presence/states/heartbeat_cooldown.ts index 52013b717..e73c1bf12 100644 --- a/src/event-engine/presence/states/heartbeat_cooldown.ts +++ b/src/event-engine/presence/states/heartbeat_cooldown.ts @@ -42,8 +42,8 @@ HeartbeatCooldownState.on(timesUp.type, (context, _) => HeartbeatCooldownState.on(joined.type, (context, event) => HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], }), ); diff --git a/src/event-engine/presence/states/heartbeat_failed.ts b/src/event-engine/presence/states/heartbeat_failed.ts index d14033699..7742ffdf7 100644 --- a/src/event-engine/presence/states/heartbeat_failed.ts +++ b/src/event-engine/presence/states/heartbeat_failed.ts @@ -33,8 +33,8 @@ export const HeartbeatFailedState = new State HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], }), ); diff --git a/src/event-engine/presence/states/heartbeat_stopped.ts b/src/event-engine/presence/states/heartbeat_stopped.ts index 3891f49a6..71631beb4 100644 --- a/src/event-engine/presence/states/heartbeat_stopped.ts +++ b/src/event-engine/presence/states/heartbeat_stopped.ts @@ -32,8 +32,8 @@ export const HeartbeatStoppedState = new State HeartbeatStoppedState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], }), ); diff --git a/src/event-engine/presence/states/heartbeating.ts b/src/event-engine/presence/states/heartbeating.ts index c0a3c6b42..5d4126064 100644 --- a/src/event-engine/presence/states/heartbeating.ts +++ b/src/event-engine/presence/states/heartbeating.ts @@ -42,8 +42,8 @@ HeartbeatingState.on(heartbeatSuccess.type, (context, event) => HeartbeatingState.on(joined.type, (context, event) => HeartbeatingState.with({ - channels: [...context.channels, ...event.payload.channels], - groups: [...context.groups, ...event.payload.groups], + channels: [...context.channels, ...event.payload.channels.filter((channel) => !context.channels.includes(channel))], + groups: [...context.groups, ...event.payload.groups.filter((group) => !context.groups.includes(group))], }), ); diff --git a/src/loggers/console-logger.ts b/src/loggers/console-logger.ts index 29ca2f89e..c0f2994dd 100644 --- a/src/loggers/console-logger.ts +++ b/src/loggers/console-logger.ts @@ -213,11 +213,20 @@ export class ConsoleLogger implements Logger { else if (typeof raw === 'object') { const isArray = Array.isArray(raw); const isEmptyArray = isArray && raw.length === 0; + const isEmptyObject = !isArray && !(raw instanceof String) && Object.keys(raw).length === 0; const hasToString = !isArray && typeof raw.toString === 'function' && raw.toString().indexOf('[object') !== 0; - const entry = maxIndentReached ? '...' : isEmptyArray ? '[]' : stringify(raw, level + 1, hasToString); + const entry = maxIndentReached + ? '...' + : isEmptyArray + ? '[]' + : isEmptyObject + ? '{}' + : stringify(raw, level + 1, hasToString); lines.push( - `${indent}${paddedKey}:${maxIndentReached || hasToString || isEmptyArray ? ' ' : '\n'}${entry}`, + `${indent}${paddedKey}:${ + maxIndentReached || hasToString || isEmptyArray || isEmptyObject ? ' ' : '\n' + }${entry}`, ); } else lines.push(`${indent}${paddedKey}: ${raw}`); @@ -283,10 +292,10 @@ export class ConsoleLogger implements Logger { if (typeof body === 'string') { stringifiedBody = ` ${body}`; - } else if (body instanceof ArrayBuffer) { + } else if (body instanceof ArrayBuffer || Object.prototype.toString.call(body) === '[object ArrayBuffer]') { if (contentType && (contentType.indexOf('javascript') !== -1 || contentType.indexOf('json') !== -1)) - stringifiedBody = ` ${ConsoleLogger.decoder.decode(body)}`; - else stringifiedBody = ` ArrayBuffer { byteLength: ${body.byteLength} }`; + stringifiedBody = ` ${ConsoleLogger.decoder.decode(body as ArrayBuffer)}`; + else stringifiedBody = ` ArrayBuffer { byteLength: ${(body as ArrayBuffer).byteLength} }`; } else { stringifiedBody = ` File { name: ${body.name}${ body.contentLength ? `, contentLength: ${body.contentLength}` : '' diff --git a/src/transport/middleware.ts b/src/transport/middleware.ts index 32a7e77f2..c8da6a255 100644 --- a/src/transport/middleware.ts +++ b/src/transport/middleware.ts @@ -79,7 +79,7 @@ class RequestSignature { if (payload) signatureInput += payload; } - this.logger.trace(this.constructor.name, () => ({ + this.logger.trace('RequestSignature', () => ({ messageType: 'text', message: `Request signature input:\n${signatureInput}`, })); @@ -185,7 +185,7 @@ export class PubNubMiddleware implements Transport { if (delay > 0) { attempt++; - this.logger.warn(this.constructor.name, `HTTP request retry #${attempt} in ${delay}ms.`); + this.logger.warn('PubNubMiddleware', `HTTP request retry #${attempt} in ${delay}ms.`); retryTimeout = setTimeout(() => trySendRequest(), delay); } else { if (res) resolve(res); diff --git a/src/transport/node-transport.ts b/src/transport/node-transport.ts index 3549cd313..6cf017849 100644 --- a/src/transport/node-transport.ts +++ b/src/transport/node-transport.ts @@ -68,7 +68,7 @@ export class NodeTransport implements Transport { private readonly keepAlive: boolean = false, private readonly keepAliveSettings: TransportKeepAlive = { timeout: 30000 }, ) { - logger.debug(this.constructor.name, () => ({ + logger.debug('NodeTransport', () => ({ messageType: 'object', message: { keepAlive, keepAliveSettings }, details: 'Create with configuration:', @@ -83,8 +83,8 @@ export class NodeTransport implements Transport { * @internal */ public setProxy(configuration?: ProxyAgentOptions) { - if (configuration) this.logger.debug(this.constructor.name, 'Proxy configuration has been set.'); - else this.logger.debug(this.constructor.name, 'Proxy configuration has been removed.'); + if (configuration) this.logger.debug('NodeTransport', 'Proxy configuration has been set.'); + else this.logger.debug('NodeTransport', 'Proxy configuration has been removed.'); this.proxyConfiguration = configuration; } @@ -99,7 +99,7 @@ export class NodeTransport implements Transport { abortController, abort: (reason) => { if (!abortController || abortController.signal.aborted) return; - this.logger.trace(this.constructor.name, `On-demand request aborting: ${reason}`); + this.logger.trace('NodeTransport', `On-demand request aborting: ${reason}`); abortController?.abort(reason); }, } as CancellationController; @@ -107,7 +107,7 @@ export class NodeTransport implements Transport { return [ this.requestFromTransportRequest(req).then((request) => { - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('NodeTransport', () => ({ messageType: 'network-request', message: req })); return fetch(request, { signal: abortController?.signal, @@ -131,7 +131,7 @@ export class NodeTransport implements Transport { body: responseBody, }; - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('NodeTransport', () => ({ messageType: 'network-response', message: transportResponse, })); @@ -145,14 +145,14 @@ export class NodeTransport implements Transport { let fetchError = typeof error === 'string' ? new Error(error) : (error as Error); if (errorMessage.includes('timeout')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('NodeTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', canceled: true, })); } else if (errorMessage.includes('cancel') || errorMessage.includes('abort')) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('NodeTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -161,14 +161,14 @@ export class NodeTransport implements Transport { fetchError = new AbortError('Aborted'); } else if (errorMessage.includes('network')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('NodeTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', failed: true, })); } else { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('NodeTransport', () => ({ messageType: 'network-request', message: req, details: PubNubAPIError.create(fetchError).message, @@ -227,7 +227,7 @@ export class NodeTransport implements Transport { body = req.compressible ? zlib.deflateSync(req.body) : req.body; if (req.compressible) { - this.logger.trace(this.constructor.name, () => { + this.logger.trace('NodeTransport', () => { const compressedSize = (body! as ArrayBuffer).byteLength; const ratio = (compressedSize / initialBodySize).toFixed(2); diff --git a/src/transport/react-native-transport.ts b/src/transport/react-native-transport.ts index 814b9bfae..e1566ff01 100644 --- a/src/transport/react-native-transport.ts +++ b/src/transport/react-native-transport.ts @@ -46,7 +46,7 @@ export class ReactNativeTransport implements Transport { private readonly logger: LoggerManager, private keepAlive: boolean = false, ) { - logger.debug(this.constructor.name, `Create with configuration:\n - keep-alive: ${keepAlive}`); + logger.debug('ReactNativeTransport', `Create with configuration:\n - keep-alive: ${keepAlive}`); } makeSendable(req: TransportRequest): [Promise, CancellationController | undefined] { @@ -56,7 +56,7 @@ export class ReactNativeTransport implements Transport { abortController, abort: (reason) => { if (!abortController.signal.aborted) { - this.logger.trace(this.constructor.name, `On-demand request aborting: ${reason}`); + this.logger.trace('ReactNativeTransport', `On-demand request aborting: ${reason}`); abortController.abort(reason); } }, @@ -64,7 +64,7 @@ export class ReactNativeTransport implements Transport { return [ this.requestFromTransportRequest(req).then((request) => { - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('ReactNativeTransport', () => ({ messageType: 'network-request', message: req })); /** * Setup request timeout promise. @@ -112,7 +112,7 @@ export class ReactNativeTransport implements Transport { body: responseBody, }; - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('ReactNativeTransport', () => ({ messageType: 'network-response', message: transportResponse, })); @@ -126,14 +126,14 @@ export class ReactNativeTransport implements Transport { let fetchError = typeof error === 'string' ? new Error(error) : (error as Error); if (errorMessage.includes('timeout')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', canceled: true, })); } else if (errorMessage.includes('cancel') || errorMessage.includes('abort')) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -143,14 +143,14 @@ export class ReactNativeTransport implements Transport { fetchError = new Error('Aborted'); fetchError.name = 'AbortError'; } else if (errorMessage.includes('network')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', failed: true, })); } else { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('ReactNativeTransport', () => ({ messageType: 'network-request', message: req, details: PubNubAPIError.create(fetchError).message, @@ -210,7 +210,7 @@ export class ReactNativeTransport implements Transport { typeof req.body === 'string' ? ReactNativeTransport.encoder.encode(req.body) : new Uint8Array(req.body); const initialBodySize = bodyArrayBuffer.byteLength; body = gzipSync(bodyArrayBuffer); - this.logger.trace(this.constructor.name, () => { + this.logger.trace('ReactNativeTransport', () => { const compressedSize = (body! as ArrayBuffer).byteLength; const ratio = (compressedSize / initialBodySize).toFixed(2); diff --git a/src/transport/subscription-worker/subscription-worker-middleware.ts b/src/transport/subscription-worker/subscription-worker-middleware.ts index f9809bb95..bd82ba721 100644 --- a/src/transport/subscription-worker/subscription-worker-middleware.ts +++ b/src/transport/subscription-worker/subscription-worker-middleware.ts @@ -150,7 +150,7 @@ export class SubscriptionWorkerMiddleware implements Transport { if (!req.path.startsWith('/v2/subscribe') && !req.path.endsWith('/heartbeat') && !req.path.endsWith('/leave')) return this.configuration.transport.makeSendable(req); - this.configuration.logger.debug(this.constructor.name, 'Process request with SharedWorker transport.'); + this.configuration.logger.debug('SubscriptionWorkerMiddleware', 'Process request with SharedWorker transport.'); let controller: CancellationController | undefined; const sendRequestEvent: PubNubSubscriptionWorker.SendRequestEvent = { @@ -266,7 +266,7 @@ export class SubscriptionWorkerMiddleware implements Transport { `/pubnub-${this.configuration.sdkVersion}`, ); } catch (error) { - this.configuration.logger.error(this.constructor.name, () => ({ + this.configuration.logger.error('SubscriptionWorkerMiddleware', () => ({ messageType: 'error', message: error, })); diff --git a/src/transport/subscription-worker/subscription-worker.ts b/src/transport/subscription-worker/subscription-worker.ts index 12dcf08b2..6ddf91228 100644 --- a/src/transport/subscription-worker/subscription-worker.ts +++ b/src/transport/subscription-worker/subscription-worker.ts @@ -449,6 +449,11 @@ type PubNubClientState = { }; heartbeat?: { + /** + * Previous heartbeat send event. + */ + heartbeatEvent?: SendRequestEvent; + /** * List of channels for which user's presence has been announced by the PubNub client. */ @@ -465,6 +470,14 @@ type PubNubClientState = { * Per-channel/group state associated with specific user. */ presenceState?: Record; + + /** + * Heartbeat timer. + * + * Timer which is started with first heartbeat request and repeat inside of SharedWorker to bypass browser's + * timers throttling. + */ + timer?: ReturnType; }; }; // endregion @@ -904,6 +917,7 @@ const handleSendLeaveRequestEvent = ( const request = leaveTransportRequestFromEvent(data, invalidatedClient); if (!client) return; + // Clean up client subscription information if there is no more channels / groups to use. const { subscription, heartbeat } = client; const serviceRequestId = invalidatedClientServiceRequestId ?? subscription?.serviceRequestId; @@ -927,6 +941,12 @@ const handleSendLeaveRequestEvent = ( hbRequestsBySubscriptionKey[heartbeatRequestKey].clientIdentifier === client.clientIdentifier ) delete hbRequestsBySubscriptionKey[heartbeatRequestKey]!.clientIdentifier; + + if (heartbeat.timer) { + clearInterval(heartbeat.timer); + delete heartbeat.heartbeatEvent; + delete heartbeat.timer; + } } } @@ -1821,11 +1841,13 @@ const unRegisterClient = (event: UnRegisterEvent) => { * Use information from request to populate list of channels and other useful information. * * @param event - Send request. + * @returns `true` if channels / groups list has been changed. May return `undefined` because `client` is missing. */ -const updateClientSubscribeStateIfRequired = (event: SendRequestEvent) => { +const updateClientSubscribeStateIfRequired = (event: SendRequestEvent): boolean | undefined => { const query = event.request.queryParameters!; const { clientIdentifier } = event; const client = pubNubClients[clientIdentifier]; + let changed = false; // This should never happen. if (!client) return; @@ -1835,6 +1857,7 @@ const updateClientSubscribeStateIfRequired = (event: SendRequestEvent) => { let subscription = client.subscription; if (!subscription) { + changed = true; subscription = { path: '', channelGroupQuery: '', @@ -1877,12 +1900,16 @@ const updateClientSubscribeStateIfRequired = (event: SendRequestEvent) => { if (subscription.path !== event.request.path) { subscription.path = event.request.path; - subscription.channels = channelsFromRequest(event.request); + const _channelsFromRequest = channelsFromRequest(event.request); + if (!changed) changed = includesStrings(subscription.channels, _channelsFromRequest); + subscription.channels = _channelsFromRequest; } if (subscription.channelGroupQuery !== channelGroupQuery) { subscription.channelGroupQuery = channelGroupQuery; - subscription.channelGroups = channelGroupsFromRequest(event.request); + const _channelGroupsFromRequest = channelGroupsFromRequest(event.request); + if (!changed) changed = includesStrings(subscription.channelGroups, _channelGroupsFromRequest); + subscription.channelGroups = _channelGroupsFromRequest; } let { authKey } = client; @@ -1911,7 +1938,8 @@ const updateClientSubscribeStateIfRequired = (event: SendRequestEvent) => { * @param event - Send heartbeat request event. */ const updateClientHeartbeatState = (event: SendRequestEvent) => { - const client = pubNubClients[event.clientIdentifier]; + const { clientIdentifier } = event; + const client = pubNubClients[clientIdentifier]; const { request } = event; // This should never happen. @@ -1922,6 +1950,17 @@ const updateClientHeartbeatState = (event: SendRequestEvent) => { channelGroups: [], }); + _clientHeartbeat.heartbeatEvent = { ...event }; + if (!_clientHeartbeat.timer) { + _clientHeartbeat.timer = setInterval(() => { + const client = pubNubClients[clientIdentifier]; + // This should never happen. + if (!client || !client.heartbeat || !client.heartbeat.heartbeatEvent) return; + + handleHeartbeatRequestEvent(client.heartbeat.heartbeatEvent); + }, client.heartbeatInterval! * 1000); + } + // Update presence heartbeat information about client. _clientHeartbeat.channelGroups = channelGroupsFromRequest(request).filter((group) => !group.endsWith('-pnpres')); _clientHeartbeat.channels = channelsFromRequest(request).filter((channel) => !channel.endsWith('-pnpres')); @@ -1987,6 +2026,10 @@ const invalidateClient = (subscriptionKey: string, clientId: string) => { if (serviceRequestId) cancelRequest(serviceRequestId); } + // Make sure to stop heartbeat timer. + if (invalidatedClient.heartbeat && invalidatedClient.heartbeat.timer) + clearInterval(invalidatedClient.heartbeat.timer); + if (serviceHeartbeatRequests[subscriptionKey]) { const hbRequestsBySubscriptionKey = (serviceHeartbeatRequests[subscriptionKey] ??= {}); const heartbeatRequestKey = `${invalidatedClient.userId}_${clientAggregateAuthKey(invalidatedClient) ?? ''}`; diff --git a/src/transport/titanium-transport.ts b/src/transport/titanium-transport.ts index 133a395aa..a9ea9b3a6 100644 --- a/src/transport/titanium-transport.ts +++ b/src/transport/titanium-transport.ts @@ -32,7 +32,7 @@ export class TitaniumTransport implements Transport { private readonly logger: LoggerManager, private readonly keepAlive: boolean = false, ) { - logger.debug(this.constructor.name, `Create with configuration:\n - keep-alive: ${keepAlive}`); + logger.debug('TitaniumTransport', `Create with configuration:\n - keep-alive: ${keepAlive}`); } makeSendable(req: TransportRequest): [Promise, CancellationController | undefined] { @@ -44,7 +44,7 @@ export class TitaniumTransport implements Transport { controller = { abort: () => { if (!aborted) { - this.logger.trace(this.constructor.name, 'On-demand request aborting.'); + this.logger.trace('TitaniumTransport', 'On-demand request aborting.'); aborted = true; xhr.abort(); } @@ -56,12 +56,12 @@ export class TitaniumTransport implements Transport { new Promise((resolve, reject) => { const start = new Date().getTime(); - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('TitaniumTransport', () => ({ messageType: 'network-request', message: req })); xhr.onload = () => { const response = this.transportResponseFromXHR(url, xhr); - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('TitaniumTransport', () => ({ messageType: 'network-response', message: response, })); @@ -74,7 +74,7 @@ export class TitaniumTransport implements Transport { let error: PubNubAPIError; if (aborted) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('TitaniumTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -83,7 +83,7 @@ export class TitaniumTransport implements Transport { error = PubNubAPIError.create(new Error('Aborted')); } else if (xhr.timeout >= elapsed - 100) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('TitaniumTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', @@ -92,7 +92,7 @@ export class TitaniumTransport implements Transport { error = PubNubAPIError.create(new Error('Request timeout')); } else if (xhr.status === 0) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('TitaniumTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', @@ -104,7 +104,7 @@ export class TitaniumTransport implements Transport { const response = this.transportResponseFromXHR(url, xhr); error = PubNubAPIError.create(response); - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('TitaniumTransport', () => ({ messageType: 'network-request', message: req, details: error.message, diff --git a/src/transport/web-transport.ts b/src/transport/web-transport.ts index d788a2dda..72294450e 100644 --- a/src/transport/web-transport.ts +++ b/src/transport/web-transport.ts @@ -95,13 +95,10 @@ export class WebTransport implements Transport { private readonly logger: LoggerManager, private readonly transport: 'fetch' | 'xhr' = 'fetch', ) { - logger.debug(this.constructor.name, `Create with configuration:\n - transport: ${transport}`); + logger.debug('WebTransport', `Create with configuration:\n - transport: ${transport}`); if (transport === 'fetch' && (!window || !window.fetch)) { - logger.warn( - this.constructor.name, - `'${transport}' not supported in this browser. Fallback to the 'xhr' transport.`, - ); + logger.warn('WebTransport', `'${transport}' not supported in this browser. Fallback to the 'xhr' transport.`); this.transport = 'xhr'; } @@ -115,16 +112,13 @@ export class WebTransport implements Transport { if (this.isFetchMonkeyPatched()) { WebTransport.originalFetch = WebTransport.getOriginalFetch(); - logger.warn(this.constructor.name, "Native Web Fetch API 'fetch' function monkey patched."); + logger.warn('WebTransport', "Native Web Fetch API 'fetch' function monkey patched."); if (!this.isFetchMonkeyPatched(WebTransport.originalFetch)) { - logger.info( - this.constructor.name, - "Use native Web Fetch API 'fetch' implementation from iframe as APM workaround.", - ); + logger.info('WebTransport', "Use native Web Fetch API 'fetch' implementation from iframe as APM workaround."); } else { logger.warn( - this.constructor.name, + 'WebTransport', 'Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation', ); } @@ -137,7 +131,7 @@ export class WebTransport implements Transport { abortController, abort: (reason) => { if (!abortController.signal.aborted) { - this.logger.trace(this.constructor.name, `On-demand request aborting: ${reason}`); + this.logger.trace('WebTransport', `On-demand request aborting: ${reason}`); abortController.abort(reason); } }, @@ -145,7 +139,7 @@ export class WebTransport implements Transport { return [ this.webTransportRequestFromTransportRequest(req).then((request) => { - this.logger.debug(this.constructor.name, () => ({ messageType: 'network-request', message: req })); + this.logger.debug('WebTransport', () => ({ messageType: 'network-request', message: req })); return this.sendRequest(request, cancellation) .then((response): Promise<[Response, ArrayBuffer]> | [Response, ArrayBuffer] => @@ -161,7 +155,7 @@ export class WebTransport implements Transport { const transportResponse: TransportResponse = { status, url: request.url, headers, body }; - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('WebTransport', () => ({ messageType: 'network-response', message: transportResponse, })); @@ -175,14 +169,14 @@ export class WebTransport implements Transport { let fetchError = typeof error === 'string' ? new Error(error) : (error as Error); if (errorMessage.includes('timeout')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('WebTransport', () => ({ messageType: 'network-request', message: req, details: 'Timeout', canceled: true, })); } else if (errorMessage.includes('cancel') || errorMessage.includes('abort')) { - this.logger.debug(this.constructor.name, () => ({ + this.logger.debug('WebTransport', () => ({ messageType: 'network-request', message: req, details: 'Aborted', @@ -192,14 +186,14 @@ export class WebTransport implements Transport { fetchError = new Error('Aborted'); fetchError.name = 'AbortError'; } else if (errorMessage.includes('network')) { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('WebTransport', () => ({ messageType: 'network-request', message: req, details: 'Network error', failed: true, })); } else { - this.logger.warn(this.constructor.name, () => ({ + this.logger.warn('WebTransport', () => ({ messageType: 'network-request', message: req, details: PubNubAPIError.create(fetchError).message, @@ -359,14 +353,14 @@ export class WebTransport implements Transport { const fileData = await file.toArrayBuffer(); formData.append('file', new Blob([fileData], { type: 'application/octet-stream' }), file.name); } catch (toBufferError) { - this.logger.warn(this.constructor.name, () => ({ messageType: 'error', message: toBufferError })); + this.logger.warn('WebTransport', () => ({ messageType: 'error', message: toBufferError })); try { const fileData = await file.toFileUri(); // @ts-expect-error React Native File Uri support. formData.append('file', fileData, file.name); } catch (toFileURLError) { - this.logger.error(this.constructor.name, () => ({ messageType: 'error', message: toFileURLError })); + this.logger.error('WebTransport', () => ({ messageType: 'error', message: toFileURLError })); } } @@ -386,7 +380,7 @@ export class WebTransport implements Transport { }); body = await new Response(bodyStream.pipeThrough(new CompressionStream('deflate'))).arrayBuffer(); - this.logger.trace(this.constructor.name, () => { + this.logger.trace('WebTransport', () => { const compressedSize = (body! as ArrayBuffer).byteLength; const ratio = (compressedSize / initialBodySize).toFixed(2); From 2f9bba11a2ed80006388c5b4c05d6df1cb2f9af2 Mon Sep 17 00:00:00 2001 From: Serhii Mamontov Date: Mon, 30 Jun 2025 15:22:47 +0200 Subject: [PATCH 2/5] refactor(dependencies): remove unused dependencies --- package-lock.json | 232 +--------------------------------------------- package.json | 4 - 2 files changed, 2 insertions(+), 234 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe7643706..0114b770e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,18 @@ { "name": "pubnub", - "version": "9.6.1", + "version": "9.6.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pubnub", - "version": "9.6.1", + "version": "9.6.2", "license": "SEE LICENSE IN LICENSE", "dependencies": { - "@jsonjoy.com/json-pack": "^1.2.0", - "@levischuck/tiny-cbor": "^0.3.1", "agentkeepalive": "^3.5.2", "buffer": "^6.0.3", "cbor-js": "^0.1.0", "cbor-sync": "^1.0.4", - "cbor-x": "^1.6.0", - "cborg": "^4.2.12", "fflate": "^0.8.2", "form-data": "^4.0.0", "lil-uuid": "^0.1.1", @@ -2200,84 +2196,6 @@ "node": ">=6.9.0" } }, - "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", - "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-darwin-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", - "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", - "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-arm64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", - "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-linux-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", - "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@cbor-extract/cbor-extract-win32-x64": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", - "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3581,66 +3499,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", - "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/util": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", - "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@levischuck/tiny-cbor": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.3.1.tgz", - "integrity": "sha512-0mqIFNx1SJBfpjuarq6cGPr1KLasCAfk93MT/rs4sfceffNZP+w7Rx3dqS7OonfmnFOZhaSNPtwUJGHV/8WmlQ==", - "license": "MIT" - }, "node_modules/@mswjs/interceptors": { "version": "0.38.3", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.38.3.tgz", @@ -5996,28 +5854,6 @@ "upper-case-first": "^2.0.2" } }, - "node_modules/cbor-extract": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", - "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.1.1" - }, - "bin": { - "download-cbor-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", - "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm": "2.2.0", - "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", - "@cbor-extract/cbor-extract-linux-x64": "2.2.0", - "@cbor-extract/cbor-extract-win32-x64": "2.2.0" - } - }, "node_modules/cbor-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cbor-js/-/cbor-js-0.1.0.tgz", @@ -6030,24 +5866,6 @@ "integrity": "sha512-GWlXN4wiz0vdWWXBU71Dvc1q3aBo0HytqwAZnXF1wOwjqNnDWA1vZ1gDMFLlqohak31VQzmhiYfiCX5QSSfagA==", "license": "MIT" }, - "node_modules/cbor-x": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", - "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", - "license": "MIT", - "optionalDependencies": { - "cbor-extract": "^2.2.0" - } - }, - "node_modules/cborg": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.2.12.tgz", - "integrity": "sha512-z126yLoavS75cdTuiKu61RC3Y3trqtDAgQRa5Q0dpHn1RmqhIedptWXKnk0lQ5yo/GmcV9myvIkzFgZ8GnqSog==", - "license": "Apache-2.0", - "bin": { - "cborg": "lib/bin.js" - } - }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", @@ -6746,16 +6564,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, "node_modules/di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", @@ -8256,15 +8064,6 @@ "ms": "^2.0.0" } }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", - "license": "MIT", - "engines": { - "node": ">=10.18" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -10639,21 +10438,6 @@ "node": ">= 6.13.0" } }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", - "license": "MIT", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -13407,18 +13191,6 @@ "node": ">=0.8" } }, - "node_modules/thingies": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", - "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", - "license": "Unlicense", - "engines": { - "node": ">=10.18" - }, - "peerDependencies": { - "tslib": "^2" - } - }, "node_modules/throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", diff --git a/package.json b/package.json index 484b6ccfe..b46f3061f 100644 --- a/package.json +++ b/package.json @@ -55,14 +55,10 @@ "messaging" ], "dependencies": { - "@jsonjoy.com/json-pack": "^1.2.0", - "@levischuck/tiny-cbor": "^0.3.1", "agentkeepalive": "^3.5.2", "buffer": "^6.0.3", "cbor-js": "^0.1.0", "cbor-sync": "^1.0.4", - "cbor-x": "^1.6.0", - "cborg": "^4.2.12", "fflate": "^0.8.2", "form-data": "^4.0.0", "lil-uuid": "^0.1.1", From d33af7b1a9c6c6a790122b9d6011b3ce28c7da24 Mon Sep 17 00:00:00 2001 From: Serhii Mamontov Date: Mon, 30 Jun 2025 15:56:21 +0200 Subject: [PATCH 3/5] fix(subscription): fix last subscription object unregister issue --- lib/core/pubnub-common.js | 6 +++++- lib/event-engine/index.js | 2 +- lib/transport/node-transport.js | 1 + src/core/pubnub-common.ts | 7 ++++++- src/event-engine/index.ts | 2 +- test/integration/endpoints/subscribe.test.ts | 5 +++++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/core/pubnub-common.js b/lib/core/pubnub-common.js index 9581f27ab..1b3b7effd 100644 --- a/lib/core/pubnub-common.js +++ b/lib/core/pubnub-common.js @@ -1073,8 +1073,12 @@ class PubNubCore { message: { subscription: subscription, subscriptions }, details: `Unregister event handle capable:`, })); - if (!subscriptions || subscriptions.length === 0) + if (!subscriptions || + subscriptions.length === 0 || + (subscriptions && subscription instanceof subscription_set_1.SubscriptionSet && subscriptions === subscriptions)) { + console.log(`~~~~> DELETED FROM STORAGE ${subscription.state.id}`); delete this.eventHandleCapable[subscription.state.id]; + } let subscriptionInput; if (!subscriptions || subscriptions.length === 0) { subscriptionInput = subscription.subscriptionInput(true); diff --git a/lib/event-engine/index.js b/lib/event-engine/index.js index a44f3be4b..a1b9d781e 100644 --- a/lib/event-engine/index.js +++ b/lib/event-engine/index.js @@ -136,7 +136,7 @@ class EventEngine { } } unsubscribeAll(isOffline = false) { - const channelGroups = this.getSubscribedChannels(); + const channelGroups = this.getSubscribedChannelGroups(); const channels = this.getSubscribedChannels(); this.channels = []; this.groups = []; diff --git a/lib/transport/node-transport.js b/lib/transport/node-transport.js index 9704f86e7..507be26e8 100644 --- a/lib/transport/node-transport.js +++ b/lib/transport/node-transport.js @@ -146,6 +146,7 @@ class NodeTransport { return transportResponse; }) .catch((error) => { + console.log(`~~~~~> ERROR: `, error); const errorMessage = (typeof error === 'string' ? error : error.message).toLowerCase(); let fetchError = typeof error === 'string' ? new Error(error) : error; if (errorMessage.includes('timeout')) { diff --git a/src/core/pubnub-common.ts b/src/core/pubnub-common.ts index a9cbbb446..5bab4068f 100644 --- a/src/core/pubnub-common.ts +++ b/src/core/pubnub-common.ts @@ -1493,7 +1493,12 @@ export class PubNubCore< details: `Unregister event handle capable:`, })); - if (!subscriptions || subscriptions.length === 0) delete this.eventHandleCapable[subscription.state.id]; + if ( + !subscriptions || + subscriptions.length === 0 || + (subscriptions && subscription instanceof SubscriptionSet && subscriptions === subscriptions) + ) + delete this.eventHandleCapable[subscription.state.id]; let subscriptionInput: SubscriptionInput; if (!subscriptions || subscriptions.length === 0) { diff --git a/src/event-engine/index.ts b/src/event-engine/index.ts index 7b8ab4bcf..9c47ac823 100644 --- a/src/event-engine/index.ts +++ b/src/event-engine/index.ts @@ -149,7 +149,7 @@ export class EventEngine { } unsubscribeAll(isOffline: boolean = false): void { - const channelGroups = this.getSubscribedChannels(); + const channelGroups = this.getSubscribedChannelGroups(); const channels = this.getSubscribedChannels(); this.channels = []; diff --git a/test/integration/endpoints/subscribe.test.ts b/test/integration/endpoints/subscribe.test.ts index e0c1b4611..9797b82a0 100644 --- a/test/integration/endpoints/subscribe.test.ts +++ b/test/integration/endpoints/subscribe.test.ts @@ -42,6 +42,7 @@ describe('subscribe endpoints', () => { // @ts-expect-error Force override default value. useRequestId: false, enableEventEngine: true, + logLevel: PubNub.LogLevel.Trace, // logVerbosity: true, }); }); @@ -395,6 +396,8 @@ describe('subscribe endpoints', () => { const connectionPromise = new Promise((resolve) => { pubnubWithEE.onStatus = (status) => { + console.log(`~~~~> STATUS:`); + console.dir(status, { depth: 10 }); if (status.category === PubNub.CATEGORIES.PNConnectedCategory) { pubnubWithEE.onStatus = undefined; resolve(); @@ -409,6 +412,8 @@ describe('subscribe endpoints', () => { const disconnectionPromise = new Promise((resolve) => { pubnubWithEE.onStatus = (status) => { + console.log(`~~~~> STATUS:`); + console.dir(status, { depth: 10 }); if (status.category === PubNub.CATEGORIES.PNDisconnectedCategory) { pubnubWithEE.onStatus = undefined; resolve(); From fef9e7b26b39e66bae0a8192f1c1bda895b5b66a Mon Sep 17 00:00:00 2001 From: Serhii Mamontov Date: Mon, 30 Jun 2025 16:15:19 +0200 Subject: [PATCH 4/5] refactor(cleanup): old files removal --- lib/entities/Channel.js | 18 -- lib/entities/Subscription.js | 308 ---------------------------------- lib/entities/channel.js | 34 ---- lib/entities/subscription.js | 309 ----------------------------------- 4 files changed, 669 deletions(-) delete mode 100644 lib/entities/Channel.js delete mode 100644 lib/entities/Subscription.js delete mode 100644 lib/entities/channel.js delete mode 100644 lib/entities/subscription.js diff --git a/lib/entities/Channel.js b/lib/entities/Channel.js deleted file mode 100644 index f71ab290d..000000000 --- a/lib/entities/Channel.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Channel = void 0; -const entity_1 = require("./entity"); -/** - * First-class objects which provides access to the channel-specific APIs. - */ -class Channel extends entity_1.Entity { - /** - * Get a unique channel name. - * - * @returns Channel name. - */ - get name() { - return this._nameOrId; - } -} -exports.Channel = Channel; diff --git a/lib/entities/Subscription.js b/lib/entities/Subscription.js deleted file mode 100644 index 1fe1e027c..000000000 --- a/lib/entities/Subscription.js +++ /dev/null @@ -1,308 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Subscription = void 0; -const subscription_capable_1 = require("./interfaces/subscription-capable"); -const subscription_1 = require("../core/types/api/subscription"); -const subscription_base_1 = require("./subscription-base"); -const subscription_set_1 = require("./subscription-set"); -const utils_1 = require("../core/utils"); -/** - * {@link Subscription} state object. - * - * State object used across multiple {@link Subscription} object clones. - * - * @internal - */ -class SubscriptionState extends subscription_base_1.SubscriptionBaseState { - /** - * Create a subscription state object. - * - * @param parameters - State configuration options - * @param parameters.client - PubNub client which will work with a subscription object. - * @param parameters.entity - Entity for which a subscription object has been created. - * @param [parameters.options] - Subscription behavior options. - */ - constructor(parameters) { - var _a, _b; - const names = parameters.entity.subscriptionNames((_b = (_a = parameters.options) === null || _a === void 0 ? void 0 : _a.receivePresenceEvents) !== null && _b !== void 0 ? _b : false); - const subscriptionInput = new subscription_1.SubscriptionInput({ - [parameters.entity.subscriptionType == subscription_capable_1.SubscriptionType.Channel ? 'channels' : 'channelGroups']: names, - }); - super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); - this.entity = parameters.entity; - } -} -/** - * Single-entity subscription object which can be used to receive and handle real-time updates. - */ -class Subscription extends subscription_base_1.SubscriptionBase { - /** - * Create a subscribing capable object for entity. - * - * @param parameters - Subscription object configuration. - * - * @internal - */ - constructor(parameters) { - if ('client' in parameters) { - parameters.client.logger.debug('Subscription', () => ({ - messageType: 'object', - details: 'Create subscription with parameters:', - message: Object.assign({ entity: parameters.entity }, (parameters.options ? parameters.options : {})), - })); - } - else - parameters.state.client.logger.debug('Subscription', 'Create subscription clone'); - super('state' in parameters ? parameters.state : new SubscriptionState(parameters)); - /** - * List of subscription {@link SubscriptionSet sets} which contains {@link Subscription subscription}. - * - * List if used to track usage of a specific {@link Subscription subscription} in other subscription - * {@link SubscriptionSet sets}. - * - * **Important:** Tracking is required to prevent cloned instance dispose if there are sets that still use it. - * - * @internal - */ - this.parents = []; - /** - * List of fingerprints from updates which has been handled already. - * - * **Important:** Tracking is required to avoid repetitive call of the subscription object's listener when the object - * is part of multiple subscribed sets. Handler will be called once, and then the fingerprint will be stored in this - * list to avoid another listener call for it. - * - * @internal - */ - this.handledUpdates = []; - this.state.storeClone(this.id, this); - } - /** - * Get a {@link Subscription} object state. - * - * @returns: {@link Subscription} object state. - * - * @internal - */ - get state() { - return super.state; - } - /** - * Get number of {@link SubscriptionSet} which use this subscription object. - * - * @returns Number of {@link SubscriptionSet} which use this subscription object. - * - * @internal - */ - get parentSetsCount() { - return this.parents.length; - } - // -------------------------------------------------------- - // -------------------- Event handler --------------------- - // -------------------------------------------------------- - // region Event handler - /** - * Dispatch received a real-time update. - * - * @param cursor - A time cursor for the next portion of events. - * @param event - A real-time event from multiplexed subscription. - * - * @return `true` if receiver has consumed event. - * - * @internal - */ - handleEvent(cursor, event) { - var _a; - if (!this.state.isSubscribed) - return; - if (this.parentSetsCount > 0) { - const fingerprint = (0, utils_1.messageFingerprint)(event.data); - if (this.handledUpdates.includes(fingerprint)) { - this.state.client.logger.trace(this.constructor.name, `Message (${fingerprint}) already handled. Ignoring.`); - return; - } - // Update a list of tracked messages and shrink it if too big. - this.handledUpdates.push(fingerprint); - if (this.handledUpdates.length > 10) - this.handledUpdates.shift(); - } - // Check whether an event is not designated for this subscription set. - if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) - return; - super.handleEvent(cursor, event); - } - // endregion - /** - * User-provided subscription input associated with this {@link Subscription} object. - * - * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). - * - * @returns Subscription input object. - * - * @internal - */ - subscriptionInput(forUnsubscribe = false) { - if (forUnsubscribe && this.state.entity.subscriptionsCount > 0) - return new subscription_1.SubscriptionInput({}); - return this.state.subscriptionInput; - } - /** - * Make a bare copy of the {@link Subscription} object. - * - * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as - * the source object. - * - * @returns Bare copy of a {@link Subscription} object. - */ - cloneEmpty() { - return new Subscription({ state: this.state }); - } - /** - * Graceful {@link Subscription} object destruction. - * - * This is an instance destructor, which will properly deinitialize it: - * - remove and unset all listeners, - * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). - * - * **Important:** {@link Subscription#dispose dispose} won't have any effect if a subscription object is part of - * {@link SubscriptionSet set}. To gracefully dispose an object, it should be removed from the set using - * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of - * {@link Subscription#dispose dispose} not required). - * - * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. - */ - dispose() { - if (this.parentSetsCount > 0) { - this.state.client.logger.debug(this.constructor.name, () => ({ - messageType: 'text', - message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, - })); - return; - } - this.handledUpdates.splice(0, this.handledUpdates.length); - super.dispose(); - } - /** - * Invalidate subscription object. - * - * Clean up resources used by a subscription object. - * - * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. - * - * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. - * - * @internal - */ - invalidate(forDestroy = false) { - if (forDestroy) - this.state.entity.decreaseSubscriptionCount(this.state.id); - this.handledUpdates.splice(0, this.handledUpdates.length); - super.invalidate(forDestroy); - } - /** - * Add another {@link SubscriptionSet} into which subscription has been added. - * - * @param parent - {@link SubscriptionSet} which has been modified. - * - * @internal - */ - addParentSet(parent) { - if (!this.parents.includes(parent)) { - this.parents.push(parent); - this.state.client.logger.trace(this.constructor.name, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); - } - } - /** - * Remove {@link SubscriptionSet} upon subscription removal from it. - * - * @param parent - {@link SubscriptionSet} which has been modified. - * - * @internal - */ - removeParentSet(parent) { - const parentIndex = this.parents.indexOf(parent); - if (parentIndex !== -1) { - this.parents.splice(parentIndex, 1); - this.state.client.logger.trace(this.constructor.name, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); - } - if (this.parentSetsCount === 0) - this.handledUpdates.splice(0, this.handledUpdates.length); - } - /** - * Merge entities' subscription objects into {@link SubscriptionSet}. - * - * @param subscription - Another entity's subscription object to be merged with receiver. - * - * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. - */ - addSubscription(subscription) { - this.state.client.logger.debug(this.constructor.name, () => ({ - messageType: 'text', - message: `Create set with subscription: ${subscription}`, - })); - const subscriptionSet = new subscription_set_1.SubscriptionSet({ - client: this.state.client, - subscriptions: [this, subscription], - options: this.state.options, - }); - // Check whether a source subscription is already subscribed or not. - if (!this.state.isSubscribed && !subscription.state.isSubscribed) - return subscriptionSet; - this.state.client.logger.trace(this.constructor.name, 'Subscribe resulting set because the receiver is already subscribed.'); - // Subscribing resulting subscription set because source subscription was subscribed. - subscriptionSet.subscribe(); - return subscriptionSet; - } - /** - * Register {@link Subscription} object for real-time events' retrieval. - * - * **Note:** Superclass calls this method only in response to a {@link Subscription.subscribe subscribe} method call. - * - * @param parameters - Object registration parameters. - * @param [parameters.cursor] - Subscription real-time events catch-up cursor. - * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial - * modification). - * - * @internal - */ - register(parameters) { - this.state.entity.increaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Register subscription for real-time events: ${this}`, - })); - this.state.client.registerEventHandleCapable(this, parameters.cursor); - } - /** - * Unregister {@link Subscription} object from real-time events' retrieval. - * - * **Note:** Superclass calls this method only in response to a {@link Subscription.unsubscribe unsubscribe} method - * call. - * - * @param [_subscriptions] - List of subscription objects which should be unregistered (in case of partial - * modification). - * - * @internal - */ - unregister(_subscriptions) { - this.state.entity.decreaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.constructor.name, () => ({ - messageType: 'text', - message: `Unregister subscription from real-time events: ${this}`, - })); - this.handledUpdates.splice(0, this.handledUpdates.length); - this.state.client.unregisterEventHandleCapable(this); - } - /** - * Stringify subscription object. - * - * @returns Serialized subscription object. - */ - toString() { - const state = this.state; - return `${this.constructor.name} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity - .subscriptionNames(false) - .pop()}, clonesCount: ${Object.keys(state.clones).length}, isSubscribed: ${state.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${state.cursor ? state.cursor.timetoken : 'not set'}, referenceTimetoken: ${state.referenceTimetoken ? state.referenceTimetoken : 'not set'} }`; - } -} -exports.Subscription = Subscription; diff --git a/lib/entities/channel.js b/lib/entities/channel.js deleted file mode 100644 index 61452410e..000000000 --- a/lib/entities/channel.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Channel = void 0; -const entity_1 = require("./entity"); -/** - * First-class objects which provides access to the channel-specific APIs. - */ -class Channel extends entity_1.Entity { - /** - * Retrieve entity type. - * - * There is four types: - * - Channel - * - ChannelGroups - * - ChannelMetadata - * - UserMetadata - * - * @return One of known entity types. - * - * @internal - */ - get entityType() { - return 'Channel'; - } - /** - * Get a unique channel name. - * - * @returns Channel name. - */ - get name() { - return this._nameOrId; - } -} -exports.Channel = Channel; diff --git a/lib/entities/subscription.js b/lib/entities/subscription.js deleted file mode 100644 index d57260421..000000000 --- a/lib/entities/subscription.js +++ /dev/null @@ -1,309 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Subscription = void 0; -const subscription_capable_1 = require("./interfaces/subscription-capable"); -const subscription_1 = require("../core/types/api/subscription"); -const subscription_base_1 = require("./subscription-base"); -const subscription_set_1 = require("./subscription-set"); -const utils_1 = require("../core/utils"); -/** - * {@link Subscription} state object. - * - * State object used across multiple {@link Subscription} object clones. - * - * @internal - */ -class SubscriptionState extends subscription_base_1.SubscriptionBaseState { - /** - * Create a subscription state object. - * - * @param parameters - State configuration options - * @param parameters.client - PubNub client which will work with a subscription object. - * @param parameters.entity - Entity for which a subscription object has been created. - * @param [parameters.options] - Subscription behavior options. - */ - constructor(parameters) { - var _a, _b; - const names = parameters.entity.subscriptionNames((_b = (_a = parameters.options) === null || _a === void 0 ? void 0 : _a.receivePresenceEvents) !== null && _b !== void 0 ? _b : false); - const subscriptionInput = new subscription_1.SubscriptionInput({ - [parameters.entity.subscriptionType == subscription_capable_1.SubscriptionType.Channel ? 'channels' : 'channelGroups']: names, - }); - super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); - this.entity = parameters.entity; - } -} -/** - * Single-entity subscription object which can be used to receive and handle real-time updates. - */ -class Subscription extends subscription_base_1.SubscriptionBase { - /** - * Create a subscribing capable object for entity. - * - * @param parameters - Subscription object configuration. - * - * @internal - */ - constructor(parameters) { - if ('client' in parameters) { - parameters.client.logger.debug('Subscription', () => ({ - messageType: 'object', - details: 'Create subscription with parameters:', - message: Object.assign({ entity: parameters.entity }, (parameters.options ? parameters.options : {})), - })); - } - else - parameters.state.client.logger.debug('Subscription', 'Create subscription clone'); - super('state' in parameters ? parameters.state : new SubscriptionState(parameters)); - /** - * List of subscription {@link SubscriptionSet sets} which contains {@link Subscription subscription}. - * - * List if used to track usage of a specific {@link Subscription subscription} in other subscription - * {@link SubscriptionSet sets}. - * - * **Important:** Tracking is required to prevent cloned instance dispose if there are sets that still use it. - * - * @internal - */ - this.parents = []; - /** - * List of fingerprints from updates which has been handled already. - * - * **Important:** Tracking is required to avoid repetitive call of the subscription object's listener when the object - * is part of multiple subscribed sets. Handler will be called once, and then the fingerprint will be stored in this - * list to avoid another listener call for it. - * - * @internal - */ - this.handledUpdates = []; - this.state.storeClone(this.id, this); - } - /** - * Get a {@link Subscription} object state. - * - * @returns: {@link Subscription} object state. - * - * @internal - */ - get state() { - return super.state; - } - /** - * Get number of {@link SubscriptionSet} which use this subscription object. - * - * @returns Number of {@link SubscriptionSet} which use this subscription object. - * - * @internal - */ - get parentSetsCount() { - return this.parents.length; - } - // -------------------------------------------------------- - // -------------------- Event handler --------------------- - // -------------------------------------------------------- - // region Event handler - /** - * Dispatch received a real-time update. - * - * @param cursor - A time cursor for the next portion of events. - * @param event - A real-time event from multiplexed subscription. - * - * @return `true` if receiver has consumed event. - * - * @internal - */ - handleEvent(cursor, event) { - var _a; - if (!this.state.isSubscribed) - return; - if (this.parentSetsCount > 0) { - // Creating from whole payload (not only for published messages). - const fingerprint = (0, utils_1.messageFingerprint)(event.data); - if (this.handledUpdates.includes(fingerprint)) { - this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled. Ignoring.`); - return; - } - // Update a list of tracked messages and shrink it if too big. - this.handledUpdates.push(fingerprint); - if (this.handledUpdates.length > 10) - this.handledUpdates.shift(); - } - // Check whether an event is not designated for this subscription set. - if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) - return; - super.handleEvent(cursor, event); - } - // endregion - /** - * User-provided subscription input associated with this {@link Subscription} object. - * - * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). - * - * @returns Subscription input object. - * - * @internal - */ - subscriptionInput(forUnsubscribe = false) { - if (forUnsubscribe && this.state.entity.subscriptionsCount > 0) - return new subscription_1.SubscriptionInput({}); - return this.state.subscriptionInput; - } - /** - * Make a bare copy of the {@link Subscription} object. - * - * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as - * the source object. - * - * @returns Bare copy of a {@link Subscription} object. - */ - cloneEmpty() { - return new Subscription({ state: this.state }); - } - /** - * Graceful {@link Subscription} object destruction. - * - * This is an instance destructor, which will properly deinitialize it: - * - remove and unset all listeners, - * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). - * - * **Important:** {@link Subscription#dispose dispose} won't have any effect if a subscription object is part of - * {@link SubscriptionSet set}. To gracefully dispose an object, it should be removed from the set using - * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of - * {@link Subscription#dispose dispose} not required). - * - * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. - */ - dispose() { - if (this.parentSetsCount > 0) { - this.state.client.logger.debug(this.subscriptionType, () => ({ - messageType: 'text', - message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, - })); - return; - } - this.handledUpdates.splice(0, this.handledUpdates.length); - super.dispose(); - } - /** - * Invalidate subscription object. - * - * Clean up resources used by a subscription object. - * - * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. - * - * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. - * - * @internal - */ - invalidate(forDestroy = false) { - if (forDestroy) - this.state.entity.decreaseSubscriptionCount(this.state.id); - this.handledUpdates.splice(0, this.handledUpdates.length); - super.invalidate(forDestroy); - } - /** - * Add another {@link SubscriptionSet} into which subscription has been added. - * - * @param parent - {@link SubscriptionSet} which has been modified. - * - * @internal - */ - addParentSet(parent) { - if (!this.parents.includes(parent)) { - this.parents.push(parent); - this.state.client.logger.trace(this.subscriptionType, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); - } - } - /** - * Remove {@link SubscriptionSet} upon subscription removal from it. - * - * @param parent - {@link SubscriptionSet} which has been modified. - * - * @internal - */ - removeParentSet(parent) { - const parentIndex = this.parents.indexOf(parent); - if (parentIndex !== -1) { - this.parents.splice(parentIndex, 1); - this.state.client.logger.trace(this.subscriptionType, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); - } - if (this.parentSetsCount === 0) - this.handledUpdates.splice(0, this.handledUpdates.length); - } - /** - * Merge entities' subscription objects into {@link SubscriptionSet}. - * - * @param subscription - Another entity's subscription object to be merged with receiver. - * - * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. - */ - addSubscription(subscription) { - this.state.client.logger.debug(this.subscriptionType, () => ({ - messageType: 'text', - message: `Create set with subscription: ${subscription}`, - })); - const subscriptionSet = new subscription_set_1.SubscriptionSet({ - client: this.state.client, - subscriptions: [this, subscription], - options: this.state.options, - }); - // Check whether a source subscription is already subscribed or not. - if (!this.state.isSubscribed && !subscription.state.isSubscribed) - return subscriptionSet; - this.state.client.logger.trace(this.subscriptionType, 'Subscribe resulting set because the receiver is already subscribed.'); - // Subscribing resulting subscription set because source subscription was subscribed. - subscriptionSet.subscribe(); - return subscriptionSet; - } - /** - * Register {@link Subscription} object for real-time events' retrieval. - * - * **Note:** Superclass calls this method only in response to a {@link Subscription.subscribe subscribe} method call. - * - * @param parameters - Object registration parameters. - * @param [parameters.cursor] - Subscription real-time events catch-up cursor. - * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial - * modification). - * - * @internal - */ - register(parameters) { - this.state.entity.increaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.subscriptionType, () => ({ - messageType: 'text', - message: `Register subscription for real-time events: ${this}`, - })); - this.state.client.registerEventHandleCapable(this, parameters.cursor); - } - /** - * Unregister {@link Subscription} object from real-time events' retrieval. - * - * **Note:** Superclass calls this method only in response to a {@link Subscription.unsubscribe unsubscribe} method - * call. - * - * @param [_subscriptions] - List of subscription objects which should be unregistered (in case of partial - * modification). - * - * @internal - */ - unregister(_subscriptions) { - this.state.entity.decreaseSubscriptionCount(this.state.id); - this.state.client.logger.trace(this.subscriptionType, () => ({ - messageType: 'text', - message: `Unregister subscription from real-time events: ${this}`, - })); - this.handledUpdates.splice(0, this.handledUpdates.length); - this.state.client.unregisterEventHandleCapable(this); - } - /** - * Stringify subscription object. - * - * @returns Serialized subscription object. - */ - toString() { - const state = this.state; - return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity - .subscriptionNames(false) - .pop()}, clonesCount: ${Object.keys(state.clones).length}, isSubscribed: ${state.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${state.cursor ? state.cursor.timetoken : 'not set'}, referenceTimetoken: ${state.referenceTimetoken ? state.referenceTimetoken : 'not set'} }`; - } -} -exports.Subscription = Subscription; From 0908a90115fad1f4403566c6a1c28ec3608721b0 Mon Sep 17 00:00:00 2001 From: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:46:47 +0000 Subject: [PATCH 5/5] PubNub SDK v9.7.0 release. --- .pubnub.yml | 19 +- CHANGELOG.md | 14 ++ README.md | 4 +- dist/web/pubnub.js | 8 +- dist/web/pubnub.min.js | 4 +- lib/core/components/configuration.js | 2 +- lib/core/pubnub-common.js | 4 +- lib/entities/channel.js | 34 +++ lib/entities/subscription.js | 309 +++++++++++++++++++++++++++ lib/transport/node-transport.js | 1 - package.json | 2 +- src/core/components/configuration.ts | 2 +- 12 files changed, 386 insertions(+), 17 deletions(-) create mode 100644 lib/entities/channel.js create mode 100644 lib/entities/subscription.js diff --git a/.pubnub.yml b/.pubnub.yml index c37c75d49..100dfe0ca 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,5 +1,18 @@ --- changelog: + - date: 2025-06-30 + version: v9.7.0 + changes: + - type: feature + text: "Launch a backup heartbeat timer per registered PubNub instance in SharedWorker context to protect against browsers throttling of background (hidden) tabs." + - type: bug + text: "Fix issue because of which in new flow `heartbeat` request not cancelled properly when issued in burst." + - type: bug + text: "Fix issue because resource names, which consist only of integers, have been decoded as Unicode characters." + - type: bug + text: "Fix issue because the entity that has been created with `-pnpres` suffix has been removed from subscription loop during unsubscribe from entity with presence listening capability." + - type: improvement + text: "Use string names of classes for locations instead of dynamic access to constructor names because it affect how logs looks like after minification." - date: 2025-06-30 version: v9.6.2 changes: @@ -1263,7 +1276,7 @@ supported-platforms: - 'Ubuntu 14.04 and up' - 'Windows 7 and up' version: 'Pubnub Javascript for Node' -version: '9.6.2' +version: '9.7.0' sdks: - full-name: PubNub Javascript SDK short-name: Javascript @@ -1279,7 +1292,7 @@ sdks: - distribution-type: source distribution-repository: GitHub release package-name: pubnub.js - location: https://github.com/pubnub/javascript/archive/refs/tags/v9.6.2.zip + location: https://github.com/pubnub/javascript/archive/refs/tags/v9.7.0.zip requires: - name: 'agentkeepalive' min-version: '3.5.2' @@ -1950,7 +1963,7 @@ sdks: - distribution-type: library distribution-repository: GitHub release package-name: pubnub.js - location: https://github.com/pubnub/javascript/releases/download/v9.6.2/pubnub.9.6.2.js + location: https://github.com/pubnub/javascript/releases/download/v9.7.0/pubnub.9.7.0.js requires: - name: 'agentkeepalive' min-version: '3.5.2' diff --git a/CHANGELOG.md b/CHANGELOG.md index c2d1c4f27..29f4c3ee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## v9.7.0 +June 30 2025 + +#### Added +- Launch a backup heartbeat timer per registered PubNub instance in SharedWorker context to protect against browsers throttling of background (hidden) tabs. + +#### Fixed +- Fix issue because of which in new flow `heartbeat` request not cancelled properly when issued in burst. +- Fix issue because resource names, which consist only of integers, have been decoded as Unicode characters. +- Fix issue because the entity that has been created with `-pnpres` suffix has been removed from subscription loop during unsubscribe from entity with presence listening capability. + +#### Modified +- Use string names of classes for locations instead of dynamic access to constructor names because it affect how logs looks like after minification. + ## v9.6.2 June 30 2025 diff --git a/README.md b/README.md index 364ab4c0d..302d3f29e 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Watch [Getting Started with PubNub JS SDK](https://app.dashcam.io/replay/64ee0d2 npm install pubnub ``` * or download one of our builds from our CDN: - * https://cdn.pubnub.com/sdk/javascript/pubnub.9.6.2.js - * https://cdn.pubnub.com/sdk/javascript/pubnub.9.6.2.min.js + * https://cdn.pubnub.com/sdk/javascript/pubnub.9.7.0.js + * https://cdn.pubnub.com/sdk/javascript/pubnub.9.7.0.min.js 2. Configure your keys: diff --git a/dist/web/pubnub.js b/dist/web/pubnub.js index 98c1b14c6..b868b154f 100644 --- a/dist/web/pubnub.js +++ b/dist/web/pubnub.js @@ -4962,7 +4962,7 @@ return base.PubNubFile; }, get version() { - return '9.6.2'; + return '9.7.0'; }, getVersion() { return this.version; @@ -9328,7 +9328,7 @@ } } unsubscribeAll(isOffline = false) { - const channelGroups = this.getSubscribedChannels(); + const channelGroups = this.getSubscribedChannelGroups(); const channels = this.getSubscribedChannels(); this.channels = []; this.groups = []; @@ -15896,7 +15896,9 @@ message: { subscription: subscription, subscriptions }, details: `Unregister event handle capable:`, })); - if (!subscriptions || subscriptions.length === 0) + if (!subscriptions || + subscriptions.length === 0 || + (subscriptions && subscription instanceof SubscriptionSet && subscriptions === subscriptions)) delete this.eventHandleCapable[subscription.state.id]; let subscriptionInput; if (!subscriptions || subscriptions.length === 0) { diff --git a/dist/web/pubnub.min.js b/dist/web/pubnub.min.js index b6d67ddc1..d2b4b1b46 100644 --- a/dist/web/pubnub.min.js +++ b/dist/web/pubnub.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),h(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function y(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var m=function e(){var r,d,m=l(),f=m>>5,v=31&m;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)w+=d,S.push(u(d));var O=new Uint8Array(w),k=0;for(r=0;r=0;)y(C,d);else y(C,d);return String.fromCharCode.apply(null,C);case 4:var j;if(d<0)for(j=[];!p();)j.push(e());else for(j=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==i?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==i&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,y,m,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),h=l,l=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),y=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=y.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=S,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],l=(o=e[i+1],e[i+2]),h=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],y=e[i+8],m=e[i+9],f=e[i+10],v=e[i+11],S=e[i+12],w=e[i+13],O=e[i+14],k=e[i+15],C=t(C=a[0],E=a[1],P=a[2],j=a[3],c,7,u[0]),j=t(j,C,E,P,o,12,u[1]),P=t(P,j,C,E,l,17,u[2]),E=t(E,P,j,C,h,22,u[3]);C=t(C,E,P,j,d,7,u[4]),j=t(j,C,E,P,p,12,u[5]),P=t(P,j,C,E,g,17,u[6]),E=t(E,P,j,C,b,22,u[7]),C=t(C,E,P,j,y,7,u[8]),j=t(j,C,E,P,m,12,u[9]),P=t(P,j,C,E,f,17,u[10]),E=t(E,P,j,C,v,22,u[11]),C=t(C,E,P,j,S,7,u[12]),j=t(j,C,E,P,w,12,u[13]),P=t(P,j,C,E,O,17,u[14]),C=s(C,E=t(E,P,j,C,k,22,u[15]),P,j,o,5,u[16]),j=s(j,C,E,P,g,9,u[17]),P=s(P,j,C,E,v,14,u[18]),E=s(E,P,j,C,c,20,u[19]),C=s(C,E,P,j,p,5,u[20]),j=s(j,C,E,P,f,9,u[21]),P=s(P,j,C,E,k,14,u[22]),E=s(E,P,j,C,d,20,u[23]),C=s(C,E,P,j,m,5,u[24]),j=s(j,C,E,P,O,9,u[25]),P=s(P,j,C,E,h,14,u[26]),E=s(E,P,j,C,y,20,u[27]),C=s(C,E,P,j,w,5,u[28]),j=s(j,C,E,P,l,9,u[29]),P=s(P,j,C,E,b,14,u[30]),C=n(C,E=s(E,P,j,C,S,20,u[31]),P,j,p,4,u[32]),j=n(j,C,E,P,y,11,u[33]),P=n(P,j,C,E,v,16,u[34]),E=n(E,P,j,C,O,23,u[35]),C=n(C,E,P,j,o,4,u[36]),j=n(j,C,E,P,d,11,u[37]),P=n(P,j,C,E,b,16,u[38]),E=n(E,P,j,C,f,23,u[39]),C=n(C,E,P,j,w,4,u[40]),j=n(j,C,E,P,c,11,u[41]),P=n(P,j,C,E,h,16,u[42]),E=n(E,P,j,C,g,23,u[43]),C=n(C,E,P,j,m,4,u[44]),j=n(j,C,E,P,S,11,u[45]),P=n(P,j,C,E,k,16,u[46]),C=r(C,E=n(E,P,j,C,l,23,u[47]),P,j,c,6,u[48]),j=r(j,C,E,P,b,10,u[49]),P=r(P,j,C,E,O,15,u[50]),E=r(E,P,j,C,p,21,u[51]),C=r(C,E,P,j,S,6,u[52]),j=r(j,C,E,P,h,10,u[53]),P=r(P,j,C,E,f,15,u[54]),E=r(E,P,j,C,o,21,u[55]),C=r(C,E,P,j,y,6,u[56]),j=r(j,C,E,P,k,10,u[57]),P=r(P,j,C,E,g,15,u[58]),E=r(E,P,j,C,w,21,u[59]),C=r(C,E,P,j,d,6,u[60]),j=r(j,C,E,P,v,10,u[61]),P=r(P,j,C,E,l,15,u[62]),E=r(E,P,j,C,m,21,u[63]);a[0]=a[0]+C|0,a[1]=a[1]+E|0,a[2]=a[2]+P|0,a[3]=a[3]+j|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,l.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,y=0;for(g=0;256>g;g++){var m=(m=y^y<<1^y<<2^y<<3^y<<4)>>>8^255&m^99;n[b]=m,r[m]=b;var f=p[b],v=p[f],w=p[v],O=257*p[m]^16843008*m;i[b]=O<<24|O>>>8,a[b]=O<<16|O>>>16,o[b]=O<<8|O>>>24,c[b]=O,O=16843009*w^65537*v^257*f^16843008*b,u[m]=O<<24|O>>>8,l[m]=O<<16|O>>>16,h[m]=O<<8|O>>>24,d[m]=O,b?(b=f^p[p[p[w^f]]],y^=p[p[y]]):b=y=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[l>>>16&255]^i[h>>>8&255]^a[255&d]^s[p++],y=n[l>>>24]^r[h>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],m=n[h>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[l>>>8&255]^a[255&h]^s[p++],u=b,l=y,h=m}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],y=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],m=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=y,e[t+2]=m,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var w=t(S);class O{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=w,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:O.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return O.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(O.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=O.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e})))}get logger(){return this._logger}HMACSHA256(e){return w.HmacSHA256(e,this.configuration.secretKey).toString(w.enc.Base64)}SHA256(e){return w.SHA256(e).toString(w.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Encrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=w.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(w.enc.Base64)}const a=this.getIV(s);return w.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(w.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Decrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=k(t.slice(0,16)),n=k(t.slice(16));try{const e=w.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(w.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=w.enc.Base64.parse(e),n=w.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(w.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?w.enc.Base64.parse(e):"hex"===t.keyEncoding?w.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?w.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?w.mode.ECB:w.mode.CBC}getIV(e){return"cbc"===e.mode?w.enc.Utf8.parse(this.iv):null}getRandomIV(){return w.lib.WordArray.random(16)}}class j{encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=j.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return j.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(j.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(j.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=j.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return j.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",j.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=j.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}j.IV_LENGTH=16,j.encoder=new TextEncoder,j.decoder=new TextDecoder;class P{constructor(e){this.config=e,this.cryptor=new C(Object.assign({},e)),this.fileCryptor=new j}set logger(e){this.cryptor.logger=e}encrypt(e){const t="string"==typeof e?e:P.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`AesCbcCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}P.encoder=new TextEncoder,P.decoder=new TextDecoder;class E extends a{set logger(e){if(this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER)this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===E.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new P(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new O({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new O({cipherKey:e.cipherKey}),cryptors:[new P(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(E.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=N.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=N.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===N.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof T)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=N.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}E.LEGACY_IDENTIFIER="";class N{static from(e,t){if(e!==N.LEGACY_IDENTIFIER)return new T(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==N.SENTINEL))return E.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>N.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+N.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new T(this.decoder.decode(n),a)}}N.SENTINEL="PNED",N.LEGACY_IDENTIFIER="",N.IDENTIFIER_LENGTH=4,N.VERSION=1,N.MAX_VERSION=1,N.decoder=new TextDecoder;class T{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return N.VERSION}get length(){return N.SENTINEL.length+1+N.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(N.SENTINEL)),e+=N.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=N.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}T.IDENTIFIER_LENGTH=4,T.SENTINEL="PNED";class _ extends Error{static create(e,t){return _.isErrorObject(e)?_.createFromError(e):_.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new _(s,t,0);if(e instanceof _)return e;if(_.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new _(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":400===i?(n=h.PNBadRequestCategory,r="Bad request"):403===i&&(n=h.PNAccessDeniedCategory,r="Access denied"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);"object"==typeof e&&(Array.isArray(e)?"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]):("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e?(s=e,i=e.status):s=e,"error"in e&&e.error instanceof Error&&(s=e.error)))}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new _(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,_.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}class I{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.token=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogVerbosity:this.configuration.workerLogVerbosity},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e)}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",t.message);else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t})}else if("request-process-success"===t.type||"request-process-error"===t.type){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);if("request-process-success"===t.type)e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body});else{let e=h.PNUnknownCategory,n="Unknown error";if(t.error)"NETWORK_ISSUE"===t.error.type?e=h.PNNetworkIssuesCategory:"TIMEOUT"===t.error.type?e=h.PNTimeoutCategory:"ABORTED"===t.error.type&&(e=h.PNCancelledCategory),n=`${t.error.message} (${t.identifier})`;else if(t.response)return s(_.create({url:t.url,headers:t.response.headers,body:t.response.body,status:t.response.status},t.response.body));s(new _(n,e,0,new Error(n)))}}}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;const s=e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0;if(s)return this.accessTokensMap[s]?this.accessTokensMap[s]:this.stringifyAccessToken(s).then((([e,t])=>{if(e&&t)return(this.accessTokensMap={[s]:{token:t,expiration:e.timestamp*e.ttl*60}})[s]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}}function M(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const r={};return Object.keys(e).forEach((i=>{const a=(e=>"string"==typeof e||e instanceof String)(i);let o=i;const c=e[i];if(t<2)if(a&&i.indexOf(",")>=0){o=i.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(i)||a&&!isNaN(Number(i)))&&(o=String.fromCharCode(n(i)?i:parseInt(i,10)));r[o]=s(c)?M(c,t+1):c})),r}const A=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,l,h,p,g,b,y;const m=Object.assign({},e);if(null!==(t=m.ssl)&&void 0!==t||(m.ssl=!0),null!==(s=m.transactionalRequestTimeout)&&void 0!==s||(m.transactionalRequestTimeout=15),null!==(n=m.subscribeRequestTimeout)&&void 0!==n||(m.subscribeRequestTimeout=310),null!==(r=m.fileRequestTimeout)&&void 0!==r||(m.fileRequestTimeout=300),null!==(i=m.restore)&&void 0!==i||(m.restore=!1),null!==(a=m.useInstanceId)&&void 0!==a||(m.useInstanceId=!1),null!==(o=m.suppressLeaveEvents)&&void 0!==o||(m.suppressLeaveEvents=!1),null!==(c=m.requestMessageCountThreshold)&&void 0!==c||(m.requestMessageCountThreshold=100),null!==(u=m.autoNetworkDetection)&&void 0!==u||(m.autoNetworkDetection=!1),null!==(l=m.enableEventEngine)&&void 0!==l||(m.enableEventEngine=!1),null!==(h=m.maintainPresenceState)&&void 0!==h||(m.maintainPresenceState=!0),null!==(p=m.useSmartHeartbeat)&&void 0!==p||(m.useSmartHeartbeat=!1),null!==(g=m.keepAlive)&&void 0!==g||(m.keepAlive=!1),m.userId&&m.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=m.userId)&&void 0!==b||(m.userId=m.uuid),!m.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=m.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");m.origin||(m.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:m.subscribeKey,publishKey:m.publishKey,secretKey:m.secretKey};void 0!==m.presenceTimeout&&(m.presenceTimeout>320?(m.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):m.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete m.presenceTimeout)),void 0!==m.presenceTimeout?m.heartbeatInterval=m.presenceTimeout/2-1:m.presenceTimeout=300;let v=!1,S=!0,w=5,O=!1,k=100,C=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(O=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(C=m.useRequestId),void 0!==m.announceSuccessfulHeartbeats&&"boolean"==typeof m.announceSuccessfulHeartbeats&&(v=m.announceSuccessfulHeartbeats),void 0!==m.announceFailedHeartbeats&&"boolean"==typeof m.announceFailedHeartbeats&&(S=m.announceFailedHeartbeats),void 0!==m.fileUploadPublishRetryLimit&&"number"==typeof m.fileUploadPublishRetryLimit&&(w=m.fileUploadPublishRetryLimit),Object.assign(Object.assign({},m),{keySet:f,dedupeOnSubscribe:O,maximumCacheSize:k,useRequestId:C,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:S,fileUploadPublishRetryLimit:w})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var U;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(U||(U={}));const $=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),R=(e,t)=>{const s=e.map((e=>$(e)));return s.length?s.join(","):null!=t?t:""},F=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},D=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),x=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&"),q=(e,t)=>{if("0"===t||"0"===e)return;const s=K(`${Date.now()}0000`,t,!1);return K(e,s,!0)},G=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=K(e,t,!1);return K(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},K=(e,t,s)=>{t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0&&(o>0?(o-=1,c+=1e7):o<0&&(c*=-1)),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},L=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};class H{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}log(e){const t=U[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==U.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?x(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===U.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,r=!(e||h instanceof String||0!==Object.keys(h).length),a=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),c=i?"...":s?"[]":r?"{}":t(h,n+1,a);o.push(`${u}${d}:${i||a||s||r?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${h}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${H.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(H.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}var B;H.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(B||(B={}));class W{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return z(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry");if(this.maximumRetry>10)throw new Error("Maximum retry for linear retry policy can not be more than 10")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return z(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry");if(this.maximumDelay>150)throw new Error("Maximum delay can not be set more than 150 seconds for retry");if(this.maximumRetry>6)throw new Error("Maximum retry for exponential retry policy can not be more than 6")}}}}const z=(e,t,s,n,r,i)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!V(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),V=(e,t)=>!!(t&&t.length>0)&&t.includes(J(e)),J=e=>{let t=B.Unknown;return e.path.startsWith("/v2/subscribe")?t=B.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=B.MessageSend:e.path.startsWith("/v2/presence")?t=B.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=B.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=B.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=B.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=B.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=B.Files),t};class X{constructor(e,t,s){this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(U.Trace,e,t)}debug(e,t){this.log(U.Debug,e,t)}info(e,t){this.log(U.Info,e,t)}warn(e,t){this.log(U.Warn,e,t)}error(e,t){this.log(U.Error,e,t)}log(e,t,s){if(ee[n](r)))}}var Q={exports:{}}; -/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(Q,Q.exports);var Y=t(Q.exports),Z={createUUID:()=>Y.uuid?Y.uuid():Y()};const ee=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=W.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[B.MessageSend,B.Presence,B.Files,B.MessageStorage,B.ChannelGroups,B.DevicePushNotifications,B.AppContext,B.MessageReactions]}));const a=`pn-${Z.createUUID()}`;e.logVerbosity?e.logLevel=U.Debug:void 0===e.logLevel&&(e.logLevel=U.None);const o=new X(se(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new H]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate(),null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),e.useRandomIVs&&o.warn("Configuration","'useRandomIVs' is deprecated. Use 'cryptoModule' instead."),e.origin=te(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const c=e.cryptoModule;c&&delete e.cryptoModule;const u=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"9.6.2"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),u.setCipherKey(e.cipherKey)):c&&(u._cryptoModule=c),u},te=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},se=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class ne{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=r.length>0,d=i.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var re,ie;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(re||(re={}));class ae{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?re.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===re.POST||t===re.PATCH){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=ae.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&")}}ae.textDecoder=new TextDecoder("utf-8");class oe{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new ae(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[l,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==h.PNCancelledCategory,l=!s||s.status>=400;let d=-1;i&&l&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class ce{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"!==t||window&&window.fetch||(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(ce.originalFetch=fetch.bind(window),this.isFetchMonkeyPatched()&&(ce.originalFetch=ce.getOriginalFetch(),e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."),this.isFetchMonkeyPatched(ce.originalFetch)?e.warn("WebTransport","Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation"):e.info("WebTransport","Use native Web Fetch API 'fetch' implementation from iframe as APM workaround.")))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw _.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:_.create(n).message,failed:!0}))),_.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([ce.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(_.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?ce.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${x(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}ce.encoder=new TextEncoder,ce.decoder=new TextDecoder;class ue{constructor(e){this.params=e,this.requestIdentifier=Z.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:re.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===re.POST||a.method===re.PATCH){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=ue.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw _.create(e);return n}}ue.decoder=new TextDecoder,function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(ie||(ie={}));var le=ie;var he;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(he||(he={}));class de extends ue{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return le.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=ue.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;return null!=t||(t=e.c.endsWith("-pnpres")?he.Presence:he.Message),t!=he.Signal&&"string"==typeof e.d?t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}:t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:t===he.Presence?{type:he.Presence,data:this.presenceEventFromEnvelope(e)}:t==he.Signal?{type:he.Signal,data:this.signalFromEnvelope(e)}:t===he.AppContext?{type:he.AppContext,data:this.appContextFromEnvelope(e)}:t===he.MessageAction?{type:he.MessageAction,data:this.messageActionFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(pe.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class pe extends de{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${R(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i}=this.parameters,a={};return e&&e.length>0&&(a["channel-group"]=e.sort().join(",")),t&&t.length>0&&(a["filter-expr"]=t),s&&(a.heartbeat=s),n&&Object.keys(n).length>0&&(a.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(a.tt=r):void 0!==r&&r>0&&(a.tt=r),i&&(a.tr=i),a}}class ge{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===he.Message)this.announce("message",e.data);else if(e.type===he.Signal)this.announce("signal",e.data);else if(e.type===he.Presence)this.announce("presence",e.data);else if(e.type===he.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:l}=o,h=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===he.MessageAction?this.announce("messageAction",e.data):e.type===he.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class be{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class ye{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size||(!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:this.currentTimetoken,lastTimetoken:this.lastTimetoken}))}))),0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0))}unsubscribeAll(e=!1){this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=G(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>{const t=e.type===he.Message||e.type===he.Signal?L(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class fe{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class ve extends fe{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class Se extends fe{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this._body=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.notification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.payload.notification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.payload.notification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={}}toObject(){let e=Object.assign({},this.payload.data),t=null;const s={};if(Object.keys(this.payload).length>2){const t=r(this.payload,["notification","data"]);e=Object.assign(Object.assign({},e),t)}return this._isSilent?e.notification=this.payload.notification:t=this.payload.notification,Object.keys(e).length&&(s.data=e),t&&Object.keys(t).length&&(s.notification=t),Object.keys(s).length?s:null}}class we{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ve(this._payload.apns,e,t),this.fcm=new Se(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_gcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Oe{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class ke{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class Ce extends Oe{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new ke(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class je{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function Pe(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ee(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Ne(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Te extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class _e extends Oe{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Te}abort(){this._aborted=!0,this.notify(new Te)}}class Ie{constructor(e,t){this.payload=e,this.dependencies=t}}class Me extends Ie{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new _e}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const Ae=e=>(t,s)=>new Me(t,s,e),Ue=Ne("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),$e=Ee("LEAVE",((e,t)=>({channels:e,groups:t}))),Re=Ee("EMIT_STATUS",(e=>e)),Fe=Ne("WAIT",(()=>({}))),De=Pe("RECONNECT",(()=>({}))),xe=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),qe=Pe("JOINED",((e,t)=>({channels:e,groups:t}))),Ge=Pe("LEFT",((e,t)=>({channels:e,groups:t}))),Ke=Pe("LEFT_ALL",((e=!1)=>({isOffline:e}))),Le=Pe("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),He=Pe("HEARTBEAT_FAILURE",(e=>e)),Be=Pe("TIMES_UP",(()=>({})));class We extends je{constructor(e,t){super(t,t.config.logger()),this.on(Ue.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(Le(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(He(t))}}}))))),this.on($e.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(Fe.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Be())}))))),this.on(Re.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:le.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const ze=new ke("HEARTBEAT_STOPPED");ze.on(qe.type,((e,t)=>ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),ze.on(Ge.type,((e,t)=>ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),ze.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),ze.on(Ke.type,((e,t)=>Qe.with(void 0)));const Ve=new ke("HEARTBEAT_COOLDOWN");Ve.onEnter((()=>Fe())),Ve.onExit((()=>Fe.cancel)),Ve.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Ve.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ve.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Ve.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Ve.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Je=new ke("HEARTBEAT_FAILED");Je.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Je.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Je.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Je.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Je.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Xe=new ke("HEARTBEATING");Xe.onEnter((e=>Ue(e.channels,e.groups))),Xe.onExit((()=>Ue.cancel)),Xe.on(Le.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[Re(Object.assign({},t.payload))]))),Xe.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Xe.on(He.type,((e,t)=>Je.with(Object.assign({},e),[...t.payload.status?[Re(Object.assign({},t.payload.status))]:[]]))),Xe.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Xe.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Qe=new ke("HEARTBEAT_INACTIVE");Qe.on(qe.type,((e,t)=>Xe.with({channels:t.payload.channels,groups:t.payload.groups})));class Ye{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ce(e.config.logger()),this.dispatcher=new We(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Qe,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(qe(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(Ge(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.engine.transition(Ke(e))}reconnect(){this.engine.transition(De())}disconnect(e=!1){this.engine.transition(xe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const Ze=Ne("HANDSHAKE",((e,t)=>({channels:e,groups:t}))),et=Ne("RECEIVE_MESSAGES",((e,t,s)=>({channels:e,groups:t,cursor:s}))),tt=Ee("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),st=Ee("EMIT_STATUS",(e=>e)),nt=Pe("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),rt=Pe("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),it=Pe("HANDSHAKE_SUCCESS",(e=>e)),at=Pe("HANDSHAKE_FAILURE",(e=>e)),ot=Pe("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),ct=Pe("RECEIVE_FAILURE",(e=>e)),ut=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),lt=Pe("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),ht=Pe("UNSUBSCRIBE_ALL",(()=>({}))),dt=new ke("UNSUBSCRIBED");dt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups}))),dt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region}})));const pt=new ke("HANDSHAKE_STOPPED");pt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),pt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),pt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),pt.on(ht.type,(e=>dt.with()));const gt=new ke("HANDSHAKE_FAILED");gt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),gt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),gt.on(rt.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0}})})),gt.on(ht.type,(e=>dt.with()));const bt=new ke("HANDSHAKING");bt.onEnter((e=>Ze(e.channels,e.groups))),bt.onExit((()=>Ze.cancel)),bt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),bt.on(it.type,((e,{payload:t})=>{var s,n,r,i,a;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:G(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[st({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),bt.on(at.type,((e,t)=>{var s;return gt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),bt.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return gt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return pt.with(Object.assign({},e))})),bt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0}})})),bt.on(ht.type,(e=>dt.with()));const yt=new ke("RECEIVE_STOPPED");yt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),yt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),yt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),yt.on(ht.type,(()=>dt.with(void 0)));const mt=new ke("RECEIVE_FAILED");mt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),mt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),mt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),mt.on(ht.type,(e=>dt.with(void 0)));const ft=new ke("RECEIVING");ft.onEnter((e=>et(e.channels,e.groups,e.cursor))),ft.onExit((()=>et.cancel)),ft.on(ot.type,((e,{payload:t})=>ft.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:G(t.cursor.timetoken)},[tt(e.cursor,t.events)]))),ft.on(nt.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation).status)||void 0===s?void 0:s.category),dt.with(void 0,[st(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory},e?{error:e}:{}))])}return ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),ft.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0,[st({category:h.PNDisconnectedCategory})]):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:G(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken)},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),ft.on(ct.type,((e,{payload:t})=>{var s;return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),ft.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return yt.with(Object.assign({},e),[st({category:h.PNDisconnectedCategory})])})),ft.on(ht.type,(e=>dt.with(void 0,[st({category:h.PNDisconnectedCategory})])));class vt extends je{constructor(e,t){super(t,t.config.logger()),this.on(Ze.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}));return e.transition(it(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(at(t))}}}))))),this.on(et.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression});e.transition(ot(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(ct(t))}}}))))),this.on(tt.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(st.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class St{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ce(e.config.logger()),this.dispatcher=new vt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(dt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===ft.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return q(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s?this.engine.transition(rt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s)):this.engine.transition(nt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])))),this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=F(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=F(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=D(this.channels,e),i=D(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(nt(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(nt(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(lt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ut(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class wt extends ue{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?re.POST:re.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return le.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${$(t)}/0${this.parameters.sendByPost?"":`/${$(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Ot extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${$(s)}/0/${$(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class kt extends de{operation(){return le.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${R(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n}=this.parameters,r={ee:""};return e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(r.tt=s):s&&s>0&&(r.tt=s),n&&(r.tr=n),r}}class Ct extends de{operation(){return le.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${R(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s}=this.parameters,n={ee:""};return e&&e.length>0&&(n["channel-group"]=e.sort().join(",")),t&&t.length>0&&(n["filter-expr"]=t),s&&Object.keys(s).length>0&&(n.state=JSON.stringify(s)),n}}var jt;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(jt||(jt={}));class Pt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new Pt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new Pt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Et{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=Z.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Nt{constructor(e){this.id=Z.createUUID(),this.eventDispatcher=new ge,this._state=e}get subscriptionType(){return"Subscription"}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Tt extends Et{constructor(e){const t=new Pt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}get subscriptionType(){return"SubscriptionSet"}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class _t extends Nt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Tt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new _t({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class It extends Et{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new Pt({[e.entity.subscriptionType==jt.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Mt extends Nt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new It(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s;if(this.state.isSubscribed){if(this.parentSetsCount>0){const e=L(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Message (${e}) already handled. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new Pt({}):this.state.subscriptionInput}cloneEmpty(){return new Mt({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new _t({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class At extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return le.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=s?s:[],",")}/uuid/${t}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Ut extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?t?0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing State":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=s?s:[],",")}/uuid/${$(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class $t extends ue{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return le.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),t&&(n.state=JSON.stringify(t)),n}}class Rt extends ue{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return le.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${R(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class Ft extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${$(t)}`}}class Dt extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=(r=this.parameters).queryParameters)&&void 0!==t||(r.queryParameters={}),null!==(s=(i=this.parameters).includeUUIDs)&&void 0!==s||(i.includeUUIDs=true),null!==(n=(a=this.parameters).includeState)&&void 0!==n||(a.includeState=false)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?le.PNGlobalHereNowOperation:le.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy}})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${R(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,queryParameters:n}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign({},t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),n)}}class xt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class qt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${R(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class Gt extends ue{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return le.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(Gt.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Kt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Kt||(Kt={}));class Lt extends ue{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return le.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Kt.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${R(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse(Lt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Kt.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Ht extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Bt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Wt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${n}/action/${s}`}}class zt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return le.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${$(t)}/0/${$(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Vt extends ue{constructor(e){super({method:re.LOCAL}),this.parameters=e}operation(){return le.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${$(e)}/files/${t}/${s}`}}class Jt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(s)}/files/${t}/${n}`}}class Xt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return le.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Qt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class Yt extends ue{constructor(e){super({method:re.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return le.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?Yt.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class Zt{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:le.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof _?e:_.create(e);throw new d("File upload error.",t.toStatus(le.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new Qt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new Yt({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}class es{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return jt.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Mt({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ts extends es{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class ss extends es{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return jt.ChannelGroup}}class ns extends es{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class rs extends es{get entityType(){return"Channel"}get name(){return this._nameOrId}}class is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class as extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class os extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}}class cs extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}/remove`}}class us extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ls{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.info("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new us({keySet:this.keySet}),s=e=>{e&&this.logger.info("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new as(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new is(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class hs extends ue{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: gcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class ds extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return le.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ps extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return le.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class gs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return le.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return le.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ys{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new ds(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ms extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return le.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class fs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}}class vs extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ws extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return le.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Os extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class ks extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Cs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}}class js extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ps extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Es extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ns extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ts{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ws(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Es(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ns(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.'`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Cs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ms(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.'`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new ks(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new vs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class _s extends ue{constructor(){super()}operation(){return le.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class Is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files/${s}/${n}`}}class Ms{static notificationPayload(e,t){return new we(e,t)}static generateUUID(){return Z.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")}))),this._objects=new Ts(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ls(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new ys(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ge,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new Ye({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new St({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===he.Message||e.type===he.Signal?L(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new me(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub",`Set auth key: ${e}`),this._configuration.setAuthKey(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}getUserId(){return this._configuration.userId}setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub",`Set cipher key: ${e}`),this.cipherKey=e}set heartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e)}setHeartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new rs(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new ss(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ts(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new ns(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new _t({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===le.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===le.PNSubscribeOperation||i===le.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Ms.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof _?e:_.create(e);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,"REST API request processing error, check status for details")}))),t(s.toStatus(i),null);const n=s.toPubNubError(i,"REST API request processing error, check status for details");throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:n}))),n}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Ot(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new Pt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];let n;if(this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"}))),t&&0!==t.length||delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new Pt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof _t?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const r=s.subscriptionInput(!1),i=r.channelGroups,a=r.channels;e.push(...n.channelGroups.filter((e=>i.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],r=n=>{const r=n.subscriptionNames(!0),i=n.subscriptionType===jt.Channel?t:e;r.some((e=>i.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof _t?e.subscriptions.forEach((e=>{r(e.state.entity)})):e instanceof Mt&&r(e.state.entity)}));let i="Some entities still in use:";return t.length+e.length===n.length&&(i="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:i}})),n.remove(new Pt({channels:t,channelGroups:e})),n.isEmpty))return}const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(r):this.eventEngine&&this.eventEngine.unsubscribe(r)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{const s=new pe(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:le.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new Rt({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub","Disconnect (while offline? "+(e?"yes":"no")),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{const t=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{const t=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Ht(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Lt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Dt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new Ft({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new At(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state)))}o="withHeartbeat"in e&&e.withHeartbeat?new $t(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new Ut(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof $t?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&this.subscriptionManager.setState(e),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:r}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(r&&(r=r.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=r?r:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const i=new $t(Object.assign(Object.assign({},e),{channels:n,channelGroups:r,keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{i.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(i,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(i).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e)}setToken(e){this.token=e}parseToken(e){return this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new Zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:le.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof _&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${$(t)}`)).join("&"):`${e}=${$(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new Is(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new _s,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Ms.decoder=new TextDecoder,Ms.OPERATIONS=le,Ms.CATEGORIES=h,Ms.Endpoint=B,Ms.ExponentialRetryPolicy=W.ExponentialRetryPolicy,Ms.LinearRetryPolicy=W.LinearRetryPolicy,Ms.NoneRetryPolicy=W.None,Ms.LogLevel=U;class As{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Us extends Ms{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=A(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=ee(i,(e=>{if(e.cipherKey){return new E({default:new P(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new O({cipherKey:e.cipherKey})]})}}));let u,l,h;a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new ne(new As((e=>M(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new C({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()})),h=new j;let d=new ce(a.logger(),i.transport);if(r.subscriptionWorkerUrl){const e=new I({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogVerbosity:i.subscriptionWorkerLogVerbosity,tokenManager:u,transport:d,logger:a.logger()});d=e,window.onpagehide=t=>{t.persisted||e.terminate()}}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const p=new oe({clientConfiguration:a,tokenManager:u,transport:d});super({configuration:a,transport:p,cryptography:h,tokenManager:u,crypto:l}),(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Us.CryptoModule=E,Us})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),h(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function y(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var m=function e(){var r,d,m=l(),f=m>>5,v=31&m;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)w+=d,S.push(u(d));var O=new Uint8Array(w),k=0;for(r=0;r=0;)y(C,d);else y(C,d);return String.fromCharCode.apply(null,C);case 4:var j;if(d<0)for(j=[];!p();)j.push(e());else for(j=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==i?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==i&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,y,m,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),h=l,l=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),y=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=y.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=S,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],l=(o=e[i+1],e[i+2]),h=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],y=e[i+8],m=e[i+9],f=e[i+10],v=e[i+11],S=e[i+12],w=e[i+13],O=e[i+14],k=e[i+15],C=t(C=a[0],E=a[1],P=a[2],j=a[3],c,7,u[0]),j=t(j,C,E,P,o,12,u[1]),P=t(P,j,C,E,l,17,u[2]),E=t(E,P,j,C,h,22,u[3]);C=t(C,E,P,j,d,7,u[4]),j=t(j,C,E,P,p,12,u[5]),P=t(P,j,C,E,g,17,u[6]),E=t(E,P,j,C,b,22,u[7]),C=t(C,E,P,j,y,7,u[8]),j=t(j,C,E,P,m,12,u[9]),P=t(P,j,C,E,f,17,u[10]),E=t(E,P,j,C,v,22,u[11]),C=t(C,E,P,j,S,7,u[12]),j=t(j,C,E,P,w,12,u[13]),P=t(P,j,C,E,O,17,u[14]),C=s(C,E=t(E,P,j,C,k,22,u[15]),P,j,o,5,u[16]),j=s(j,C,E,P,g,9,u[17]),P=s(P,j,C,E,v,14,u[18]),E=s(E,P,j,C,c,20,u[19]),C=s(C,E,P,j,p,5,u[20]),j=s(j,C,E,P,f,9,u[21]),P=s(P,j,C,E,k,14,u[22]),E=s(E,P,j,C,d,20,u[23]),C=s(C,E,P,j,m,5,u[24]),j=s(j,C,E,P,O,9,u[25]),P=s(P,j,C,E,h,14,u[26]),E=s(E,P,j,C,y,20,u[27]),C=s(C,E,P,j,w,5,u[28]),j=s(j,C,E,P,l,9,u[29]),P=s(P,j,C,E,b,14,u[30]),C=n(C,E=s(E,P,j,C,S,20,u[31]),P,j,p,4,u[32]),j=n(j,C,E,P,y,11,u[33]),P=n(P,j,C,E,v,16,u[34]),E=n(E,P,j,C,O,23,u[35]),C=n(C,E,P,j,o,4,u[36]),j=n(j,C,E,P,d,11,u[37]),P=n(P,j,C,E,b,16,u[38]),E=n(E,P,j,C,f,23,u[39]),C=n(C,E,P,j,w,4,u[40]),j=n(j,C,E,P,c,11,u[41]),P=n(P,j,C,E,h,16,u[42]),E=n(E,P,j,C,g,23,u[43]),C=n(C,E,P,j,m,4,u[44]),j=n(j,C,E,P,S,11,u[45]),P=n(P,j,C,E,k,16,u[46]),C=r(C,E=n(E,P,j,C,l,23,u[47]),P,j,c,6,u[48]),j=r(j,C,E,P,b,10,u[49]),P=r(P,j,C,E,O,15,u[50]),E=r(E,P,j,C,p,21,u[51]),C=r(C,E,P,j,S,6,u[52]),j=r(j,C,E,P,h,10,u[53]),P=r(P,j,C,E,f,15,u[54]),E=r(E,P,j,C,o,21,u[55]),C=r(C,E,P,j,y,6,u[56]),j=r(j,C,E,P,k,10,u[57]),P=r(P,j,C,E,g,15,u[58]),E=r(E,P,j,C,w,21,u[59]),C=r(C,E,P,j,d,6,u[60]),j=r(j,C,E,P,v,10,u[61]),P=r(P,j,C,E,l,15,u[62]),E=r(E,P,j,C,m,21,u[63]);a[0]=a[0]+C|0,a[1]=a[1]+E|0,a[2]=a[2]+P|0,a[3]=a[3]+j|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,l.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,y=0;for(g=0;256>g;g++){var m=(m=y^y<<1^y<<2^y<<3^y<<4)>>>8^255&m^99;n[b]=m,r[m]=b;var f=p[b],v=p[f],w=p[v],O=257*p[m]^16843008*m;i[b]=O<<24|O>>>8,a[b]=O<<16|O>>>16,o[b]=O<<8|O>>>24,c[b]=O,O=16843009*w^65537*v^257*f^16843008*b,u[m]=O<<24|O>>>8,l[m]=O<<16|O>>>16,h[m]=O<<8|O>>>24,d[m]=O,b?(b=f^p[p[p[w^f]]],y^=p[p[y]]):b=y=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[l>>>16&255]^i[h>>>8&255]^a[255&d]^s[p++],y=n[l>>>24]^r[h>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],m=n[h>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[l>>>8&255]^a[255&h]^s[p++],u=b,l=y,h=m}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],y=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],m=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=y,e[t+2]=m,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var w=t(S);class O{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=w,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:O.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return O.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(O.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=O.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e})))}get logger(){return this._logger}HMACSHA256(e){return w.HmacSHA256(e,this.configuration.secretKey).toString(w.enc.Base64)}SHA256(e){return w.SHA256(e).toString(w.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Encrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=w.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(w.enc.Base64)}const a=this.getIV(s);return w.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(w.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Decrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=k(t.slice(0,16)),n=k(t.slice(16));try{const e=w.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(w.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=w.enc.Base64.parse(e),n=w.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(w.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?w.enc.Base64.parse(e):"hex"===t.keyEncoding?w.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?w.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?w.mode.ECB:w.mode.CBC}getIV(e){return"cbc"===e.mode?w.enc.Utf8.parse(this.iv):null}getRandomIV(){return w.lib.WordArray.random(16)}}class j{encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=j.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return j.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(j.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(j.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=j.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return j.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",j.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=j.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}j.IV_LENGTH=16,j.encoder=new TextEncoder,j.decoder=new TextDecoder;class P{constructor(e){this.config=e,this.cryptor=new C(Object.assign({},e)),this.fileCryptor=new j}set logger(e){this.cryptor.logger=e}encrypt(e){const t="string"==typeof e?e:P.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`AesCbcCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}P.encoder=new TextEncoder,P.decoder=new TextDecoder;class E extends a{set logger(e){if(this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER)this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===E.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new P(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new O({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new E({default:new O({cipherKey:e.cipherKey}),cryptors:[new P(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===E.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(E.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=N.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=N.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===N.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof T)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=N.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}E.LEGACY_IDENTIFIER="";class N{static from(e,t){if(e!==N.LEGACY_IDENTIFIER)return new T(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==N.SENTINEL))return E.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>N.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+N.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new T(this.decoder.decode(n),a)}}N.SENTINEL="PNED",N.LEGACY_IDENTIFIER="",N.IDENTIFIER_LENGTH=4,N.VERSION=1,N.MAX_VERSION=1,N.decoder=new TextDecoder;class T{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return N.VERSION}get length(){return N.SENTINEL.length+1+N.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(N.SENTINEL)),e+=N.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=N.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}T.IDENTIFIER_LENGTH=4,T.SENTINEL="PNED";class _ extends Error{static create(e,t){return _.isErrorObject(e)?_.createFromError(e):_.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new _(s,t,0);if(e instanceof _)return e;if(_.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new _(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":400===i?(n=h.PNBadRequestCategory,r="Bad request"):403===i&&(n=h.PNAccessDeniedCategory,r="Access denied"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);"object"==typeof e&&(Array.isArray(e)?"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]):("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e?(s=e,i=e.status):s=e,"error"in e&&e.error instanceof Error&&(s=e.error)))}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new _(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,_.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}class I{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.token=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogVerbosity:this.configuration.workerLogVerbosity},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e)}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",t.message);else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t})}else if("request-process-success"===t.type||"request-process-error"===t.type){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);if("request-process-success"===t.type)e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body});else{let e=h.PNUnknownCategory,n="Unknown error";if(t.error)"NETWORK_ISSUE"===t.error.type?e=h.PNNetworkIssuesCategory:"TIMEOUT"===t.error.type?e=h.PNTimeoutCategory:"ABORTED"===t.error.type&&(e=h.PNCancelledCategory),n=`${t.error.message} (${t.identifier})`;else if(t.response)return s(_.create({url:t.url,headers:t.response.headers,body:t.response.body,status:t.response.status},t.response.body));s(new _(n,e,0,new Error(n)))}}}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;const s=e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0;if(s)return this.accessTokensMap[s]?this.accessTokensMap[s]:this.stringifyAccessToken(s).then((([e,t])=>{if(e&&t)return(this.accessTokensMap={[s]:{token:t,expiration:e.timestamp*e.ttl*60}})[s]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}}function M(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const r={};return Object.keys(e).forEach((i=>{const a=(e=>"string"==typeof e||e instanceof String)(i);let o=i;const c=e[i];if(t<2)if(a&&i.indexOf(",")>=0){o=i.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(i)||a&&!isNaN(Number(i)))&&(o=String.fromCharCode(n(i)?i:parseInt(i,10)));r[o]=s(c)?M(c,t+1):c})),r}const A=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,l,h,p,g,b,y;const m=Object.assign({},e);if(null!==(t=m.ssl)&&void 0!==t||(m.ssl=!0),null!==(s=m.transactionalRequestTimeout)&&void 0!==s||(m.transactionalRequestTimeout=15),null!==(n=m.subscribeRequestTimeout)&&void 0!==n||(m.subscribeRequestTimeout=310),null!==(r=m.fileRequestTimeout)&&void 0!==r||(m.fileRequestTimeout=300),null!==(i=m.restore)&&void 0!==i||(m.restore=!1),null!==(a=m.useInstanceId)&&void 0!==a||(m.useInstanceId=!1),null!==(o=m.suppressLeaveEvents)&&void 0!==o||(m.suppressLeaveEvents=!1),null!==(c=m.requestMessageCountThreshold)&&void 0!==c||(m.requestMessageCountThreshold=100),null!==(u=m.autoNetworkDetection)&&void 0!==u||(m.autoNetworkDetection=!1),null!==(l=m.enableEventEngine)&&void 0!==l||(m.enableEventEngine=!1),null!==(h=m.maintainPresenceState)&&void 0!==h||(m.maintainPresenceState=!0),null!==(p=m.useSmartHeartbeat)&&void 0!==p||(m.useSmartHeartbeat=!1),null!==(g=m.keepAlive)&&void 0!==g||(m.keepAlive=!1),m.userId&&m.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=m.userId)&&void 0!==b||(m.userId=m.uuid),!m.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=m.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");m.origin||(m.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:m.subscribeKey,publishKey:m.publishKey,secretKey:m.secretKey};void 0!==m.presenceTimeout&&(m.presenceTimeout>320?(m.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):m.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete m.presenceTimeout)),void 0!==m.presenceTimeout?m.heartbeatInterval=m.presenceTimeout/2-1:m.presenceTimeout=300;let v=!1,S=!0,w=5,O=!1,k=100,C=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(O=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(C=m.useRequestId),void 0!==m.announceSuccessfulHeartbeats&&"boolean"==typeof m.announceSuccessfulHeartbeats&&(v=m.announceSuccessfulHeartbeats),void 0!==m.announceFailedHeartbeats&&"boolean"==typeof m.announceFailedHeartbeats&&(S=m.announceFailedHeartbeats),void 0!==m.fileUploadPublishRetryLimit&&"number"==typeof m.fileUploadPublishRetryLimit&&(w=m.fileUploadPublishRetryLimit),Object.assign(Object.assign({},m),{keySet:f,dedupeOnSubscribe:O,maximumCacheSize:k,useRequestId:C,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:S,fileUploadPublishRetryLimit:w})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var U;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(U||(U={}));const $=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),R=(e,t)=>{const s=e.map((e=>$(e)));return s.length?s.join(","):null!=t?t:""},F=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},D=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),x=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&"),G=(e,t)=>{if("0"===t||"0"===e)return;const s=K(`${Date.now()}0000`,t,!1);return K(e,s,!0)},q=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=K(e,t,!1);return K(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},K=(e,t,s)=>{t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0&&(o>0?(o-=1,c+=1e7):o<0&&(c*=-1)),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},L=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};class H{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}log(e){const t=U[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==U.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?x(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===U.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,r=!(e||h instanceof String||0!==Object.keys(h).length),a=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),c=i?"...":s?"[]":r?"{}":t(h,n+1,a);o.push(`${u}${d}:${i||a||s||r?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${h}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${H.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(H.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}var B;H.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(B||(B={}));class W{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return z(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry");if(this.maximumRetry>10)throw new Error("Maximum retry for linear retry policy can not be more than 10")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return z(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry");if(this.maximumDelay>150)throw new Error("Maximum delay can not be set more than 150 seconds for retry");if(this.maximumRetry>6)throw new Error("Maximum retry for exponential retry policy can not be more than 6")}}}}const z=(e,t,s,n,r,i)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!V(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),V=(e,t)=>!!(t&&t.length>0)&&t.includes(J(e)),J=e=>{let t=B.Unknown;return e.path.startsWith("/v2/subscribe")?t=B.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=B.MessageSend:e.path.startsWith("/v2/presence")?t=B.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=B.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=B.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=B.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=B.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=B.Files),t};class X{constructor(e,t,s){this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(U.Trace,e,t)}debug(e,t){this.log(U.Debug,e,t)}info(e,t){this.log(U.Info,e,t)}warn(e,t){this.log(U.Warn,e,t)}error(e,t){this.log(U.Error,e,t)}log(e,t,s){if(ee[n](r)))}}var Q={exports:{}}; +/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(Q,Q.exports);var Y=t(Q.exports),Z={createUUID:()=>Y.uuid?Y.uuid():Y()};const ee=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=W.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[B.MessageSend,B.Presence,B.Files,B.MessageStorage,B.ChannelGroups,B.DevicePushNotifications,B.AppContext,B.MessageReactions]}));const a=`pn-${Z.createUUID()}`;e.logVerbosity?e.logLevel=U.Debug:void 0===e.logLevel&&(e.logLevel=U.None);const o=new X(se(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new H]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate(),null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),e.useRandomIVs&&o.warn("Configuration","'useRandomIVs' is deprecated. Use 'cryptoModule' instead."),e.origin=te(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const c=e.cryptoModule;c&&delete e.cryptoModule;const u=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"9.7.0"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),u.setCipherKey(e.cipherKey)):c&&(u._cryptoModule=c),u},te=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},se=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class ne{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=r.length>0,d=i.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var re,ie;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(re||(re={}));class ae{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?re.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===re.POST||t===re.PATCH){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=ae.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&")}}ae.textDecoder=new TextDecoder("utf-8");class oe{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new ae(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[l,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==h.PNCancelledCategory,l=!s||s.status>=400;let d=-1;i&&l&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class ce{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"!==t||window&&window.fetch||(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(ce.originalFetch=fetch.bind(window),this.isFetchMonkeyPatched()&&(ce.originalFetch=ce.getOriginalFetch(),e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."),this.isFetchMonkeyPatched(ce.originalFetch)?e.warn("WebTransport","Unable receive native Web Fetch API. There can be issues with subscribe long-poll cancellation"):e.info("WebTransport","Use native Web Fetch API 'fetch' implementation from iframe as APM workaround.")))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw _.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:_.create(n).message,failed:!0}))),_.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([ce.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(_.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?ce.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${x(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}ce.encoder=new TextEncoder,ce.decoder=new TextDecoder;class ue{constructor(e){this.params=e,this.requestIdentifier=Z.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:re.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===re.POST||a.method===re.PATCH){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=ue.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw _.create(e);return n}}ue.decoder=new TextDecoder,function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(ie||(ie={}));var le=ie;var he;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(he||(he={}));class de extends ue{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return le.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=ue.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;return null!=t||(t=e.c.endsWith("-pnpres")?he.Presence:he.Message),t!=he.Signal&&"string"==typeof e.d?t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}:t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e)}:t===he.Presence?{type:he.Presence,data:this.presenceEventFromEnvelope(e)}:t==he.Signal?{type:he.Signal,data:this.signalFromEnvelope(e)}:t===he.AppContext?{type:he.AppContext,data:this.appContextFromEnvelope(e)}:t===he.MessageAction?{type:he.MessageAction,data:this.messageActionFromEnvelope(e)}:{type:he.Files,data:this.fileFromEnvelope(e)}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(pe.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class pe extends de{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${R(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i}=this.parameters,a={};return e&&e.length>0&&(a["channel-group"]=e.sort().join(",")),t&&t.length>0&&(a["filter-expr"]=t),s&&(a.heartbeat=s),n&&Object.keys(n).length>0&&(a.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(a.tt=r):void 0!==r&&r>0&&(a.tt=r),i&&(a.tr=i),a}}class ge{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===he.Message)this.announce("message",e.data);else if(e.type===he.Signal)this.announce("signal",e.data);else if(e.type===he.Presence)this.announce("presence",e.data);else if(e.type===he.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:l}=o,h=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===he.MessageAction?this.announce("messageAction",e.data):e.type===he.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class be{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class ye{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size||(!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:this.currentTimetoken,lastTimetoken:this.lastTimetoken}))}))),0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0))}unsubscribeAll(e=!1){this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=q(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>{const t=e.type===he.Message||e.type===he.Signal?L(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class fe{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class ve extends fe{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class Se extends fe{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this._body=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.notification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.payload.notification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.payload.notification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={}}toObject(){let e=Object.assign({},this.payload.data),t=null;const s={};if(Object.keys(this.payload).length>2){const t=r(this.payload,["notification","data"]);e=Object.assign(Object.assign({},e),t)}return this._isSilent?e.notification=this.payload.notification:t=this.payload.notification,Object.keys(e).length&&(s.data=e),t&&Object.keys(t).length&&(s.notification=t),Object.keys(s).length?s:null}}class we{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ve(this._payload.apns,e,t),this.fcm=new Se(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_gcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Oe{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class ke{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class Ce extends Oe{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new ke(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class je{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function Pe(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ee(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Ne(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Te extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class _e extends Oe{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Te}abort(){this._aborted=!0,this.notify(new Te)}}class Ie{constructor(e,t){this.payload=e,this.dependencies=t}}class Me extends Ie{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new _e}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const Ae=e=>(t,s)=>new Me(t,s,e),Ue=Ne("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),$e=Ee("LEAVE",((e,t)=>({channels:e,groups:t}))),Re=Ee("EMIT_STATUS",(e=>e)),Fe=Ne("WAIT",(()=>({}))),De=Pe("RECONNECT",(()=>({}))),xe=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),Ge=Pe("JOINED",((e,t)=>({channels:e,groups:t}))),qe=Pe("LEFT",((e,t)=>({channels:e,groups:t}))),Ke=Pe("LEFT_ALL",((e=!1)=>({isOffline:e}))),Le=Pe("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),He=Pe("HEARTBEAT_FAILURE",(e=>e)),Be=Pe("TIMES_UP",(()=>({})));class We extends je{constructor(e,t){super(t,t.config.logger()),this.on(Ue.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(Le(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(He(t))}}}))))),this.on($e.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(Fe.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Be())}))))),this.on(Re.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:le.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const ze=new ke("HEARTBEAT_STOPPED");ze.on(Ge.type,((e,t)=>ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),ze.on(qe.type,((e,t)=>ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),ze.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),ze.on(Ke.type,((e,t)=>Qe.with(void 0)));const Ve=new ke("HEARTBEAT_COOLDOWN");Ve.onEnter((()=>Fe())),Ve.onExit((()=>Fe.cancel)),Ve.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Ve.on(Ge.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ve.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Ve.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Ve.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Je=new ke("HEARTBEAT_FAILED");Je.on(Ge.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Je.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Je.on(De.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Je.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Je.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Xe=new ke("HEARTBEATING");Xe.onEnter((e=>Ue(e.channels,e.groups))),Xe.onExit((()=>Ue.cancel)),Xe.on(Le.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[Re(Object.assign({},t.payload))]))),Xe.on(Ge.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Xe.on(He.type,((e,t)=>Je.with(Object.assign({},e),[...t.payload.status?[Re(Object.assign({},t.payload.status))]:[]]))),Xe.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Xe.on(Ke.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Qe=new ke("HEARTBEAT_INACTIVE");Qe.on(Ge.type,((e,t)=>Xe.with({channels:t.payload.channels,groups:t.payload.groups})));class Ye{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ce(e.config.logger()),this.dispatcher=new We(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Qe,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(Ge(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(qe(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.engine.transition(Ke(e))}reconnect(){this.engine.transition(De())}disconnect(e=!1){this.engine.transition(xe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const Ze=Ne("HANDSHAKE",((e,t)=>({channels:e,groups:t}))),et=Ne("RECEIVE_MESSAGES",((e,t,s)=>({channels:e,groups:t,cursor:s}))),tt=Ee("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),st=Ee("EMIT_STATUS",(e=>e)),nt=Pe("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),rt=Pe("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),it=Pe("HANDSHAKE_SUCCESS",(e=>e)),at=Pe("HANDSHAKE_FAILURE",(e=>e)),ot=Pe("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),ct=Pe("RECEIVE_FAILURE",(e=>e)),ut=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),lt=Pe("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),ht=Pe("UNSUBSCRIBE_ALL",(()=>({}))),dt=new ke("UNSUBSCRIBED");dt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups}))),dt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region}})));const pt=new ke("HANDSHAKE_STOPPED");pt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),pt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),pt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),pt.on(ht.type,(e=>dt.with()));const gt=new ke("HANDSHAKE_FAILED");gt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),gt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor})))),gt.on(rt.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0}})})),gt.on(ht.type,(e=>dt.with()));const bt=new ke("HANDSHAKING");bt.onEnter((e=>Ze(e.channels,e.groups))),bt.onExit((()=>Ze.cancel)),bt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),bt.on(it.type,((e,{payload:t})=>{var s,n,r,i,a;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:q(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[st({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),bt.on(at.type,((e,t)=>{var s;return gt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),bt.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return gt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return pt.with(Object.assign({},e))})),bt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0}})})),bt.on(ht.type,(e=>dt.with()));const yt=new ke("RECEIVE_STOPPED");yt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),yt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),yt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),yt.on(ht.type,(()=>dt.with(void 0)));const mt=new ke("RECEIVE_FAILED");mt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region}})})),mt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),mt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),mt.on(ht.type,(e=>dt.with(void 0)));const ft=new ke("RECEIVING");ft.onEnter((e=>et(e.channels,e.groups,e.cursor))),ft.onExit((()=>et.cancel)),ft.on(ot.type,((e,{payload:t})=>ft.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:q(t.cursor.timetoken)},[tt(e.cursor,t.events)]))),ft.on(nt.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation).status)||void 0===s?void 0:s.category),dt.with(void 0,[st(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory},e?{error:e}:{}))])}return ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),ft.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0,[st({category:h.PNDisconnectedCategory})]):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:q(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken)},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),ft.on(ct.type,((e,{payload:t})=>{var s;return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),ft.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=_.create(new Error("Network connection error")).toPubNubError(le.PNSubscribeOperation);return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return yt.with(Object.assign({},e),[st({category:h.PNDisconnectedCategory})])})),ft.on(ht.type,(e=>dt.with(void 0,[st({category:h.PNDisconnectedCategory})])));class vt extends je{constructor(e,t){super(t,t.config.logger()),this.on(Ze.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}));return e.transition(it(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(at(t))}}}))))),this.on(et.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression});e.transition(ot(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(ct(t))}}}))))),this.on(tt.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(st.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class St{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ce(e.config.logger()),this.dispatcher=new vt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(dt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===ft.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return G(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s?this.engine.transition(rt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s)):this.engine.transition(nt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])))),this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=F(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=F(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=D(this.channels,e),i=D(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(nt(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannelGroups(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(nt(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(lt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ut(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class wt extends ue{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?re.POST:re.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return le.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${$(t)}/0${this.parameters.sendByPost?"":`/${$(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Ot extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${$(s)}/0/${$(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class kt extends de{operation(){return le.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${R(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n}=this.parameters,r={ee:""};return e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(r.tt=s):s&&s>0&&(r.tt=s),n&&(r.tr=n),r}}class Ct extends de{operation(){return le.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${R(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s}=this.parameters,n={ee:""};return e&&e.length>0&&(n["channel-group"]=e.sort().join(",")),t&&t.length>0&&(n["filter-expr"]=t),s&&Object.keys(s).length>0&&(n.state=JSON.stringify(s)),n}}var jt;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(jt||(jt={}));class Pt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new Pt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new Pt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Et{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=Z.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Nt{constructor(e){this.id=Z.createUUID(),this.eventDispatcher=new ge,this._state=e}get subscriptionType(){return"Subscription"}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Tt extends Et{constructor(e){const t=new Pt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}get subscriptionType(){return"SubscriptionSet"}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class _t extends Nt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Tt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new _t({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class It extends Et{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new Pt({[e.entity.subscriptionType==jt.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Mt extends Nt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new It(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s;if(this.state.isSubscribed){if(this.parentSetsCount>0){const e=L(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Message (${e}) already handled. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new Pt({}):this.state.subscriptionInput}cloneEmpty(){return new Mt({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new _t({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class At extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return le.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=s?s:[],",")}/uuid/${t}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Ut extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?t?0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing State":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=s?s:[],",")}/uuid/${$(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class $t extends ue{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return le.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${R(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),t&&(n.state=JSON.stringify(t)),n}}class Rt extends ue{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return le.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${R(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class Ft extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${$(t)}`}}class Dt extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=(r=this.parameters).queryParameters)&&void 0!==t||(r.queryParameters={}),null!==(s=(i=this.parameters).includeUUIDs)&&void 0!==s||(i.includeUUIDs=true),null!==(n=(a=this.parameters).includeState)&&void 0!==n||(a.includeState=false)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?le.PNGlobalHereNowOperation:le.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy}})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${R(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,queryParameters:n}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign({},t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),n)}}class xt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class Gt extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${R(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class qt extends ue{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return le.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(qt.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Kt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Kt||(Kt={}));class Lt extends ue{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return le.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Kt.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${R(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse(Lt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Kt.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Ht extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Bt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Wt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${n}/action/${s}`}}class zt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return le.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${$(t)}/0/${$(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Vt extends ue{constructor(e){super({method:re.LOCAL}),this.parameters=e}operation(){return le.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${$(e)}/files/${t}/${s}`}}class Jt extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(s)}/files/${t}/${n}`}}class Xt extends ue{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return le.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Qt extends ue{constructor(e){super({method:re.POST}),this.parameters=e}operation(){return le.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class Yt extends ue{constructor(e){super({method:re.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return le.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?Yt.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class Zt{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:le.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof _?e:_.create(e);throw new d("File upload error.",t.toStatus(le.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new Qt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new Yt({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}class es{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return jt.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Mt({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ts extends es{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class ss extends es{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return jt.ChannelGroup}}class ns extends es{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class rs extends es{get entityType(){return"Channel"}get name(){return this._nameOrId}}class is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class as extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class os extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}}class cs extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}/remove`}}class us extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ls{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.info("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new us({keySet:this.keySet}),s=e=>{e&&this.logger.info("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new as(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new is(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.info("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class hs extends ue{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: gcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class ds extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return le.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ps extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return le.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class gs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return le.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return le.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ys{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new ds(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ms extends ue{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return le.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class fs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e}operation(){return le.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}}class vs extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ws extends ue{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return le.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Os extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class ks extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return le.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Cs extends ue{constructor(e){super({method:re.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}}class js extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ps extends ue{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return le.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Es extends ue{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ns extends ue{constructor(e){var t,s,n;super({method:re.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return le.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ts{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ws(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Es(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ns(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.'`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Cs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ms(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.'`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new ks(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new vs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class _s extends ue{constructor(){super()}operation(){return le.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class Is extends ue{constructor(e){super(),this.parameters=e}operation(){return le.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files/${s}/${n}`}}class Ms{static notificationPayload(e,t){return new we(e,t)}static generateUUID(){return Z.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")}))),this._objects=new Ts(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ls(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new ys(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ge,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new Ye({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new St({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===he.Message||e.type===he.Signal?L(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new me(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub",`Set auth key: ${e}`),this._configuration.setAuthKey(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}getUserId(){return this._configuration.userId}setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub",`Set cipher key: ${e}`),this.cipherKey=e}set heartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e)}setHeartbeatInterval(e){this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new rs(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new ss(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ts(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new ns(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new _t({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===le.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===le.PNSubscribeOperation||i===le.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Ms.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof _?e:_.create(e);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,"REST API request processing error, check status for details")}))),t(s.toStatus(i),null);const n=s.toPubNubError(i,"REST API request processing error, check status for details");throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:n}))),n}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Ot(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new Pt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];let n;if(this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"}))),(!t||0===t.length||t&&e instanceof _t&&t==t)&&delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new Pt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof _t?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const r=s.subscriptionInput(!1),i=r.channelGroups,a=r.channels;e.push(...n.channelGroups.filter((e=>i.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],r=n=>{const r=n.subscriptionNames(!0),i=n.subscriptionType===jt.Channel?t:e;r.some((e=>i.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof _t?e.subscriptions.forEach((e=>{r(e.state.entity)})):e instanceof Mt&&r(e.state.entity)}));let i="Some entities still in use:";return t.length+e.length===n.length&&(i="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:i}})),n.remove(new Pt({channels:t,channelGroups:e})),n.isEmpty))return}const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(r):this.eventEngine&&this.eventEngine.unsubscribe(r)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{const s=new pe(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:le.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new Rt({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub","Disconnect (while offline? "+(e?"yes":"no")),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{const t=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{const t=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Ht(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Lt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Dt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new Ft({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new At(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state)))}o="withHeartbeat"in e&&e.withHeartbeat?new $t(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new Ut(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof $t?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&this.subscriptionManager.setState(e),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:r}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(r&&(r=r.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=r?r:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:le.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const i=new $t(Object.assign(Object.assign({},e),{channels:n,channelGroups:r,keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{i.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(i,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(i).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e)}setToken(e){this.token=e}parseToken(e){return this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new Zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:le.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof _&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${$(t)}`)).join("&"):`${e}=${$(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new Is(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new _s,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Ms.decoder=new TextDecoder,Ms.OPERATIONS=le,Ms.CATEGORIES=h,Ms.Endpoint=B,Ms.ExponentialRetryPolicy=W.ExponentialRetryPolicy,Ms.LinearRetryPolicy=W.LinearRetryPolicy,Ms.NoneRetryPolicy=W.None,Ms.LogLevel=U;class As{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Us extends Ms{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=A(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=ee(i,(e=>{if(e.cipherKey){return new E({default:new P(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new O({cipherKey:e.cipherKey})]})}}));let u,l,h;a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new ne(new As((e=>M(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new C({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()})),h=new j;let d=new ce(a.logger(),i.transport);if(r.subscriptionWorkerUrl){const e=new I({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogVerbosity:i.subscriptionWorkerLogVerbosity,tokenManager:u,transport:d,logger:a.logger()});d=e,window.onpagehide=t=>{t.persisted||e.terminate()}}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const p=new oe({clientConfiguration:a,tokenManager:u,transport:d});super({configuration:a,transport:p,cryptography:h,tokenManager:u,crypto:l}),(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Us.CryptoModule=E,Us})); diff --git a/lib/core/components/configuration.js b/lib/core/components/configuration.js index 83ed62acb..469bf5c9f 100644 --- a/lib/core/components/configuration.js +++ b/lib/core/components/configuration.js @@ -164,7 +164,7 @@ const makeConfiguration = (base, setupCryptoModule) => { return base.PubNubFile; }, get version() { - return '9.6.2'; + return '9.7.0'; }, getVersion() { return this.version; diff --git a/lib/core/pubnub-common.js b/lib/core/pubnub-common.js index 1b3b7effd..0186c8c5c 100644 --- a/lib/core/pubnub-common.js +++ b/lib/core/pubnub-common.js @@ -1075,10 +1075,8 @@ class PubNubCore { })); if (!subscriptions || subscriptions.length === 0 || - (subscriptions && subscription instanceof subscription_set_1.SubscriptionSet && subscriptions === subscriptions)) { - console.log(`~~~~> DELETED FROM STORAGE ${subscription.state.id}`); + (subscriptions && subscription instanceof subscription_set_1.SubscriptionSet && subscriptions === subscriptions)) delete this.eventHandleCapable[subscription.state.id]; - } let subscriptionInput; if (!subscriptions || subscriptions.length === 0) { subscriptionInput = subscription.subscriptionInput(true); diff --git a/lib/entities/channel.js b/lib/entities/channel.js new file mode 100644 index 000000000..61452410e --- /dev/null +++ b/lib/entities/channel.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Channel = void 0; +const entity_1 = require("./entity"); +/** + * First-class objects which provides access to the channel-specific APIs. + */ +class Channel extends entity_1.Entity { + /** + * Retrieve entity type. + * + * There is four types: + * - Channel + * - ChannelGroups + * - ChannelMetadata + * - UserMetadata + * + * @return One of known entity types. + * + * @internal + */ + get entityType() { + return 'Channel'; + } + /** + * Get a unique channel name. + * + * @returns Channel name. + */ + get name() { + return this._nameOrId; + } +} +exports.Channel = Channel; diff --git a/lib/entities/subscription.js b/lib/entities/subscription.js new file mode 100644 index 000000000..d57260421 --- /dev/null +++ b/lib/entities/subscription.js @@ -0,0 +1,309 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Subscription = void 0; +const subscription_capable_1 = require("./interfaces/subscription-capable"); +const subscription_1 = require("../core/types/api/subscription"); +const subscription_base_1 = require("./subscription-base"); +const subscription_set_1 = require("./subscription-set"); +const utils_1 = require("../core/utils"); +/** + * {@link Subscription} state object. + * + * State object used across multiple {@link Subscription} object clones. + * + * @internal + */ +class SubscriptionState extends subscription_base_1.SubscriptionBaseState { + /** + * Create a subscription state object. + * + * @param parameters - State configuration options + * @param parameters.client - PubNub client which will work with a subscription object. + * @param parameters.entity - Entity for which a subscription object has been created. + * @param [parameters.options] - Subscription behavior options. + */ + constructor(parameters) { + var _a, _b; + const names = parameters.entity.subscriptionNames((_b = (_a = parameters.options) === null || _a === void 0 ? void 0 : _a.receivePresenceEvents) !== null && _b !== void 0 ? _b : false); + const subscriptionInput = new subscription_1.SubscriptionInput({ + [parameters.entity.subscriptionType == subscription_capable_1.SubscriptionType.Channel ? 'channels' : 'channelGroups']: names, + }); + super(parameters.client, subscriptionInput, parameters.options, parameters.client.subscriptionTimetoken); + this.entity = parameters.entity; + } +} +/** + * Single-entity subscription object which can be used to receive and handle real-time updates. + */ +class Subscription extends subscription_base_1.SubscriptionBase { + /** + * Create a subscribing capable object for entity. + * + * @param parameters - Subscription object configuration. + * + * @internal + */ + constructor(parameters) { + if ('client' in parameters) { + parameters.client.logger.debug('Subscription', () => ({ + messageType: 'object', + details: 'Create subscription with parameters:', + message: Object.assign({ entity: parameters.entity }, (parameters.options ? parameters.options : {})), + })); + } + else + parameters.state.client.logger.debug('Subscription', 'Create subscription clone'); + super('state' in parameters ? parameters.state : new SubscriptionState(parameters)); + /** + * List of subscription {@link SubscriptionSet sets} which contains {@link Subscription subscription}. + * + * List if used to track usage of a specific {@link Subscription subscription} in other subscription + * {@link SubscriptionSet sets}. + * + * **Important:** Tracking is required to prevent cloned instance dispose if there are sets that still use it. + * + * @internal + */ + this.parents = []; + /** + * List of fingerprints from updates which has been handled already. + * + * **Important:** Tracking is required to avoid repetitive call of the subscription object's listener when the object + * is part of multiple subscribed sets. Handler will be called once, and then the fingerprint will be stored in this + * list to avoid another listener call for it. + * + * @internal + */ + this.handledUpdates = []; + this.state.storeClone(this.id, this); + } + /** + * Get a {@link Subscription} object state. + * + * @returns: {@link Subscription} object state. + * + * @internal + */ + get state() { + return super.state; + } + /** + * Get number of {@link SubscriptionSet} which use this subscription object. + * + * @returns Number of {@link SubscriptionSet} which use this subscription object. + * + * @internal + */ + get parentSetsCount() { + return this.parents.length; + } + // -------------------------------------------------------- + // -------------------- Event handler --------------------- + // -------------------------------------------------------- + // region Event handler + /** + * Dispatch received a real-time update. + * + * @param cursor - A time cursor for the next portion of events. + * @param event - A real-time event from multiplexed subscription. + * + * @return `true` if receiver has consumed event. + * + * @internal + */ + handleEvent(cursor, event) { + var _a; + if (!this.state.isSubscribed) + return; + if (this.parentSetsCount > 0) { + // Creating from whole payload (not only for published messages). + const fingerprint = (0, utils_1.messageFingerprint)(event.data); + if (this.handledUpdates.includes(fingerprint)) { + this.state.client.logger.trace(this.subscriptionType, `Message (${fingerprint}) already handled. Ignoring.`); + return; + } + // Update a list of tracked messages and shrink it if too big. + this.handledUpdates.push(fingerprint); + if (this.handledUpdates.length > 10) + this.handledUpdates.shift(); + } + // Check whether an event is not designated for this subscription set. + if (!this.state.subscriptionInput.contains((_a = event.data.subscription) !== null && _a !== void 0 ? _a : event.data.channel)) + return; + super.handleEvent(cursor, event); + } + // endregion + /** + * User-provided subscription input associated with this {@link Subscription} object. + * + * @param forUnsubscribe - Whether list subscription input created for unsubscription (means entity should be free). + * + * @returns Subscription input object. + * + * @internal + */ + subscriptionInput(forUnsubscribe = false) { + if (forUnsubscribe && this.state.entity.subscriptionsCount > 0) + return new subscription_1.SubscriptionInput({}); + return this.state.subscriptionInput; + } + /** + * Make a bare copy of the {@link Subscription} object. + * + * Copy won't have any type-specific listeners or added listener objects but will have the same internal state as + * the source object. + * + * @returns Bare copy of a {@link Subscription} object. + */ + cloneEmpty() { + return new Subscription({ state: this.state }); + } + /** + * Graceful {@link Subscription} object destruction. + * + * This is an instance destructor, which will properly deinitialize it: + * - remove and unset all listeners, + * - try to unsubscribe (if subscribed and there are no more instances interested in the same data stream). + * + * **Important:** {@link Subscription#dispose dispose} won't have any effect if a subscription object is part of + * {@link SubscriptionSet set}. To gracefully dispose an object, it should be removed from the set using + * {@link SubscriptionSet#removeSubscription removeSubscription} (in this case call of + * {@link Subscription#dispose dispose} not required). + * + * **Note:** Disposed instance won't call the dispatcher to deliver updates to the listeners. + */ + dispose() { + if (this.parentSetsCount > 0) { + this.state.client.logger.debug(this.subscriptionType, () => ({ + messageType: 'text', + message: `'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`, + })); + return; + } + this.handledUpdates.splice(0, this.handledUpdates.length); + super.dispose(); + } + /** + * Invalidate subscription object. + * + * Clean up resources used by a subscription object. + * + * **Note:** An invalidated instance won't call the dispatcher to deliver updates to the listeners. + * + * @param forDestroy - Whether subscription object invalidated as part of PubNub client destroy process or not. + * + * @internal + */ + invalidate(forDestroy = false) { + if (forDestroy) + this.state.entity.decreaseSubscriptionCount(this.state.id); + this.handledUpdates.splice(0, this.handledUpdates.length); + super.invalidate(forDestroy); + } + /** + * Add another {@link SubscriptionSet} into which subscription has been added. + * + * @param parent - {@link SubscriptionSet} which has been modified. + * + * @internal + */ + addParentSet(parent) { + if (!this.parents.includes(parent)) { + this.parents.push(parent); + this.state.client.logger.trace(this.subscriptionType, `Add parent subscription set for ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); + } + } + /** + * Remove {@link SubscriptionSet} upon subscription removal from it. + * + * @param parent - {@link SubscriptionSet} which has been modified. + * + * @internal + */ + removeParentSet(parent) { + const parentIndex = this.parents.indexOf(parent); + if (parentIndex !== -1) { + this.parents.splice(parentIndex, 1); + this.state.client.logger.trace(this.subscriptionType, `Remove parent subscription set from ${this.id}: ${parent.id}. Parent subscription set count: ${this.parentSetsCount}`); + } + if (this.parentSetsCount === 0) + this.handledUpdates.splice(0, this.handledUpdates.length); + } + /** + * Merge entities' subscription objects into {@link SubscriptionSet}. + * + * @param subscription - Another entity's subscription object to be merged with receiver. + * + * @return {@link SubscriptionSet} which contains both receiver and other entities' subscription objects. + */ + addSubscription(subscription) { + this.state.client.logger.debug(this.subscriptionType, () => ({ + messageType: 'text', + message: `Create set with subscription: ${subscription}`, + })); + const subscriptionSet = new subscription_set_1.SubscriptionSet({ + client: this.state.client, + subscriptions: [this, subscription], + options: this.state.options, + }); + // Check whether a source subscription is already subscribed or not. + if (!this.state.isSubscribed && !subscription.state.isSubscribed) + return subscriptionSet; + this.state.client.logger.trace(this.subscriptionType, 'Subscribe resulting set because the receiver is already subscribed.'); + // Subscribing resulting subscription set because source subscription was subscribed. + subscriptionSet.subscribe(); + return subscriptionSet; + } + /** + * Register {@link Subscription} object for real-time events' retrieval. + * + * **Note:** Superclass calls this method only in response to a {@link Subscription.subscribe subscribe} method call. + * + * @param parameters - Object registration parameters. + * @param [parameters.cursor] - Subscription real-time events catch-up cursor. + * @param [parameters.subscriptions] - List of subscription objects which should be registered (in case of partial + * modification). + * + * @internal + */ + register(parameters) { + this.state.entity.increaseSubscriptionCount(this.state.id); + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Register subscription for real-time events: ${this}`, + })); + this.state.client.registerEventHandleCapable(this, parameters.cursor); + } + /** + * Unregister {@link Subscription} object from real-time events' retrieval. + * + * **Note:** Superclass calls this method only in response to a {@link Subscription.unsubscribe unsubscribe} method + * call. + * + * @param [_subscriptions] - List of subscription objects which should be unregistered (in case of partial + * modification). + * + * @internal + */ + unregister(_subscriptions) { + this.state.entity.decreaseSubscriptionCount(this.state.id); + this.state.client.logger.trace(this.subscriptionType, () => ({ + messageType: 'text', + message: `Unregister subscription from real-time events: ${this}`, + })); + this.handledUpdates.splice(0, this.handledUpdates.length); + this.state.client.unregisterEventHandleCapable(this); + } + /** + * Stringify subscription object. + * + * @returns Serialized subscription object. + */ + toString() { + const state = this.state; + return `${this.subscriptionType} { id: ${this.id}, stateId: ${state.id}, entity: ${state.entity + .subscriptionNames(false) + .pop()}, clonesCount: ${Object.keys(state.clones).length}, isSubscribed: ${state.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${state.cursor ? state.cursor.timetoken : 'not set'}, referenceTimetoken: ${state.referenceTimetoken ? state.referenceTimetoken : 'not set'} }`; + } +} +exports.Subscription = Subscription; diff --git a/lib/transport/node-transport.js b/lib/transport/node-transport.js index 507be26e8..9704f86e7 100644 --- a/lib/transport/node-transport.js +++ b/lib/transport/node-transport.js @@ -146,7 +146,6 @@ class NodeTransport { return transportResponse; }) .catch((error) => { - console.log(`~~~~~> ERROR: `, error); const errorMessage = (typeof error === 'string' ? error : error.message).toLowerCase(); let fetchError = typeof error === 'string' ? new Error(error) : error; if (errorMessage.includes('timeout')) { diff --git a/package.json b/package.json index b46f3061f..b9152aa80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pubnub", - "version": "9.6.2", + "version": "9.7.0", "author": "PubNub ", "description": "Publish & Subscribe Real-time Messaging with PubNub", "scripts": { diff --git a/src/core/components/configuration.ts b/src/core/components/configuration.ts index 6610bfc0b..d2f980521 100644 --- a/src/core/components/configuration.ts +++ b/src/core/components/configuration.ts @@ -232,7 +232,7 @@ export const makeConfiguration = ( return base.PubNubFile; }, get version(): string { - return '9.6.2'; + return '9.7.0'; }, getVersion(): string { return this.version;