turbo_reflex 0.0.2 → 0.0.4
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 +4 -4
- data/Dockerfile +43 -0
- data/Dockerfile.orig +49 -0
- data/Gemfile.lock +25 -5
- data/README.md +30 -28
- data/app/assets/builds/turbo_reflex.js +2 -0
- data/app/assets/builds/turbo_reflex.js.map +7 -0
- data/app/assets/images/turbo-reflex-mark.webp +0 -0
- data/app/controllers/concerns/turbo_reflex/controller.rb +1 -0
- data/app/controllers/turbo_reflex/application_controller.rb +5 -0
- data/app/controllers/turbo_reflex/turbo_reflexes_controller.rb +10 -0
- data/app/helpers/turbo_reflex/turbo_reflex_helper.rb +9 -0
- data/app/javascript/elements.js +2 -2
- data/bin/standardize +2 -0
- data/config/routes.rb +5 -0
- data/docker-compose.yml +46 -0
- data/fly.toml +38 -0
- data/lib/turbo_reflex/base.rb +6 -0
- data/lib/turbo_reflex/engine.rb +15 -0
- data/lib/turbo_reflex/errors.rb +6 -0
- data/lib/turbo_reflex/version.rb +1 -1
- data/package.json +6 -4
- data/turbo_reflex.gemspec +5 -1
- data/yarn-error.log +3033 -0
- data/yarn.lock +193 -134
- metadata +71 -5
- data/app/assets/builds/turbo_reflex.min.js +0 -2
- data/app/assets/builds/turbo_reflex.min.js.map +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9fe08630cc0c938fc6b2eb4ed55b841bd968d3b1a9e47c4d7831eba6877994f
|
4
|
+
data.tar.gz: 41e2891f690ec5d77c0c3ec537145f4126e750351bcd9b9040fa701374a35afa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2069894ceef06beac578f28a4c4729ab272e089fbe4556f71743ef2d7dfdd328512102ac24d0cf4d8d1f5379fc67e2c356e1ec05b74a207ddf656ac470d7bdf
|
7
|
+
data.tar.gz: f316ed002e6560cd93d4d30c600c51d5181c82a500e75b93baad27195d0934fd5ebf4fb0ea1cdecd72fd7b5d6654f4671c104d9d46c30e446c77df876a7f9911
|
data/Dockerfile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
FROM ruby:3.1.2
|
2
|
+
|
3
|
+
RUN apt-get -y update && \
|
4
|
+
apt-get -y upgrade && \
|
5
|
+
apt-get -y --allow-downgrades --allow-remove-essential --allow-change-held-packages install \
|
6
|
+
build-essential \
|
7
|
+
git \
|
8
|
+
nodejs \
|
9
|
+
npm \
|
10
|
+
sqlite3 \
|
11
|
+
tzdata && \
|
12
|
+
apt-get clean
|
13
|
+
|
14
|
+
# setup ruby gems
|
15
|
+
RUN gem update --system && \
|
16
|
+
gem install bundler && \
|
17
|
+
bundle config set --global --without test
|
18
|
+
|
19
|
+
# setup yarn
|
20
|
+
RUN npm install -g yarn
|
21
|
+
|
22
|
+
# get application code
|
23
|
+
RUN rm -rf /opt/turbo_reflex
|
24
|
+
RUN git clone --origin github --branch main --depth 1 https://github.com/hopsoft/turbo_reflex.git /opt/turbo_reflex
|
25
|
+
|
26
|
+
# install application dependencies 1st time
|
27
|
+
WORKDIR /opt/turbo_reflex
|
28
|
+
RUN yarn
|
29
|
+
RUN bundle
|
30
|
+
|
31
|
+
# prepare the environment
|
32
|
+
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
33
|
+
|
34
|
+
# prepare and run the application
|
35
|
+
CMD git pull --no-rebase github main && \
|
36
|
+
yarn && \
|
37
|
+
cd test/dummy && \
|
38
|
+
bundle && \
|
39
|
+
rm -f tmp/pids/server.pid && \
|
40
|
+
bin/rails db:create db:migrate && \
|
41
|
+
bin/rails assets:clobber && \
|
42
|
+
bin/rails assets:precompile && \
|
43
|
+
bin/rails s --binding=0.0.0.0 --port=3000
|
data/Dockerfile.orig
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
FROM ruby:3.1.2
|
2
|
+
|
3
|
+
RUN apt-get -y update && \
|
4
|
+
apt-get -y upgrade && \
|
5
|
+
apt-get -y --allow-downgrades --allow-remove-essential --allow-change-held-packages install \
|
6
|
+
build-essential \
|
7
|
+
git \
|
8
|
+
nodejs \
|
9
|
+
npm \
|
10
|
+
sqlite3 \
|
11
|
+
tzdata && \
|
12
|
+
apt-get clean
|
13
|
+
|
14
|
+
<<<<<<< HEAD
|
15
|
+
# prepare the environment
|
16
|
+
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
17
|
+
|
18
|
+
=======
|
19
|
+
>>>>>>> main
|
20
|
+
# setup ruby gems
|
21
|
+
RUN gem update --system && \
|
22
|
+
gem install bundler && \
|
23
|
+
bundle config set --global --without test
|
24
|
+
|
25
|
+
# setup yarn
|
26
|
+
RUN npm install -g yarn
|
27
|
+
|
28
|
+
# get application code
|
29
|
+
RUN git clone --origin github --branch main --depth 1 https://github.com/hopsoft/turbo_reflex.git /opt/turbo_reflex
|
30
|
+
|
31
|
+
# install application dependencies 1st time
|
32
|
+
WORKDIR /opt/turbo_reflex
|
33
|
+
RUN yarn
|
34
|
+
WORKDIR /opt/turbo_reflex/test/dummy
|
35
|
+
RUN bundle
|
36
|
+
|
37
|
+
# prepare the environment
|
38
|
+
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
39
|
+
|
40
|
+
# prepare and run the application
|
41
|
+
CMD git pull --no-rebase github && \
|
42
|
+
git checkout hopsoft/hijack && \
|
43
|
+
cd /opt/turbo_reflex && yarn && \
|
44
|
+
cd /opt/turbo_reflex/test/dummy && bundle && \
|
45
|
+
rm -f tmp/pids/server.pid && \
|
46
|
+
bin/rails db:create db:migrate && \
|
47
|
+
bin/rails assets:clobber && \
|
48
|
+
bin/rails assets:precompile && \
|
49
|
+
bin/rails s --binding=0.0.0.0 --port=3000
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
turbo_reflex (0.0.
|
4
|
+
turbo_reflex (0.0.4)
|
5
5
|
rails (>= 6.1)
|
6
6
|
turbo-rails (>= 1.1)
|
7
7
|
|
@@ -77,6 +77,7 @@ GEM
|
|
77
77
|
public_suffix (>= 2.0.2, < 6.0)
|
78
78
|
ansi (1.5.0)
|
79
79
|
ast (2.4.2)
|
80
|
+
bindex (0.8.1)
|
80
81
|
builder (3.2.4)
|
81
82
|
byebug (11.1.3)
|
82
83
|
capybara (3.37.1)
|
@@ -103,6 +104,7 @@ GEM
|
|
103
104
|
cliver (~> 0.3)
|
104
105
|
concurrent-ruby (~> 1.1)
|
105
106
|
websocket-driver (>= 0.6, < 0.8)
|
107
|
+
foreman (0.87.2)
|
106
108
|
globalid (1.0.0)
|
107
109
|
activesupport (>= 5.0)
|
108
110
|
i18n (1.12.0)
|
@@ -111,7 +113,7 @@ GEM
|
|
111
113
|
actionpack (>= 6.0.0)
|
112
114
|
railties (>= 6.0.0)
|
113
115
|
json (2.6.2)
|
114
|
-
loofah (2.
|
116
|
+
loofah (2.19.0)
|
115
117
|
crass (~> 1.0.2)
|
116
118
|
nokogiri (>= 1.5.9)
|
117
119
|
magic_frozen_string_literal (1.2.0)
|
@@ -142,6 +144,8 @@ GEM
|
|
142
144
|
net-protocol
|
143
145
|
timeout
|
144
146
|
nio4r (2.5.8)
|
147
|
+
nokogiri (1.13.8-aarch64-linux)
|
148
|
+
racc (~> 1.4)
|
145
149
|
nokogiri (1.13.8-arm64-darwin)
|
146
150
|
racc (~> 1.4)
|
147
151
|
parallel (1.22.1)
|
@@ -190,6 +194,7 @@ GEM
|
|
190
194
|
rake (13.0.6)
|
191
195
|
regexp_parser (2.5.0)
|
192
196
|
rexml (3.2.5)
|
197
|
+
rouge (4.0.0)
|
193
198
|
rubocop (1.35.1)
|
194
199
|
json (~> 2.3)
|
195
200
|
parallel (~> 1.10)
|
@@ -219,6 +224,7 @@ GEM
|
|
219
224
|
actionpack (>= 5.2)
|
220
225
|
activesupport (>= 5.2)
|
221
226
|
sprockets (>= 3.0.0)
|
227
|
+
sqlite3 (1.5.0-aarch64-linux)
|
222
228
|
sqlite3 (1.5.0-arm64-darwin)
|
223
229
|
standard (1.16.1)
|
224
230
|
rubocop (= 1.35.1)
|
@@ -226,19 +232,28 @@ GEM
|
|
226
232
|
standardrb (1.0.1)
|
227
233
|
standard
|
228
234
|
strscan (3.0.4)
|
235
|
+
tailwindcss-rails (2.0.14-aarch64-linux)
|
236
|
+
railties (>= 6.0.0)
|
237
|
+
tailwindcss-rails (2.0.14-arm64-darwin)
|
238
|
+
railties (>= 6.0.0)
|
229
239
|
thor (1.2.1)
|
230
240
|
timeout (0.3.0)
|
231
241
|
turbo-rails (1.1.1)
|
232
242
|
actionpack (>= 6.0.0)
|
233
243
|
activejob (>= 6.0.0)
|
234
244
|
railties (>= 6.0.0)
|
235
|
-
turbo_ready (0.0
|
245
|
+
turbo_ready (0.1.0)
|
236
246
|
rails (>= 6.1)
|
237
247
|
turbo-rails (>= 1.1)
|
238
248
|
tzinfo (2.0.5)
|
239
249
|
concurrent-ruby (~> 1.0)
|
240
|
-
unicode-display_width (2.
|
241
|
-
|
250
|
+
unicode-display_width (2.3.0)
|
251
|
+
web-console (4.2.0)
|
252
|
+
actionview (>= 6.0.0)
|
253
|
+
activemodel (>= 6.0.0)
|
254
|
+
bindex (>= 0.4.0)
|
255
|
+
railties (>= 6.0.0)
|
256
|
+
webdrivers (5.1.0)
|
242
257
|
nokogiri (~> 1.6)
|
243
258
|
rubyzip (>= 1.3.0)
|
244
259
|
selenium-webdriver (~> 4.0)
|
@@ -251,11 +266,13 @@ GEM
|
|
251
266
|
zeitwerk (2.6.0)
|
252
267
|
|
253
268
|
PLATFORMS
|
269
|
+
aarch64-linux
|
254
270
|
arm64-darwin-21
|
255
271
|
|
256
272
|
DEPENDENCIES
|
257
273
|
capybara
|
258
274
|
cuprite
|
275
|
+
foreman
|
259
276
|
importmap-rails
|
260
277
|
magic_frozen_string_literal
|
261
278
|
minitest-reporters
|
@@ -264,11 +281,14 @@ DEPENDENCIES
|
|
264
281
|
puma
|
265
282
|
rake
|
266
283
|
rexml
|
284
|
+
rouge
|
267
285
|
sprockets-rails
|
268
286
|
sqlite3
|
269
287
|
standardrb
|
288
|
+
tailwindcss-rails
|
270
289
|
turbo_ready
|
271
290
|
turbo_reflex!
|
291
|
+
web-console
|
272
292
|
webdrivers
|
273
293
|
|
274
294
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -117,14 +117,14 @@ TurboReflex is a lightweight Turbo Frame extension... which means that reactivit
|
|
117
117
|
|
118
118
|
```diff
|
119
119
|
# Gemfile
|
120
|
-
+gem "turbo_reflex", "~> 0.0.
|
120
|
+
+gem "turbo_reflex", "~> 0.0.3"
|
121
121
|
```
|
122
122
|
|
123
123
|
```diff
|
124
124
|
# package.json
|
125
125
|
"dependencies": {
|
126
126
|
"@hotwired/turbo-rails": ">=7.1",
|
127
|
-
+ "turbo_reflex": "^0.0.
|
127
|
+
+ "turbo_reflex": "^0.0.3"
|
128
128
|
```
|
129
129
|
|
130
130
|
*Be sure to install the __same version__ of the Ruby and JavaScript libraries.*
|
@@ -142,16 +142,12 @@ TurboReflex is a lightweight Turbo Frame extension... which means that reactivit
|
|
142
142
|
# app/views/layouts/application.html.erb
|
143
143
|
<html>
|
144
144
|
<head>
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
# /app/controllers/application_controller.rb
|
152
|
-
class ApplicationController < ActionController::Base
|
153
|
-
+ include TurboReflex::Controller
|
154
|
-
end
|
145
|
+
+ <%= turbo_reflex_meta_tag %>
|
146
|
+
</head>
|
147
|
+
<body>
|
148
|
+
+ <%= turbo_reflex_frame_tag %>
|
149
|
+
</body>
|
150
|
+
</html>
|
155
151
|
```
|
156
152
|
|
157
153
|
## Usage
|
@@ -163,7 +159,7 @@ This example illustrates how to use TurboReflex to manage upvotes on a Post.
|
|
163
159
|
```erb
|
164
160
|
<!-- app/views/posts/show.html.erb -->
|
165
161
|
<%= turbo_frame_tag dom_id(@post) do %>
|
166
|
-
<a href="#" data-turbo-reflex="
|
162
|
+
<a href="#" data-turbo-reflex="PostReflex#upvote">Upvote</a>
|
167
163
|
Upvote Count: <%= @post.votes >
|
168
164
|
<% end %>
|
169
165
|
```
|
@@ -172,7 +168,7 @@ This example illustrates how to use TurboReflex to manage upvotes on a Post.
|
|
172
168
|
|
173
169
|
```ruby
|
174
170
|
# app/reflexes/posts_reflex.rb
|
175
|
-
class
|
171
|
+
class PostReflex < TurboReflex::Base
|
176
172
|
def upvote
|
177
173
|
Post.find(controller.params[:id]).increment! :votes
|
178
174
|
end
|
@@ -221,18 +217,10 @@ TurboReflex supports the following lifecycle events.
|
|
221
217
|
|
222
218
|
### Targeting Frames
|
223
219
|
|
224
|
-
|
225
|
-
but you can also explicitly target other frames.
|
226
|
-
|
227
|
-
1. Look for `data-turbo-reflex-frame` on the reflex elemnt
|
228
|
-
|
229
|
-
```erb
|
230
|
-
<input type="checkbox"
|
231
|
-
data-turbo-reflex="ExampleReflex#work"
|
232
|
-
data-turbo-reflex-frame="some-frame-id">
|
233
|
-
```
|
220
|
+
TurboReflex targets the [`closest`](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest) `<turbo-frame>` element by default,
|
221
|
+
but you can also explicitly target other frames just like you normally would with Turbo Frames.
|
234
222
|
|
235
|
-
|
223
|
+
1. Look for `data-turbo-frame` on the reflex element
|
236
224
|
|
237
225
|
```erb
|
238
226
|
<input type="checkbox"
|
@@ -240,7 +228,7 @@ but you can also explicitly target other frames.
|
|
240
228
|
data-turbo-frame="some-frame-id">
|
241
229
|
```
|
242
230
|
|
243
|
-
|
231
|
+
1. Find the closest `<turbo-frame>` to the reflex element
|
244
232
|
|
245
233
|
```erb
|
246
234
|
<turbo-frame id="example-frame">
|
@@ -442,6 +430,8 @@ The best way to learn this stuff is from working examples.
|
|
442
430
|
Be sure to clone the library and run the test application.
|
443
431
|
Then dig into the internals.
|
444
432
|
|
433
|
+
#### Running Locally
|
434
|
+
|
445
435
|
```sh
|
446
436
|
git clone https://github.com/hopsoft/turbo_reflex.git
|
447
437
|
cd turbo_reflex
|
@@ -451,6 +441,17 @@ bin/rails s
|
|
451
441
|
# View the app in a browser at http://localhost:3000
|
452
442
|
```
|
453
443
|
|
444
|
+
#### Running in Docker
|
445
|
+
|
446
|
+
Docker users can get up and running even faster.
|
447
|
+
|
448
|
+
```sh
|
449
|
+
git clone https://github.com/hopsoft/turbo_reflex.git
|
450
|
+
cd turbo_reflex
|
451
|
+
docker compose up -d
|
452
|
+
# View the app in a browser at http://localhost:3000
|
453
|
+
```
|
454
|
+
|
454
455
|
You can review the implementation in [`test/dummy/app`](https://github.com/hopsoft/turbo_reflex/tree/main/test/dummy).
|
455
456
|
*Feel free to add some demos and submit a pull request while you're in there.*
|
456
457
|
|
@@ -462,13 +463,14 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
462
463
|
|
463
464
|
## Todos
|
464
465
|
|
466
|
+
- [ ] Consider falling back to the turbo-reflex-frame when a frame can't be identified
|
467
|
+
- [ ] Consider how to best support `link_to` with methods other than GET
|
468
|
+
- [ ] Update system tests for new demos
|
465
469
|
- [ ] Add tests for lifecycle events
|
466
470
|
- [ ] Add tests for select elements
|
467
471
|
- [ ] Add tests for checkbox elements
|
468
|
-
- [ ] Add controller tests
|
469
472
|
- [ ] Add tests for all variants of frame targeting
|
470
473
|
|
471
|
-
|
472
474
|
## Releasing
|
473
475
|
|
474
476
|
1. Run `yarn upgrade` and `bundle update` to pick up the latest
|
@@ -0,0 +1,2 @@
|
|
1
|
+
var l={beforeStart:"turbo-reflex:before-start",start:"turbo-reflex:start",finish:"turbo-reflex:finish",error:"turbo-reflex:error",missingFrameId:"turbo-reflex:missing-frame-id",missingFrame:"turbo-reflex:missing-frame",missingFrameSrc:"turbo-reflex:missing-frame-src"};function y(t,e=document,r={}){let n=new CustomEvent(t,{detail:r,cancelable:!0,bubbles:!0});e.dispatchEvent(n)}function L(){Object.values(l).forEach(t=>console.log(t))}var o={...l,dispatch:y,logEventNames:L};var c={};addEventListener("turbo:before-fetch-response",t=>{let e=t.target;c[e.id]=e.src;let{turboReflexActive:r,turboReflexElementId:n}=e.dataset;if(!r)return;let s=document.getElementById(n);delete e.dataset.turboReflexActive,delete e.dataset.turboReflexElementId,o.dispatch(o.finish,s||document,{frame:e,element:s||"Unknown! Missing id attribute."})});addEventListener("turbo:frame-load",t=>{let e=t.target;e.dataset.turboReflexSrc=c[e.id]||e.src||e.dataset.turboReflexSrc,delete c[e.id]});var S={get token(){return document.getElementById("turbo-reflex-token").getAttribute("content")}},f=S;function m(t){return t.closest("[data-turbo-reflex]")}function F(t){return t.closest("turbo-frame")}function b(t){let e=t.dataset.turboFrame;if(!e){let r=F(t);r&&(e=r.id)}return e||(console.error("The reflex element does not specify a frame!","Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-frame' attribute.",t),o.dispatch(o.missingFrameId,t,{element:t})),e}function g(t){let e=document.getElementById(t);return e||(console.error(`The frame '${t}' does not exist!`),o.dispatch(o.missingFrame,document,{id:t})),e}function x(t){let e=t.dataset.turboReflexSrc||t.src;return e||(console.error(`The the 'src' for <turbo-frame id='${t.id}'> is unknown!`,"TurboReflex uses 'src' to (re)render frame content after the reflex is invoked.","Please set the 'src' or 'data-turbo-reflex-src' attribute on the <turbo-frame> element.",t),o.dispatch(o.missingFrameSrc,t,{frame:t})),e}function k(t,e={}){if(t.tagName.toLowerCase()!=="select")return e.value=t.value;if(!t.multiple)return e.value=t.options[t.selectedIndex].value;e.values=Array.from(t.options).reduce((r,n)=>(n.selected&&r.push(n.value),r),[])}function v(t){let e=Array.from(t.attributes).reduce((r,n)=>(r[n.name]=n.value,r),{});return e.tag=t.tagName,e.checked=t.checked,e.disabled=t.disabled,k(t,e),e}var a={},h;function p(t){h=t}function u(t,e){a[t]=e,document.addEventListener(t,h,!0)}function E(t,e){return e=e.toLowerCase(),a[t].includes(e)||!Object.values(a).flat().includes(e)&&a[t].includes("*")}function R(){console.log(a)}addEventListener("turbo:before-fetch-request",t=>{let e=t.target,{turboReflexActive:r}=e.dataset;if(!r)return;let{fetchOptions:n}=t.detail;n.headers["Turbo-Reflex"]=f.token});function I(t){let e=document.createElement("a");return e.href=t,new URL(e)}function A(t,e={}){e.token=f.token;let r=document.createElement("input");r.type="hidden",r.name="turbo_reflex",r.value=JSON.stringify(e),t.appendChild(r)}function C(t){let e,r,n,s;try{if(e=m(t.target),!e||!E(t.type,e.tagName)||(o.dispatch(o.beforeStart,e,{element:e}),r=b(e),!r)||(n=g(r),!n)||(s=x(n),!s))return;let i={frameId:r,element:v(e)};if(o.dispatch(o.start,e,{element:e,frameId:r,frame:n,frameSrc:s,payload:i}),n.dataset.turboReflexActive=!0,n.dataset.turboReflexElementId=e.id,e.tagName.toLowerCase()==="form")return A(e,i);t.preventDefault();let d=I(s);d.searchParams.set("turbo_reflex",JSON.stringify(i)),n.src=d.toString()}catch(i){console.error("TurboReflex encountered an unexpected error!",{element:e,frameId:r,frame:n,frameSrc:s,target:t.target},i),o.dispatch(o.error,e||document,{element:e,frameId:r,frame:n,frameSrc:s,error:i})}}p(C);u("change",["input","select","textarea"]);u("submit",["form"]);u("click",["*"]);var M={registerEvent:u,logRegisteredEvents:R,logLifecycleEventNames:o.logEventNames};export{M as default};
|
2
|
+
//# sourceMappingURL=turbo_reflex.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../javascript/lifecycle_events.js", "../../javascript/frame_sources.js", "../../javascript/security.js", "../../javascript/elements.js", "../../javascript/event_registry.js", "../../javascript/turbo_reflex.js"],
|
4
|
+
"sourcesContent": ["const events = {\n beforeStart: 'turbo-reflex:before-start',\n start: 'turbo-reflex:start',\n finish: 'turbo-reflex:finish',\n error: 'turbo-reflex:error',\n missingFrameId: 'turbo-reflex:missing-frame-id',\n missingFrame: 'turbo-reflex:missing-frame',\n missingFrameSrc: 'turbo-reflex:missing-frame-src'\n}\n\nfunction dispatch (name, target = document, detail = {}) {\n const event = new CustomEvent(name, {\n detail,\n cancelable: true,\n bubbles: true\n })\n target.dispatchEvent(event)\n}\n\nfunction logEventNames () {\n Object.values(events).forEach(name => console.log(name))\n}\n\nexport default { ...events, dispatch, logEventNames }\n", "import LifecycleEvents from './lifecycle_events'\nconst frameSources = {}\n\n// fires after receiving a turbo HTTP response\naddEventListener('turbo:before-fetch-response', event => {\n const frame = event.target\n frameSources[frame.id] = frame.src\n\n const { turboReflexActive, turboReflexElementId } = frame.dataset\n if (!turboReflexActive) return\n\n const element = document.getElementById(turboReflexElementId)\n delete frame.dataset.turboReflexActive\n delete frame.dataset.turboReflexElementId\n\n LifecycleEvents.dispatch(LifecycleEvents.finish, element || document, {\n frame,\n element: element || 'Unknown! Missing id attribute.'\n })\n})\n\n// fires when a frame element is navigated and finishes loading\naddEventListener('turbo:frame-load', event => {\n const frame = event.target\n frame.dataset.turboReflexSrc =\n frameSources[frame.id] || frame.src || frame.dataset.turboReflexSrc\n delete frameSources[frame.id]\n})\n", "const Security = {\n get token () {\n return document.getElementById('turbo-reflex-token').getAttribute('content')\n }\n}\n\nexport default Security\n", "import LifecycleEvents from './lifecycle_events'\n\nfunction findClosestReflex (element) {\n return element.closest('[data-turbo-reflex]')\n}\n\nfunction findClosestFrame (element) {\n return element.closest('turbo-frame')\n}\n\nfunction findFrameId (element) {\n let id = element.dataset.turboFrame\n if (!id) {\n const frame = findClosestFrame(element)\n if (frame) id = frame.id\n }\n if (!id) {\n console.error(\n `The reflex element does not specify a frame!`,\n `Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-frame' attribute.`,\n element\n )\n LifecycleEvents.dispatch(LifecycleEvents.missingFrameId, element, {\n element\n })\n }\n return id\n}\n\nfunction findFrame (id) {\n const frame = document.getElementById(id)\n if (!frame) {\n console.error(`The frame '${id}' does not exist!`)\n LifecycleEvents.dispatch(LifecycleEvents.missingFrame, document, { id })\n }\n return frame\n}\n\nfunction findFrameSrc (frame) {\n const frameSrc = frame.dataset.turboReflexSrc || frame.src\n if (!frameSrc) {\n console.error(\n `The the 'src' for <turbo-frame id='${frame.id}'> is unknown!`,\n `TurboReflex uses 'src' to (re)render frame content after the reflex is invoked.`,\n `Please set the 'src' or 'data-turbo-reflex-src' attribute on the <turbo-frame> element.`,\n frame\n )\n LifecycleEvents.dispatch(LifecycleEvents.missingFrameSrc, frame, { frame })\n }\n return frameSrc\n}\n\nfunction assignElementValueToPayload (element, payload = {}) {\n if (element.tagName.toLowerCase() !== 'select')\n return (payload.value = element.value)\n\n if (!element.multiple)\n return (payload.value = element.options[element.selectedIndex].value)\n\n payload.values = Array.from(element.options).reduce((memo, option) => {\n if (option.selected) memo.push(option.value)\n return memo\n }, [])\n}\n\nfunction buildAttributePayload (element) {\n const payload = Array.from(element.attributes).reduce((memo, attr) => {\n memo[attr.name] = attr.value\n return memo\n }, {})\n\n payload.tag = element.tagName\n payload.checked = element.checked\n payload.disabled = element.disabled\n assignElementValueToPayload(element, payload)\n\n return payload\n}\n\nexport {\n findClosestReflex,\n findClosestFrame,\n findFrameId,\n findFrame,\n findFrameSrc,\n buildAttributePayload\n}\n", "const registeredEvents = {}\nlet eventListener\n\nfunction registerEventListener (fn) {\n eventListener = fn\n}\n\nfunction registerEvent (eventName, tagNames) {\n registeredEvents[eventName] = tagNames\n document.addEventListener(eventName, eventListener, true)\n}\n\nfunction isRegisteredEvent (eventName, tagName) {\n tagName = tagName.toLowerCase()\n return (\n registeredEvents[eventName].includes(tagName) ||\n (!Object.values(registeredEvents)\n .flat()\n .includes(tagName) &&\n registeredEvents[eventName].includes('*'))\n )\n}\n\nfunction logRegisteredEvents () {\n console.log(registeredEvents)\n}\n\nexport {\n registerEventListener,\n registerEvent,\n registeredEvents,\n isRegisteredEvent,\n logRegisteredEvents\n}\n", "import './frame_sources'\nimport Security from './security'\nimport LifecycleEvents from './lifecycle_events'\nimport {\n findClosestReflex,\n findClosestFrame,\n findFrameId,\n findFrame,\n findFrameSrc,\n buildAttributePayload\n} from './elements'\nimport {\n registerEventListener,\n registerEvent,\n registeredEvents,\n isRegisteredEvent,\n logRegisteredEvents\n} from './event_registry'\n\n// fires before making a turbo HTTP request\naddEventListener('turbo:before-fetch-request', event => {\n const frame = event.target\n const { turboReflexActive } = frame.dataset\n if (!turboReflexActive) return\n const { fetchOptions } = event.detail\n fetchOptions.headers['Turbo-Reflex'] = Security.token\n})\n\nfunction buildURL (urlString) {\n const a = document.createElement('a')\n a.href = urlString\n return new URL(a)\n}\n\nfunction invokeFormReflex (form, payload = {}) {\n payload.token = Security.token\n const input = document.createElement('input')\n input.type = 'hidden'\n input.name = 'turbo_reflex'\n input.value = JSON.stringify(payload)\n form.appendChild(input)\n}\n\nfunction invokeReflex (event) {\n let element, frameId, frame, frameSrc\n try {\n element = findClosestReflex(event.target)\n if (!element) return\n\n if (!isRegisteredEvent(event.type, element.tagName)) return\n\n LifecycleEvents.dispatch(LifecycleEvents.beforeStart, element, { element })\n\n frameId = findFrameId(element)\n if (!frameId) return\n\n frame = findFrame(frameId)\n if (!frame) return\n\n frameSrc = findFrameSrc(frame)\n if (!frameSrc) return\n\n const payload = {\n frameId: frameId,\n element: buildAttributePayload(element)\n }\n\n LifecycleEvents.dispatch(LifecycleEvents.start, element, {\n element,\n frameId,\n frame,\n frameSrc,\n payload\n })\n frame.dataset.turboReflexActive = true\n frame.dataset.turboReflexElementId = element.id\n\n if (element.tagName.toLowerCase() === 'form')\n return invokeFormReflex(element, payload)\n\n event.preventDefault()\n const frameURL = buildURL(frameSrc)\n frameURL.searchParams.set('turbo_reflex', JSON.stringify(payload))\n frame.src = frameURL.toString()\n } catch (error) {\n console.error(\n `TurboReflex encountered an unexpected error!`,\n { element, frameId, frame, frameSrc, target: event.target },\n error\n )\n LifecycleEvents.dispatch(LifecycleEvents.error, element || document, {\n element,\n frameId,\n frame,\n frameSrc,\n error\n })\n }\n}\n\n// wire things up and setup default events\nregisterEventListener(invokeReflex)\nregisterEvent('change', ['input', 'select', 'textarea'])\nregisterEvent('submit', ['form'])\nregisterEvent('click', ['*'])\n\nexport default {\n registerEvent,\n logRegisteredEvents,\n logLifecycleEventNames: LifecycleEvents.logEventNames\n}\n"],
|
5
|
+
"mappings": "AAAA,IAAMA,EAAS,CACb,YAAa,4BACb,MAAO,qBACP,OAAQ,sBACR,MAAO,qBACP,eAAgB,gCAChB,aAAc,6BACd,gBAAiB,gCACnB,EAEA,SAASC,EAAUC,EAAMC,EAAS,SAAUC,EAAS,CAAC,EAAG,CACvD,IAAMC,EAAQ,IAAI,YAAYH,EAAM,CAClC,OAAAE,EACA,WAAY,GACZ,QAAS,EACX,CAAC,EACDD,EAAO,cAAcE,CAAK,CAC5B,CAEA,SAASC,GAAiB,CACxB,OAAO,OAAON,CAAM,EAAE,QAAQE,GAAQ,QAAQ,IAAIA,CAAI,CAAC,CACzD,CAEA,IAAOK,EAAQ,CAAE,GAAGP,EAAQ,SAAAC,EAAU,cAAAK,CAAc,ECtBpD,IAAME,EAAe,CAAC,EAGtB,iBAAiB,8BAA+BC,GAAS,CACvD,IAAMC,EAAQD,EAAM,OACpBD,EAAaE,EAAM,IAAMA,EAAM,IAE/B,GAAM,CAAE,kBAAAC,EAAmB,qBAAAC,CAAqB,EAAIF,EAAM,QAC1D,GAAI,CAACC,EAAmB,OAExB,IAAME,EAAU,SAAS,eAAeD,CAAoB,EAC5D,OAAOF,EAAM,QAAQ,kBACrB,OAAOA,EAAM,QAAQ,qBAErBI,EAAgB,SAASA,EAAgB,OAAQD,GAAW,SAAU,CACpE,MAAAH,EACA,QAASG,GAAW,gCACtB,CAAC,CACH,CAAC,EAGD,iBAAiB,mBAAoBJ,GAAS,CAC5C,IAAMC,EAAQD,EAAM,OACpBC,EAAM,QAAQ,eACZF,EAAaE,EAAM,KAAOA,EAAM,KAAOA,EAAM,QAAQ,eACvD,OAAOF,EAAaE,EAAM,GAC5B,CAAC,EC3BD,IAAMK,EAAW,CACf,IAAI,OAAS,CACX,OAAO,SAAS,eAAe,oBAAoB,EAAE,aAAa,SAAS,CAC7E,CACF,EAEOC,EAAQD,ECJf,SAASE,EAAmBC,EAAS,CACnC,OAAOA,EAAQ,QAAQ,qBAAqB,CAC9C,CAEA,SAASC,EAAkBD,EAAS,CAClC,OAAOA,EAAQ,QAAQ,aAAa,CACtC,CAEA,SAASE,EAAaF,EAAS,CAC7B,IAAIG,EAAKH,EAAQ,QAAQ,WACzB,GAAI,CAACG,EAAI,CACP,IAAMC,EAAQH,EAAiBD,CAAO,EAClCI,IAAOD,EAAKC,EAAM,GACxB,CACA,OAAKD,IACH,QAAQ,MACN,+CACA,iGACAH,CACF,EACAK,EAAgB,SAASA,EAAgB,eAAgBL,EAAS,CAChE,QAAAA,CACF,CAAC,GAEIG,CACT,CAEA,SAASG,EAAWH,EAAI,CACtB,IAAMC,EAAQ,SAAS,eAAeD,CAAE,EACxC,OAAKC,IACH,QAAQ,MAAM,cAAcD,oBAAqB,EACjDE,EAAgB,SAASA,EAAgB,aAAc,SAAU,CAAE,GAAAF,CAAG,CAAC,GAElEC,CACT,CAEA,SAASG,EAAcH,EAAO,CAC5B,IAAMI,EAAWJ,EAAM,QAAQ,gBAAkBA,EAAM,IACvD,OAAKI,IACH,QAAQ,MACN,sCAAsCJ,EAAM,mBAC5C,kFACA,0FACAA,CACF,EACAC,EAAgB,SAASA,EAAgB,gBAAiBD,EAAO,CAAE,MAAAA,CAAM,CAAC,GAErEI,CACT,CAEA,SAASC,EAA6BT,EAASU,EAAU,CAAC,EAAG,CAC3D,GAAIV,EAAQ,QAAQ,YAAY,IAAM,SACpC,OAAQU,EAAQ,MAAQV,EAAQ,MAElC,GAAI,CAACA,EAAQ,SACX,OAAQU,EAAQ,MAAQV,EAAQ,QAAQA,EAAQ,eAAe,MAEjEU,EAAQ,OAAS,MAAM,KAAKV,EAAQ,OAAO,EAAE,OAAO,CAACW,EAAMC,KACrDA,EAAO,UAAUD,EAAK,KAAKC,EAAO,KAAK,EACpCD,GACN,CAAC,CAAC,CACP,CAEA,SAASE,EAAuBb,EAAS,CACvC,IAAMU,EAAU,MAAM,KAAKV,EAAQ,UAAU,EAAE,OAAO,CAACW,EAAMG,KAC3DH,EAAKG,EAAK,MAAQA,EAAK,MAChBH,GACN,CAAC,CAAC,EAEL,OAAAD,EAAQ,IAAMV,EAAQ,QACtBU,EAAQ,QAAUV,EAAQ,QAC1BU,EAAQ,SAAWV,EAAQ,SAC3BS,EAA4BT,EAASU,CAAO,EAErCA,CACT,CC7EA,IAAMK,EAAmB,CAAC,EACtBC,EAEJ,SAASC,EAAuBC,EAAI,CAClCF,EAAgBE,CAClB,CAEA,SAASC,EAAeC,EAAWC,EAAU,CAC3CN,EAAiBK,GAAaC,EAC9B,SAAS,iBAAiBD,EAAWJ,EAAe,EAAI,CAC1D,CAEA,SAASM,EAAmBF,EAAWG,EAAS,CAC9C,OAAAA,EAAUA,EAAQ,YAAY,EAE5BR,EAAiBK,GAAW,SAASG,CAAO,GAC3C,CAAC,OAAO,OAAOR,CAAgB,EAC7B,KAAK,EACL,SAASQ,CAAO,GACjBR,EAAiBK,GAAW,SAAS,GAAG,CAE9C,CAEA,SAASI,GAAuB,CAC9B,QAAQ,IAAIT,CAAgB,CAC9B,CCLA,iBAAiB,6BAA8BU,GAAS,CACtD,IAAMC,EAAQD,EAAM,OACd,CAAE,kBAAAE,CAAkB,EAAID,EAAM,QACpC,GAAI,CAACC,EAAmB,OACxB,GAAM,CAAE,aAAAC,CAAa,EAAIH,EAAM,OAC/BG,EAAa,QAAQ,gBAAkBC,EAAS,KAClD,CAAC,EAED,SAASC,EAAUC,EAAW,CAC5B,IAAMC,EAAI,SAAS,cAAc,GAAG,EACpC,OAAAA,EAAE,KAAOD,EACF,IAAI,IAAIC,CAAC,CAClB,CAEA,SAASC,EAAkBC,EAAMC,EAAU,CAAC,EAAG,CAC7CA,EAAQ,MAAQN,EAAS,MACzB,IAAMO,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,KAAO,SACbA,EAAM,KAAO,eACbA,EAAM,MAAQ,KAAK,UAAUD,CAAO,EACpCD,EAAK,YAAYE,CAAK,CACxB,CAEA,SAASC,EAAcZ,EAAO,CAC5B,IAAIa,EAASC,EAASb,EAAOc,EAC7B,GAAI,CAeF,GAdAF,EAAUG,EAAkBhB,EAAM,MAAM,EACpC,CAACa,GAED,CAACI,EAAkBjB,EAAM,KAAMa,EAAQ,OAAO,IAElDK,EAAgB,SAASA,EAAgB,YAAaL,EAAS,CAAE,QAAAA,CAAQ,CAAC,EAE1EC,EAAUK,EAAYN,CAAO,EACzB,CAACC,KAELb,EAAQmB,EAAUN,CAAO,EACrB,CAACb,KAELc,EAAWM,EAAapB,CAAK,EACzB,CAACc,GAAU,OAEf,IAAML,EAAU,CACd,QAASI,EACT,QAASQ,EAAsBT,CAAO,CACxC,EAYA,GAVAK,EAAgB,SAASA,EAAgB,MAAOL,EAAS,CACvD,QAAAA,EACA,QAAAC,EACA,MAAAb,EACA,SAAAc,EACA,QAAAL,CACF,CAAC,EACDT,EAAM,QAAQ,kBAAoB,GAClCA,EAAM,QAAQ,qBAAuBY,EAAQ,GAEzCA,EAAQ,QAAQ,YAAY,IAAM,OACpC,OAAOL,EAAiBK,EAASH,CAAO,EAE1CV,EAAM,eAAe,EACrB,IAAMuB,EAAWlB,EAASU,CAAQ,EAClCQ,EAAS,aAAa,IAAI,eAAgB,KAAK,UAAUb,CAAO,CAAC,EACjET,EAAM,IAAMsB,EAAS,SAAS,CAChC,OAASC,EAAP,CACA,QAAQ,MACN,+CACA,CAAE,QAAAX,EAAS,QAAAC,EAAS,MAAAb,EAAO,SAAAc,EAAU,OAAQf,EAAM,MAAO,EAC1DwB,CACF,EACAN,EAAgB,SAASA,EAAgB,MAAOL,GAAW,SAAU,CACnE,QAAAA,EACA,QAAAC,EACA,MAAAb,EACA,SAAAc,EACA,MAAAS,CACF,CAAC,CACH,CACF,CAGAC,EAAsBb,CAAY,EAClCc,EAAc,SAAU,CAAC,QAAS,SAAU,UAAU,CAAC,EACvDA,EAAc,SAAU,CAAC,MAAM,CAAC,EAChCA,EAAc,QAAS,CAAC,GAAG,CAAC,EAE5B,IAAOC,EAAQ,CACb,cAAAD,EACA,oBAAAE,EACA,uBAAwBV,EAAgB,aAC1C",
|
6
|
+
"names": ["events", "dispatch", "name", "target", "detail", "event", "logEventNames", "lifecycle_events_default", "frameSources", "event", "frame", "turboReflexActive", "turboReflexElementId", "element", "lifecycle_events_default", "Security", "security_default", "findClosestReflex", "element", "findClosestFrame", "findFrameId", "id", "frame", "lifecycle_events_default", "findFrame", "findFrameSrc", "frameSrc", "assignElementValueToPayload", "payload", "memo", "option", "buildAttributePayload", "attr", "registeredEvents", "eventListener", "registerEventListener", "fn", "registerEvent", "eventName", "tagNames", "isRegisteredEvent", "tagName", "logRegisteredEvents", "event", "frame", "turboReflexActive", "fetchOptions", "security_default", "buildURL", "urlString", "a", "invokeFormReflex", "form", "payload", "input", "invokeReflex", "element", "frameId", "frameSrc", "findClosestReflex", "isRegisteredEvent", "lifecycle_events_default", "findFrameId", "findFrame", "findFrameSrc", "buildAttributePayload", "frameURL", "error", "registerEventListener", "registerEvent", "turbo_reflex_default", "logRegisteredEvents"]
|
7
|
+
}
|
Binary file
|
@@ -8,6 +8,7 @@ module TurboReflex::Controller
|
|
8
8
|
after_action :append_turbo_reflex_turbo_streams, if: :turbo_reflex_performed?
|
9
9
|
after_action :assign_turbo_reflex_token
|
10
10
|
helper_method :turbo_reflex_meta_tag, :turbo_reflex_performed?, :turbo_reflex_requested?
|
11
|
+
# helper TurboReflex::TurboReflexHelper # only required if we isolate_namespace
|
11
12
|
end
|
12
13
|
|
13
14
|
def turbo_reflex_meta_tag
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TurboReflex::TurboReflexesController < TurboReflex::ApplicationController
|
4
|
+
def show
|
5
|
+
return head(:ok) unless turbo_reflex_instance&.turbo_streams.present?
|
6
|
+
render html: view_context.turbo_reflex_frame_tag do
|
7
|
+
turbo_reflex_instance.turbo_streams.map(&:to_s).join
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/app/javascript/elements.js
CHANGED
@@ -9,7 +9,7 @@ function findClosestFrame (element) {
|
|
9
9
|
}
|
10
10
|
|
11
11
|
function findFrameId (element) {
|
12
|
-
let id = element.dataset.
|
12
|
+
let id = element.dataset.turboFrame
|
13
13
|
if (!id) {
|
14
14
|
const frame = findClosestFrame(element)
|
15
15
|
if (frame) id = frame.id
|
@@ -17,7 +17,7 @@ function findFrameId (element) {
|
|
17
17
|
if (!id) {
|
18
18
|
console.error(
|
19
19
|
`The reflex element does not specify a frame!`,
|
20
|
-
`Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-
|
20
|
+
`Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-frame' attribute.`,
|
21
21
|
element
|
22
22
|
)
|
23
23
|
LifecycleEvents.dispatch(LifecycleEvents.missingFrameId, element, {
|
data/bin/standardize
CHANGED
@@ -3,3 +3,5 @@
|
|
3
3
|
bundle exec magic_frozen_string_literal
|
4
4
|
bundle exec standardrb --fix
|
5
5
|
yarn run prettier-standard "app/javascript/**/*.js"
|
6
|
+
yarn run rustywind --write test/dummy/app
|
7
|
+
yarn run rustywind --write --custom-regex "(:\s[\"'])(.+)[\"']" test/dummy/app/views/_tailwind.yml.erb
|
data/config/routes.rb
ADDED
data/docker-compose.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
version: "3.9"
|
2
|
+
|
3
|
+
x-default-app: &default_app
|
4
|
+
build: .
|
5
|
+
image: turbo_reflex
|
6
|
+
tty: true
|
7
|
+
stdin_open: true
|
8
|
+
working_dir: /opt/turbo_reflex/test/dummy
|
9
|
+
environment:
|
10
|
+
RAILS_ENV: development
|
11
|
+
volumes:
|
12
|
+
- bundle:/usr/local/bundle:delegated
|
13
|
+
- node_modules:/opt/turbo_reflex/node_modules
|
14
|
+
|
15
|
+
volumes:
|
16
|
+
bundle:
|
17
|
+
node_modules:
|
18
|
+
|
19
|
+
services:
|
20
|
+
# ----------------------------------------------------------------------------
|
21
|
+
# Shell - Intended for tinkering and running misc commands
|
22
|
+
# ----------------------------------------------------------------------------
|
23
|
+
shell:
|
24
|
+
<<: *default_app
|
25
|
+
container_name: turbo_reflex-shell
|
26
|
+
command: /bin/bash -c "tail -f /dev/null"
|
27
|
+
|
28
|
+
# ----------------------------------------------------------------------------
|
29
|
+
# Web - Runs the test/dummy Rails app
|
30
|
+
# ----------------------------------------------------------------------------
|
31
|
+
web:
|
32
|
+
<<: *default_app
|
33
|
+
container_name: turbo_reflex-web
|
34
|
+
ports:
|
35
|
+
- 3000:3000
|
36
|
+
command: >
|
37
|
+
/bin/bash -c "git pull --no-rebase github main &&
|
38
|
+
cd /opt/turbo_reflex &&
|
39
|
+
bundle &&
|
40
|
+
yarn &&
|
41
|
+
cd /opt/turbo_reflex/test/dummy &&
|
42
|
+
rm -f tmp/pids/server.pid &&
|
43
|
+
bin/rails db:create db:migrate &&
|
44
|
+
bin/rails assets:clobber &&
|
45
|
+
bin/rails assets:precompile &&
|
46
|
+
bin/rails s --binding=0.0.0.0 --port=3000"
|
data/fly.toml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# fly.toml file generated for turbo-reflex on 2022-09-19T05:16:01-06:00
|
2
|
+
|
3
|
+
app = "turbo-reflex"
|
4
|
+
kill_signal = "SIGINT"
|
5
|
+
kill_timeout = 5
|
6
|
+
processes = []
|
7
|
+
|
8
|
+
[env]
|
9
|
+
|
10
|
+
[experimental]
|
11
|
+
allowed_public_ports = []
|
12
|
+
auto_rollback = true
|
13
|
+
|
14
|
+
[[services]]
|
15
|
+
http_checks = []
|
16
|
+
internal_port = 3000
|
17
|
+
processes = ["app"]
|
18
|
+
protocol = "tcp"
|
19
|
+
script_checks = []
|
20
|
+
[services.concurrency]
|
21
|
+
hard_limit = 25
|
22
|
+
soft_limit = 20
|
23
|
+
type = "connections"
|
24
|
+
|
25
|
+
[[services.ports]]
|
26
|
+
force_https = true
|
27
|
+
handlers = ["http"]
|
28
|
+
port = 80
|
29
|
+
|
30
|
+
[[services.ports]]
|
31
|
+
handlers = ["tls", "http"]
|
32
|
+
port = 443
|
33
|
+
|
34
|
+
[[services.tcp_checks]]
|
35
|
+
grace_period = "1s"
|
36
|
+
interval = "15s"
|
37
|
+
restart_limit = 0
|
38
|
+
timeout = "2s"
|
data/lib/turbo_reflex/base.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
class TurboReflex::Base
|
4
4
|
attr_reader :controller, :turbo_streams
|
5
5
|
|
6
|
+
delegate :render, to: :renderer
|
7
|
+
|
6
8
|
def initialize(controller)
|
7
9
|
@controller = controller
|
8
10
|
@turbo_streams = Set.new
|
@@ -29,4 +31,8 @@ class TurboReflex::Base
|
|
29
31
|
def turbo_stream
|
30
32
|
@turbo_stream ||= Turbo::Streams::TagBuilder.new(controller.view_context)
|
31
33
|
end
|
34
|
+
|
35
|
+
def renderer
|
36
|
+
ActionController::Renderer.for controller.class, controller.request.env
|
37
|
+
end
|
32
38
|
end
|
data/lib/turbo_reflex/engine.rb
CHANGED
@@ -2,8 +2,23 @@
|
|
2
2
|
|
3
3
|
require "turbo-rails"
|
4
4
|
require_relative "version"
|
5
|
+
require_relative "errors"
|
5
6
|
require_relative "sanitizer"
|
6
7
|
require_relative "base"
|
7
8
|
|
8
9
|
class TurboReflex::Engine < ::Rails::Engine
|
10
|
+
# isolate_namespace TurboReflex
|
11
|
+
|
12
|
+
config.turbo_reflex = ActiveSupport::OrderedOptions.new
|
13
|
+
initializer "turbo_reflex.configuration" do
|
14
|
+
config.to_prepare do |app|
|
15
|
+
::ApplicationController.send :include, TurboReflex::Controller
|
16
|
+
end
|
17
|
+
|
18
|
+
config.after_initialize do |app|
|
19
|
+
app.routes.draw do
|
20
|
+
mount TurboReflex::Engine => "/turbo_reflex"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
9
24
|
end
|
data/lib/turbo_reflex/version.rb
CHANGED
data/package.json
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
{
|
2
2
|
"name": "turbo_reflex",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.3",
|
4
4
|
"description": "Reflexes for Turbo Frames that help you build robust reactive applications",
|
5
|
-
"main": "app/
|
5
|
+
"main": "app/javascript/turbo_reflex.js",
|
6
6
|
"repository": "https://github.com/hopsoft/turbo_reflex",
|
7
7
|
"author": "Nate Hopkins (hopsoft) <natehop@gmail.com>",
|
8
8
|
"license": "MIT",
|
@@ -12,9 +12,11 @@
|
|
12
12
|
"devDependencies": {
|
13
13
|
"esbuild": "^0.15.7",
|
14
14
|
"eslint": "^8.19.0",
|
15
|
-
"
|
15
|
+
"flowbite": "^1.5.3",
|
16
|
+
"prettier-standard": "^16.4.1",
|
17
|
+
"rustywind": "^0.15.1"
|
16
18
|
},
|
17
19
|
"scripts": {
|
18
|
-
"build": "esbuild app/javascript/turbo_reflex.js --bundle --minify --sourcemap --format=esm --outfile=app/assets/builds/turbo_reflex.
|
20
|
+
"build": "esbuild app/javascript/turbo_reflex.js --bundle --minify --sourcemap --format=esm --outfile=app/assets/builds/turbo_reflex.js"
|
19
21
|
}
|
20
22
|
}
|