svelte-on-rails 5.0.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +152 -66
- data/lib/generators/svelte_on_rails/install/install_generator.rb +4 -0
- data/lib/svelte-on-rails.rb +1 -0
- data/lib/svelte_on_rails/action_cable.rb +36 -0
- data/lib/svelte_on_rails/turbo_stream.rb +9 -5
- data/templates/config_base/config/svelte_on_rails.yml +5 -1
- data/templates/rails_vite_hello_world/app/channels/svelte_on_rails_channel.rb +9 -0
- data/templates/rails_vite_hello_world/app/controllers/svelte_on_rails_hello_world_controller.rb +31 -11
- data/templates/rails_vite_hello_world/app/frontend/initializers/actionCable.js +17 -0
- data/templates/rails_vite_hello_world/app/frontend/javascript/components/ReceiveFromChannel.svelte +53 -0
- data/templates/rails_vite_hello_world/app/views/svelte_on_rails_hello_world/turbo_streams_channel.html.erb +1 -1
- metadata +5 -2
- data/templates/rails_vite_hello_world/app/frontend/javascript/components/TurboStreamsChannel.svelte +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f7ba72715095d212a289e5fba57a8ddd78b358474e4219a5b3c47f3b7d66c88
|
4
|
+
data.tar.gz: e690deefa5507a42cf31176efc368c3ff2f304ce1ff057dc79f431e33b5c4232
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1b2150fa517ce388feaf13c9816b8d71cb339c9ac9670d7552096430a8cddff8688629ca96c58dbcde715e4f9e9b3953e6760ab6e67c37f3a0ad10797b8fcc9
|
7
|
+
data.tar.gz: 275691b15976c8dbcd551b3c07ec7495da686c7fa23192b5aca471527b4fe63c20fa8048851a3d9b0085756de52bc7ae1d1e4e5a663114a9fbed9608873ba68e
|
data/README.md
CHANGED
@@ -346,92 +346,196 @@ on the svelte-on-rails config file or pass the `expires_in` as argument to the v
|
|
346
346
|
|
347
347
|
Pass `debug: true` to the helper and you will see on the logs how your configuration works.
|
348
348
|
|
349
|
-
|
349
|
+
## ActionCable / TurboStream
|
350
350
|
|
351
|
-
There are
|
351
|
+
There are two ways that the server can talk to the client over Websocket:
|
352
352
|
|
353
|
-
|
353
|
+
- ActionCable transmits directly to the frontends javascript
|
354
|
+
- TurboStreams is a wrapper around ActionCable
|
355
|
+
- You always need a html part for communication
|
354
356
|
|
355
|
-
|
357
|
+
**Configs**
|
356
358
|
|
357
|
-
|
359
|
+
Check the regarding keys and their commends on the [config file](https://gitlab.com/sedl/svelte-on-rails/-/blob/main/templates/config_base/config/svelte_on_rails.yml?ref_type=heads).
|
360
|
+
From there, you just need:
|
361
|
+
|
362
|
+
```yaml
|
363
|
+
turbo_stream:
|
364
|
+
target_html_id: 'svelte-on-rails-stream-actions-box'
|
365
|
+
channel: 'public'
|
366
|
+
```
|
367
|
+
|
368
|
+
## ActionCable vs TurboStream
|
358
369
|
|
359
|
-
|
370
|
+
- **ActionCable**
|
371
|
+
- Cleaner setup no html needed
|
372
|
+
- Seams to initialize securer, especially for testings (not: production)
|
373
|
+
- **TurboStream**
|
374
|
+
- Secured Streams by html-tag `signed-stream-name` if you want to send confidential data
|
375
|
+
over streams or have different channels for each user privileges
|
376
|
+
- Has [Compatibility issue with UJS](https://github.com/hotwired/turbo-rails?tab=readme-ov-file#compatibility-with-rails-ujs)
|
360
377
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
378
|
+
## SvelteOnRails::ActionCable.send
|
379
|
+
|
380
|
+
ActionCable is the more basic library behind `TurboStream` and it is a second Option to call Javascript Actions from the server.
|
381
|
+
|
382
|
+
**Setup**
|
383
|
+
|
384
|
+
Add `app/channels/svelte_on_rails_channel.rb`
|
365
385
|
|
366
386
|
```ruby
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
387
|
+
class SvelteOnRailsChannel < ApplicationCable::Channel
|
388
|
+
def subscribed
|
389
|
+
stream_from "svelte_on_rails_channel"
|
390
|
+
end
|
391
|
+
|
392
|
+
def unsubscribed
|
393
|
+
# Any cleanup needed when channel is unsubscribed
|
394
|
+
end
|
395
|
+
end
|
396
|
+
```
|
397
|
+
|
398
|
+
run
|
399
|
+
|
400
|
+
```shell
|
401
|
+
npm i @rails/actioncable
|
402
|
+
```
|
403
|
+
|
404
|
+
Add to `application.js`
|
405
|
+
|
406
|
+
```javascript
|
407
|
+
import { createConsumer } from "@rails/actioncable"
|
408
|
+
import { SvelteOnRails, dispatchSvelteStreamEvent, actionCableDebugLog } from '@csedl/svelte-on-rails'
|
409
|
+
SvelteOnRails.debug = true
|
410
|
+
|
411
|
+
const consumer = createConsumer()
|
412
|
+
|
413
|
+
consumer.subscriptions.create("SvelteOnRailsChannel", {
|
414
|
+
connected() {
|
415
|
+
actionCableDebugLog("Connected to SvelteOnRailsChannel")
|
416
|
+
},
|
417
|
+
disconnected() {
|
418
|
+
actionCableDebugLog("Disconnected from SvelteOnRailsChannel")
|
419
|
+
},
|
420
|
+
received(data) {
|
421
|
+
actionCableDebugLog("Received:", data)
|
422
|
+
dispatchSvelteStreamEvent(data)
|
423
|
+
}
|
424
|
+
})
|
373
425
|
```
|
374
426
|
|
375
|
-
|
376
|
-
|
427
|
+
**What dispatchSvelteStreamEvent does**
|
428
|
+
|
429
|
+
- Without the attribute `component` given,
|
430
|
+
it searches for all elements with the class `svelte-component` and fires the event `channel-action`
|
431
|
+
- When `selector` is given, it searches for all matching elements within each component.
|
432
|
+
- The event can be overriden by the argument `event`
|
377
433
|
|
378
|
-
**Usage
|
434
|
+
**Usage**
|
379
435
|
|
380
|
-
|
436
|
+
`app/frontend/javascript/components/folder/MyComponent.svelte`
|
381
437
|
|
382
438
|
```sveltehtml
|
383
439
|
<script>
|
384
440
|
import {addComponentStreamListener} from '@csedl/svelte-on-rails/src/componentStreamListener'
|
385
441
|
|
386
442
|
function handleCableEvent(event) {
|
387
|
-
console.log(event.detail
|
443
|
+
console.log('Event received by Turbo Stream', event.detail)
|
388
444
|
}
|
389
445
|
</script>
|
390
|
-
<!--on
|
446
|
+
<!--on ANY element:-->
|
391
447
|
<h1 use:addComponentStreamListener={handleCableEvent}>Test TurboStreams Channel</h1>
|
392
448
|
```
|
393
449
|
|
394
|
-
|
450
|
+
The `addComponentStreamListener` adds the eventListener `stream-action` on the wrapping Element.
|
451
|
+
The «wrapping Element» is the Element from the view helper `svelte_component` with the class `svelte-component`.
|
452
|
+
|
453
|
+
Now you can dispatch events on the component by:
|
454
|
+
|
455
|
+
```ruby
|
456
|
+
SvelteOnRails::ActionCable.send(
|
457
|
+
'folder/MyComponent',
|
458
|
+
{ message: "greetings from Server: äöü🤣🌴🌍漢字" }
|
459
|
+
)
|
460
|
+
```
|
461
|
+
|
462
|
+
And you will find the object, with the message key on the browser logs.
|
463
|
+
|
464
|
+
Without any arguments, just by `SvelteOnRails::ActionCable.send` it would fire the `stream-action` event on all components.
|
465
|
+
|
466
|
+
# SvelteOnRails::TurboStream.send
|
467
|
+
|
468
|
+
Turbo Stream makes more sense when you think of sending confidential data to the components
|
469
|
+
or you want to separate to channels based on user groups, for example.
|
470
|
+
|
471
|
+
Few setup is needed for that:
|
472
|
+
|
473
|
+
**Setup**
|
474
|
+
|
475
|
+
Please setup the `turbo-rails` gem and follow the chapter [Come alive with Turbo Streams](https://github.com/hotwired/turbo-rails?tab=readme-ov-file#come-alive-with-turbo-streams), which mainly is:
|
476
|
+
|
477
|
+
```shell
|
478
|
+
bundle add turbo-rails
|
479
|
+
rails turbo:install
|
480
|
+
```
|
481
|
+
|
482
|
+
make sure that `import "@hotwired/turbo-rails"` is on your application.js and set the view helper
|
483
|
+
`<%= turbo_stream_from 'authenticated' if current_user %>` to your view.
|
484
|
+
|
485
|
+
If a channel (e.g.: `authenticated`) is active and you have an HTML element with a HTML-ID (e.g.: `svelte-on-rails-stream-actions-box`),
|
486
|
+
you can test it by:
|
395
487
|
|
396
488
|
```ruby
|
397
|
-
|
398
|
-
|
489
|
+
Turbo::StreamsChannel.send(
|
490
|
+
"broadcast_append_to",
|
491
|
+
'authenticated',
|
492
|
+
target: 'svelte-on-rails-stream-actions-box',
|
493
|
+
content: "<div>Turbo-Streams are working!</div>"
|
399
494
|
)
|
400
495
|
```
|
401
496
|
|
402
|
-
|
497
|
+
When this works you are good to go.
|
403
498
|
|
404
|
-
|
405
|
-
component that is rendered by the view helper `svelte_component`, found by `currentElement.closest('.svelte-component')`
|
406
|
-
- A Stimulus controller is pushed to all subscribers of the configured channel.
|
407
|
-
- You can override this by passing `stream_name` to the method.
|
408
|
-
- Without the attribute `component` given,
|
409
|
-
it searches for all elements with the class `svelte-component` and fires the event `channel-action`
|
410
|
-
- When `selector` is given, it searches for all matching elements within each component.
|
411
|
-
- The event can be overriden by the argument `event`
|
499
|
+
**Minimal Usage Example**
|
412
500
|
|
413
|
-
|
501
|
+
And call this by:
|
414
502
|
|
415
|
-
|
503
|
+
```ruby
|
504
|
+
SvelteOnRails::TurboStream.send
|
505
|
+
```
|
506
|
+
**What it does**
|
507
|
+
|
508
|
+
- A Stimulus controller is pushed to all subscribers of the configured channel.
|
509
|
+
- You can override the channel name by passing `channel` to the method.
|
510
|
+
|
511
|
+
**Usage Example, more detailed**
|
416
512
|
|
417
513
|
If you want to fire a event on a specific element within the component, you do not need `addComponentStreamListener`.
|
418
|
-
Just do something like
|
514
|
+
Just do something like:
|
419
515
|
|
420
516
|
```sveltehtml
|
421
|
-
<
|
517
|
+
<script>
|
518
|
+
function logStreamMessage(event) {
|
519
|
+
console.log(event.detail.message)
|
520
|
+
}
|
521
|
+
</script>
|
522
|
+
<button class="counter-button" onclick="{logStreamMessage}">Show Contents</button>
|
422
523
|
```
|
423
524
|
|
424
|
-
within the svelte component
|
525
|
+
within the svelte component.
|
526
|
+
|
527
|
+
Then, call it by:
|
425
528
|
|
426
529
|
```ruby
|
427
530
|
SvelteOnRails::TurboStream.new.dispatch_event(
|
428
|
-
|
531
|
+
channel: 'my-custom-stream',
|
532
|
+
component: '/javascript/components/TurboStreamsChannel',
|
429
533
|
selector: '.counter-button',
|
430
|
-
|
534
|
+
event: 'click',
|
535
|
+
event_detail: { message: "Greetings from Server: äöü🤣🌴🌍漢字" }
|
431
536
|
)
|
432
537
|
```
|
433
538
|
|
434
|
-
|
435
539
|
## More rake tasks
|
436
540
|
|
437
541
|
This tasks are more for testing/playground purposes
|
@@ -486,30 +590,12 @@ This will cause the installer, to install the npm package from a local path inst
|
|
486
590
|
Then run the tests and start contributing.
|
487
591
|
|
488
592
|
**RUN THE FIRST TEST (!)**: Testing is complex here because of the design based on the installer test.
|
489
|
-
On Problems, i always run the `Installer > destroy and create rails app > FIRST TEST > [...] check if javascript works`.
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
test_helpers. But I have done my best to give all the code a clear structure.
|
496
|
-
I hope you like it, and improvements are welcome.
|
497
|
-
|
498
|
-
**Installer tests** starting with completely destroy the rails app within the `generated_test_app_path`,
|
499
|
-
generating a new rails app and running the installer and test by `playwright` if the components are working.
|
500
|
-
|
501
|
-
**component tests** only checking if a rails server is alive, and if not, install and run a rails app.
|
502
|
-
For this is the testing helper `start_rails_server_unless_ping`. This step may only be slow on the
|
503
|
-
first run, then it is fast. And on every repeating the test it always overwrites the components
|
504
|
-
with the components from the template by the testing helper `install_hello_world(
|
505
|
-
['rails_vite_hello_world'],
|
506
|
-
app_root: generated_rails_app_root,
|
507
|
-
force: true,
|
508
|
-
silent: true
|
509
|
-
)`. At the end of the test it leaves the rails server running.
|
510
|
-
|
511
|
-
On that way a developer can just edit the templates and run a test and see always the refreshed
|
512
|
-
content on the browser and on the app within the `generated_test_app_path`.
|
593
|
+
On Problems, i always run the `Installer > destroy and create rails app > FIRST TEST > [...] check if javascript works`.
|
594
|
+
If there are problems, open the generated app on a IDE and check errors there.
|
595
|
+
|
596
|
+
When this passes, all the others passing mostly.
|
597
|
+
|
598
|
+
At the end of the most tests it leaves the rails server running, so that you can see the result on `localhost:3000`.
|
513
599
|
|
514
600
|
NOTE: Theese tests are dependend on your environment, including the running ruby version!
|
515
601
|
I am working on rvm. If you work on a different environment, some (not many) changes may be necessary.
|
@@ -133,6 +133,10 @@ module SvelteOnRails
|
|
133
133
|
utils_i.add_route(" get \"svelte_on_rails_hello_world/turbo_stream_action\"", app_root: Rails.root)
|
134
134
|
npm_i = SvelteOnRails::Installer::Npm
|
135
135
|
npm_i.install_or_update_package('axios')
|
136
|
+
npm_i.install_or_update_package('@rails/actioncable')
|
137
|
+
js_i = SvelteOnRails::Installer::Javascript
|
138
|
+
init_stat = '../initializers/actionCable.js'
|
139
|
+
js_i.append_import_statement(application_js_path, init_stat, "import '#{init_stat}';")
|
136
140
|
@hello_world_path = hw_i.install_hello_world(['rails_vite_hello_world'], app_root: nil, force: true, silent: true)
|
137
141
|
end
|
138
142
|
|
data/lib/svelte-on-rails.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
module SvelteOnRails
|
2
|
+
class ActionCable
|
3
|
+
def self.send(component = nil, event_detail = nil, event: 'stream-action', selector: nil, channel: nil)
|
4
|
+
|
5
|
+
_channel = configs['channel'] || channel
|
6
|
+
unless _channel.present?
|
7
|
+
raise 'Missing attribute or configuration: action_cable/channel'
|
8
|
+
end
|
9
|
+
|
10
|
+
if event != 'stream-action' && !selector
|
11
|
+
raise "Another event name than the default one is only possible together with a selector"
|
12
|
+
end
|
13
|
+
|
14
|
+
args = {
|
15
|
+
eventDetail: event_detail,
|
16
|
+
component: component,
|
17
|
+
event: event,
|
18
|
+
selector: selector
|
19
|
+
}
|
20
|
+
|
21
|
+
::ActionCable.server.broadcast(
|
22
|
+
_channel,
|
23
|
+
args
|
24
|
+
)
|
25
|
+
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.configs
|
32
|
+
SvelteOnRails::Configuration.instance.configs[:action_cable]
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module SvelteOnRails
|
2
2
|
class TurboStream
|
3
|
-
def
|
3
|
+
def self.send(component = nil, event_detail = nil, event: 'stream-action', selector: nil, channel: nil)
|
4
|
+
|
5
|
+
if event != 'stream-action' && !selector
|
6
|
+
raise "Another event name than the default one is only possible together with a selector"
|
7
|
+
end
|
4
8
|
|
5
9
|
args = {
|
6
10
|
eventDetail: event_detail,
|
@@ -13,7 +17,7 @@ module SvelteOnRails
|
|
13
17
|
|
14
18
|
Turbo::StreamsChannel.send(
|
15
19
|
"broadcast_append_to",
|
16
|
-
|
20
|
+
channel || configs['channel'],
|
17
21
|
target: configs['target_html_id'],
|
18
22
|
content: "<div style=\"display: none;\" data-controller=\"svelte-on-rails-turbo-stream\" data-args=\"#{args_enc}\"></div>"
|
19
23
|
)
|
@@ -22,7 +26,7 @@ module SvelteOnRails
|
|
22
26
|
|
23
27
|
private
|
24
28
|
|
25
|
-
def configs
|
29
|
+
def self.configs
|
26
30
|
@configs ||= begin
|
27
31
|
|
28
32
|
conf = SvelteOnRails::Configuration.instance
|
@@ -32,8 +36,8 @@ module SvelteOnRails
|
|
32
36
|
unless conf.configs[:turbo_stream]['target_html_id']
|
33
37
|
raise '[svelte-on-rails] missing configuration: turbo_stream/target_html_id'
|
34
38
|
end
|
35
|
-
unless conf.configs[:turbo_stream]['
|
36
|
-
raise '[svelte-on-rails] missing configuration: turbo_stream/
|
39
|
+
unless conf.configs[:turbo_stream]['channel']
|
40
|
+
raise '[svelte-on-rails] missing configuration: turbo_stream/channel'
|
37
41
|
end
|
38
42
|
|
39
43
|
conf.configs[:turbo_stream]
|
@@ -25,7 +25,11 @@ turbo_stream:
|
|
25
25
|
# this part you need when you want to be able to trigger javascript actions on svelte-components from the backend
|
26
26
|
target_html_id: 'svelte-on-rails-stream-actions-box'
|
27
27
|
# html-id of any element that must exist for being able to receive actions (turbo streams can only work this way)
|
28
|
-
|
28
|
+
channel: 'public'
|
29
|
+
|
30
|
+
action_cable:
|
31
|
+
# if you want to use it
|
32
|
+
channel: "svelte_on_rails_channel"
|
29
33
|
|
30
34
|
development:
|
31
35
|
watch_changes: true
|
data/templates/rails_vite_hello_world/app/controllers/svelte_on_rails_hello_world_controller.rb
CHANGED
@@ -5,21 +5,41 @@ class SvelteOnRailsHelloWorldController < ApplicationController
|
|
5
5
|
|
6
6
|
def turbo_stream_action
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
comp = '/javascript/components/ReceiveFromChannel'
|
9
|
+
|
10
|
+
case params['stream']
|
11
|
+
|
12
|
+
when 'action-cable-to-component'
|
13
|
+
SvelteOnRails::ActionCable.send(
|
14
|
+
comp,
|
15
|
+
{ message: "#{SecureRandom.hex(2)} Sent by <span class='transfer'>ActionCable</span>: äöü🤣🌴🌍漢字", class: 'action-cable-to-component' },
|
16
|
+
event: 'stream-action'
|
13
17
|
)
|
14
|
-
|
15
|
-
|
16
|
-
SvelteOnRails::
|
17
|
-
|
18
|
+
|
19
|
+
when 'action-cable-to-element'
|
20
|
+
SvelteOnRails::ActionCable.send(
|
21
|
+
comp,
|
22
|
+
{ message: "#{SecureRandom.hex(2)} <span class='transfer'>ActionCable to .my-custom-class / my-custom-event</span>", class: 'action-cable-to-element' },
|
23
|
+
selector: '.my-custom-class',
|
24
|
+
event: 'my-custom-event'
|
18
25
|
)
|
19
|
-
|
26
|
+
|
27
|
+
when 'turbo-stream-to-all-components'
|
28
|
+
SvelteOnRails::TurboStream.send(
|
29
|
+
nil,
|
30
|
+
{ message: "Sent by TurboStream: äöü🤣🌴🌍漢字", class: 'turbo-stream-to-all-components' },
|
31
|
+
)
|
32
|
+
|
33
|
+
when 'turbo-stream-to-element'
|
34
|
+
SvelteOnRails::TurboStream.send(
|
35
|
+
nil,
|
36
|
+
{ message: "Sent by TurboStream: äöü🤣🌴🌍漢字", class: 'turbo-stream-to-element' },
|
37
|
+
selector: '.my-custom-class',
|
38
|
+
event: 'my-custom-event'
|
39
|
+
)
|
40
|
+
|
20
41
|
end
|
21
42
|
|
22
|
-
head :ok
|
23
43
|
end
|
24
44
|
|
25
45
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { createConsumer } from "@rails/actioncable"
|
2
|
+
import {dispatchSvelteStreamEvent, actionCableDebugLog} from '@csedl/svelte-on-rails'
|
3
|
+
|
4
|
+
const consumer = createConsumer()
|
5
|
+
|
6
|
+
consumer.subscriptions.create("SvelteOnRailsChannel", {
|
7
|
+
connected() {
|
8
|
+
actionCableDebugLog("Connected to SvelteOnRailsChannel")
|
9
|
+
},
|
10
|
+
disconnected() {
|
11
|
+
actionCableDebugLog("Disconnected from SvelteOnRailsChannel")
|
12
|
+
},
|
13
|
+
received(data) {
|
14
|
+
actionCableDebugLog("Received:", data)
|
15
|
+
dispatchSvelteStreamEvent(data)
|
16
|
+
}
|
17
|
+
})
|
data/templates/rails_vite_hello_world/app/frontend/javascript/components/ReceiveFromChannel.svelte
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
import axios from "axios";
|
3
|
+
import {addComponentStreamListener} from '@csedl/svelte-on-rails/src/componentStreamListener'
|
4
|
+
|
5
|
+
let results = $state([])
|
6
|
+
|
7
|
+
function callChannelAction(action) {
|
8
|
+
results = []
|
9
|
+
axios.get(`/svelte_on_rails_hello_world/turbo_stream_action?stream=${action}`)
|
10
|
+
.then(function (response) {
|
11
|
+
console.log(`server action called, status: ${response.status}`)
|
12
|
+
})
|
13
|
+
}
|
14
|
+
|
15
|
+
const handleCableEvent = (ev) => {
|
16
|
+
results.push(
|
17
|
+
{
|
18
|
+
text: `Message received from Server: ${JSON.stringify(ev.detail.message)}`,
|
19
|
+
class: ev.detail.class
|
20
|
+
}
|
21
|
+
)
|
22
|
+
};
|
23
|
+
|
24
|
+
function handleElementEvent(ev) {
|
25
|
+
results.push(
|
26
|
+
{
|
27
|
+
text: `Element triggered from Server: ${JSON.stringify(ev.detail.message)}`,
|
28
|
+
class: ev.detail.class
|
29
|
+
}
|
30
|
+
)
|
31
|
+
};
|
32
|
+
|
33
|
+
</script>
|
34
|
+
|
35
|
+
<h1 use:addComponentStreamListener={handleCableEvent}>Test TurboStreams Channel</h1>
|
36
|
+
|
37
|
+
<p>Actions that are triggered by SvelteOnRails::TurboStream channel from the server</p>
|
38
|
+
|
39
|
+
<button class="action-cable-to-component" onclick="{() => callChannelAction('action-cable-to-component')}">ActionCable to component</button>
|
40
|
+
<button class="action-cable-to-element" onclick="{() => callChannelAction('action-cable-to-element')}">ActionCable to element</button>
|
41
|
+
<button class="turbo-stream-to-all-components" onclick="{() => callChannelAction('turbo-stream-to-all-components')}">TurboStream to all components</button>
|
42
|
+
<button class="turbo-stream-to-element" onclick="{() => callChannelAction('turbo-stream-to-element')}">TurboStream to element</button>
|
43
|
+
|
44
|
+
<span class="my-custom-class" onmy-custom-event="{handleElementEvent}"></span>
|
45
|
+
|
46
|
+
<div class="results-box">
|
47
|
+
<p>Result:</p>
|
48
|
+
<ul class="results">
|
49
|
+
{#each results as result}
|
50
|
+
<li class="{result.class}">{@html result.text}</li>
|
51
|
+
{/each}
|
52
|
+
</ul>
|
53
|
+
</div>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: svelte-on-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Sedlmair
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- README.md
|
32
32
|
- lib/generators/svelte_on_rails/install/install_generator.rb
|
33
33
|
- lib/svelte-on-rails.rb
|
34
|
+
- lib/svelte_on_rails/action_cable.rb
|
34
35
|
- lib/svelte_on_rails/configuration.rb
|
35
36
|
- lib/svelte_on_rails/installer/gem_utils.rb
|
36
37
|
- lib/svelte_on_rails/installer/haml.rb
|
@@ -53,17 +54,19 @@ files:
|
|
53
54
|
- templates/config_base/app/frontend/ssr/ssr.js
|
54
55
|
- templates/config_base/config/svelte_on_rails.yml
|
55
56
|
- templates/config_base/vite-ssr.config.ts
|
57
|
+
- templates/rails_vite_hello_world/app/channels/svelte_on_rails_channel.rb
|
56
58
|
- templates/rails_vite_hello_world/app/controllers/svelte_on_rails_hello_world_controller.rb
|
57
59
|
- templates/rails_vite_hello_world/app/frontend/images/svelte-on-rails-hello-world-england.png
|
58
60
|
- templates/rails_vite_hello_world/app/frontend/images/svelte-on-rails-hello-world-face-smile-wink.svg
|
59
61
|
- templates/rails_vite_hello_world/app/frontend/images/svelte-on-rails-hello-world-switzerland.jpg
|
62
|
+
- templates/rails_vite_hello_world/app/frontend/initializers/actionCable.js
|
60
63
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/JavascriptImport.svelte
|
61
64
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/JpgImport.svelte
|
62
65
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/ParentWithChild.svelte
|
63
66
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/PngImport.svelte
|
67
|
+
- templates/rails_vite_hello_world/app/frontend/javascript/components/ReceiveFromChannel.svelte
|
64
68
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/SvelteOnRailsHelloWorld.svelte
|
65
69
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/SvgRawImport.svelte
|
66
|
-
- templates/rails_vite_hello_world/app/frontend/javascript/components/TurboStreamsChannel.svelte
|
67
70
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/sub/NestedComponent.svelte
|
68
71
|
- templates/rails_vite_hello_world/app/frontend/javascript/nestedJavascript.js
|
69
72
|
- templates/rails_vite_hello_world/app/frontend/javascript/nestedJavascriptToggled.js
|
data/templates/rails_vite_hello_world/app/frontend/javascript/components/TurboStreamsChannel.svelte
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
<script lang="ts">
|
2
|
-
import axios from "axios";
|
3
|
-
import {addComponentStreamListener} from '@csedl/svelte-on-rails/src/componentStreamListener'
|
4
|
-
import { onMount } from "svelte";
|
5
|
-
|
6
|
-
let counter = $state(0)
|
7
|
-
let results = $state([])
|
8
|
-
let incrBtn
|
9
|
-
|
10
|
-
|
11
|
-
onMount(() => {
|
12
|
-
incrBtn.addEventListener('click', increaseCounter)
|
13
|
-
});
|
14
|
-
|
15
|
-
function callChannelAction(params) {
|
16
|
-
results = []
|
17
|
-
axios.get(`/svelte_on_rails_hello_world/turbo_stream_action?${params}`)
|
18
|
-
.then(function (response) {
|
19
|
-
results.push(
|
20
|
-
{
|
21
|
-
text: `server action called, status: ${response.status}`,
|
22
|
-
class: 'called-for-action'
|
23
|
-
})
|
24
|
-
})
|
25
|
-
}
|
26
|
-
|
27
|
-
function increaseCounter() {
|
28
|
-
counter += 1
|
29
|
-
}
|
30
|
-
|
31
|
-
const handleCableEvent = (ev) => {
|
32
|
-
results.push(
|
33
|
-
{
|
34
|
-
text: `Message received from TurboStream: ${JSON.stringify(ev.detail.message)}`,
|
35
|
-
class: 'stream-action-received'
|
36
|
-
}
|
37
|
-
)
|
38
|
-
};
|
39
|
-
|
40
|
-
</script>
|
41
|
-
|
42
|
-
<h1 use:addComponentStreamListener={handleCableEvent}>Test TurboStreams Channel</h1>
|
43
|
-
|
44
|
-
<p>Actions that are triggered by SvelteOnRails::TurboStream channel from the server</p>
|
45
|
-
|
46
|
-
<button onstream-action="{() => callChannelAction('increase=true')}">Call increase action over Channel</button>
|
47
|
-
|
48
|
-
<button bind:this={incrBtn} class="counter-button" onclick="{increaseCounter}">increase {counter}</button>
|
49
|
-
|
50
|
-
<button class="call-channel-action" onclick="{callChannelAction}">Action</button>
|
51
|
-
|
52
|
-
<ul class="results">
|
53
|
-
{#each results as result}
|
54
|
-
<li class="{result.class}">{result.text}</li>
|
55
|
-
{/each}
|
56
|
-
</ul>
|