hotwire-livereload 1.4.1 → 2.0.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.
@@ -25,585 +25,6 @@
25
25
  mod
26
26
  ));
27
27
 
28
- // node_modules/@rails/actioncable/app/assets/javascripts/action_cable.js
29
- var require_action_cable = __commonJS({
30
- "node_modules/@rails/actioncable/app/assets/javascripts/action_cable.js"(exports, module) {
31
- (function(global, factory) {
32
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : factory(global.ActionCable = {});
33
- })(exports, function(exports2) {
34
- "use strict";
35
- var adapters = {
36
- logger: self.console,
37
- WebSocket: self.WebSocket
38
- };
39
- var logger = {
40
- log: function log() {
41
- if (this.enabled) {
42
- var _adapters$logger;
43
- for (var _len = arguments.length, messages = Array(_len), _key = 0; _key < _len; _key++) {
44
- messages[_key] = arguments[_key];
45
- }
46
- messages.push(Date.now());
47
- (_adapters$logger = adapters.logger).log.apply(_adapters$logger, ["[ActionCable]"].concat(messages));
48
- }
49
- }
50
- };
51
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
52
- return typeof obj;
53
- } : function(obj) {
54
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
55
- };
56
- var classCallCheck = function(instance, Constructor) {
57
- if (!(instance instanceof Constructor)) {
58
- throw new TypeError("Cannot call a class as a function");
59
- }
60
- };
61
- var createClass = function() {
62
- function defineProperties(target, props) {
63
- for (var i = 0; i < props.length; i++) {
64
- var descriptor = props[i];
65
- descriptor.enumerable = descriptor.enumerable || false;
66
- descriptor.configurable = true;
67
- if ("value" in descriptor)
68
- descriptor.writable = true;
69
- Object.defineProperty(target, descriptor.key, descriptor);
70
- }
71
- }
72
- return function(Constructor, protoProps, staticProps) {
73
- if (protoProps)
74
- defineProperties(Constructor.prototype, protoProps);
75
- if (staticProps)
76
- defineProperties(Constructor, staticProps);
77
- return Constructor;
78
- };
79
- }();
80
- var now = function now2() {
81
- return (/* @__PURE__ */ new Date()).getTime();
82
- };
83
- var secondsSince = function secondsSince2(time) {
84
- return (now() - time) / 1e3;
85
- };
86
- var clamp = function clamp2(number, min, max) {
87
- return Math.max(min, Math.min(max, number));
88
- };
89
- var ConnectionMonitor = function() {
90
- function ConnectionMonitor2(connection) {
91
- classCallCheck(this, ConnectionMonitor2);
92
- this.visibilityDidChange = this.visibilityDidChange.bind(this);
93
- this.connection = connection;
94
- this.reconnectAttempts = 0;
95
- }
96
- ConnectionMonitor2.prototype.start = function start() {
97
- if (!this.isRunning()) {
98
- this.startedAt = now();
99
- delete this.stoppedAt;
100
- this.startPolling();
101
- addEventListener("visibilitychange", this.visibilityDidChange);
102
- logger.log("ConnectionMonitor started. pollInterval = " + this.getPollInterval() + " ms");
103
- }
104
- };
105
- ConnectionMonitor2.prototype.stop = function stop() {
106
- if (this.isRunning()) {
107
- this.stoppedAt = now();
108
- this.stopPolling();
109
- removeEventListener("visibilitychange", this.visibilityDidChange);
110
- logger.log("ConnectionMonitor stopped");
111
- }
112
- };
113
- ConnectionMonitor2.prototype.isRunning = function isRunning() {
114
- return this.startedAt && !this.stoppedAt;
115
- };
116
- ConnectionMonitor2.prototype.recordPing = function recordPing() {
117
- this.pingedAt = now();
118
- };
119
- ConnectionMonitor2.prototype.recordConnect = function recordConnect() {
120
- this.reconnectAttempts = 0;
121
- this.recordPing();
122
- delete this.disconnectedAt;
123
- logger.log("ConnectionMonitor recorded connect");
124
- };
125
- ConnectionMonitor2.prototype.recordDisconnect = function recordDisconnect() {
126
- this.disconnectedAt = now();
127
- logger.log("ConnectionMonitor recorded disconnect");
128
- };
129
- ConnectionMonitor2.prototype.startPolling = function startPolling() {
130
- this.stopPolling();
131
- this.poll();
132
- };
133
- ConnectionMonitor2.prototype.stopPolling = function stopPolling() {
134
- clearTimeout(this.pollTimeout);
135
- };
136
- ConnectionMonitor2.prototype.poll = function poll() {
137
- var _this = this;
138
- this.pollTimeout = setTimeout(function() {
139
- _this.reconnectIfStale();
140
- _this.poll();
141
- }, this.getPollInterval());
142
- };
143
- ConnectionMonitor2.prototype.getPollInterval = function getPollInterval() {
144
- var _constructor$pollInte = this.constructor.pollInterval, min = _constructor$pollInte.min, max = _constructor$pollInte.max, multiplier = _constructor$pollInte.multiplier;
145
- var interval = multiplier * Math.log(this.reconnectAttempts + 1);
146
- return Math.round(clamp(interval, min, max) * 1e3);
147
- };
148
- ConnectionMonitor2.prototype.reconnectIfStale = function reconnectIfStale() {
149
- if (this.connectionIsStale()) {
150
- logger.log("ConnectionMonitor detected stale connection. reconnectAttempts = " + this.reconnectAttempts + ", pollInterval = " + this.getPollInterval() + " ms, time disconnected = " + secondsSince(this.disconnectedAt) + " s, stale threshold = " + this.constructor.staleThreshold + " s");
151
- this.reconnectAttempts++;
152
- if (this.disconnectedRecently()) {
153
- logger.log("ConnectionMonitor skipping reopening recent disconnect");
154
- } else {
155
- logger.log("ConnectionMonitor reopening");
156
- this.connection.reopen();
157
- }
158
- }
159
- };
160
- ConnectionMonitor2.prototype.connectionIsStale = function connectionIsStale() {
161
- return secondsSince(this.pingedAt ? this.pingedAt : this.startedAt) > this.constructor.staleThreshold;
162
- };
163
- ConnectionMonitor2.prototype.disconnectedRecently = function disconnectedRecently() {
164
- return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
165
- };
166
- ConnectionMonitor2.prototype.visibilityDidChange = function visibilityDidChange() {
167
- var _this2 = this;
168
- if (document.visibilityState === "visible") {
169
- setTimeout(function() {
170
- if (_this2.connectionIsStale() || !_this2.connection.isOpen()) {
171
- logger.log("ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = " + document.visibilityState);
172
- _this2.connection.reopen();
173
- }
174
- }, 200);
175
- }
176
- };
177
- return ConnectionMonitor2;
178
- }();
179
- ConnectionMonitor.pollInterval = {
180
- min: 3,
181
- max: 30,
182
- multiplier: 5
183
- };
184
- ConnectionMonitor.staleThreshold = 6;
185
- var INTERNAL = {
186
- message_types: {
187
- welcome: "welcome",
188
- disconnect: "disconnect",
189
- ping: "ping",
190
- confirmation: "confirm_subscription",
191
- rejection: "reject_subscription"
192
- },
193
- disconnect_reasons: {
194
- unauthorized: "unauthorized",
195
- invalid_request: "invalid_request",
196
- server_restart: "server_restart"
197
- },
198
- default_mount_path: "/cable",
199
- protocols: ["actioncable-v1-json", "actioncable-unsupported"]
200
- };
201
- var message_types = INTERNAL.message_types, protocols = INTERNAL.protocols;
202
- var supportedProtocols = protocols.slice(0, protocols.length - 1);
203
- var indexOf = [].indexOf;
204
- var Connection = function() {
205
- function Connection2(consumer2) {
206
- classCallCheck(this, Connection2);
207
- this.open = this.open.bind(this);
208
- this.consumer = consumer2;
209
- this.subscriptions = this.consumer.subscriptions;
210
- this.monitor = new ConnectionMonitor(this);
211
- this.disconnected = true;
212
- }
213
- Connection2.prototype.send = function send(data) {
214
- if (this.isOpen()) {
215
- this.webSocket.send(JSON.stringify(data));
216
- return true;
217
- } else {
218
- return false;
219
- }
220
- };
221
- Connection2.prototype.open = function open() {
222
- if (this.isActive()) {
223
- logger.log("Attempted to open WebSocket, but existing socket is " + this.getState());
224
- return false;
225
- } else {
226
- logger.log("Opening WebSocket, current state is " + this.getState() + ", subprotocols: " + protocols);
227
- if (this.webSocket) {
228
- this.uninstallEventHandlers();
229
- }
230
- this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);
231
- this.installEventHandlers();
232
- this.monitor.start();
233
- return true;
234
- }
235
- };
236
- Connection2.prototype.close = function close() {
237
- var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {
238
- allowReconnect: true
239
- }, allowReconnect = _ref.allowReconnect;
240
- if (!allowReconnect) {
241
- this.monitor.stop();
242
- }
243
- if (this.isActive()) {
244
- return this.webSocket.close();
245
- }
246
- };
247
- Connection2.prototype.reopen = function reopen() {
248
- logger.log("Reopening WebSocket, current state is " + this.getState());
249
- if (this.isActive()) {
250
- try {
251
- return this.close();
252
- } catch (error) {
253
- logger.log("Failed to reopen WebSocket", error);
254
- } finally {
255
- logger.log("Reopening WebSocket in " + this.constructor.reopenDelay + "ms");
256
- setTimeout(this.open, this.constructor.reopenDelay);
257
- }
258
- } else {
259
- return this.open();
260
- }
261
- };
262
- Connection2.prototype.getProtocol = function getProtocol() {
263
- if (this.webSocket) {
264
- return this.webSocket.protocol;
265
- }
266
- };
267
- Connection2.prototype.isOpen = function isOpen() {
268
- return this.isState("open");
269
- };
270
- Connection2.prototype.isActive = function isActive() {
271
- return this.isState("open", "connecting");
272
- };
273
- Connection2.prototype.isProtocolSupported = function isProtocolSupported() {
274
- return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
275
- };
276
- Connection2.prototype.isState = function isState() {
277
- for (var _len = arguments.length, states = Array(_len), _key = 0; _key < _len; _key++) {
278
- states[_key] = arguments[_key];
279
- }
280
- return indexOf.call(states, this.getState()) >= 0;
281
- };
282
- Connection2.prototype.getState = function getState() {
283
- if (this.webSocket) {
284
- for (var state in adapters.WebSocket) {
285
- if (adapters.WebSocket[state] === this.webSocket.readyState) {
286
- return state.toLowerCase();
287
- }
288
- }
289
- }
290
- return null;
291
- };
292
- Connection2.prototype.installEventHandlers = function installEventHandlers() {
293
- for (var eventName in this.events) {
294
- var handler = this.events[eventName].bind(this);
295
- this.webSocket["on" + eventName] = handler;
296
- }
297
- };
298
- Connection2.prototype.uninstallEventHandlers = function uninstallEventHandlers() {
299
- for (var eventName in this.events) {
300
- this.webSocket["on" + eventName] = function() {
301
- };
302
- }
303
- };
304
- return Connection2;
305
- }();
306
- Connection.reopenDelay = 500;
307
- Connection.prototype.events = {
308
- message: function message(event) {
309
- if (!this.isProtocolSupported()) {
310
- return;
311
- }
312
- var _JSON$parse = JSON.parse(event.data), identifier = _JSON$parse.identifier, message2 = _JSON$parse.message, reason = _JSON$parse.reason, reconnect = _JSON$parse.reconnect, type = _JSON$parse.type;
313
- switch (type) {
314
- case message_types.welcome:
315
- this.monitor.recordConnect();
316
- return this.subscriptions.reload();
317
- case message_types.disconnect:
318
- logger.log("Disconnecting. Reason: " + reason);
319
- return this.close({
320
- allowReconnect: reconnect
321
- });
322
- case message_types.ping:
323
- return this.monitor.recordPing();
324
- case message_types.confirmation:
325
- this.subscriptions.confirmSubscription(identifier);
326
- return this.subscriptions.notify(identifier, "connected");
327
- case message_types.rejection:
328
- return this.subscriptions.reject(identifier);
329
- default:
330
- return this.subscriptions.notify(identifier, "received", message2);
331
- }
332
- },
333
- open: function open() {
334
- logger.log("WebSocket onopen event, using '" + this.getProtocol() + "' subprotocol");
335
- this.disconnected = false;
336
- if (!this.isProtocolSupported()) {
337
- logger.log("Protocol is unsupported. Stopping monitor and disconnecting.");
338
- return this.close({
339
- allowReconnect: false
340
- });
341
- }
342
- },
343
- close: function close(event) {
344
- logger.log("WebSocket onclose event");
345
- if (this.disconnected) {
346
- return;
347
- }
348
- this.disconnected = true;
349
- this.monitor.recordDisconnect();
350
- return this.subscriptions.notifyAll("disconnected", {
351
- willAttemptReconnect: this.monitor.isRunning()
352
- });
353
- },
354
- error: function error() {
355
- logger.log("WebSocket onerror event");
356
- }
357
- };
358
- var extend = function extend2(object, properties) {
359
- if (properties != null) {
360
- for (var key in properties) {
361
- var value = properties[key];
362
- object[key] = value;
363
- }
364
- }
365
- return object;
366
- };
367
- var Subscription = function() {
368
- function Subscription2(consumer2) {
369
- var params = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
370
- var mixin = arguments[2];
371
- classCallCheck(this, Subscription2);
372
- this.consumer = consumer2;
373
- this.identifier = JSON.stringify(params);
374
- extend(this, mixin);
375
- }
376
- Subscription2.prototype.perform = function perform(action) {
377
- var data = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
378
- data.action = action;
379
- return this.send(data);
380
- };
381
- Subscription2.prototype.send = function send(data) {
382
- return this.consumer.send({
383
- command: "message",
384
- identifier: this.identifier,
385
- data: JSON.stringify(data)
386
- });
387
- };
388
- Subscription2.prototype.unsubscribe = function unsubscribe() {
389
- return this.consumer.subscriptions.remove(this);
390
- };
391
- return Subscription2;
392
- }();
393
- var SubscriptionGuarantor = function() {
394
- function SubscriptionGuarantor2(subscriptions) {
395
- classCallCheck(this, SubscriptionGuarantor2);
396
- this.subscriptions = subscriptions;
397
- this.pendingSubscriptions = [];
398
- }
399
- SubscriptionGuarantor2.prototype.guarantee = function guarantee(subscription2) {
400
- if (this.pendingSubscriptions.indexOf(subscription2) == -1) {
401
- logger.log("SubscriptionGuarantor guaranteeing " + subscription2.identifier);
402
- this.pendingSubscriptions.push(subscription2);
403
- } else {
404
- logger.log("SubscriptionGuarantor already guaranteeing " + subscription2.identifier);
405
- }
406
- this.startGuaranteeing();
407
- };
408
- SubscriptionGuarantor2.prototype.forget = function forget(subscription2) {
409
- logger.log("SubscriptionGuarantor forgetting " + subscription2.identifier);
410
- this.pendingSubscriptions = this.pendingSubscriptions.filter(function(s) {
411
- return s !== subscription2;
412
- });
413
- };
414
- SubscriptionGuarantor2.prototype.startGuaranteeing = function startGuaranteeing() {
415
- this.stopGuaranteeing();
416
- this.retrySubscribing();
417
- };
418
- SubscriptionGuarantor2.prototype.stopGuaranteeing = function stopGuaranteeing() {
419
- clearTimeout(this.retryTimeout);
420
- };
421
- SubscriptionGuarantor2.prototype.retrySubscribing = function retrySubscribing() {
422
- var _this = this;
423
- this.retryTimeout = setTimeout(function() {
424
- if (_this.subscriptions && typeof _this.subscriptions.subscribe === "function") {
425
- _this.pendingSubscriptions.map(function(subscription2) {
426
- logger.log("SubscriptionGuarantor resubscribing " + subscription2.identifier);
427
- _this.subscriptions.subscribe(subscription2);
428
- });
429
- }
430
- }, 500);
431
- };
432
- return SubscriptionGuarantor2;
433
- }();
434
- var Subscriptions = function() {
435
- function Subscriptions2(consumer2) {
436
- classCallCheck(this, Subscriptions2);
437
- this.consumer = consumer2;
438
- this.guarantor = new SubscriptionGuarantor(this);
439
- this.subscriptions = [];
440
- }
441
- Subscriptions2.prototype.create = function create(channelName, mixin) {
442
- var channel = channelName;
443
- var params = (typeof channel === "undefined" ? "undefined" : _typeof(channel)) === "object" ? channel : {
444
- channel
445
- };
446
- var subscription2 = new Subscription(this.consumer, params, mixin);
447
- return this.add(subscription2);
448
- };
449
- Subscriptions2.prototype.add = function add(subscription2) {
450
- this.subscriptions.push(subscription2);
451
- this.consumer.ensureActiveConnection();
452
- this.notify(subscription2, "initialized");
453
- this.subscribe(subscription2);
454
- return subscription2;
455
- };
456
- Subscriptions2.prototype.remove = function remove2(subscription2) {
457
- this.forget(subscription2);
458
- if (!this.findAll(subscription2.identifier).length) {
459
- this.sendCommand(subscription2, "unsubscribe");
460
- }
461
- return subscription2;
462
- };
463
- Subscriptions2.prototype.reject = function reject(identifier) {
464
- var _this = this;
465
- return this.findAll(identifier).map(function(subscription2) {
466
- _this.forget(subscription2);
467
- _this.notify(subscription2, "rejected");
468
- return subscription2;
469
- });
470
- };
471
- Subscriptions2.prototype.forget = function forget(subscription2) {
472
- this.guarantor.forget(subscription2);
473
- this.subscriptions = this.subscriptions.filter(function(s) {
474
- return s !== subscription2;
475
- });
476
- return subscription2;
477
- };
478
- Subscriptions2.prototype.findAll = function findAll(identifier) {
479
- return this.subscriptions.filter(function(s) {
480
- return s.identifier === identifier;
481
- });
482
- };
483
- Subscriptions2.prototype.reload = function reload() {
484
- var _this2 = this;
485
- return this.subscriptions.map(function(subscription2) {
486
- return _this2.subscribe(subscription2);
487
- });
488
- };
489
- Subscriptions2.prototype.notifyAll = function notifyAll(callbackName) {
490
- var _this3 = this;
491
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
492
- args[_key - 1] = arguments[_key];
493
- }
494
- return this.subscriptions.map(function(subscription2) {
495
- return _this3.notify.apply(_this3, [subscription2, callbackName].concat(args));
496
- });
497
- };
498
- Subscriptions2.prototype.notify = function notify(subscription2, callbackName) {
499
- for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
500
- args[_key2 - 2] = arguments[_key2];
501
- }
502
- var subscriptions = void 0;
503
- if (typeof subscription2 === "string") {
504
- subscriptions = this.findAll(subscription2);
505
- } else {
506
- subscriptions = [subscription2];
507
- }
508
- return subscriptions.map(function(subscription3) {
509
- return typeof subscription3[callbackName] === "function" ? subscription3[callbackName].apply(subscription3, args) : void 0;
510
- });
511
- };
512
- Subscriptions2.prototype.subscribe = function subscribe(subscription2) {
513
- if (this.sendCommand(subscription2, "subscribe")) {
514
- this.guarantor.guarantee(subscription2);
515
- }
516
- };
517
- Subscriptions2.prototype.confirmSubscription = function confirmSubscription(identifier) {
518
- var _this4 = this;
519
- logger.log("Subscription confirmed " + identifier);
520
- this.findAll(identifier).map(function(subscription2) {
521
- return _this4.guarantor.forget(subscription2);
522
- });
523
- };
524
- Subscriptions2.prototype.sendCommand = function sendCommand(subscription2, command) {
525
- var identifier = subscription2.identifier;
526
- return this.consumer.send({
527
- command,
528
- identifier
529
- });
530
- };
531
- return Subscriptions2;
532
- }();
533
- var Consumer = function() {
534
- function Consumer2(url) {
535
- classCallCheck(this, Consumer2);
536
- this._url = url;
537
- this.subscriptions = new Subscriptions(this);
538
- this.connection = new Connection(this);
539
- }
540
- Consumer2.prototype.send = function send(data) {
541
- return this.connection.send(data);
542
- };
543
- Consumer2.prototype.connect = function connect() {
544
- return this.connection.open();
545
- };
546
- Consumer2.prototype.disconnect = function disconnect() {
547
- return this.connection.close({
548
- allowReconnect: false
549
- });
550
- };
551
- Consumer2.prototype.ensureActiveConnection = function ensureActiveConnection() {
552
- if (!this.connection.isActive()) {
553
- return this.connection.open();
554
- }
555
- };
556
- createClass(Consumer2, [{
557
- key: "url",
558
- get: function get$$1() {
559
- return createWebSocketURL(this._url);
560
- }
561
- }]);
562
- return Consumer2;
563
- }();
564
- function createWebSocketURL(url) {
565
- if (typeof url === "function") {
566
- url = url();
567
- }
568
- if (url && !/^wss?:/i.test(url)) {
569
- var a = document.createElement("a");
570
- a.href = url;
571
- a.href = a.href;
572
- a.protocol = a.protocol.replace("http", "ws");
573
- return a.href;
574
- } else {
575
- return url;
576
- }
577
- }
578
- function createConsumer2() {
579
- var url = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getConfig("url") || INTERNAL.default_mount_path;
580
- return new Consumer(url);
581
- }
582
- function getConfig(name) {
583
- var element = document.head.querySelector("meta[name='action-cable-" + name + "']");
584
- if (element) {
585
- return element.getAttribute("content");
586
- }
587
- }
588
- exports2.Connection = Connection;
589
- exports2.ConnectionMonitor = ConnectionMonitor;
590
- exports2.Consumer = Consumer;
591
- exports2.INTERNAL = INTERNAL;
592
- exports2.Subscription = Subscription;
593
- exports2.Subscriptions = Subscriptions;
594
- exports2.SubscriptionGuarantor = SubscriptionGuarantor;
595
- exports2.adapters = adapters;
596
- exports2.createWebSocketURL = createWebSocketURL;
597
- exports2.logger = logger;
598
- exports2.createConsumer = createConsumer2;
599
- exports2.getConfig = getConfig;
600
- Object.defineProperty(exports2, "__esModule", {
601
- value: true
602
- });
603
- });
604
- }
605
- });
606
-
607
28
  // node_modules/debounce/index.js
608
29
  var require_debounce = __commonJS({
609
30
  "node_modules/debounce/index.js"(exports, module) {
@@ -658,8 +79,471 @@
658
79
  }
659
80
  });
660
81
 
661
- // app/javascript/hotwire-livereload.js
662
- var import_actioncable = __toESM(require_action_cable());
82
+ // node_modules/@rails/actioncable/app/assets/javascripts/actioncable.esm.js
83
+ var adapters = {
84
+ logger: self.console,
85
+ WebSocket: self.WebSocket
86
+ };
87
+ var logger = {
88
+ log(...messages) {
89
+ if (this.enabled) {
90
+ messages.push(Date.now());
91
+ adapters.logger.log("[ActionCable]", ...messages);
92
+ }
93
+ }
94
+ };
95
+ var now = () => (/* @__PURE__ */ new Date()).getTime();
96
+ var secondsSince = (time) => (now() - time) / 1e3;
97
+ var ConnectionMonitor = class {
98
+ constructor(connection) {
99
+ this.visibilityDidChange = this.visibilityDidChange.bind(this);
100
+ this.connection = connection;
101
+ this.reconnectAttempts = 0;
102
+ }
103
+ start() {
104
+ if (!this.isRunning()) {
105
+ this.startedAt = now();
106
+ delete this.stoppedAt;
107
+ this.startPolling();
108
+ addEventListener("visibilitychange", this.visibilityDidChange);
109
+ logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`);
110
+ }
111
+ }
112
+ stop() {
113
+ if (this.isRunning()) {
114
+ this.stoppedAt = now();
115
+ this.stopPolling();
116
+ removeEventListener("visibilitychange", this.visibilityDidChange);
117
+ logger.log("ConnectionMonitor stopped");
118
+ }
119
+ }
120
+ isRunning() {
121
+ return this.startedAt && !this.stoppedAt;
122
+ }
123
+ recordPing() {
124
+ this.pingedAt = now();
125
+ }
126
+ recordConnect() {
127
+ this.reconnectAttempts = 0;
128
+ this.recordPing();
129
+ delete this.disconnectedAt;
130
+ logger.log("ConnectionMonitor recorded connect");
131
+ }
132
+ recordDisconnect() {
133
+ this.disconnectedAt = now();
134
+ logger.log("ConnectionMonitor recorded disconnect");
135
+ }
136
+ startPolling() {
137
+ this.stopPolling();
138
+ this.poll();
139
+ }
140
+ stopPolling() {
141
+ clearTimeout(this.pollTimeout);
142
+ }
143
+ poll() {
144
+ this.pollTimeout = setTimeout(() => {
145
+ this.reconnectIfStale();
146
+ this.poll();
147
+ }, this.getPollInterval());
148
+ }
149
+ getPollInterval() {
150
+ const { staleThreshold, reconnectionBackoffRate } = this.constructor;
151
+ const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));
152
+ const jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;
153
+ const jitter = jitterMax * Math.random();
154
+ return staleThreshold * 1e3 * backoff * (1 + jitter);
155
+ }
156
+ reconnectIfStale() {
157
+ if (this.connectionIsStale()) {
158
+ logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`);
159
+ this.reconnectAttempts++;
160
+ if (this.disconnectedRecently()) {
161
+ logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`);
162
+ } else {
163
+ logger.log("ConnectionMonitor reopening");
164
+ this.connection.reopen();
165
+ }
166
+ }
167
+ }
168
+ get refreshedAt() {
169
+ return this.pingedAt ? this.pingedAt : this.startedAt;
170
+ }
171
+ connectionIsStale() {
172
+ return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;
173
+ }
174
+ disconnectedRecently() {
175
+ return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
176
+ }
177
+ visibilityDidChange() {
178
+ if (document.visibilityState === "visible") {
179
+ setTimeout(() => {
180
+ if (this.connectionIsStale() || !this.connection.isOpen()) {
181
+ logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`);
182
+ this.connection.reopen();
183
+ }
184
+ }, 200);
185
+ }
186
+ }
187
+ };
188
+ ConnectionMonitor.staleThreshold = 6;
189
+ ConnectionMonitor.reconnectionBackoffRate = 0.15;
190
+ var INTERNAL = {
191
+ message_types: {
192
+ welcome: "welcome",
193
+ disconnect: "disconnect",
194
+ ping: "ping",
195
+ confirmation: "confirm_subscription",
196
+ rejection: "reject_subscription"
197
+ },
198
+ disconnect_reasons: {
199
+ unauthorized: "unauthorized",
200
+ invalid_request: "invalid_request",
201
+ server_restart: "server_restart"
202
+ },
203
+ default_mount_path: "/cable",
204
+ protocols: ["actioncable-v1-json", "actioncable-unsupported"]
205
+ };
206
+ var { message_types, protocols } = INTERNAL;
207
+ var supportedProtocols = protocols.slice(0, protocols.length - 1);
208
+ var indexOf = [].indexOf;
209
+ var Connection = class {
210
+ constructor(consumer2) {
211
+ this.open = this.open.bind(this);
212
+ this.consumer = consumer2;
213
+ this.subscriptions = this.consumer.subscriptions;
214
+ this.monitor = new ConnectionMonitor(this);
215
+ this.disconnected = true;
216
+ }
217
+ send(data) {
218
+ if (this.isOpen()) {
219
+ this.webSocket.send(JSON.stringify(data));
220
+ return true;
221
+ } else {
222
+ return false;
223
+ }
224
+ }
225
+ open() {
226
+ if (this.isActive()) {
227
+ logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
228
+ return false;
229
+ } else {
230
+ logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${protocols}`);
231
+ if (this.webSocket) {
232
+ this.uninstallEventHandlers();
233
+ }
234
+ this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);
235
+ this.installEventHandlers();
236
+ this.monitor.start();
237
+ return true;
238
+ }
239
+ }
240
+ close({ allowReconnect } = {
241
+ allowReconnect: true
242
+ }) {
243
+ if (!allowReconnect) {
244
+ this.monitor.stop();
245
+ }
246
+ if (this.isOpen()) {
247
+ return this.webSocket.close();
248
+ }
249
+ }
250
+ reopen() {
251
+ logger.log(`Reopening WebSocket, current state is ${this.getState()}`);
252
+ if (this.isActive()) {
253
+ try {
254
+ return this.close();
255
+ } catch (error) {
256
+ logger.log("Failed to reopen WebSocket", error);
257
+ } finally {
258
+ logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`);
259
+ setTimeout(this.open, this.constructor.reopenDelay);
260
+ }
261
+ } else {
262
+ return this.open();
263
+ }
264
+ }
265
+ getProtocol() {
266
+ if (this.webSocket) {
267
+ return this.webSocket.protocol;
268
+ }
269
+ }
270
+ isOpen() {
271
+ return this.isState("open");
272
+ }
273
+ isActive() {
274
+ return this.isState("open", "connecting");
275
+ }
276
+ isProtocolSupported() {
277
+ return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
278
+ }
279
+ isState(...states) {
280
+ return indexOf.call(states, this.getState()) >= 0;
281
+ }
282
+ getState() {
283
+ if (this.webSocket) {
284
+ for (let state in adapters.WebSocket) {
285
+ if (adapters.WebSocket[state] === this.webSocket.readyState) {
286
+ return state.toLowerCase();
287
+ }
288
+ }
289
+ }
290
+ return null;
291
+ }
292
+ installEventHandlers() {
293
+ for (let eventName in this.events) {
294
+ const handler = this.events[eventName].bind(this);
295
+ this.webSocket[`on${eventName}`] = handler;
296
+ }
297
+ }
298
+ uninstallEventHandlers() {
299
+ for (let eventName in this.events) {
300
+ this.webSocket[`on${eventName}`] = function() {
301
+ };
302
+ }
303
+ }
304
+ };
305
+ Connection.reopenDelay = 500;
306
+ Connection.prototype.events = {
307
+ message(event) {
308
+ if (!this.isProtocolSupported()) {
309
+ return;
310
+ }
311
+ const { identifier, message, reason, reconnect, type } = JSON.parse(event.data);
312
+ switch (type) {
313
+ case message_types.welcome:
314
+ this.monitor.recordConnect();
315
+ return this.subscriptions.reload();
316
+ case message_types.disconnect:
317
+ logger.log(`Disconnecting. Reason: ${reason}`);
318
+ return this.close({
319
+ allowReconnect: reconnect
320
+ });
321
+ case message_types.ping:
322
+ return this.monitor.recordPing();
323
+ case message_types.confirmation:
324
+ this.subscriptions.confirmSubscription(identifier);
325
+ return this.subscriptions.notify(identifier, "connected");
326
+ case message_types.rejection:
327
+ return this.subscriptions.reject(identifier);
328
+ default:
329
+ return this.subscriptions.notify(identifier, "received", message);
330
+ }
331
+ },
332
+ open() {
333
+ logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`);
334
+ this.disconnected = false;
335
+ if (!this.isProtocolSupported()) {
336
+ logger.log("Protocol is unsupported. Stopping monitor and disconnecting.");
337
+ return this.close({
338
+ allowReconnect: false
339
+ });
340
+ }
341
+ },
342
+ close(event) {
343
+ logger.log("WebSocket onclose event");
344
+ if (this.disconnected) {
345
+ return;
346
+ }
347
+ this.disconnected = true;
348
+ this.monitor.recordDisconnect();
349
+ return this.subscriptions.notifyAll("disconnected", {
350
+ willAttemptReconnect: this.monitor.isRunning()
351
+ });
352
+ },
353
+ error() {
354
+ logger.log("WebSocket onerror event");
355
+ }
356
+ };
357
+ var extend = function(object, properties) {
358
+ if (properties != null) {
359
+ for (let key in properties) {
360
+ const value = properties[key];
361
+ object[key] = value;
362
+ }
363
+ }
364
+ return object;
365
+ };
366
+ var Subscription = class {
367
+ constructor(consumer2, params = {}, mixin) {
368
+ this.consumer = consumer2;
369
+ this.identifier = JSON.stringify(params);
370
+ extend(this, mixin);
371
+ }
372
+ perform(action, data = {}) {
373
+ data.action = action;
374
+ return this.send(data);
375
+ }
376
+ send(data) {
377
+ return this.consumer.send({
378
+ command: "message",
379
+ identifier: this.identifier,
380
+ data: JSON.stringify(data)
381
+ });
382
+ }
383
+ unsubscribe() {
384
+ return this.consumer.subscriptions.remove(this);
385
+ }
386
+ };
387
+ var SubscriptionGuarantor = class {
388
+ constructor(subscriptions) {
389
+ this.subscriptions = subscriptions;
390
+ this.pendingSubscriptions = [];
391
+ }
392
+ guarantee(subscription) {
393
+ if (this.pendingSubscriptions.indexOf(subscription) == -1) {
394
+ logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
395
+ this.pendingSubscriptions.push(subscription);
396
+ } else {
397
+ logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
398
+ }
399
+ this.startGuaranteeing();
400
+ }
401
+ forget(subscription) {
402
+ logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
403
+ this.pendingSubscriptions = this.pendingSubscriptions.filter((s) => s !== subscription);
404
+ }
405
+ startGuaranteeing() {
406
+ this.stopGuaranteeing();
407
+ this.retrySubscribing();
408
+ }
409
+ stopGuaranteeing() {
410
+ clearTimeout(this.retryTimeout);
411
+ }
412
+ retrySubscribing() {
413
+ this.retryTimeout = setTimeout(() => {
414
+ if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
415
+ this.pendingSubscriptions.map((subscription) => {
416
+ logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
417
+ this.subscriptions.subscribe(subscription);
418
+ });
419
+ }
420
+ }, 500);
421
+ }
422
+ };
423
+ var Subscriptions = class {
424
+ constructor(consumer2) {
425
+ this.consumer = consumer2;
426
+ this.guarantor = new SubscriptionGuarantor(this);
427
+ this.subscriptions = [];
428
+ }
429
+ create(channelName, mixin) {
430
+ const channel = channelName;
431
+ const params = typeof channel === "object" ? channel : {
432
+ channel
433
+ };
434
+ const subscription = new Subscription(this.consumer, params, mixin);
435
+ return this.add(subscription);
436
+ }
437
+ add(subscription) {
438
+ this.subscriptions.push(subscription);
439
+ this.consumer.ensureActiveConnection();
440
+ this.notify(subscription, "initialized");
441
+ this.subscribe(subscription);
442
+ return subscription;
443
+ }
444
+ remove(subscription) {
445
+ this.forget(subscription);
446
+ if (!this.findAll(subscription.identifier).length) {
447
+ this.sendCommand(subscription, "unsubscribe");
448
+ }
449
+ return subscription;
450
+ }
451
+ reject(identifier) {
452
+ return this.findAll(identifier).map((subscription) => {
453
+ this.forget(subscription);
454
+ this.notify(subscription, "rejected");
455
+ return subscription;
456
+ });
457
+ }
458
+ forget(subscription) {
459
+ this.guarantor.forget(subscription);
460
+ this.subscriptions = this.subscriptions.filter((s) => s !== subscription);
461
+ return subscription;
462
+ }
463
+ findAll(identifier) {
464
+ return this.subscriptions.filter((s) => s.identifier === identifier);
465
+ }
466
+ reload() {
467
+ return this.subscriptions.map((subscription) => this.subscribe(subscription));
468
+ }
469
+ notifyAll(callbackName, ...args) {
470
+ return this.subscriptions.map((subscription) => this.notify(subscription, callbackName, ...args));
471
+ }
472
+ notify(subscription, callbackName, ...args) {
473
+ let subscriptions;
474
+ if (typeof subscription === "string") {
475
+ subscriptions = this.findAll(subscription);
476
+ } else {
477
+ subscriptions = [subscription];
478
+ }
479
+ return subscriptions.map((subscription2) => typeof subscription2[callbackName] === "function" ? subscription2[callbackName](...args) : void 0);
480
+ }
481
+ subscribe(subscription) {
482
+ if (this.sendCommand(subscription, "subscribe")) {
483
+ this.guarantor.guarantee(subscription);
484
+ }
485
+ }
486
+ confirmSubscription(identifier) {
487
+ logger.log(`Subscription confirmed ${identifier}`);
488
+ this.findAll(identifier).map((subscription) => this.guarantor.forget(subscription));
489
+ }
490
+ sendCommand(subscription, command) {
491
+ const { identifier } = subscription;
492
+ return this.consumer.send({
493
+ command,
494
+ identifier
495
+ });
496
+ }
497
+ };
498
+ var Consumer = class {
499
+ constructor(url) {
500
+ this._url = url;
501
+ this.subscriptions = new Subscriptions(this);
502
+ this.connection = new Connection(this);
503
+ }
504
+ get url() {
505
+ return createWebSocketURL(this._url);
506
+ }
507
+ send(data) {
508
+ return this.connection.send(data);
509
+ }
510
+ connect() {
511
+ return this.connection.open();
512
+ }
513
+ disconnect() {
514
+ return this.connection.close({
515
+ allowReconnect: false
516
+ });
517
+ }
518
+ ensureActiveConnection() {
519
+ if (!this.connection.isActive()) {
520
+ return this.connection.open();
521
+ }
522
+ }
523
+ };
524
+ function createWebSocketURL(url) {
525
+ if (typeof url === "function") {
526
+ url = url();
527
+ }
528
+ if (url && !/^wss?:/i.test(url)) {
529
+ const a = document.createElement("a");
530
+ a.href = url;
531
+ a.href = a.href;
532
+ a.protocol = a.protocol.replace("http", "ws");
533
+ return a.href;
534
+ } else {
535
+ return url;
536
+ }
537
+ }
538
+ function createConsumer(url = getConfig("url") || INTERNAL.default_mount_path) {
539
+ return new Consumer(url);
540
+ }
541
+ function getConfig(name) {
542
+ const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
543
+ if (element) {
544
+ return element.getAttribute("content");
545
+ }
546
+ }
663
547
 
664
548
  // app/javascript/lib/hotwire-livereload-received.js
665
549
  var import_debounce = __toESM(require_debounce());
@@ -703,9 +587,8 @@
703
587
  }, 300);
704
588
 
705
589
  // app/javascript/hotwire-livereload.js
706
- var consumer = (0, import_actioncable.createConsumer)();
707
- var subscription = null;
708
- var createSubscription = () => consumer.subscriptions.create("Hotwire::Livereload::ReloadChannel", {
590
+ var consumer = createConsumer("/hotwire-livereload");
591
+ consumer.subscriptions.create("Hotwire::Livereload::ReloadChannel", {
709
592
  received: hotwire_livereload_received_default,
710
593
  connected() {
711
594
  console.log("[Hotwire::Livereload] Websocket connected");
@@ -714,14 +597,8 @@
714
597
  console.log("[Hotwire::Livereload] Websocket disconnected");
715
598
  }
716
599
  });
717
- subscription = createSubscription();
718
600
  document.addEventListener("turbo:load", () => {
719
601
  hotwire_livereload_scroll_position_default.restore();
720
602
  hotwire_livereload_scroll_position_default.remove();
721
- if (subscription) {
722
- consumer.subscriptions.remove(subscription);
723
- subscription = null;
724
- }
725
- subscription = createSubscription();
726
603
  });
727
604
  })();