Server : nginx/1.18.0 System : Linux localhost 6.14.3-x86_64-linode168 #1 SMP PREEMPT_DYNAMIC Mon Apr 21 19:47:55 EDT 2025 x86_64 User : www-data ( 33) PHP Version : 8.0.16 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /var/www/ecommerce/node_modules/pusher-js/src/core/strategies/ |
import Util from '../util';
import Runtime from 'runtime';
import Strategy from './strategy';
import SequentialStrategy from './sequential_strategy';
import StrategyOptions from './strategy_options';
import TransportStrategy from './transport_strategy';
import Timeline from '../timeline/timeline';
import * as Collections from '../utils/collections';
export interface TransportStrategyDictionary {
[key: string]: TransportStrategy;
}
/** Caches last successful transport and uses it for following attempts.
*
* @param {Strategy} strategy
* @param {Object} transports
* @param {Object} options
*/
export default class CachedStrategy implements Strategy {
strategy: Strategy;
transports: TransportStrategyDictionary;
ttl: number;
usingTLS: boolean;
timeline: Timeline;
constructor(
strategy: Strategy,
transports: TransportStrategyDictionary,
options: StrategyOptions
) {
this.strategy = strategy;
this.transports = transports;
this.ttl = options.ttl || 1800 * 1000;
this.usingTLS = options.useTLS;
this.timeline = options.timeline;
}
isSupported(): boolean {
return this.strategy.isSupported();
}
connect(minPriority: number, callback: Function) {
var usingTLS = this.usingTLS;
var info = fetchTransportCache(usingTLS);
var strategies = [this.strategy];
if (info && info.timestamp + this.ttl >= Util.now()) {
var transport = this.transports[info.transport];
if (transport) {
this.timeline.info({
cached: true,
transport: info.transport,
latency: info.latency
});
strategies.push(
new SequentialStrategy([transport], {
timeout: info.latency * 2 + 1000,
failFast: true
})
);
}
}
var startTimestamp = Util.now();
var runner = strategies
.pop()
.connect(minPriority, function cb(error, handshake) {
if (error) {
flushTransportCache(usingTLS);
if (strategies.length > 0) {
startTimestamp = Util.now();
runner = strategies.pop().connect(minPriority, cb);
} else {
callback(error);
}
} else {
storeTransportCache(
usingTLS,
handshake.transport.name,
Util.now() - startTimestamp
);
callback(null, handshake);
}
});
return {
abort: function() {
runner.abort();
},
forceMinPriority: function(p) {
minPriority = p;
if (runner) {
runner.forceMinPriority(p);
}
}
};
}
}
function getTransportCacheKey(usingTLS: boolean): string {
return 'pusherTransport' + (usingTLS ? 'TLS' : 'NonTLS');
}
function fetchTransportCache(usingTLS: boolean): any {
var storage = Runtime.getLocalStorage();
if (storage) {
try {
var serializedCache = storage[getTransportCacheKey(usingTLS)];
if (serializedCache) {
return JSON.parse(serializedCache);
}
} catch (e) {
flushTransportCache(usingTLS);
}
}
return null;
}
function storeTransportCache(
usingTLS: boolean,
transport: TransportStrategy,
latency: number
) {
var storage = Runtime.getLocalStorage();
if (storage) {
try {
storage[getTransportCacheKey(usingTLS)] = Collections.safeJSONStringify({
timestamp: Util.now(),
transport: transport,
latency: latency
});
} catch (e) {
// catch over quota exceptions raised by localStorage
}
}
}
function flushTransportCache(usingTLS: boolean) {
var storage = Runtime.getLocalStorage();
if (storage) {
try {
delete storage[getTransportCacheKey(usingTLS)];
} catch (e) {
// catch exceptions raised by localStorage
}
}
}