optics_view_components 0.1.8 → 0.1.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db165928ba46774fcb8412d71cd02ae0c4e066e323bff171c7bedaae7f7e1cf9
4
- data.tar.gz: 482b366146b1e0ff14e8cd2c6c5819e51374ae142bb969b7f520f8f68a5de220
3
+ metadata.gz: 1a951c750d000275cbaab0ba1647db5d7cd22d45b4fd727af9ce8a85ebebfbae
4
+ data.tar.gz: f26dcc64414812ba6ec93bae0be942b803f2da601876506e23782eaed9084334
5
5
  SHA512:
6
- metadata.gz: e8783ca32282a2e8f8f45b97b443198be8507f65d1c48cc773fe6f4ddd5ef737bdfa3a865b7591101b57fbf700e9d1af96858443f1ad3883338713f662ad2b7d
7
- data.tar.gz: e21dd5880c6d94568f53c3202b154e7702d809fe7535e31134b3aef6c9ee56c8ce06a60de87a1069fb4381b4ee993c4bf5bb56b2d2ec3442720a479a7838d4c9
6
+ metadata.gz: 9cc9ad65a1cbdb94c2553d35db1c52f1c11176c75af7ff8064fbd144dc67b80a3d6e90f56615e57c2566b06f90202a16545d313ee6924d7207217171521ff1c8
7
+ data.tar.gz: 14d71daf38ad04f2cd667ca17aa7e3810e91233c88103d082e4fa7acb0369734fca03b131218367f577bfac54dc10c2844eddd5fa56b5667fa5f07c4aed91e84
data/Gemfile CHANGED
@@ -9,6 +9,8 @@ gem 'rails', '~> 7.0'
9
9
 
10
10
  gem 'bootsnap', require: false
11
11
  gem 'lookbook'
12
+ gem 'puma', '~> 6.3'
13
+ gem 'sprockets-rails'
12
14
  gem 'rake', '~> 13.0'
13
15
  gem 'rspec', '~> 3.0'
14
16
  gem 'rubocop', '~> 1.21'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- optics_view_components (0.1.8)
4
+ optics_view_components (0.1.9)
5
5
  view_component (> 2.0, < 4.0)
6
6
 
7
7
  GEM
@@ -138,6 +138,8 @@ GEM
138
138
  net-smtp (0.3.3)
139
139
  net-protocol
140
140
  nio4r (2.5.9)
141
+ nokogiri (1.15.1-arm64-darwin)
142
+ racc (~> 1.4)
141
143
  nokogiri (1.15.1-x86_64-linux)
142
144
  racc (~> 1.4)
143
145
  parallel (1.23.0)
@@ -147,6 +149,8 @@ GEM
147
149
  coderay (~> 1.1)
148
150
  method_source (~> 1.0)
149
151
  public_suffix (5.0.1)
152
+ puma (6.3.1)
153
+ nio4r (~> 2.0)
150
154
  racc (1.6.2)
151
155
  rack (2.2.7)
152
156
  rack-test (2.1.0)
@@ -242,6 +246,7 @@ GEM
242
246
  zeitwerk (2.6.8)
243
247
 
244
248
  PLATFORMS
249
+ arm64-darwin-21
245
250
  x86_64-linux
246
251
 
247
252
  DEPENDENCIES
@@ -250,6 +255,7 @@ DEPENDENCIES
250
255
  lookbook
251
256
  optics_view_components!
252
257
  pry
258
+ puma (~> 6.3)
253
259
  rails (~> 7.0)
254
260
  rake (~> 13.0)
255
261
  rspec (~> 3.0)
data/Procfile ADDED
@@ -0,0 +1 @@
1
+ web: bundle exec rackup -p ${PORT:-5000} config.ru
@@ -14,7 +14,8 @@ module Optics
14
14
  def call
15
15
  content_tag(
16
16
  :nav,
17
- class: classes
17
+ class: classes,
18
+ **@attributes.except(:class)
18
19
  ) do
19
20
  capture do
20
21
  concat brand
@@ -40,12 +41,13 @@ module Optics
40
41
 
41
42
  class Brand < ApplicationViewComponent
42
43
  accepts :url
43
- accepts :img_src
44
+ accepts :image_source
45
+ accepts :image_label
44
46
  accepts :name
45
47
 
46
48
  def call
47
- link_to(url, class: 'sidebar__brand') do
48
- name || image_tag(img_src)
49
+ link_to(url, class: 'sidebar__brand', **@attributes) do
50
+ name || image_tag(image_source, alt: image_label)
49
51
  end
50
52
  end
51
53
  end
@@ -54,7 +56,7 @@ module Optics
54
56
  accepts :position, default: 'center'
55
57
 
56
58
  def call
57
- content_tag(:div, class: classes) do
59
+ content_tag(:div, class: classes, **@attributes) do
58
60
  content
59
61
  end
60
62
  end
@@ -62,7 +64,8 @@ module Optics
62
64
  def classes
63
65
  class_names(
64
66
  'sidebar__content',
65
- position_class
67
+ position_class,
68
+ @attributes[:class]
66
69
  ).join(' ')
67
70
  end
68
71
 
@@ -76,7 +79,7 @@ module Optics
76
79
  accepts :url
77
80
 
78
81
  def call
79
- link_to(url, class: 'sidebar__brand') do
82
+ link_to(url, class: 'sidebar__brand', **@attributes) do
80
83
  image_tag(img_src)
81
84
  end
82
85
  end
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require './demo/config/environment'
2
+ run Demo::Application
3
+
data/demo/Gemfile CHANGED
@@ -6,7 +6,7 @@ gem 'rails', '~> 7.0.4', '>= 7.0.4.3'
6
6
 
7
7
  gem 'bootsnap', require: false
8
8
  gem 'cssbundling-rails', '~> 1.1'
9
- gem 'puma', '~> 6.0'
9
+ gem 'puma', '~> 6.3'
10
10
  gem 'sprockets-rails'
11
11
 
12
12
  gem 'lookbook'
data/demo/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- optics_view_components (0.1.8)
4
+ optics_view_components (0.1.9)
5
5
  view_component (> 2.0, < 4.0)
6
6
 
7
7
  GEM
@@ -133,10 +133,12 @@ GEM
133
133
  net-smtp (0.3.3)
134
134
  net-protocol
135
135
  nio4r (2.5.9)
136
- nokogiri (1.15.1-x86_64-linux)
136
+ nokogiri (1.15.3-arm64-darwin)
137
+ racc (~> 1.4)
138
+ nokogiri (1.15.3-x86_64-linux)
137
139
  racc (~> 1.4)
138
140
  public_suffix (5.0.1)
139
- puma (6.2.2)
141
+ puma (6.3.1)
140
142
  nio4r (~> 2.0)
141
143
  racc (1.6.2)
142
144
  rack (2.2.7)
@@ -200,6 +202,7 @@ GEM
200
202
  zeitwerk (2.6.8)
201
203
 
202
204
  PLATFORMS
205
+ arm64-darwin-22
203
206
  x86_64-linux
204
207
 
205
208
  DEPENDENCIES
@@ -208,7 +211,7 @@ DEPENDENCIES
208
211
  debug
209
212
  lookbook
210
213
  optics_view_components!
211
- puma (~> 6.0)
214
+ puma (~> 6.3)
212
215
  rails (~> 7.0.4, >= 7.0.4.3)
213
216
  sprockets-rails
214
217
  web-console
@@ -25,8 +25,9 @@ module Demo
25
25
  config.load_defaults 7.0
26
26
 
27
27
  config.view_component.default_preview_layout = 'preview'
28
- config.view_component.preview_paths << Rails.root.join('..', 'previews')
28
+ config.view_component.preview_paths = [Optics::ViewComponents::Engine.root.join('previews')]
29
29
  config.lookbook.project_name = "Optics ViewComponents v#{Optics::ViewComponents::VERSION}"
30
30
  config.lookbook.component_paths = [Optics::ViewComponents::Engine.root.join('app', 'components')]
31
+ config.view_component.show_previews = true
31
32
  end
32
33
  end
@@ -0,0 +1 @@
1
+ {"files":{"manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js":{"logical_path":"manifest.js","mtime":"2023-07-21T16:26:54-04:00","size":3,"digest":"6a3cf5192354f71615ac51034b3e97c20eda99643fcaf5bbe6d41ad59bd12167","integrity":"sha256-ajz1GSNU9xYVrFEDSz6Xwg7amWQ/yvW75tQa1ZvRIWc="},"application-0637d2874099d8ba663ba7c4b7ae404ed5d14dce524e1199c89ad93f13956807.css":{"logical_path":"application.css","mtime":"2023-07-21T16:26:54-04:00","size":191384,"digest":"804e47b010668b842d5c04f570a7a3a8346cb83928c31ebb7d08b3c9c0b4417b","integrity":"sha256-gE5HsBBmi4QtXAT1cKejqDRsuDkowx67fQizycC0QXs="},"actioncable-5433453f9b6619a9de91aaab2d7fc7ff183e5260c0107cbc9a1aa0c838d9a74e.js":{"logical_path":"actioncable.js","mtime":"2023-07-21T16:26:54-04:00","size":15699,"digest":"6b2fe44d9e4546fcc6b92f0a37b61d6b555020041ede1dd603c007b1c0904ec1","integrity":"sha256-ay/kTZ5FRvzGuS8KN7Yda1VQIAQe3h3WA8AHscCQTsE="},"actioncable.esm-e01089c3ec4fe7817fa9abcad06cab6bdc387f95f0ca6aab4bf7ba7537f70690.js":{"logical_path":"actioncable.esm.js","mtime":"2023-07-21T16:26:54-04:00","size":14080,"digest":"a9e53dfa810276aa0aee8791a910c4878d48b75093398f3d6d822db41b428b7b","integrity":"sha256-qeU9+oECdqoK7oeRqRDEh41It1CTOY89bYIttBtCi3s="}},"assets":{"manifest.js":"manifest-dad05bf766af0fe3d79dd746db3c1361c0583026cdf35d6a2921bccaea835331.js","application.css":"application-0637d2874099d8ba663ba7c4b7ae404ed5d14dce524e1199c89ad93f13956807.css","actioncable.js":"actioncable-5433453f9b6619a9de91aaab2d7fc7ff183e5260c0107cbc9a1aa0c838d9a74e.js","actioncable.esm.js":"actioncable.esm-e01089c3ec4fe7817fa9abcad06cab6bdc387f95f0ca6aab4bf7ba7537f70690.js"}}
@@ -0,0 +1,489 @@
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self,
3
+ factory(global.ActionCable = {}));
4
+ })(this, (function(exports) {
5
+ "use strict";
6
+ var adapters = {
7
+ logger: self.console,
8
+ WebSocket: self.WebSocket
9
+ };
10
+ var logger = {
11
+ log(...messages) {
12
+ if (this.enabled) {
13
+ messages.push(Date.now());
14
+ adapters.logger.log("[ActionCable]", ...messages);
15
+ }
16
+ }
17
+ };
18
+ const now = () => (new Date).getTime();
19
+ const secondsSince = time => (now() - time) / 1e3;
20
+ class ConnectionMonitor {
21
+ constructor(connection) {
22
+ this.visibilityDidChange = this.visibilityDidChange.bind(this);
23
+ this.connection = connection;
24
+ this.reconnectAttempts = 0;
25
+ }
26
+ start() {
27
+ if (!this.isRunning()) {
28
+ this.startedAt = now();
29
+ delete this.stoppedAt;
30
+ this.startPolling();
31
+ addEventListener("visibilitychange", this.visibilityDidChange);
32
+ logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`);
33
+ }
34
+ }
35
+ stop() {
36
+ if (this.isRunning()) {
37
+ this.stoppedAt = now();
38
+ this.stopPolling();
39
+ removeEventListener("visibilitychange", this.visibilityDidChange);
40
+ logger.log("ConnectionMonitor stopped");
41
+ }
42
+ }
43
+ isRunning() {
44
+ return this.startedAt && !this.stoppedAt;
45
+ }
46
+ recordPing() {
47
+ this.pingedAt = now();
48
+ }
49
+ recordConnect() {
50
+ this.reconnectAttempts = 0;
51
+ this.recordPing();
52
+ delete this.disconnectedAt;
53
+ logger.log("ConnectionMonitor recorded connect");
54
+ }
55
+ recordDisconnect() {
56
+ this.disconnectedAt = now();
57
+ logger.log("ConnectionMonitor recorded disconnect");
58
+ }
59
+ startPolling() {
60
+ this.stopPolling();
61
+ this.poll();
62
+ }
63
+ stopPolling() {
64
+ clearTimeout(this.pollTimeout);
65
+ }
66
+ poll() {
67
+ this.pollTimeout = setTimeout((() => {
68
+ this.reconnectIfStale();
69
+ this.poll();
70
+ }), this.getPollInterval());
71
+ }
72
+ getPollInterval() {
73
+ const {staleThreshold: staleThreshold, reconnectionBackoffRate: reconnectionBackoffRate} = this.constructor;
74
+ const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));
75
+ const jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;
76
+ const jitter = jitterMax * Math.random();
77
+ return staleThreshold * 1e3 * backoff * (1 + jitter);
78
+ }
79
+ reconnectIfStale() {
80
+ if (this.connectionIsStale()) {
81
+ logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`);
82
+ this.reconnectAttempts++;
83
+ if (this.disconnectedRecently()) {
84
+ logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`);
85
+ } else {
86
+ logger.log("ConnectionMonitor reopening");
87
+ this.connection.reopen();
88
+ }
89
+ }
90
+ }
91
+ get refreshedAt() {
92
+ return this.pingedAt ? this.pingedAt : this.startedAt;
93
+ }
94
+ connectionIsStale() {
95
+ return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;
96
+ }
97
+ disconnectedRecently() {
98
+ return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
99
+ }
100
+ visibilityDidChange() {
101
+ if (document.visibilityState === "visible") {
102
+ setTimeout((() => {
103
+ if (this.connectionIsStale() || !this.connection.isOpen()) {
104
+ logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`);
105
+ this.connection.reopen();
106
+ }
107
+ }), 200);
108
+ }
109
+ }
110
+ }
111
+ ConnectionMonitor.staleThreshold = 6;
112
+ ConnectionMonitor.reconnectionBackoffRate = .15;
113
+ var INTERNAL = {
114
+ message_types: {
115
+ welcome: "welcome",
116
+ disconnect: "disconnect",
117
+ ping: "ping",
118
+ confirmation: "confirm_subscription",
119
+ rejection: "reject_subscription"
120
+ },
121
+ disconnect_reasons: {
122
+ unauthorized: "unauthorized",
123
+ invalid_request: "invalid_request",
124
+ server_restart: "server_restart"
125
+ },
126
+ default_mount_path: "/cable",
127
+ protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
128
+ };
129
+ const {message_types: message_types, protocols: protocols} = INTERNAL;
130
+ const supportedProtocols = protocols.slice(0, protocols.length - 1);
131
+ const indexOf = [].indexOf;
132
+ class Connection {
133
+ constructor(consumer) {
134
+ this.open = this.open.bind(this);
135
+ this.consumer = consumer;
136
+ this.subscriptions = this.consumer.subscriptions;
137
+ this.monitor = new ConnectionMonitor(this);
138
+ this.disconnected = true;
139
+ }
140
+ send(data) {
141
+ if (this.isOpen()) {
142
+ this.webSocket.send(JSON.stringify(data));
143
+ return true;
144
+ } else {
145
+ return false;
146
+ }
147
+ }
148
+ open() {
149
+ if (this.isActive()) {
150
+ logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
151
+ return false;
152
+ } else {
153
+ logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${protocols}`);
154
+ if (this.webSocket) {
155
+ this.uninstallEventHandlers();
156
+ }
157
+ this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);
158
+ this.installEventHandlers();
159
+ this.monitor.start();
160
+ return true;
161
+ }
162
+ }
163
+ close({allowReconnect: allowReconnect} = {
164
+ allowReconnect: true
165
+ }) {
166
+ if (!allowReconnect) {
167
+ this.monitor.stop();
168
+ }
169
+ if (this.isOpen()) {
170
+ return this.webSocket.close();
171
+ }
172
+ }
173
+ reopen() {
174
+ logger.log(`Reopening WebSocket, current state is ${this.getState()}`);
175
+ if (this.isActive()) {
176
+ try {
177
+ return this.close();
178
+ } catch (error) {
179
+ logger.log("Failed to reopen WebSocket", error);
180
+ } finally {
181
+ logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`);
182
+ setTimeout(this.open, this.constructor.reopenDelay);
183
+ }
184
+ } else {
185
+ return this.open();
186
+ }
187
+ }
188
+ getProtocol() {
189
+ if (this.webSocket) {
190
+ return this.webSocket.protocol;
191
+ }
192
+ }
193
+ isOpen() {
194
+ return this.isState("open");
195
+ }
196
+ isActive() {
197
+ return this.isState("open", "connecting");
198
+ }
199
+ isProtocolSupported() {
200
+ return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
201
+ }
202
+ isState(...states) {
203
+ return indexOf.call(states, this.getState()) >= 0;
204
+ }
205
+ getState() {
206
+ if (this.webSocket) {
207
+ for (let state in adapters.WebSocket) {
208
+ if (adapters.WebSocket[state] === this.webSocket.readyState) {
209
+ return state.toLowerCase();
210
+ }
211
+ }
212
+ }
213
+ return null;
214
+ }
215
+ installEventHandlers() {
216
+ for (let eventName in this.events) {
217
+ const handler = this.events[eventName].bind(this);
218
+ this.webSocket[`on${eventName}`] = handler;
219
+ }
220
+ }
221
+ uninstallEventHandlers() {
222
+ for (let eventName in this.events) {
223
+ this.webSocket[`on${eventName}`] = function() {};
224
+ }
225
+ }
226
+ }
227
+ Connection.reopenDelay = 500;
228
+ Connection.prototype.events = {
229
+ message(event) {
230
+ if (!this.isProtocolSupported()) {
231
+ return;
232
+ }
233
+ const {identifier: identifier, message: message, reason: reason, reconnect: reconnect, type: type} = JSON.parse(event.data);
234
+ switch (type) {
235
+ case message_types.welcome:
236
+ this.monitor.recordConnect();
237
+ return this.subscriptions.reload();
238
+
239
+ case message_types.disconnect:
240
+ logger.log(`Disconnecting. Reason: ${reason}`);
241
+ return this.close({
242
+ allowReconnect: reconnect
243
+ });
244
+
245
+ case message_types.ping:
246
+ return this.monitor.recordPing();
247
+
248
+ case message_types.confirmation:
249
+ this.subscriptions.confirmSubscription(identifier);
250
+ return this.subscriptions.notify(identifier, "connected");
251
+
252
+ case message_types.rejection:
253
+ return this.subscriptions.reject(identifier);
254
+
255
+ default:
256
+ return this.subscriptions.notify(identifier, "received", message);
257
+ }
258
+ },
259
+ open() {
260
+ logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`);
261
+ this.disconnected = false;
262
+ if (!this.isProtocolSupported()) {
263
+ logger.log("Protocol is unsupported. Stopping monitor and disconnecting.");
264
+ return this.close({
265
+ allowReconnect: false
266
+ });
267
+ }
268
+ },
269
+ close(event) {
270
+ logger.log("WebSocket onclose event");
271
+ if (this.disconnected) {
272
+ return;
273
+ }
274
+ this.disconnected = true;
275
+ this.monitor.recordDisconnect();
276
+ return this.subscriptions.notifyAll("disconnected", {
277
+ willAttemptReconnect: this.monitor.isRunning()
278
+ });
279
+ },
280
+ error() {
281
+ logger.log("WebSocket onerror event");
282
+ }
283
+ };
284
+ const extend = function(object, properties) {
285
+ if (properties != null) {
286
+ for (let key in properties) {
287
+ const value = properties[key];
288
+ object[key] = value;
289
+ }
290
+ }
291
+ return object;
292
+ };
293
+ class Subscription {
294
+ constructor(consumer, params = {}, mixin) {
295
+ this.consumer = consumer;
296
+ this.identifier = JSON.stringify(params);
297
+ extend(this, mixin);
298
+ }
299
+ perform(action, data = {}) {
300
+ data.action = action;
301
+ return this.send(data);
302
+ }
303
+ send(data) {
304
+ return this.consumer.send({
305
+ command: "message",
306
+ identifier: this.identifier,
307
+ data: JSON.stringify(data)
308
+ });
309
+ }
310
+ unsubscribe() {
311
+ return this.consumer.subscriptions.remove(this);
312
+ }
313
+ }
314
+ class SubscriptionGuarantor {
315
+ constructor(subscriptions) {
316
+ this.subscriptions = subscriptions;
317
+ this.pendingSubscriptions = [];
318
+ }
319
+ guarantee(subscription) {
320
+ if (this.pendingSubscriptions.indexOf(subscription) == -1) {
321
+ logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
322
+ this.pendingSubscriptions.push(subscription);
323
+ } else {
324
+ logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
325
+ }
326
+ this.startGuaranteeing();
327
+ }
328
+ forget(subscription) {
329
+ logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
330
+ this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
331
+ }
332
+ startGuaranteeing() {
333
+ this.stopGuaranteeing();
334
+ this.retrySubscribing();
335
+ }
336
+ stopGuaranteeing() {
337
+ clearTimeout(this.retryTimeout);
338
+ }
339
+ retrySubscribing() {
340
+ this.retryTimeout = setTimeout((() => {
341
+ if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
342
+ this.pendingSubscriptions.map((subscription => {
343
+ logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
344
+ this.subscriptions.subscribe(subscription);
345
+ }));
346
+ }
347
+ }), 500);
348
+ }
349
+ }
350
+ class Subscriptions {
351
+ constructor(consumer) {
352
+ this.consumer = consumer;
353
+ this.guarantor = new SubscriptionGuarantor(this);
354
+ this.subscriptions = [];
355
+ }
356
+ create(channelName, mixin) {
357
+ const channel = channelName;
358
+ const params = typeof channel === "object" ? channel : {
359
+ channel: channel
360
+ };
361
+ const subscription = new Subscription(this.consumer, params, mixin);
362
+ return this.add(subscription);
363
+ }
364
+ add(subscription) {
365
+ this.subscriptions.push(subscription);
366
+ this.consumer.ensureActiveConnection();
367
+ this.notify(subscription, "initialized");
368
+ this.subscribe(subscription);
369
+ return subscription;
370
+ }
371
+ remove(subscription) {
372
+ this.forget(subscription);
373
+ if (!this.findAll(subscription.identifier).length) {
374
+ this.sendCommand(subscription, "unsubscribe");
375
+ }
376
+ return subscription;
377
+ }
378
+ reject(identifier) {
379
+ return this.findAll(identifier).map((subscription => {
380
+ this.forget(subscription);
381
+ this.notify(subscription, "rejected");
382
+ return subscription;
383
+ }));
384
+ }
385
+ forget(subscription) {
386
+ this.guarantor.forget(subscription);
387
+ this.subscriptions = this.subscriptions.filter((s => s !== subscription));
388
+ return subscription;
389
+ }
390
+ findAll(identifier) {
391
+ return this.subscriptions.filter((s => s.identifier === identifier));
392
+ }
393
+ reload() {
394
+ return this.subscriptions.map((subscription => this.subscribe(subscription)));
395
+ }
396
+ notifyAll(callbackName, ...args) {
397
+ return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
398
+ }
399
+ notify(subscription, callbackName, ...args) {
400
+ let subscriptions;
401
+ if (typeof subscription === "string") {
402
+ subscriptions = this.findAll(subscription);
403
+ } else {
404
+ subscriptions = [ subscription ];
405
+ }
406
+ return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
407
+ }
408
+ subscribe(subscription) {
409
+ if (this.sendCommand(subscription, "subscribe")) {
410
+ this.guarantor.guarantee(subscription);
411
+ }
412
+ }
413
+ confirmSubscription(identifier) {
414
+ logger.log(`Subscription confirmed ${identifier}`);
415
+ this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
416
+ }
417
+ sendCommand(subscription, command) {
418
+ const {identifier: identifier} = subscription;
419
+ return this.consumer.send({
420
+ command: command,
421
+ identifier: identifier
422
+ });
423
+ }
424
+ }
425
+ class Consumer {
426
+ constructor(url) {
427
+ this._url = url;
428
+ this.subscriptions = new Subscriptions(this);
429
+ this.connection = new Connection(this);
430
+ }
431
+ get url() {
432
+ return createWebSocketURL(this._url);
433
+ }
434
+ send(data) {
435
+ return this.connection.send(data);
436
+ }
437
+ connect() {
438
+ return this.connection.open();
439
+ }
440
+ disconnect() {
441
+ return this.connection.close({
442
+ allowReconnect: false
443
+ });
444
+ }
445
+ ensureActiveConnection() {
446
+ if (!this.connection.isActive()) {
447
+ return this.connection.open();
448
+ }
449
+ }
450
+ }
451
+ function createWebSocketURL(url) {
452
+ if (typeof url === "function") {
453
+ url = url();
454
+ }
455
+ if (url && !/^wss?:/i.test(url)) {
456
+ const a = document.createElement("a");
457
+ a.href = url;
458
+ a.href = a.href;
459
+ a.protocol = a.protocol.replace("http", "ws");
460
+ return a.href;
461
+ } else {
462
+ return url;
463
+ }
464
+ }
465
+ function createConsumer(url = getConfig("url") || INTERNAL.default_mount_path) {
466
+ return new Consumer(url);
467
+ }
468
+ function getConfig(name) {
469
+ const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
470
+ if (element) {
471
+ return element.getAttribute("content");
472
+ }
473
+ }
474
+ exports.Connection = Connection;
475
+ exports.ConnectionMonitor = ConnectionMonitor;
476
+ exports.Consumer = Consumer;
477
+ exports.INTERNAL = INTERNAL;
478
+ exports.Subscription = Subscription;
479
+ exports.SubscriptionGuarantor = SubscriptionGuarantor;
480
+ exports.Subscriptions = Subscriptions;
481
+ exports.adapters = adapters;
482
+ exports.createConsumer = createConsumer;
483
+ exports.createWebSocketURL = createWebSocketURL;
484
+ exports.getConfig = getConfig;
485
+ exports.logger = logger;
486
+ Object.defineProperty(exports, "__esModule", {
487
+ value: true
488
+ });
489
+ }));