turbo_ready 0.0.3 → 0.0.6
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/Gemfile +0 -3
- data/Gemfile.lock +55 -52
- data/README.md +261 -96
- data/README.md.orig +292 -0
- data/Rakefile +13 -1
- data/app/assets/builds/turbo_ready.js +1 -1
- data/app/assets/builds/turbo_ready.js.map +3 -3
- data/app/assets/images/turbo-ready-logo-dark.webp +0 -0
- data/app/assets/images/turbo-ready-logo-light.webp +0 -0
- data/app/javascript/turbo_ready.js +1 -1
- data/app/jobs/turbo_ready/broadcast_invoke_job.rb +9 -0
- data/bin/loc +1 -1
- data/lib/turbo_ready/engine.rb +13 -0
- data/lib/turbo_ready/patches/broadcastable.rb +21 -0
- data/lib/turbo_ready/patches/broadcasts.rb +18 -0
- data/lib/turbo_ready/patches/tag_builder.rb +15 -0
- data/lib/turbo_ready/patches.rb +8 -0
- data/lib/turbo_ready/string_wrapper.rb +32 -0
- data/lib/turbo_ready/tag_helper.rb +42 -0
- data/lib/turbo_ready/version.rb +1 -1
- data/lib/turbo_ready.rb +1 -10
- data/package.json +2 -2
- data/turbo_ready.gemspec +28 -19
- data/yarn.lock +155 -150
- metadata +141 -7
- data/lib/turbo_ready/railtie.rb +0 -6
- data/lib/turbo_ready/string.rb +0 -35
- data/lib/turbo_ready/tag_builder.rb +0 -33
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
<p align="center">
|
2
|
-
<
|
2
|
+
<picture>
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://ik.imagekit.io/hopsoft/turbo-ready-logo-light_df4jcvbDL.webp?ik-sdk-version=javascript-1.4.3&updatedAt=1661615678275">
|
4
|
+
<img height="200" src="https://ik.imagekit.io/hopsoft/turbo-ready-logo-dark_VN4hA2ctc.webp?ik-sdk-version=javascript-1.4.3&updatedAt=1661615678278" />
|
5
|
+
</picture>
|
3
6
|
<h3 align="center">
|
4
7
|
Turbo Stream's Swiss Army Knife
|
5
8
|
</h3>
|
@@ -7,44 +10,76 @@
|
|
7
10
|
Welcome to TurboReady 👋
|
8
11
|
</h1>
|
9
12
|
<p align="center">
|
10
|
-
<a href="http://blog.codinghorror.com/the-best-code-is-no-code-at-all/"
|
11
|
-
<img alt="Lines of Code" src="https://img.shields.io/badge/
|
13
|
+
<a href="http://blog.codinghorror.com/the-best-code-is-no-code-at-all/">
|
14
|
+
<img alt="Lines of Code" src="https://img.shields.io/badge/loc-143-47d299.svg" />
|
12
15
|
</a>
|
13
|
-
<a href="https://
|
14
|
-
<img
|
16
|
+
<a href="https://codeclimate.com/github/hopsoft/turbo_ready/maintainability">
|
17
|
+
<img src="https://api.codeclimate.com/v1/badges/a69b6f73abc3ccd49261/maintainability" />
|
15
18
|
</a>
|
16
|
-
<a href="https://
|
17
|
-
<img alt="
|
19
|
+
<a href="https://rubygems.org/gems/turbo_ready">
|
20
|
+
<img alt="GEM" src="https://img.shields.io/gem/v/turbo_ready?color=168AFE&include_prereleases&logo=ruby&logoColor=FE1616">
|
21
|
+
</a>
|
22
|
+
<a href="https://rubygems.org/gems/turbo_ready">
|
23
|
+
<img alt="Gem" src="https://img.shields.io/gem/dt/turbo_ready?color=168AFE&logo=ruby&logoColor=FE1616">
|
24
|
+
</a>
|
25
|
+
<a href="https://github.com/testdouble/standard">
|
26
|
+
<img alt="Ruby Style" src="https://img.shields.io/badge/style-standard-168AFE?logo=ruby&logoColor=FE1616" />
|
27
|
+
</a>
|
28
|
+
<a href="https://www.npmjs.com/package/turbo_ready">
|
29
|
+
<img alt="NPM" src="https://img.shields.io/npm/v/turbo_ready?color=168AFE&logo=npm">
|
30
|
+
</a>
|
31
|
+
<a href="https://www.npmjs.com/package/turbo_ready">
|
32
|
+
<img alt="npm" src="https://img.shields.io/npm/dm/turbo_ready?color=168AFE&logo=npm">
|
33
|
+
</a>
|
34
|
+
<a href="https://bundlephobia.com/package/turbo_ready@">
|
35
|
+
<img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/turbo_ready?label=bundle%20size&logo=npm&color=47d299">
|
36
|
+
</a>
|
37
|
+
<a href="https://github.com/sheerun/prettier-standard">
|
38
|
+
<img alt="JavaScript Style" src="https://img.shields.io/badge/style-prettier--standard-168AFE?logo=javascript&logoColor=f4e137" />
|
39
|
+
</a>
|
40
|
+
<a href="https://github.com/hopsoft/turbo_ready/actions/workflows/tests.yml">
|
41
|
+
<img alt="Tests" src="https://github.com/hopsoft/turbo_ready/actions/workflows/tests.yml/badge.svg" />
|
42
|
+
</a>
|
43
|
+
<a href="https://twitter.com/hopsoft">
|
44
|
+
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/hopsoft?logo=twitter&style=social">
|
18
45
|
</a>
|
19
46
|
</p>
|
20
47
|
</p>
|
21
48
|
|
22
|
-
TurboReady extends [Turbo Streams](https://turbo.hotwired.dev/reference/streams) to give you full control of the
|
23
|
-
browser's [Document Object Model (DOM).](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)
|
24
|
-
|
25
|
-
**Thats right!**
|
26
|
-
You can `invoke` any DOM method on any DOM object *(including 3rd party libs)* using Turbo Streams.
|
49
|
+
**TurboReady extends [Turbo Streams](https://turbo.hotwired.dev/reference/streams) to give you full control of the
|
50
|
+
browser's [Document Object Model (DOM).](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)**
|
27
51
|
|
28
52
|
```ruby
|
29
|
-
turbo_stream.invoke "console.log", "Hello World!"
|
53
|
+
turbo_stream.invoke "console.log", args: ["Hello World!"]
|
30
54
|
```
|
31
55
|
|
56
|
+
**Thats right!**
|
57
|
+
You can `invoke` any DOM method on the client with Turbo Streams.
|
58
|
+
|
32
59
|
<!-- Tocer[start]: Auto-generated, don't remove. -->
|
33
60
|
|
34
61
|
## Table of Contents
|
35
62
|
|
36
63
|
- [Why TurboReady?](#why-turboready)
|
37
|
-
- [Discord Community](#discord-community)
|
38
64
|
- [Sponsors](#sponsors)
|
39
65
|
- [Dependencies](#dependencies)
|
40
66
|
- [Installation](#installation)
|
41
67
|
- [Setup](#setup)
|
42
68
|
- [Usage](#usage)
|
43
|
-
|
44
|
-
|
69
|
+
- [Method Chaining](#method-chaining)
|
70
|
+
- [Dispatching Events](#dispatching-events)
|
71
|
+
- [Syntax Styles](#syntax-styles)
|
45
72
|
- [Extending Behavior](#extending-behavior)
|
46
|
-
|
73
|
+
- [Implementation Details](#implementation-details)
|
74
|
+
- [Broadcasting](#broadcasting)
|
75
|
+
- [Background Job Queues](#background-job-queues)
|
76
|
+
- [FAQ](#faq)
|
47
77
|
- [A Word of Caution](#a-word-of-caution)
|
78
|
+
- [Community](#community)
|
79
|
+
- [Discord](#discord)
|
80
|
+
- [Discussions](#discussions)
|
81
|
+
- [Twitter](#twitter)
|
82
|
+
- [TODOs](#todos)
|
48
83
|
- [Releasing](#releasing)
|
49
84
|
- [License](#license)
|
50
85
|
|
@@ -52,21 +87,17 @@ turbo_stream.invoke "console.log", "Hello World!"
|
|
52
87
|
|
53
88
|
## Why TurboReady?
|
54
89
|
|
55
|
-
Turbo Streams [intentionally restricts](https://turbo.hotwired.dev/handbook/streams#but-what-about-running-javascript)
|
90
|
+
Turbo Streams [intentionally restricts](https://turbo.hotwired.dev/handbook/streams#but-what-about-running-javascript%3F)
|
56
91
|
official actions to CRUD related activity.
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
If you discover that CRUD isn't enough, TurboReady covers pretty much everything else.
|
61
|
-
|
62
|
-
## Community
|
92
|
+
These [official actions](https://turbo.hotwired.dev/reference/streams#the-seven-actions) work well for a considerable number of use cases.
|
93
|
+
*Try pushing Turbo Streams as far as possible before reaching for TurboReady.*
|
63
94
|
|
64
|
-
|
65
|
-
as well as active discussions around Rails, Hotwire, Stimulus, Turbo (Drive, Frames, Streams), TurboReady, CableReady, StimulusReflex, ViewComponent, Phlex, and more.
|
95
|
+
If you find that CRUD isn't enough, TurboReady is there to handle pretty much everything else.
|
66
96
|
|
67
|
-
|
97
|
+
> ⚠️ TurboReady is intended for Rails apps that use Hotwire but not [CableReady](https://github.com/stimulusreflex/cable_ready).
|
98
|
+
This is because CableReady already provides a rich set of powerful [DOM operations](https://cableready.stimulusreflex.com/reference/operations).
|
68
99
|
|
69
|
-
|
100
|
+
> 📘 **NOTE:** Efforts are underway to bring [CableReady's DOM operations to Turbo Streams](https://github.com/marcoroth/turbo_power).
|
70
101
|
|
71
102
|
## Sponsors
|
72
103
|
|
@@ -87,79 +118,84 @@ Stop by #newcomers and introduce yourselves!
|
|
87
118
|
|
88
119
|
## Installation
|
89
120
|
|
121
|
+
Be sure to install the same version for each libary.
|
122
|
+
|
90
123
|
```sh
|
91
124
|
bundle add "turbo_ready --version VERSION"
|
92
125
|
yarn add "turbo_ready@VERSION --exact"
|
93
126
|
```
|
94
127
|
|
95
|
-
**IMPORTANT:** Be sure to use the same version for each libary.
|
96
|
-
|
97
128
|
## Setup
|
98
129
|
|
99
|
-
|
130
|
+
Import and intialize TurboReady in your application.
|
100
131
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
2. Import and intialize TurboReady in your JavaScript application.
|
132
|
+
```diff
|
133
|
+
# Gemfile
|
134
|
+
+gem "turbo_ready", "~> 0.0.6"
|
135
|
+
```
|
106
136
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
137
|
+
```diff
|
138
|
+
# package.json
|
139
|
+
"dependencies": {
|
140
|
+
+ "@hotwired/turbo-rails": ">=7.2.0-beta.2",
|
141
|
+
+ "turbo_ready": "^0.0.6"
|
142
|
+
```
|
111
143
|
|
112
|
-
|
113
|
-
|
144
|
+
```diff
|
145
|
+
# app/javascript/application.js
|
146
|
+
import '@hotwired/turbo-rails'
|
147
|
+
+import TurboReady from 'turbo_ready'
|
148
|
+
|
149
|
+
+TurboReady.initialize(Turbo.StreamActions) // Adds TurboReady stream actions to Turbo
|
150
|
+
```
|
114
151
|
|
115
152
|
## Usage
|
116
153
|
|
117
|
-
Manipulate the DOM from anywhere you use
|
118
|
-
|
119
|
-
[
|
120
|
-
and [**C**ontrollers](https://github.com/hotwired/turbo-rails/blob/main/app/models/concerns/turbo/broadcastable.rb).
|
154
|
+
Manipulate the DOM from anywhere you use official [Turbo Streams](https://turbo.hotwired.dev/handbook/streams#integration-with-server-side-frameworks).
|
155
|
+
The possibilities are endless.
|
156
|
+
[Learn more about the DOM at MDN.](https://developer.mozilla.org/en-US/docs/Web/API.)
|
121
157
|
|
122
|
-
|
158
|
+
```ruby
|
159
|
+
turbo_stream.invoke "console.log", args: ["Hello World!"]
|
160
|
+
```
|
161
|
+
|
162
|
+
### Method Chaining
|
163
|
+
|
164
|
+
You can use [dot notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#dot_notation)
|
165
|
+
or [selectors](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) and even combine them!
|
123
166
|
|
124
167
|
```ruby
|
125
168
|
turbo_stream
|
126
|
-
.invoke("document.body.insertAdjacentHTML", "afterbegin", "<h1>Hello World!</h1>") # dot notation
|
127
|
-
.invoke("setAttribute", "data-turbo-ready", true, selector: ".button") # selector
|
128
|
-
.invoke("classList.add", "turbo-ready", selector: "a") # dot notation + selector
|
129
|
-
.flush # flush
|
169
|
+
.invoke("document.body.insertAdjacentHTML", args: ["afterbegin", "<h1>Hello World!</h1>"]) # dot notation
|
170
|
+
.invoke("setAttribute", args: ["data-turbo-ready", true], selector: ".button") # selector
|
171
|
+
.invoke("classList.add", args: ["turbo-ready"], selector: "a") # dot notation + selector
|
172
|
+
.flush # call flush when chaining invocations
|
130
173
|
```
|
131
174
|
|
132
|
-
|
133
|
-
or [selectors](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)... and can even combine them!** 🤯
|
175
|
+
### Dispatching Events
|
134
176
|
|
135
|
-
|
177
|
+
It's possible to fire events on `window`, `document`, and element(s).
|
136
178
|
|
137
179
|
```ruby
|
138
180
|
turbo_stream
|
139
|
-
.invoke("dispatchEvent", "turbo-ready:demo")
|
140
|
-
.invoke("dispatchEvent", "turbo-ready:demo"
|
141
|
-
.invoke("dispatchEvent",
|
181
|
+
.invoke("dispatchEvent", args: ["turbo-ready:demo"]) # fires on window
|
182
|
+
.invoke("document.dispatchEvent", args: ["turbo-ready:demo"]) # fires on document
|
183
|
+
.invoke("dispatchEvent", args: ["turbo-ready:demo"], selector: "#my-element") # fires on matching element(s)
|
184
|
+
.invoke("dispatchEvent", args: ["turbo-ready:demo", {bubbles: true, detail: {...}}]) # set event options
|
142
185
|
.flush
|
143
186
|
```
|
144
187
|
|
145
|
-
|
146
|
-
|
147
|
-
**What else can I do?**
|
148
|
-
MDN has your back... [learn about the DOM and web APIs here.](https://developer.mozilla.org/en-US/docs/Web/API.)
|
188
|
+
### Syntax Styles
|
149
189
|
|
150
|
-
|
151
|
-
|
152
|
-
You can use symbols and [snake case](https://en.wikipedia.org/wiki/Snake_case) when invoking DOM functionality.
|
153
|
-
It'll implicitly convert to [camel case](https://en.wikipedia.org/wiki/Camel_case). 💎
|
190
|
+
You can use [`snake_case`](https://en.wikipedia.org/wiki/Snake_case) when invoking DOM functionality.
|
191
|
+
It will implicitly convert to [`camelCase`](https://en.wikipedia.org/wiki/Camel_case).
|
154
192
|
|
155
193
|
```ruby
|
156
|
-
turbo_stream
|
157
|
-
|
158
|
-
.invoke(:dispatch_event, {detail: {converts_to_camel_case: true}})
|
159
|
-
.flush
|
194
|
+
turbo_stream.invoke :dispatch_event,
|
195
|
+
args: ["turbo-ready:demo", {detail: {converts_to_camel_case: true}}]
|
160
196
|
```
|
161
197
|
|
162
|
-
Need to opt
|
198
|
+
Need to opt-out? No problem... just disable it.
|
163
199
|
|
164
200
|
```ruby
|
165
201
|
turbo_stream.invoke :contrived_demo, camelize: false
|
@@ -167,10 +203,10 @@ turbo_stream.invoke :contrived_demo, camelize: false
|
|
167
203
|
|
168
204
|
### Extending Behavior
|
169
205
|
|
170
|
-
|
206
|
+
If you add new capabilities to the browser, you can control them from the server.
|
171
207
|
|
172
208
|
```js
|
173
|
-
// JavaScript
|
209
|
+
// JavaScript on the client
|
174
210
|
import morphdom from 'morphdom'
|
175
211
|
|
176
212
|
window.MyNamespace = {
|
@@ -181,51 +217,180 @@ window.MyNamespace = {
|
|
181
217
|
```
|
182
218
|
|
183
219
|
```ruby
|
184
|
-
# Ruby
|
185
|
-
turbo_stream
|
186
|
-
|
220
|
+
# Ruby on the server
|
221
|
+
turbo_stream.invoke "MyNamespace.morph",
|
222
|
+
args: [
|
223
|
+
"#demo",
|
224
|
+
"<div id='demo'><p>You've changed...</p></div>",
|
225
|
+
{children_only: true}
|
226
|
+
]
|
187
227
|
```
|
188
228
|
|
189
|
-
|
229
|
+
### Implementation Details
|
190
230
|
|
191
|
-
There's
|
192
|
-
[tag builder](https://github.com/hopsoft/turbo_ready/blob/main/lib/turbo_ready/tag_builder.rb).
|
231
|
+
There's basically one method to learn... `invoke`
|
193
232
|
|
194
233
|
```ruby
|
195
234
|
# Ruby
|
196
235
|
turbo_stream
|
197
|
-
.invoke(method,
|
198
|
-
# |
|
199
|
-
# |
|
200
|
-
# |
|
201
|
-
# |
|
202
|
-
# |
|
203
|
-
# |
|
204
|
-
# |
|
205
|
-
# |
|
206
|
-
# |
|
236
|
+
.invoke(method, args: [], selector: nil, camelize: true, id: nil)
|
237
|
+
# | | | | |
|
238
|
+
# | | | | |- Identifies this invocation (optional)
|
239
|
+
# | | | |
|
240
|
+
# | | | |- Should we camelize the JavaScript stuff? (optional)
|
241
|
+
# | | | (allows us to write snake_case in Ruby)
|
242
|
+
# | | |
|
243
|
+
# | | |- A CSS selector for the element(s) to target (optional)
|
244
|
+
# | |
|
245
|
+
# | |- The arguments to pass to the JavaScript method (optional)
|
207
246
|
# |
|
208
247
|
# |- The JavaScript method to invoke (can use dot notation)
|
209
248
|
```
|
210
249
|
|
211
|
-
**NOTE:** The
|
250
|
+
> 📘 **NOTE:** The method will be invoked on all matching elements if a `selector` is present.
|
251
|
+
|
252
|
+
The following Ruby code,
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
turbo_stream.invoke "console.log", args: ["Hello World!"], id: "1"
|
256
|
+
```
|
257
|
+
|
258
|
+
emits this HTML markup.
|
259
|
+
|
260
|
+
```html
|
261
|
+
<turbo-stream action="invoke" target="DOM">
|
262
|
+
<template>{"id":"1","receiver":"console","method":"log","args":["Hello World!"]}</template>
|
263
|
+
</turbo-stream>
|
264
|
+
```
|
265
|
+
|
266
|
+
When this element enters the DOM,
|
267
|
+
Turbo Streams automatically executes `invoke` on the client with the template's JSON payload and then removes the element from the DOM.
|
268
|
+
|
269
|
+
### Broadcasting
|
270
|
+
|
271
|
+
You can also broadcast DOM invocations to subscribed users.
|
272
|
+
|
273
|
+
1. First, setup the stream subscription.
|
274
|
+
|
275
|
+
```erb
|
276
|
+
<!-- app/views/posts/show.html.erb -->
|
277
|
+
<%= turbo_stream_from @post %>
|
278
|
+
<!-- |
|
279
|
+
|- *streamables - model(s), string(s), etc...
|
280
|
+
-->
|
281
|
+
```
|
282
|
+
|
283
|
+
2. Then, broadcast to the subscription.
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
# app/models/post.rb
|
287
|
+
class Post < ApplicationRecord
|
288
|
+
after_save do
|
289
|
+
# emit a message in the browser conosle for anyone subscribed to this post
|
290
|
+
broadcast_invoke "console.log", args: ["Post was saved! #{to_gid.to_s}"]
|
291
|
+
|
292
|
+
# broadcast with a background job
|
293
|
+
broadcast_invoke_later "console.log", args: ["Post was saved! #{to_gid.to_s}"]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
# app/controllers/posts_controller.rb
|
300
|
+
class PostsController < ApplicationController
|
301
|
+
def create
|
302
|
+
@post = Post.find params[:id]
|
303
|
+
|
304
|
+
if @post.update post_params
|
305
|
+
# emit a message in the browser conosle for anyone subscribed to this post
|
306
|
+
@post.broadcast_invoke "console.log", args: ["Post was saved! #{to_gid.to_s}"]
|
307
|
+
|
308
|
+
# broadcast with a background job
|
309
|
+
@post.broadcast_invoke_later "console.log", args: ["Post was saved! #{to_gid.to_s}"]
|
310
|
+
|
311
|
+
# you can also broadcast directly from the channel
|
312
|
+
Turbo::StreamsChannel.broadcast_invoke_to @post, "console.log",
|
313
|
+
args: ["Post was saved! #{@post.to_gid.to_s}"]
|
314
|
+
|
315
|
+
# broadcast with a background job
|
316
|
+
Turbo::StreamsChannel.broadcast_invoke_later_to @post, "console.log",
|
317
|
+
args: ["Post was saved! #{@post.to_gid.to_s}"]
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
```
|
322
|
+
|
323
|
+
> 📘 **NOTE:** [Method Chaining](#method-chaining) is not currently supported when broadcasting.
|
324
|
+
|
325
|
+
#### Background Job Queues
|
326
|
+
|
327
|
+
You may want to change the queue name for Turbo Stream background jobs in order to isolate, prioritize, and scale the workers independently.
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
# config/initializers/turbo_streams.rb
|
331
|
+
Turbo::Streams::BroadcastJob.queue_name = :turbo_streams
|
332
|
+
TurboReady::BroadcastInvokeJob.queue_name = :turbo_streams
|
333
|
+
```
|
334
|
+
|
335
|
+
## FAQ
|
336
|
+
|
337
|
+
- Isn't this just RJS?
|
338
|
+
|
339
|
+
> No. But, perhaps it could be considered RJS's "modern" spirtual successor. 🤷♂️
|
340
|
+
> Though it embraces JavaScript instead of trying to avoid it.
|
341
|
+
|
342
|
+
- Does it use `eval`?
|
343
|
+
|
344
|
+
> **No.** TurboReady can only invoke existing functions on the client.
|
345
|
+
> It's not a carte blanche invitation to emit free-form JavaScript to be evaluated on the client.
|
212
346
|
|
213
347
|
## A Word of Caution
|
214
348
|
|
215
|
-
|
216
|
-
**⚠️ Don't abuse this superpower!**
|
349
|
+
**Don't abuse this superpower!**
|
217
350
|
|
218
351
|
> With great power comes great responsibility. *-Uncle Ben*
|
219
352
|
|
353
|
+
Manually orchestrating DOM activity is tedious.
|
354
|
+
*Don't overdo it... or you may find that you've created spaghetti reminiscent of the jQuery days.*
|
355
|
+
|
220
356
|
This library is an extremely sharp tool. 🔪
|
221
|
-
Consider it a low-level building block that can be used to craft additional libraries
|
222
|
-
great [DX](https://en.wikipedia.org/wiki/User_experience#Developer_experience)
|
357
|
+
Consider it a low-level building block that can be used to craft additional libraries
|
223
358
|
like [CableReady](https://github.com/stimulusreflex/cable_ready)
|
224
359
|
and [StimulusReflex](https://github.com/stimulusreflex/stimulus_reflex).
|
225
360
|
|
226
|
-
|
227
|
-
|
228
|
-
|
361
|
+
## Community
|
362
|
+
|
363
|
+
### Discord
|
364
|
+
|
365
|
+
Please join nearly 2000 of us on [Discord](https://discord.gg/stimulus-reflex) for support getting started,
|
366
|
+
as well as active discussions around Rails, Hotwire, Stimulus, Turbo (Drive, Frames, Streams), TurboReady, CableReady, StimulusReflex, ViewComponent, Phlex, and more.
|
367
|
+
|
368
|
+
<a href="https://discord.gg/stimulus-reflex" target="_blank">
|
369
|
+
<img alt="Discord" src="https://img.shields.io/discord/629472241427415060?color=168AFE&logo=discord&logoColor=FFF">
|
370
|
+
</a>
|
371
|
+
|
372
|
+
Be sure to introduce yourselves in the #newcomers channel!
|
373
|
+
|
374
|
+
### Discussions
|
375
|
+
|
376
|
+
Feel free to add to the conversation here on [GitHub Discussions](https://github.com/hopsoft/turbo_ready/discussions).
|
377
|
+
|
378
|
+
<a href="https://github.com/hopsoft/turbo_ready/discussions" target="_blank">
|
379
|
+
<img alt="GitHub Discussions" src="https://img.shields.io/github/discussions/hopsoft/turbo_ready?color=168AFE&logo=github">
|
380
|
+
</a>
|
381
|
+
|
382
|
+
### Twitter
|
383
|
+
|
384
|
+
Connect with the core team on Twitter.
|
385
|
+
|
386
|
+
<a href="https://twitter.com/hopsoft" target="_blank">
|
387
|
+
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/hopsoft?logo=twitter&style=social">
|
388
|
+
</a>
|
389
|
+
|
390
|
+
## TODOs
|
391
|
+
|
392
|
+
- [ ] Add system tests [(review turbo-rails for guidance)](https://github.com/hotwired/turbo-rails/blob/main/test/system/broadcasts_test.rb)
|
393
|
+
- [ ] Look into adding method chaining for broadcasts
|
229
394
|
|
230
395
|
## Releasing
|
231
396
|
|