futurism 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +86 -84
- data/README.md +26 -0
- data/app/assets/javascripts/futurism.min.js.map +1 -1
- data/app/assets/javascripts/futurism.umd.min.js.map +1 -1
- data/futurism.gemspec +0 -3
- data/futurism.gemspec~ +1 -1
- data/lib/futurism/engine.rb +4 -0
- data/lib/futurism/helpers.rb +5 -5
- data/lib/futurism/options_transformer.rb +1 -1
- data/lib/futurism/resolver/controller/instrumentation.rb +33 -0
- data/lib/futurism/resolver/controller/renderer.rb +5 -1
- data/lib/futurism/resolver/resources.rb +3 -3
- data/lib/futurism/version.rb +1 -1
- data/lib/futurism.rb +11 -3
- data/package.json +1 -1
- data/package.json~ +2 -2
- data/yarn.lock +61 -21
- metadata +5 -94
- data/test/cable/channel_test.rb +0 -319
- data/test/dummy/app/channels/application_cable/channel.rb +0 -4
- data/test/dummy/app/channels/application_cable/connection.rb +0 -4
- data/test/dummy/app/controllers/application_controller.rb +0 -2
- data/test/dummy/app/controllers/home_controller.rb +0 -6
- data/test/dummy/app/controllers/posts_controller.rb +0 -59
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/helpers/posts_helper.rb +0 -2
- data/test/dummy/app/jobs/application_job.rb +0 -7
- data/test/dummy/app/models/action_item.rb +0 -2
- data/test/dummy/app/models/application_record.rb +0 -3
- data/test/dummy/app/models/post.rb +0 -2
- data/test/dummy/config/application.rb +0 -29
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -40
- data/test/dummy/config/environments/production.rb +0 -94
- data/test/dummy/config/environments/test.rb +0 -39
- data/test/dummy/config/initializers/application_controller_renderer.rb +0 -8
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/content_security_policy.rb +0 -28
- data/test/dummy/config/initializers/cookies_serializer.rb +0 -5
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -4
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -9
- data/test/dummy/config/puma.rb +0 -38
- data/test/dummy/config/routes.rb +0 -12
- data/test/dummy/config/spring.rb +0 -6
- data/test/dummy/db/migrate/20200711122838_create_posts.rb +0 -9
- data/test/dummy/db/migrate/2021042923813_create_action_items.rb +0 -9
- data/test/dummy/db/schema.rb +0 -27
- data/test/futurism_test.rb +0 -28
- data/test/helper/helper_test.rb +0 -206
- data/test/integration/navigation_test.rb +0 -7
- data/test/resolver/controller/renderer_test.rb +0 -120
- data/test/resolver/controller_test.rb +0 -26
- data/test/test_helper.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4476a6d522e4145058c729ace6e4cf7adf19a11778e0c0537912bd512e7623df
|
4
|
+
data.tar.gz: 12446b79d1739073c4c21c3d95e8eafdf4b4e5ec110a04aa7c2e9b007b97310a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cabf9ea5de23694fbbc1cdcb06f857bc6e5d2bd066966def655e4f1c3cc94c64787ea268cd4d2a7026b0ccaf4a5b0fe43d0b695dd6739b7696671b505b20b5a2
|
7
|
+
data.tar.gz: 35734fb8141a9abb9c76dad89ae42b3f1858a1d0e165a6eaef1782d382d72e6f31d8e7be3d88887c8c323660ee742cd689ad129cacdcfe729330a451c6f7c1e5
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
futurism (1.
|
4
|
+
futurism (1.3.0)
|
5
5
|
cable_ready (>= 5.0)
|
6
6
|
rack (~> 2.0)
|
7
7
|
rails (>= 5.2)
|
@@ -9,67 +9,67 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
actioncable (7.0.
|
13
|
-
actionpack (= 7.0.
|
14
|
-
activesupport (= 7.0.
|
12
|
+
actioncable (7.0.8)
|
13
|
+
actionpack (= 7.0.8)
|
14
|
+
activesupport (= 7.0.8)
|
15
15
|
nio4r (~> 2.0)
|
16
16
|
websocket-driver (>= 0.6.1)
|
17
|
-
actionmailbox (7.0.
|
18
|
-
actionpack (= 7.0.
|
19
|
-
activejob (= 7.0.
|
20
|
-
activerecord (= 7.0.
|
21
|
-
activestorage (= 7.0.
|
22
|
-
activesupport (= 7.0.
|
17
|
+
actionmailbox (7.0.8)
|
18
|
+
actionpack (= 7.0.8)
|
19
|
+
activejob (= 7.0.8)
|
20
|
+
activerecord (= 7.0.8)
|
21
|
+
activestorage (= 7.0.8)
|
22
|
+
activesupport (= 7.0.8)
|
23
23
|
mail (>= 2.7.1)
|
24
24
|
net-imap
|
25
25
|
net-pop
|
26
26
|
net-smtp
|
27
|
-
actionmailer (7.0.
|
28
|
-
actionpack (= 7.0.
|
29
|
-
actionview (= 7.0.
|
30
|
-
activejob (= 7.0.
|
31
|
-
activesupport (= 7.0.
|
27
|
+
actionmailer (7.0.8)
|
28
|
+
actionpack (= 7.0.8)
|
29
|
+
actionview (= 7.0.8)
|
30
|
+
activejob (= 7.0.8)
|
31
|
+
activesupport (= 7.0.8)
|
32
32
|
mail (~> 2.5, >= 2.5.4)
|
33
33
|
net-imap
|
34
34
|
net-pop
|
35
35
|
net-smtp
|
36
36
|
rails-dom-testing (~> 2.0)
|
37
|
-
actionpack (7.0.
|
38
|
-
actionview (= 7.0.
|
39
|
-
activesupport (= 7.0.
|
40
|
-
rack (~> 2.0, >= 2.2.
|
37
|
+
actionpack (7.0.8)
|
38
|
+
actionview (= 7.0.8)
|
39
|
+
activesupport (= 7.0.8)
|
40
|
+
rack (~> 2.0, >= 2.2.4)
|
41
41
|
rack-test (>= 0.6.3)
|
42
42
|
rails-dom-testing (~> 2.0)
|
43
43
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
44
|
-
actiontext (7.0.
|
45
|
-
actionpack (= 7.0.
|
46
|
-
activerecord (= 7.0.
|
47
|
-
activestorage (= 7.0.
|
48
|
-
activesupport (= 7.0.
|
44
|
+
actiontext (7.0.8)
|
45
|
+
actionpack (= 7.0.8)
|
46
|
+
activerecord (= 7.0.8)
|
47
|
+
activestorage (= 7.0.8)
|
48
|
+
activesupport (= 7.0.8)
|
49
49
|
globalid (>= 0.6.0)
|
50
50
|
nokogiri (>= 1.8.5)
|
51
|
-
actionview (7.0.
|
52
|
-
activesupport (= 7.0.
|
51
|
+
actionview (7.0.8)
|
52
|
+
activesupport (= 7.0.8)
|
53
53
|
builder (~> 3.1)
|
54
54
|
erubi (~> 1.4)
|
55
55
|
rails-dom-testing (~> 2.0)
|
56
56
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
57
|
-
activejob (7.0.
|
58
|
-
activesupport (= 7.0.
|
57
|
+
activejob (7.0.8)
|
58
|
+
activesupport (= 7.0.8)
|
59
59
|
globalid (>= 0.3.6)
|
60
|
-
activemodel (7.0.
|
61
|
-
activesupport (= 7.0.
|
62
|
-
activerecord (7.0.
|
63
|
-
activemodel (= 7.0.
|
64
|
-
activesupport (= 7.0.
|
65
|
-
activestorage (7.0.
|
66
|
-
actionpack (= 7.0.
|
67
|
-
activejob (= 7.0.
|
68
|
-
activerecord (= 7.0.
|
69
|
-
activesupport (= 7.0.
|
60
|
+
activemodel (7.0.8)
|
61
|
+
activesupport (= 7.0.8)
|
62
|
+
activerecord (7.0.8)
|
63
|
+
activemodel (= 7.0.8)
|
64
|
+
activesupport (= 7.0.8)
|
65
|
+
activestorage (7.0.8)
|
66
|
+
actionpack (= 7.0.8)
|
67
|
+
activejob (= 7.0.8)
|
68
|
+
activerecord (= 7.0.8)
|
69
|
+
activesupport (= 7.0.8)
|
70
70
|
marcel (~> 1.0)
|
71
71
|
mini_mime (>= 1.1.0)
|
72
|
-
activesupport (7.0.
|
72
|
+
activesupport (7.0.8)
|
73
73
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
74
74
|
i18n (>= 1.6, < 2)
|
75
75
|
minitest (>= 5.1)
|
@@ -80,79 +80,79 @@ GEM
|
|
80
80
|
thor (>= 0.14.0)
|
81
81
|
ast (2.4.2)
|
82
82
|
builder (3.2.4)
|
83
|
-
cable_ready (5.0.
|
83
|
+
cable_ready (5.0.3)
|
84
84
|
actionpack (>= 5.2)
|
85
85
|
actionview (>= 5.2)
|
86
86
|
activesupport (>= 5.2)
|
87
87
|
railties (>= 5.2)
|
88
88
|
thread-local (>= 1.1.0)
|
89
|
-
coderay (1.1.3)
|
90
89
|
concurrent-ruby (1.2.2)
|
91
90
|
crass (1.0.6)
|
92
|
-
date (3.3.
|
91
|
+
date (3.3.4)
|
93
92
|
erubi (1.12.0)
|
94
|
-
globalid (1.1
|
95
|
-
activesupport (>=
|
96
|
-
i18n (1.
|
93
|
+
globalid (1.2.1)
|
94
|
+
activesupport (>= 6.1)
|
95
|
+
i18n (1.14.1)
|
97
96
|
concurrent-ruby (~> 1.0)
|
98
97
|
json (2.6.3)
|
99
98
|
language_server-protocol (3.17.0.3)
|
100
|
-
loofah (2.
|
99
|
+
loofah (2.22.0)
|
101
100
|
crass (~> 1.0.2)
|
102
|
-
nokogiri (>= 1.
|
101
|
+
nokogiri (>= 1.12.0)
|
103
102
|
mail (2.8.1)
|
104
103
|
mini_mime (>= 0.1.1)
|
105
104
|
net-imap
|
106
105
|
net-pop
|
107
106
|
net-smtp
|
108
107
|
marcel (1.0.2)
|
109
|
-
method_source (0.
|
110
|
-
mini_mime (1.1.
|
111
|
-
minitest (5.
|
112
|
-
net-imap (0.
|
108
|
+
method_source (1.0.0)
|
109
|
+
mini_mime (1.1.5)
|
110
|
+
minitest (5.20.0)
|
111
|
+
net-imap (0.4.7)
|
113
112
|
date
|
114
113
|
net-protocol
|
115
114
|
net-pop (0.1.2)
|
116
115
|
net-protocol
|
117
|
-
net-protocol (0.2.
|
116
|
+
net-protocol (0.2.2)
|
118
117
|
timeout
|
119
|
-
net-smtp (0.
|
118
|
+
net-smtp (0.4.0)
|
120
119
|
net-protocol
|
121
|
-
nio4r (2.
|
122
|
-
nokogiri (1.
|
120
|
+
nio4r (2.7.0)
|
121
|
+
nokogiri (1.15.4-arm64-darwin)
|
122
|
+
racc (~> 1.4)
|
123
|
+
nokogiri (1.15.4-x86_64-linux)
|
123
124
|
racc (~> 1.4)
|
124
125
|
parallel (1.22.1)
|
125
126
|
parser (3.2.1.1)
|
126
127
|
ast (~> 2.4.1)
|
127
|
-
|
128
|
-
|
129
|
-
method_source (~> 0.9.0)
|
130
|
-
racc (1.6.2)
|
131
|
-
rack (2.2.6.4)
|
128
|
+
racc (1.7.1)
|
129
|
+
rack (2.2.8)
|
132
130
|
rack-test (2.1.0)
|
133
131
|
rack (>= 1.3)
|
134
|
-
rails (7.0.
|
135
|
-
actioncable (= 7.0.
|
136
|
-
actionmailbox (= 7.0.
|
137
|
-
actionmailer (= 7.0.
|
138
|
-
actionpack (= 7.0.
|
139
|
-
actiontext (= 7.0.
|
140
|
-
actionview (= 7.0.
|
141
|
-
activejob (= 7.0.
|
142
|
-
activemodel (= 7.0.
|
143
|
-
activerecord (= 7.0.
|
144
|
-
activestorage (= 7.0.
|
145
|
-
activesupport (= 7.0.
|
132
|
+
rails (7.0.8)
|
133
|
+
actioncable (= 7.0.8)
|
134
|
+
actionmailbox (= 7.0.8)
|
135
|
+
actionmailer (= 7.0.8)
|
136
|
+
actionpack (= 7.0.8)
|
137
|
+
actiontext (= 7.0.8)
|
138
|
+
actionview (= 7.0.8)
|
139
|
+
activejob (= 7.0.8)
|
140
|
+
activemodel (= 7.0.8)
|
141
|
+
activerecord (= 7.0.8)
|
142
|
+
activestorage (= 7.0.8)
|
143
|
+
activesupport (= 7.0.8)
|
146
144
|
bundler (>= 1.15.0)
|
147
|
-
railties (= 7.0.
|
148
|
-
rails-dom-testing (2.0
|
149
|
-
activesupport (>=
|
145
|
+
railties (= 7.0.8)
|
146
|
+
rails-dom-testing (2.2.0)
|
147
|
+
activesupport (>= 5.0.0)
|
148
|
+
minitest
|
150
149
|
nokogiri (>= 1.6)
|
151
|
-
rails-html-sanitizer (1.
|
152
|
-
loofah (~> 2.
|
153
|
-
|
154
|
-
|
155
|
-
|
150
|
+
rails-html-sanitizer (1.6.0)
|
151
|
+
loofah (~> 2.21)
|
152
|
+
nokogiri (~> 1.14)
|
153
|
+
railties (7.0.8)
|
154
|
+
actionpack (= 7.0.8)
|
155
|
+
activesupport (= 7.0.8)
|
156
156
|
method_source
|
157
157
|
rake (>= 12.2)
|
158
158
|
thor (~> 1.0)
|
@@ -178,6 +178,7 @@ GEM
|
|
178
178
|
rubocop-ast (>= 0.4.0)
|
179
179
|
ruby-progressbar (1.13.0)
|
180
180
|
sqlite3 (1.6.1-arm64-darwin)
|
181
|
+
sqlite3 (1.6.1-x86_64-linux)
|
181
182
|
standard (1.25.3)
|
182
183
|
language_server-protocol (~> 3.17.0.2)
|
183
184
|
rubocop (~> 1.48.1)
|
@@ -186,24 +187,25 @@ GEM
|
|
186
187
|
standard
|
187
188
|
thor (1.2.1)
|
188
189
|
thread-local (1.1.0)
|
189
|
-
timeout (0.
|
190
|
+
timeout (0.4.1)
|
190
191
|
tzinfo (2.0.6)
|
191
192
|
concurrent-ruby (~> 1.0)
|
192
193
|
unicode-display_width (2.4.2)
|
193
|
-
websocket-driver (0.7.
|
194
|
+
websocket-driver (0.7.6)
|
194
195
|
websocket-extensions (>= 0.1.0)
|
195
196
|
websocket-extensions (0.1.5)
|
196
|
-
zeitwerk (2.6.
|
197
|
+
zeitwerk (2.6.12)
|
197
198
|
|
198
199
|
PLATFORMS
|
199
200
|
arm64-darwin-21
|
201
|
+
arm64-darwin-22
|
202
|
+
x86_64-linux
|
200
203
|
|
201
204
|
DEPENDENCIES
|
202
205
|
appraisal
|
203
206
|
bundler (~> 2.0)
|
204
207
|
futurism!
|
205
208
|
nokogiri
|
206
|
-
pry (~> 0.12.2)
|
207
209
|
rake (~> 13.0)
|
208
210
|
sqlite3
|
209
211
|
standardrb
|
data/README.md
CHANGED
@@ -25,6 +25,7 @@ Lazy-load Rails partials via CableReady
|
|
25
25
|
- [Broadcast Partials Individually](#broadcast-partials-individually)
|
26
26
|
- [Contextual Placeholder Arguments](#contextual-placeholder-arguments)
|
27
27
|
- [Events](#events)
|
28
|
+
- [Instrumentation](#instrumentation)
|
28
29
|
- [Installation](#installation)
|
29
30
|
- [Manual Installation](#manual-installation)
|
30
31
|
- [Authentication](#authentication)
|
@@ -228,6 +229,31 @@ For individual models or arbitrary collections, you can pass `record` and `index
|
|
228
229
|
|
229
230
|
Once your futurize element has been rendered, the `futurism:appeared` custom event will be called.
|
230
231
|
|
232
|
+
## Instrumentation
|
233
|
+
|
234
|
+
Futurism includes support for instrumenting rendering events.
|
235
|
+
|
236
|
+
To enable ActiveSupport notifications, use the `instrumentation` option:
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
Futurism.instrumentation = true
|
240
|
+
```
|
241
|
+
|
242
|
+
Then subscribe to the `render.futurism` event:
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
ActiveSupport::Notifications.subscribe("render.futurism") do |*args|
|
246
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
247
|
+
event.name # => "render.futurism"
|
248
|
+
event.payload[:channel] # => "Futurism::Channel" # ActionCable channel to broadcast
|
249
|
+
event.payload[:controller] # => "posts" # The controller that invokes `futurize` call
|
250
|
+
event.payload[:action] # => "show" # The action that invokes `futurize` call
|
251
|
+
event.payload[:partial] # => "posts/card" # The partial that was rendered
|
252
|
+
end
|
253
|
+
```
|
254
|
+
|
255
|
+
This is useful for performance monitoring, specifically for tracking the source of `futurize` calls.
|
256
|
+
|
231
257
|
## Installation
|
232
258
|
Add this line to your application's Gemfile:
|
233
259
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"futurism.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = this\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["createSubscription","consumer","subscriptions","create","connected","window","Futurism","this","document","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","setTimeout","debounceEvents","send","signed_params","map","e","target","dataset","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","dispatchEvent","CustomEvent","bubbles","cancelable","dispatchAppearEvent","entry","observer","evt","detail","callWithRetry","async","fn","depth","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","filter","key","_payload","startsWith","payload","match","exec","targetElement","querySelector","removeItem","initializeElements","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"futurism.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = this\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["createSubscription","consumer","subscriptions","create","connected","window","Futurism","this","document","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","setTimeout","debounceEvents","send","signed_params","map","e","target","dataset","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","dispatchEvent","CustomEvent","bubbles","cancelable","dispatchAppearEvent","entry","observer","evt","detail","callWithRetry","async","fn","depth","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","filter","key","_payload","startsWith","payload","match","exec","targetElement","querySelector","removeItem","initializeElements","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"futurism.umd.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = this\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["dispatchAppearEvent","entry","observer","window","Futurism","setTimeout","target","evt","CustomEvent","bubbles","detail","dispatchEvent","callWithRetry","async","fn","depth","e","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","dataset","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","this","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","map","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","filter","key","_payload","startsWith","payload","match","exec","targetElement","document","querySelector","removeItem","consumer","subscriptions","create","connected","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","debounceEvents","send","signed_params","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","cancelable","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"futurism.umd.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = this\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["dispatchAppearEvent","entry","observer","window","Futurism","setTimeout","target","evt","CustomEvent","bubbles","detail","dispatchEvent","callWithRetry","async","fn","depth","e","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","dataset","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","this","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","map","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","filter","key","_payload","startsWith","payload","match","exec","targetElement","document","querySelector","removeItem","consumer","subscriptions","create","connected","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","debounceEvents","send","signed_params","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","cancelable","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
|
data/futurism.gemspec
CHANGED
@@ -22,12 +22,9 @@ Gem::Specification.new do |spec|
|
|
22
22
|
"[A-Z]*"
|
23
23
|
]
|
24
24
|
|
25
|
-
spec.test_files = Dir["test/**/*.rb"]
|
26
|
-
|
27
25
|
spec.add_development_dependency "appraisal"
|
28
26
|
spec.add_development_dependency "bundler", "~> 2.0"
|
29
27
|
spec.add_development_dependency "rake", "~> 13.0"
|
30
|
-
spec.add_development_dependency "pry", "~> 0.12.2"
|
31
28
|
spec.add_development_dependency "nokogiri"
|
32
29
|
spec.add_development_dependency "standardrb"
|
33
30
|
spec.add_development_dependency "sqlite3"
|
data/futurism.gemspec~
CHANGED
data/lib/futurism/engine.rb
CHANGED
@@ -19,5 +19,9 @@ module Futurism
|
|
19
19
|
app.config.importmap.cache_sweepers << Engine.root.join("app/assets/javascripts")
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
initializer "futurism.logger", after: "initialize_logger" do
|
24
|
+
Futurism.logger ||= Rails.logger || Logger.new($stdout)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
data/lib/futurism/helpers.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Futurism
|
2
2
|
module Helpers
|
3
3
|
def futurize(records_or_string = nil, extends: :div, **options, &block)
|
4
|
-
if (Rails.env.test? && Futurism.skip_in_test) || options[:unless]
|
4
|
+
if (Rails.env.test? && Futurism.skip_in_test?) || options[:unless]
|
5
5
|
if records_or_string.nil?
|
6
6
|
return render(**options)
|
7
7
|
else
|
@@ -9,7 +9,7 @@ module Futurism
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
options[:eager] = true unless
|
12
|
+
options[:eager] = true unless block
|
13
13
|
|
14
14
|
# cannot serialize a proc
|
15
15
|
options.delete(:cached) if options[:cached].is_a?(Proc)
|
@@ -27,7 +27,7 @@ module Futurism
|
|
27
27
|
def futurize_with_options(extends:, **options, &block)
|
28
28
|
collection = options.delete(:collection)
|
29
29
|
if collection.nil?
|
30
|
-
placeholder = capture(&block) if
|
30
|
+
placeholder = capture(&block) if block
|
31
31
|
|
32
32
|
WrappingFuturismElement.new(extends: extends, placeholder: placeholder, options: options).render
|
33
33
|
else
|
@@ -36,7 +36,7 @@ module Futurism
|
|
36
36
|
broadcast_each = options.delete(:broadcast_each) || false
|
37
37
|
|
38
38
|
collection.each_with_index.map { |record, index|
|
39
|
-
placeholder = capture(record, index, &block) if
|
39
|
+
placeholder = capture(record, index, &block) if block
|
40
40
|
|
41
41
|
WrappingFuturismElement.new(extends: extends, placeholder: placeholder, options: options.deep_merge(
|
42
42
|
broadcast_each: broadcast_each,
|
@@ -48,7 +48,7 @@ module Futurism
|
|
48
48
|
|
49
49
|
def futurize_active_record(records, extends:, **options, &block)
|
50
50
|
Array(records).map.with_index { |record, index|
|
51
|
-
placeholder = capture(record, index, &block) if
|
51
|
+
placeholder = capture(record, index, &block) if block
|
52
52
|
|
53
53
|
WrappingFuturismElement.new(extends: extends, options: options.merge(model: record), placeholder: placeholder).render
|
54
54
|
}.join.html_safe
|
@@ -14,7 +14,7 @@ module Futurism
|
|
14
14
|
def load_options(options)
|
15
15
|
require_relative "shims/deep_transform_values" unless options.respond_to? :deep_transform_values
|
16
16
|
|
17
|
-
options.deep_transform_values { |value| value.is_a?(String) && value.start_with?("gid://") ? GlobalID::Locator.locate(value) : value }
|
17
|
+
options.deep_transform_values { |value| (value.is_a?(String) && value.start_with?("gid://")) ? GlobalID::Locator.locate(value) : value }
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "active_support/notifications"
|
2
|
+
|
3
|
+
module Futurism
|
4
|
+
module Resolver
|
5
|
+
class Controller
|
6
|
+
class Instrumentation < SimpleDelegator
|
7
|
+
PARAMETERS_KEY = ActionDispatch::Http::Parameters::PARAMETERS_KEY
|
8
|
+
|
9
|
+
def render(*args)
|
10
|
+
ActiveSupport::Notifications.instrument(
|
11
|
+
"render.futurism",
|
12
|
+
channel: get_param(:channel),
|
13
|
+
controller: get_param(:controller),
|
14
|
+
action: get_param(:action),
|
15
|
+
partial: extract_partial_name(*args)
|
16
|
+
) do
|
17
|
+
super(*args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def get_param(key)
|
24
|
+
__getobj__.instance_variable_get(:@env).dig(PARAMETERS_KEY, key)
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract_partial_name(opts_or_model, *args)
|
28
|
+
opts_or_model.is_a?(Hash) ? opts_or_model[:partial] : opts_or_model.to_partial_path
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -7,7 +7,11 @@ module Futurism
|
|
7
7
|
HTTP_METHODS = [:get, :post, :put, :patch, :delete]
|
8
8
|
|
9
9
|
def self.for(controller:, connection:, url:, params:)
|
10
|
-
new(
|
10
|
+
controller_renderer = new(
|
11
|
+
controller: controller, connection: connection, url: url, params: params
|
12
|
+
).renderer
|
13
|
+
|
14
|
+
Futurism.instrumentation? ? Instrumentation.new(controller_renderer) : controller_renderer
|
11
15
|
end
|
12
16
|
|
13
17
|
def initialize(controller:, connection:, url:, params:)
|
@@ -83,9 +83,9 @@ module Futurism
|
|
83
83
|
|
84
84
|
def renderer_for(resource_definition:)
|
85
85
|
Resolver::Controller::Renderer.for(controller: resource_definition.controller,
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
connection: @connection,
|
87
|
+
url: resource_definition.url,
|
88
|
+
params: @params)
|
89
89
|
end
|
90
90
|
|
91
91
|
def resolved_models
|
data/lib/futurism/version.rb
CHANGED
data/lib/futurism.rb
CHANGED
@@ -9,6 +9,7 @@ require "futurism/options_transformer"
|
|
9
9
|
require "futurism/resolver/resources"
|
10
10
|
require "futurism/resolver/controller"
|
11
11
|
require "futurism/resolver/controller/renderer"
|
12
|
+
require "futurism/resolver/controller/instrumentation"
|
12
13
|
require "futurism/helpers"
|
13
14
|
|
14
15
|
module Futurism
|
@@ -17,16 +18,23 @@ module Futurism
|
|
17
18
|
autoload :Helpers, "futurism/helpers"
|
18
19
|
|
19
20
|
mattr_accessor :skip_in_test, default: false
|
21
|
+
mattr_accessor :instrumentation, default: false
|
22
|
+
mattr_accessor :logger
|
20
23
|
|
21
24
|
mattr_writer :default_controller
|
22
25
|
def self.default_controller
|
23
26
|
(@@default_controller || "::ApplicationController").to_s.constantize
|
24
27
|
end
|
25
28
|
|
29
|
+
def self.skip_in_test?
|
30
|
+
skip_in_test.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.instrumentation?
|
34
|
+
instrumentation.present?
|
35
|
+
end
|
36
|
+
|
26
37
|
ActiveSupport.on_load(:action_view) do
|
27
38
|
include Futurism::Helpers
|
28
39
|
end
|
29
|
-
|
30
|
-
mattr_accessor :logger
|
31
|
-
self.logger ||= Rails.logger ? Rails.logger.new : Logger.new($stdout)
|
32
40
|
end
|