pusher-js 8.4.2 → 8.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.github/workflows/release.yml +5 -5
  2. package/.github/workflows/release_pr.yml +4 -4
  3. package/.github/workflows/run-tests.yml +13 -8
  4. package/CHANGELOG.md +12 -0
  5. package/dist/node/pusher.js +5715 -5673
  6. package/dist/node/pusher.js.map +1 -1
  7. package/dist/react-native/pusher.js +2 -8
  8. package/dist/react-native/pusher.js.LICENSE.txt +7 -0
  9. package/dist/react-native/pusher.js.map +1 -1
  10. package/dist/web/pusher-with-encryption.js +353 -363
  11. package/dist/web/pusher-with-encryption.js.map +1 -1
  12. package/dist/web/pusher-with-encryption.min.js +2 -8
  13. package/dist/web/pusher-with-encryption.min.js.LICENSE.txt +7 -0
  14. package/dist/web/pusher-with-encryption.min.js.map +1 -1
  15. package/dist/web/pusher.js +340 -348
  16. package/dist/web/pusher.js.map +1 -1
  17. package/dist/web/pusher.min.js +2 -8
  18. package/dist/web/pusher.min.js.LICENSE.txt +7 -0
  19. package/dist/web/pusher.min.js.map +1 -1
  20. package/dist/worker/pusher-with-encryption.worker.js +327 -337
  21. package/dist/worker/pusher-with-encryption.worker.js.map +1 -1
  22. package/dist/worker/pusher-with-encryption.worker.min.js +2 -8
  23. package/dist/worker/pusher-with-encryption.worker.min.js.LICENSE.txt +7 -0
  24. package/dist/worker/pusher-with-encryption.worker.min.js.map +1 -1
  25. package/dist/worker/pusher.worker.js +314 -322
  26. package/dist/worker/pusher.worker.js.map +1 -1
  27. package/dist/worker/pusher.worker.min.js +2 -8
  28. package/dist/worker/pusher.worker.min.js.LICENSE.txt +7 -0
  29. package/dist/worker/pusher.worker.min.js.map +1 -1
  30. package/integration_tests_server/package-lock.json +565 -245
  31. package/integration_tests_server/package.json +2 -1
  32. package/package.json +21 -8
  33. package/spec/config/jasmine/webpack.integration.js +1 -1
  34. package/spec/config/jasmine/webpack.unit.js +1 -1
  35. package/spec/config/karma/config.ci.js +18 -18
  36. package/spec/javascripts/helpers/mocks.js +1 -0
  37. package/spec/javascripts/integration/index.web.js +14 -0
  38. package/spec/javascripts/unit/core/connection/connection_manager_spec.js +43 -0
  39. package/spec/javascripts/unit/core/pusher_spec.js +58 -0
  40. package/src/core/auth/options.ts +9 -11
  41. package/src/core/config.ts +23 -14
  42. package/src/core/connection/connection_manager.ts +9 -0
  43. package/src/core/options.ts +5 -0
  44. package/src/core/pusher.ts +17 -6
  45. package/types/src/core/auth/options.d.ts +5 -10
  46. package/types/src/core/connection/connection_manager.d.ts +1 -0
  47. package/types/src/core/options.d.ts +4 -0
  48. package/types/src/core/pusher.d.ts +3 -1
  49. package/webpack/config.node.js +1 -2
  50. package/webpack/config.react-native.js +1 -2
  51. package/webpack/config.shared.js +6 -6
  52. package/webpack/config.web.js +1 -2
  53. package/webpack/config.worker.js +1 -2
  54. package/webpack/dev.server.js +2 -9
@@ -9,7 +9,8 @@
9
9
  "author": "",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
- "express": "^4.18.2",
12
+ "express": "^4.22.1",
13
+ "path-to-regexp": "^0.1.13",
13
14
  "pusher": "^5.1.1-beta"
14
15
  }
15
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pusher-js",
3
- "version": "8.4.2",
3
+ "version": "8.5.0",
4
4
  "description": "Pusher Channels JavaScript library for browsers, React Native, NodeJS and web workers",
5
5
  "main": "dist/node/pusher.js",
6
6
  "browser": "dist/web/pusher.js",
@@ -50,31 +50,44 @@
50
50
  "karma-safari-launcher": "^1.0.0",
51
51
  "karma-spec-reporter": "0.0.32",
52
52
  "karma-verbose-reporter": "0.0.6",
53
- "karma-webpack": "^4.0.2",
53
+ "karma-webpack": "^5.0.1",
54
54
  "prettier": "^3.4.2",
55
55
  "source-map-loader": "^1.1.3",
56
56
  "ts-loader": "^6.0.4",
57
57
  "typescript": "^5.1.3",
58
- "uglify-js": "^2.6.2",
59
- "webpack": "^4.46.0",
60
- "webpack-cli": "^3.3.12",
61
- "webpack-dev-server": "^4.11.1",
58
+ "uglify-js": "^3.19.3",
59
+ "webpack": "^5.105.4",
60
+ "webpack-cli": "^7.0.2",
61
+ "webpack-dev-server": "^5.2.3",
62
62
  "webpack-merge": "^5.8.0",
63
63
  "xmlhttprequest": "^1.8.0",
64
- "@types/node": "^20.3.0",
64
+ "@types/node": "^25.5.0",
65
65
  "@types/express-serve-static-core": "4.17.28"
66
66
  },
67
67
  "dependencies": {
68
68
  "tweetnacl": "^1.0.3"
69
69
  },
70
70
  "overrides": {
71
+ "flatted": "^3.4.2",
72
+ "picomatch": "^2.3.2",
73
+ "body-parser": "^1.20.3",
74
+ "browserstack-local": "^1.5.12",
71
75
  "cipher-base": "^1.0.6",
72
76
  "compression": "^1.8.1",
77
+ "express": "^4.22.1",
73
78
  "js-yaml": "^3.14.2",
79
+ "lodash": "^4.17.23",
80
+ "minimatch": "^9.0.3",
81
+ "karma": {
82
+ "minimatch": "^3.1.2"
83
+ },
74
84
  "node-forge": "^1.3.2",
75
85
  "on-headers": "^1.1.0",
76
86
  "pbkdf2": "^3.1.5",
87
+ "qs": "^6.14.0",
77
88
  "sha.js": "^2.4.12",
78
- "tmp": "^0.2.4"
89
+ "tmp": "^0.2.4",
90
+ "ws": "^7.5.10",
91
+ "json5": "^2.2.3"
79
92
  }
80
93
  }
@@ -16,7 +16,7 @@ module.exports = merge({}, baseConfig, {
16
16
  output: {
17
17
  filename: "integration_tests_spec.js",
18
18
  path: path.join(__dirname, "..", "..", "..", "tmp", "node_integration"),
19
- libraryTarget: "var"
19
+ library: { type: "var" }
20
20
  },
21
21
  resolve: {
22
22
  modules: ['spec/javascripts/helpers'],
@@ -16,7 +16,7 @@ module.exports = merge({}, baseConfig, {
16
16
  output: {
17
17
  filename: "unit_tests_spec.js",
18
18
  path: path.join(__dirname, "..", "..", "..", "tmp", "node_unit"),
19
- libraryTarget: "var"
19
+ library: { type: "var" }
20
20
  },
21
21
  externals: {
22
22
  testenv: "'node'"
@@ -1,25 +1,25 @@
1
1
  var config = {
2
- browserStack: {
3
- startTunnel: true,
4
- timeout: 1800,
5
- },
6
- browsers: ['ChromeHeadless', 'FirefoxHeadless'],
2
+ browsers: ['ChromeHeadlessNoHttpsUpgrade', 'FirefoxHeadlessNoHttpsUpgrade'],
7
3
  customLaunchers: {
8
- bs_safari_12: {
9
- base: 'BrowserStack',
10
- os_version: "Mojave",
11
- browser: "Safari",
12
- browser_version: "12",
13
- os: "OS X"
4
+ // When forceTLS=true XHR tests run first, browsers store an HSTS entry for
5
+ // sockjs-*.pusher.com (Pusher servers send Strict-Transport-Security headers).
6
+ // Subsequent forceTLS=false XHR tests request HTTP URLs which are then
7
+ // silently upgraded to HTTPS via HSTS. The resulting CORS preflight for the
8
+ // upgraded URL fails, blocking the connection. Disabling web security (Chrome)
9
+ // or HTTPS-only mode (Firefox) bypasses this so the HSTS-upgraded HTTPS
10
+ // response is returned to the Pusher client and the connection can establish.
11
+ ChromeHeadlessNoHttpsUpgrade: {
12
+ base: 'ChromeHeadless',
13
+ flags: ['--disable-web-security']
14
+ },
15
+ FirefoxHeadlessNoHttpsUpgrade: {
16
+ base: 'FirefoxHeadless',
17
+ prefs: {
18
+ 'dom.security.https_only_mode': false,
19
+ 'network.stricttransportsecurity.preloadlist': false
20
+ }
14
21
  }
15
22
  }
16
23
  };
17
- if (process.env.CI === 'full' && browserStackCredsAvailable()) {
18
- config.browsers.push('bs_safari_12');
19
- }
20
-
21
- function browserStackCredsAvailable() {
22
- return process.env.BROWSER_STACK_USERNAME && process.env.BROWSER_STACK_ACCESS_KEY
23
- }
24
24
 
25
25
  module.exports = config;
@@ -245,6 +245,7 @@ var Mocks = {
245
245
  manager.disconnect = jasmine.createSpy("disconnect");
246
246
  manager.send_event = jasmine.createSpy("send_event");
247
247
  manager.isUsingTLS = jasmine.createSpy("isUsingTLS").and.returnValue(false);
248
+ manager.switchCluster = jasmine.createSpy("switchCluster");
248
249
  return manager;
249
250
  },
250
251
 
@@ -59,5 +59,19 @@ function getTestConfigs() {
59
59
  testConfigs.push({ transport: "sockjs", forceTLS: true})
60
60
  testConfigs.push({ transport: "sockjs", forceTLS: false})
61
61
  }
62
+
63
+ // Test all forceTLS: false before forceTLS: true
64
+ // Because browsers prevent a URL from downgrading from HTTPS to HTTP
65
+ // This is probably the result of Strict-Transport-Security header returned when calling the HTTPS endpoint.
66
+ testConfigs.sort((a, b) => {
67
+ if (a.forceTLS == false && b.forceTLS == true) {
68
+ return -1;
69
+ } else if (a.forceTLS == true && b.forceTLS == false) {
70
+ return 1;
71
+ } else {
72
+ return 0;
73
+ }
74
+ })
75
+
62
76
  return testConfigs
63
77
  }
@@ -116,6 +116,49 @@ describe("ConnectionManager", function() {
116
116
  });
117
117
  });
118
118
 
119
+ describe("#switchCluster", function() {
120
+ it("should update cluster key", function() {
121
+ expect(manager.key).toEqual("foo");
122
+ manager.switchCluster("bar");
123
+ expect(manager.key).toEqual("bar");
124
+ });
125
+
126
+ it("should re-build the strategy", function() {
127
+ expect(managerOptions.getStrategy.calls.count()).toEqual(1);
128
+ manager.switchCluster("bar");
129
+ expect(managerOptions.getStrategy.calls.count()).toEqual(2);
130
+ expect(managerOptions.getStrategy).toHaveBeenCalledWith({
131
+ key: "bar",
132
+ useTLS: false,
133
+ timeline: timeline
134
+ });
135
+ });
136
+
137
+ it("should try to connect using the strategy", function() {
138
+ manager.switchCluster("bar");
139
+ // connection is retried with a zero delay
140
+ jasmine.clock().tick(0);
141
+ expect(strategy.connect).toHaveBeenCalled();
142
+ });
143
+
144
+ it("should transition to connecting", function() {
145
+ var onConnecting = jasmine.createSpy("onConnecting");
146
+ var onStateChange = jasmine.createSpy("onStateChange");
147
+ manager.bind("connecting", onConnecting);
148
+ manager.bind("state_change", onStateChange);
149
+
150
+ manager.switchCluster("bar");// connection is retried with a zero delay
151
+ jasmine.clock().tick(0);
152
+
153
+ expect(manager.state).toEqual("connecting");
154
+ expect(onConnecting).toHaveBeenCalled();
155
+ expect(onStateChange).toHaveBeenCalledWith({
156
+ previous: "initialized",
157
+ current: "connecting"
158
+ });
159
+ });
160
+ });
161
+
119
162
  describe("before establishing a connection", function() {
120
163
  beforeEach(function() {
121
164
  manager.connect();
@@ -307,6 +307,64 @@ describe("Pusher", function() {
307
307
  });
308
308
  });
309
309
 
310
+ describe("switch cluster", function() {
311
+ var pusher;
312
+ var subscribedChannels
313
+
314
+ beforeEach(function() {
315
+ pusher = new Pusher("foo", {cluster: "mt1"});
316
+
317
+ subscribedChannels = {
318
+ channel1: pusher.subscribe("channel1"),
319
+ channel2: pusher.subscribe("channel2")
320
+ };
321
+
322
+ pusher.connect();
323
+ pusher.connection.state = "connected";
324
+ pusher.connection.emit("connected");
325
+ });
326
+
327
+ it("should resubscribe to all channels", function() {
328
+ expect(subscribedChannels.channel1.subscribe).toHaveBeenCalledTimes(1);
329
+ expect(subscribedChannels.channel2.subscribe).toHaveBeenCalledTimes(1);
330
+
331
+ pusher.switchCluster({ appKey: 'bar', cluster: 'us3' });
332
+ pusher.connect();
333
+ pusher.connection.state = 'connected';
334
+ pusher.connection.emit('connected');
335
+
336
+ expect(subscribedChannels.channel1.subscribe).toHaveBeenCalledTimes(2);
337
+ expect(subscribedChannels.channel2.subscribe).toHaveBeenCalledTimes(2);
338
+ });
339
+
340
+ it("should send events via the connection manager", function() {
341
+ pusher.switchCluster({ appKey: 'bar', cluster: 'us3' });
342
+ pusher.send_event("event", { key: "value" }, "channel");
343
+ expect(pusher.connection.send_event).toHaveBeenCalledWith(
344
+ "event",
345
+ { key: "value" },
346
+ "channel"
347
+ );
348
+ });
349
+
350
+ it('should keep the persist the previous options', () => {
351
+ var authorizeSpy = jasmine.createSpy("authorizeSpy");
352
+ const options = {
353
+ cluster: "mt1",
354
+ enableStats: true,
355
+ channelAuthorization: {
356
+ customHandler: authorizeSpy
357
+ }
358
+ };
359
+
360
+ var pusher = new Pusher("foo", options);
361
+ pusher.connect();
362
+ pusher.switchCluster({ appKey: 'bar', cluster: 'us3' });
363
+
364
+ expect(pusher.options).toEqual({ ...options, cluster: 'us3' });
365
+ })
366
+ })
367
+
310
368
  describe("#unsubscribe", function() {
311
369
  it("should unsubscribe the channel if subscription is not pending", function() {
312
370
  var channel = pusher.subscribe("yyy");
@@ -51,26 +51,24 @@ export type AuthTransportCallback =
51
51
  | ChannelAuthorizationCallback
52
52
  | UserAuthenticationCallback;
53
53
 
54
- export interface AuthOptionsT<AuthHandler> {
54
+ export interface InternalAuthOptions {
55
55
  transport: 'ajax' | 'jsonp';
56
56
  endpoint: string;
57
57
  params?: any;
58
58
  headers?: any;
59
59
  paramsProvider?: () => any;
60
60
  headersProvider?: () => any;
61
- customHandler?: AuthHandler;
62
61
  }
63
62
 
63
+ export type CustomAuthOptions<AuthHandler> = {
64
+ customHandler: AuthHandler;
65
+ };
66
+
67
+ export type AuthOptionsT<AuthHandler> =
68
+ | InternalAuthOptions
69
+ | CustomAuthOptions<AuthHandler>;
70
+
64
71
  export declare type UserAuthenticationOptions =
65
72
  AuthOptionsT<UserAuthenticationHandler>;
66
73
  export declare type ChannelAuthorizationOptions =
67
74
  AuthOptionsT<ChannelAuthorizationHandler>;
68
-
69
- export interface InternalAuthOptions {
70
- transport: 'ajax' | 'jsonp';
71
- endpoint: string;
72
- params?: any;
73
- headers?: any;
74
- paramsProvider?: () => any;
75
- headersProvider?: () => any;
76
- }
@@ -4,6 +4,8 @@ import {
4
4
  ChannelAuthorizationHandler,
5
5
  UserAuthenticationHandler,
6
6
  ChannelAuthorizationOptions,
7
+ AuthOptionsT,
8
+ CustomAuthOptions,
7
9
  } from './auth/options';
8
10
  import UserAuthenticator from './auth/user_authenticator';
9
11
  import ChannelAuthorizer from './auth/channel_authorizer';
@@ -131,15 +133,19 @@ function getEnableStatsConfig(opts: Options): boolean {
131
133
  return false;
132
134
  }
133
135
 
136
+ const hasCustomHandler = <T>(
137
+ auth: AuthOptionsT<T>,
138
+ ): auth is CustomAuthOptions<T> => {
139
+ return 'customHandler' in auth && auth['customHandler'] != null;
140
+ };
141
+
134
142
  function buildUserAuthenticator(opts: Options): UserAuthenticationHandler {
135
143
  const userAuthentication = {
136
144
  ...Defaults.userAuthentication,
137
145
  ...opts.userAuthentication,
138
146
  };
139
- if (
140
- 'customHandler' in userAuthentication &&
141
- userAuthentication['customHandler'] != null
142
- ) {
147
+
148
+ if (hasCustomHandler(userAuthentication)) {
143
149
  return userAuthentication['customHandler'];
144
150
  }
145
151
 
@@ -158,17 +164,22 @@ function buildChannelAuth(opts: Options, pusher): ChannelAuthorizationOptions {
158
164
  transport: opts.authTransport || Defaults.authTransport,
159
165
  endpoint: opts.authEndpoint || Defaults.authEndpoint,
160
166
  };
167
+
161
168
  if ('auth' in opts) {
162
169
  if ('params' in opts.auth) channelAuthorization.params = opts.auth.params;
163
170
  if ('headers' in opts.auth)
164
171
  channelAuthorization.headers = opts.auth.headers;
165
172
  }
166
- if ('authorizer' in opts)
167
- channelAuthorization.customHandler = ChannelAuthorizerProxy(
168
- pusher,
169
- channelAuthorization,
170
- opts.authorizer,
171
- );
173
+
174
+ if ('authorizer' in opts) {
175
+ return {
176
+ customHandler: ChannelAuthorizerProxy(
177
+ pusher,
178
+ channelAuthorization,
179
+ opts.authorizer,
180
+ ),
181
+ };
182
+ }
172
183
  }
173
184
  return channelAuthorization;
174
185
  }
@@ -178,10 +189,8 @@ function buildChannelAuthorizer(
178
189
  pusher,
179
190
  ): ChannelAuthorizationHandler {
180
191
  const channelAuthorization = buildChannelAuth(opts, pusher);
181
- if (
182
- 'customHandler' in channelAuthorization &&
183
- channelAuthorization['customHandler'] != null
184
- ) {
192
+
193
+ if (hasCustomHandler(channelAuthorization)) {
185
194
  return channelAuthorization['customHandler'];
186
195
  }
187
196
 
@@ -96,6 +96,15 @@ export default class ConnectionManager extends EventsDispatcher {
96
96
  this.updateStrategy();
97
97
  }
98
98
 
99
+ switchCluster(key: string) {
100
+ this.key = key;
101
+ // This ensures that the new config coming from
102
+ // pusher instance are taken into account
103
+ // such as appKey and cluster
104
+ this.updateStrategy();
105
+ this.retryIn(0);
106
+ }
107
+
99
108
  /** Establishes a connection to Pusher.
100
109
  *
101
110
  * Does nothing when connection is already established. See top-level doc
@@ -44,6 +44,11 @@ export interface Options {
44
44
  wssPort?: number;
45
45
  }
46
46
 
47
+ export interface ClusterOptions {
48
+ appKey: string;
49
+ cluster: string;
50
+ }
51
+
47
52
  export function validateOptions(options) {
48
53
  if (options == null) {
49
54
  throw 'You must pass an options object';
@@ -1,6 +1,5 @@
1
1
  import AbstractRuntime from '../runtimes/interface';
2
2
  import Runtime from 'runtime';
3
- import Util from './util';
4
3
  import * as Collections from './utils/collections';
5
4
  import Channels from './channels/channels';
6
5
  import Channel from './channels/channel';
@@ -10,14 +9,11 @@ import TimelineSender from './timeline/timeline_sender';
10
9
  import TimelineLevel from './timeline/level';
11
10
  import { defineTransport } from './strategies/strategy_builder';
12
11
  import ConnectionManager from './connection/connection_manager';
13
- import ConnectionManagerOptions from './connection/connection_manager_options';
14
12
  import { PeriodicTimer } from './utils/timers';
15
13
  import Defaults from './defaults';
16
- import * as DefaultConfig from './config';
17
14
  import Logger from './logger';
18
15
  import Factory from './utils/factory';
19
- import UrlStore from 'core/utils/url_store';
20
- import { Options, validateOptions } from './options';
16
+ import { Options, ClusterOptions, validateOptions } from './options';
21
17
  import { Config, getConfig } from './config';
22
18
  import StrategyOptions from './strategies/strategy_options';
23
19
  import UserFacade from './user';
@@ -53,6 +49,7 @@ export default class Pusher {
53
49
 
54
50
  /* INSTANCE PROPERTIES */
55
51
  key: string;
52
+ options: Options;
56
53
  config: Config;
57
54
  channels: Channels;
58
55
  global_emitter: EventsDispatcher;
@@ -66,7 +63,8 @@ export default class Pusher {
66
63
  checkAppKey(app_key);
67
64
  validateOptions(options);
68
65
  this.key = app_key;
69
- this.config = getConfig(options, this);
66
+ this.options = options;
67
+ this.config = getConfig(this.options, this);
70
68
 
71
69
  this.channels = Factory.createChannels();
72
70
  this.global_emitter = new EventsDispatcher();
@@ -141,6 +139,19 @@ export default class Pusher {
141
139
  }
142
140
  }
143
141
 
142
+ /**
143
+ * Allows you to switch Pusher cluster without
144
+ * losing all the channels/subscription binding
145
+ * as this is internally managed by the SDK.
146
+ */
147
+ switchCluster(options: ClusterOptions) {
148
+ const { appKey, cluster } = options;
149
+ this.key = appKey;
150
+ this.options = { ...this.options, cluster };
151
+ this.config = getConfig(this.options, this);
152
+ this.connection.switchCluster(this.key);
153
+ }
154
+
144
155
  channel(name: string): Channel {
145
156
  return this.channels.find(name);
146
157
  }
@@ -27,22 +27,17 @@ export interface UserAuthenticationHandler {
27
27
  (params: UserAuthenticationRequestParams, callback: UserAuthenticationCallback): void;
28
28
  }
29
29
  export type AuthTransportCallback = ChannelAuthorizationCallback | UserAuthenticationCallback;
30
- export interface AuthOptionsT<AuthHandler> {
30
+ export interface InternalAuthOptions {
31
31
  transport: 'ajax' | 'jsonp';
32
32
  endpoint: string;
33
33
  params?: any;
34
34
  headers?: any;
35
35
  paramsProvider?: () => any;
36
36
  headersProvider?: () => any;
37
- customHandler?: AuthHandler;
38
37
  }
38
+ export type CustomAuthOptions<AuthHandler> = {
39
+ customHandler: AuthHandler;
40
+ };
41
+ export type AuthOptionsT<AuthHandler> = InternalAuthOptions | CustomAuthOptions<AuthHandler>;
39
42
  export declare type UserAuthenticationOptions = AuthOptionsT<UserAuthenticationHandler>;
40
43
  export declare type ChannelAuthorizationOptions = AuthOptionsT<ChannelAuthorizationHandler>;
41
- export interface InternalAuthOptions {
42
- transport: 'ajax' | 'jsonp';
43
- endpoint: string;
44
- params?: any;
45
- headers?: any;
46
- paramsProvider?: () => any;
47
- headersProvider?: () => any;
48
- }
@@ -24,6 +24,7 @@ export default class ConnectionManager extends EventsDispatcher {
24
24
  handshakeCallbacks: HandshakeCallbacks;
25
25
  connectionCallbacks: ConnectionCallbacks;
26
26
  constructor(key: string, options: ConnectionManagerOptions);
27
+ switchCluster(key: string): void;
27
28
  connect(): void;
28
29
  send(data: any): boolean;
29
30
  send_event(name: string, data: any, channel?: string): boolean;
@@ -31,4 +31,8 @@ export interface Options {
31
31
  wsPort?: number;
32
32
  wssPort?: number;
33
33
  }
34
+ export interface ClusterOptions {
35
+ appKey: string;
36
+ cluster: string;
37
+ }
34
38
  export declare function validateOptions(options: any): void;
@@ -6,7 +6,7 @@ import Timeline from './timeline/timeline';
6
6
  import TimelineSender from './timeline/timeline_sender';
7
7
  import ConnectionManager from './connection/connection_manager';
8
8
  import { PeriodicTimer } from './utils/timers';
9
- import { Options } from './options';
9
+ import { Options, ClusterOptions } from './options';
10
10
  import { Config } from './config';
11
11
  import UserFacade from './user';
12
12
  export default class Pusher {
@@ -21,6 +21,7 @@ export default class Pusher {
21
21
  static log: (message: any) => void;
22
22
  private static getClientFeatures;
23
23
  key: string;
24
+ options: Options;
24
25
  config: Config;
25
26
  channels: Channels;
26
27
  global_emitter: EventsDispatcher;
@@ -31,6 +32,7 @@ export default class Pusher {
31
32
  timelineSenderTimer: PeriodicTimer;
32
33
  user: UserFacade;
33
34
  constructor(app_key: string, options: Options);
35
+ switchCluster(options: ClusterOptions): void;
34
36
  channel(name: string): Channel;
35
37
  allChannels(): Channel[];
36
38
  connect(): void;
@@ -8,8 +8,7 @@ module.exports = merge({}, configShared, {
8
8
  pusher: './src/core/pusher-with-encryption.js',
9
9
  },
10
10
  output: {
11
- library: 'Pusher',
12
- libraryTarget: 'commonjs2',
11
+ library: { name: 'Pusher', type: 'commonjs2' },
13
12
  path: path.join(__dirname, '../dist/node'),
14
13
  filename: 'pusher.js',
15
14
  },
@@ -12,8 +12,7 @@ module.exports = merge({}, configShared, {
12
12
  pusher: './src/core/pusher-with-encryption.js',
13
13
  },
14
14
  output: {
15
- library: 'Pusher',
16
- libraryTarget: 'commonjs2',
15
+ library: { name: 'Pusher', type: 'commonjs2' },
17
16
  path: path.join(__dirname, '../dist/react-native'),
18
17
  filename: 'pusher.js',
19
18
  },
@@ -21,6 +21,12 @@ module.exports = {
21
21
  extensions: ['.webpack.js', '.web.js', '.ts', '.js'],
22
22
  // add runtimes for easier importing of isomorphic runtime modules
23
23
  modules: ['src', 'src/runtimes', 'node_modules'],
24
+ fallback: {
25
+ // nacl uses Buffer on node.js but has a different code path for the browser.
26
+ // We don't need webpack to include a Buffer polyfill when seeing the usage,
27
+ // as it won't be used.
28
+ buffer: false,
29
+ },
24
30
  },
25
31
  module: {
26
32
  rules: [
@@ -32,12 +38,6 @@ module.exports = {
32
38
  },
33
39
  ],
34
40
  },
35
- node: {
36
- // nacl uses Buffer on node.js but has a different code path for the browser.
37
- // We don't need webpack to include a Buffer polyfill when seeing the usage,
38
- // as it won't be used.
39
- Buffer: false,
40
- },
41
41
  plugins: [
42
42
  new webpack.BannerPlugin({ banner: banner, raw: true }),
43
43
  new webpack.DefinePlugin({
@@ -19,10 +19,9 @@ module.exports = merge({}, configShared, {
19
19
  pusher: entry,
20
20
  },
21
21
  output: {
22
- library: 'Pusher',
22
+ library: { name: 'Pusher', type: 'umd' },
23
23
  path: path.join(__dirname, '../dist/web'),
24
24
  filename: filename,
25
- libraryTarget: 'umd',
26
25
  },
27
26
  resolve: {
28
27
  modules: ['src/runtimes/web'],
@@ -21,10 +21,9 @@ var config = merge(configShared, {
21
21
  pusher: entry,
22
22
  },
23
23
  output: {
24
- library: 'Pusher',
24
+ library: { name: 'Pusher', type: 'umd' },
25
25
  path: path.join(__dirname, '../dist/worker'),
26
26
  filename: filename,
27
- libraryTarget: 'umd',
28
27
  globalObject: 'this',
29
28
  },
30
29
  resolve: {
@@ -4,14 +4,7 @@ var WebpackDevServer = require('webpack-dev-server');
4
4
 
5
5
  var port = parseInt(process.env.PORT) || 5555;
6
6
 
7
- config.entry.app = [
8
- 'webpack-dev-server/client?http://localhost:' + port + '/',
9
- 'webpack/hot/dev-server',
10
- ];
11
-
12
7
  var compiler = webpack(config);
13
- var server = new WebpackDevServer(compiler, {
14
- hot: true,
15
- });
8
+ var server = new WebpackDevServer({ hot: true, port: port }, compiler);
16
9
 
17
- server.listen(port);
10
+ server.start();