Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .mocharc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"spec": "test/**/*.test.ts",
"exclude": [
"test/dist/*.{js,ts}",
"test/feature/*.{js,ts}"
"test/feature/*.{js,ts}",
"test/integration/shared-worker/*.{js,ts}"
],
"timeout": 5000,
"reporter": "spec"
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"parser" : "typescript",
"parser": "typescript",
"semi": true,
"printWidth": 120,
"singleQuote": true,
Expand Down
1,688 changes: 910 additions & 778 deletions dist/web/pubnub.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/web/pubnub.min.js

Large diffs are not rendered by default.

413 changes: 330 additions & 83 deletions dist/web/pubnub.worker.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/web/pubnub.worker.min.js

Large diffs are not rendered by default.

134 changes: 134 additions & 0 deletions karma/shared-worker.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
const process = require('process');

module.exports = function (config) {
config.set({
// Base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '../',

// Frameworks to use
frameworks: ['mocha', 'chai'],

// List of files / patterns to load in the browser
files: [
// Include the built PubNub library
'dist/web/pubnub.js',
// Include the shared worker file
{ pattern: 'dist/web/pubnub.worker.js', included: false, served: true },
// Include the test file
'test/integration/shared-worker/shared-worker.test.ts',
],

// List of files to exclude
exclude: [],

// Preprocess matching files before serving them to the browser
preprocessors: {
'test/**/*.ts': ['webpack', 'sourcemap'],
},

// Webpack configuration
webpack: {
mode: 'development',
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.ts', '.js'],
fallback: {
"crypto": false,
"stream": false,
"buffer": require.resolve("buffer"),
"util": require.resolve("util/"),
"url": false,
"querystring": false,
"path": false,
"fs": false,
"net": false,
"tls": false,
"os": false,
"process": require.resolve("process/browser"),
},
},
plugins: [
new (require('webpack')).ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer'],
}),
],
devtool: 'inline-source-map',
stats: 'errors-only',
},

webpackMiddleware: {
logLevel: 'error',
},

// Test results reporter to use
reporters: ['spec'],

// Web server port
port: 9876,

// Enable / disable colors in the output (reporters and logs)
colors: true,

// Level of logging
logLevel: config.LOG_INFO,

// Enable / disable watching file and executing tests whenever any file changes
autoWatch: false,

// Start these browsers
browsers: ['Chrome_SharedWorker'],

// Continuous Integration mode
singleRun: true,

// Browser disconnect timeout
browserDisconnectTimeout: 30000,

// Browser no activity timeout
browserNoActivityTimeout: 30000,

// Capture timeout
captureTimeout: 30000,

// Custom launcher for shared worker testing
customLaunchers: {
Chrome_SharedWorker: {
base: 'ChromeHeadless',
flags: [
'--disable-web-security',
'--disable-features=VizDisplayCompositor',
'--enable-shared-worker',
'--allow-running-insecure-content',
'--disable-background-timer-throttling',
'--disable-renderer-backgrounding',
'--disable-backgrounding-occluded-windows',
'--no-sandbox',
'--disable-setuid-sandbox',
],
},
},

// Client configuration
client: {
mocha: {
timeout: 30000, // Longer timeout for network tests
reporter: 'spec',
},
captureConsole: true,
},

// Proxies for serving worker files
proxies: {
'/dist/': '/base/dist/',
},
});
};
8 changes: 8 additions & 0 deletions lib/core/constants/categories.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ var StatusCategory;
* - Wi-Fi hotspot authorization page.
*/
StatusCategory["PNMalformedResponseCategory"] = "PNMalformedResponseCategory";
/**
* Server can't process request.
*
* There can be few sources of unexpected return with success code:
* - potentially an ongoing incident;
* - proxy server / VPN.
*/
StatusCategory["PNServerErrorCategory"] = "PNServerErrorCategory";
/**
* Something strange happened; please check the logs.
*/
Expand Down
29 changes: 18 additions & 11 deletions lib/core/pubnub-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ class PubNubCore {
setAuthKey(authKey) {
this.logger.debug('PubNub', `Set auth key: ${authKey}`);
this._configuration.setAuthKey(authKey);
if (this.onAuthenticationChange)
this.onAuthenticationChange(authKey);
}
/**
* Get a PubNub client user identifier.
Expand All @@ -469,6 +471,8 @@ class PubNubCore {
}
this.logger.debug('PubNub', `Set user ID: ${value}`);
this._configuration.userId = value;
if (this.onUserIdChange)
this.onUserIdChange(this._configuration.userId);
}
/**
* Get a PubNub client user identifier.
Expand All @@ -488,13 +492,7 @@ class PubNubCore {
* @throws Error empty user identifier has been provided.
*/
setUserId(value) {
if (!value || typeof value !== 'string' || value.trim().length === 0) {
const error = new Error('Missing or invalid userId parameter. Provide a valid string userId');
this.logger.error('PubNub', () => ({ messageType: 'error', message: error }));
throw error;
}
this.logger.debug('PubNub', `Set user ID: ${value}`);
this._configuration.userId = value;
this.userId = value;
}
/**
* Real-time updates filtering expression.
Expand Down Expand Up @@ -562,16 +560,18 @@ class PubNubCore {
* @param interval - New presence request heartbeat intervals.
*/
set heartbeatInterval(interval) {
var _a;
this.logger.debug('PubNub', `Set heartbeat interval: ${interval}`);
this._configuration.setHeartbeatInterval(interval);
if (this.onHeartbeatIntervalChange)
this.onHeartbeatIntervalChange((_a = this._configuration.getHeartbeatInterval()) !== null && _a !== void 0 ? _a : 0);
}
/**
* Change a heartbeat requests interval.
*
* @param interval - New presence request heartbeat intervals.
*/
setHeartbeatInterval(interval) {
this.logger.debug('PubNub', `Set heartbeat interval: ${interval}`);
this.heartbeatInterval = interval;
}
/**
Expand Down Expand Up @@ -1073,9 +1073,14 @@ class PubNubCore {
message: { subscription: subscription, subscriptions },
details: `Unregister event handle capable:`,
}));
if (!subscriptions ||
subscriptions.length === 0 ||
(subscriptions && subscription instanceof subscription_set_1.SubscriptionSet && subscriptions === subscriptions))
// Check whether only subscription object has been passed to be unregistered.
let shouldDeleteEventHandler = !subscriptions || subscriptions.length === 0;
// Check whether subscription set is unregistering with all managed Subscription objects,
if (!shouldDeleteEventHandler &&
subscription instanceof subscription_set_1.SubscriptionSet &&
subscription.subscriptions.length === (subscriptions === null || subscriptions === void 0 ? void 0 : subscriptions.length))
shouldDeleteEventHandler = subscription.subscriptions.every((sub) => subscriptions.includes(sub));
if (shouldDeleteEventHandler)
delete this.eventHandleCapable[subscription.state.id];
let subscriptionInput;
if (!subscriptions || subscriptions.length === 0) {
Expand Down Expand Up @@ -2149,6 +2154,8 @@ class PubNubCore {
set token(token) {
if (this.tokenManager)
this.tokenManager.setToken(token);
if (this.onAuthenticationChange)
this.onAuthenticationChange(token);
}
/**
* Set current access token.
Expand Down
18 changes: 3 additions & 15 deletions lib/entities/subscription-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ class SubscriptionBase {
* Create a subscription object from the state.
*
* @param state - Subscription state object.
* @param subscriptionType - Actual subscription object type.
*
* @internal
*/
constructor(state) {
constructor(state, subscriptionType = 'Subscription') {
this.subscriptionType = subscriptionType;
/**
* Unique subscription object identifier.
*
Expand All @@ -150,20 +152,6 @@ 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.
*
Expand Down
38 changes: 19 additions & 19 deletions lib/entities/subscription-set.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,6 @@ 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.
*
Expand Down Expand Up @@ -151,7 +137,7 @@ class SubscriptionSet extends subscription_base_1.SubscriptionBase {
state = parameters.state;
state.client.logger.debug('SubscriptionSet', 'Create subscription set clone');
}
super(state);
super(state, 'SubscriptionSet');
this.state.storeClone(this.id, this);
// Update a parent sets list for original set subscriptions.
state.subscriptions.forEach((subscription) => subscription.addParentSet(this));
Expand Down Expand Up @@ -428,10 +414,24 @@ 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.subscriptionType, () => ({
messageType: 'text',
message: `Unregister subscription from real-time events: ${this}`,
}));
this.state.client.logger.trace(this.subscriptionType, () => {
if (!subscriptions) {
return {
messageType: 'text',
message: `Unregister subscription from real-time events: ${this}`,
};
}
else {
return {
messageType: 'object',
message: {
subscription: this,
subscriptions,
},
details: 'Unregister subscriptions of subscription set from real-time events:',
};
}
});
this.state.client.unregisterEventHandleCapable(this, activeSubscriptions);
}
/**
Expand Down
4 changes: 4 additions & 0 deletions lib/errors/pubnub-api-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ class PubNubAPIError extends Error {
category = categories_1.default.PNAccessDeniedCategory;
message = 'Access denied';
}
else if (status >= 500) {
category = categories_1.default.PNServerErrorCategory;
message = 'Internal server error';
}
if (typeof response === 'object' && Object.keys(response).length === 0) {
category = categories_1.default.PNMalformedResponseCategory;
message = 'Malformed response (network issues)';
Expand Down
11 changes: 10 additions & 1 deletion lib/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ declare class PubNubCore<
* configured PubNub client `uuid` if not set.
* @param callback - Request completion handler callback.
*
* @deprecated Use {@link PubNubCore#objects.getUUIDMetadata getUUIDMetadata} method instead.
* @deprecated Use {@link PubNubCore#objects.getUUIDMetadata|getUUIDMetadata} method instead.
*/
fetchUser<Custom extends PubNub.AppContext.CustomData = PubNub.AppContext.CustomData>(
parameters: PubNub.AppContext.GetUUIDMetadataParameters,
Expand Down Expand Up @@ -2143,6 +2143,14 @@ declare namespace PubNub {
* - Wi-Fi hotspot authorization page.
*/
PNMalformedResponseCategory = 'PNMalformedResponseCategory',
/**
* Server can't process request.
*
* There can be few sources of unexpected return with success code:
* - potentially an ongoing incident;
* - proxy server / VPN.
*/
PNServerErrorCategory = 'PNServerErrorCategory',
/**
* Something strange happened; please check the logs.
*/
Expand Down Expand Up @@ -4577,6 +4585,7 @@ declare namespace PubNub {
* Implementation of base functionality used by {@link SubscriptionObject Subscription} and {@link SubscriptionSet}.
*/
export abstract class SubscriptionBase implements EventEmitCapable, EventHandleCapable {
protected readonly subscriptionType: 'Subscription' | 'SubscriptionSet';
/**
* Get a list of channels which is used for subscription.
*
Expand Down
Loading
Loading