svelte-on-rails 5.0.0 → 5.1.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 +126 -37
- data/lib/svelte-on-rails.rb +1 -0
- data/lib/svelte_on_rails/action_cable.rb +42 -0
- data/lib/svelte_on_rails/turbo_stream.rb +8 -4
- data/templates/config_base/config/svelte_on_rails.yml +1 -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 +13 -3
- data/templates/rails_vite_hello_world/app/frontend/javascript/components/{TurboStreamsChannel.svelte → ReceiveFromChannel.svelte} +3 -2
- data/templates/rails_vite_hello_world/app/views/svelte_on_rails_hello_world/turbo_streams_channel.html.erb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e2782073f696f72736004ae21d57a71e4429fb878f915954e36628e16904de9
|
4
|
+
data.tar.gz: 2d041a60e7908ce20ab64f490ccebe3d3c673882986c83a64981aaf1e9931768
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d1fef990a79dfa782b0101f33ed64f3631d126ea6ef16dfde8d21d240653d8d938a87689955af288b862362216fbb760db61e79d709c512b242d0f86ad823d1
|
7
|
+
data.tar.gz: 430b9cf7ab45fb7e0ab629b4de95bd262e8b02bd68a58793dcd614832dfd2bb04d63f52d20ddc6639dc951d8ae132188dee755dadab1042f98a0268dcf4bab63
|
data/README.md
CHANGED
@@ -346,45 +346,133 @@ 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
|
+
|
351
|
+
There are two ways that the server can talk to the client over Websocket:
|
352
|
+
|
353
|
+
- ActionCable transmits directly to the frontends javascript
|
354
|
+
- TurboStreams is a wrapper around ActionCable
|
355
|
+
- You always need a html part for communication
|
356
|
+
|
357
|
+
**Configs**
|
358
|
+
|
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!
|
369
|
+
|
370
|
+
ActionCable is the more basic library behind `TurboStream` and it is a second Option to call Javascript Actions from the server.
|
371
|
+
|
372
|
+
**Setup**
|
373
|
+
|
374
|
+
Add `app/channels/svelte_on_rails_channel.rb`
|
375
|
+
|
376
|
+
```ruby
|
377
|
+
class SvelteOnRailsChannel < ApplicationCable::Channel
|
378
|
+
def subscribed
|
379
|
+
stream_from "svelte_on_rails_channel"
|
380
|
+
end
|
381
|
+
|
382
|
+
def unsubscribed
|
383
|
+
# Any cleanup needed when channel is unsubscribed
|
384
|
+
end
|
385
|
+
end
|
386
|
+
```
|
387
|
+
|
388
|
+
run
|
389
|
+
|
390
|
+
```shell
|
391
|
+
npm i @rails/actioncable
|
392
|
+
```
|
393
|
+
|
394
|
+
Add to `application.js`
|
395
|
+
|
396
|
+
```javascript
|
397
|
+
import { createConsumer } from "@rails/actioncable"
|
398
|
+
import {dispatchSvelteStreamEvent, actionCableDebugLog} from '@csedl/svelte-on-rails'
|
399
|
+
|
400
|
+
const consumer = createConsumer()
|
401
|
+
|
402
|
+
consumer.subscriptions.create("SvelteOnRailsChannel", {
|
403
|
+
connected() {
|
404
|
+
actionCableDebugLog("Connected to SvelteOnRailsChannel")
|
405
|
+
},
|
406
|
+
disconnected() {
|
407
|
+
actionCableDebugLog("Disconnected from SvelteOnRailsChannel")
|
408
|
+
},
|
409
|
+
received(data) {
|
410
|
+
actionCableDebugLog("Received:", data)
|
411
|
+
dispatchSvelteStreamEvent(data)
|
412
|
+
}
|
413
|
+
})
|
414
|
+
```
|
415
|
+
|
416
|
+
By setting `debug = true` [node package](https://www.npmjs.com/package/@csedl/svelte-on-rails) you see what it is doing.
|
417
|
+
|
418
|
+
**WhatdispatchSvelteStreamEvent does**
|
419
|
+
|
420
|
+
- Without the attribute `component` given,
|
421
|
+
it searches for all elements with the class `svelte-component` and fires the event `channel-action`
|
422
|
+
- When `selector` is given, it searches for all matching elements within each component.
|
423
|
+
- The event can be overriden by the argument `event`
|
424
|
+
|
425
|
+
**Usage**
|
350
426
|
|
351
|
-
|
427
|
+
Now you can dispatch events on the component by:
|
352
428
|
|
353
|
-
|
429
|
+
```ruby
|
430
|
+
ActionCable.server.broadcast("svelte_on_rails_channel",
|
431
|
+
{
|
432
|
+
eventDetail: { message: "Sent by ActionCable: äöü🤣🌴🌍漢字" },
|
433
|
+
component: '/javascript/components/ReceiveFromChannel',
|
434
|
+
}
|
435
|
+
)
|
436
|
+
```
|
437
|
+
|
438
|
+
# Turbo::StreamsChannel.send!
|
354
439
|
|
355
440
|
Few setup is needed for that:
|
356
441
|
|
357
442
|
**Setup**
|
358
443
|
|
359
|
-
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)
|
444
|
+
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:
|
445
|
+
|
446
|
+
```shell
|
447
|
+
bundle add turbo-rails
|
448
|
+
rails turbo:install
|
449
|
+
```
|
450
|
+
|
451
|
+
make sure that `import "@hotwired/turbo-rails"` is on your application.js and set the view helper
|
452
|
+
`<%= turbo_stream_from 'public' %>` to your view.
|
360
453
|
|
361
|
-
If a channel
|
362
|
-
|
363
|
-
you could just give the body-tag a ID // it is just the way hotwired works)
|
364
|
-
and a code Block like
|
454
|
+
If a channel (e.g.: `public`) is active and you have an HTML element with a HTML-ID (e.g.: `svelte-on-rails-stream-actions-box`),
|
455
|
+
you can test it by:
|
365
456
|
|
366
457
|
```ruby
|
367
458
|
Turbo::StreamsChannel.send(
|
368
459
|
"broadcast_append_to",
|
369
460
|
'public',
|
370
461
|
target: 'svelte-on-rails-stream-actions-box',
|
371
|
-
content: "<div>
|
462
|
+
content: "<div>Turbo-Streams are working!</div>"
|
372
463
|
)
|
373
464
|
```
|
374
465
|
|
375
|
-
|
376
|
-
Please check the regarding keys and theyr 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).
|
377
|
-
|
378
|
-
**Usage Example: Component Event**
|
466
|
+
When this works you are good to go.
|
379
467
|
|
380
|
-
|
468
|
+
**Minimal Usage Example**
|
381
469
|
|
382
470
|
```sveltehtml
|
383
471
|
<script>
|
384
472
|
import {addComponentStreamListener} from '@csedl/svelte-on-rails/src/componentStreamListener'
|
385
473
|
|
386
|
-
function handleCableEvent(
|
387
|
-
console.log(
|
474
|
+
function handleCableEvent() {
|
475
|
+
console.log('Event received by Turbo Stream')
|
388
476
|
}
|
389
477
|
</script>
|
390
478
|
<!--on any element:-->
|
@@ -394,44 +482,45 @@ The easiest way on the svelte component is:
|
|
394
482
|
And call this by:
|
395
483
|
|
396
484
|
```ruby
|
397
|
-
SvelteOnRails::TurboStream.new.dispatch_event
|
398
|
-
event_detail: { message: "Special Chars from the server: äöü🤣🌴🌍漢字" }
|
399
|
-
)
|
485
|
+
SvelteOnRails::TurboStream.new.dispatch_event
|
400
486
|
```
|
487
|
+
**What it does**
|
401
488
|
|
402
|
-
|
403
|
-
|
404
|
-
-
|
405
|
-
|
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`
|
412
|
-
|
413
|
-
By setting `debug = true` [node package](https://www.npmjs.com/package/@csedl/svelte-on-rails) you see what it is doing.
|
489
|
+
- The `addComponentStreamListener` adds the eventListener `stream-action` on the wrapping Element
|
490
|
+
- The «wrapping Element» is the Element from the view helper `svelte_component` with the class `svelte-component`.
|
491
|
+
- A Stimulus controller is pushed to all subscribers of the configured channel.
|
492
|
+
- You can override the channel name by passing `channel` to the method.
|
414
493
|
|
415
|
-
**Usage Example
|
494
|
+
**Usage Example, more detailed**
|
416
495
|
|
417
496
|
If you want to fire a event on a specific element within the component, you do not need `addComponentStreamListener`.
|
418
|
-
Just do something like
|
497
|
+
Just do something like:
|
419
498
|
|
420
499
|
```sveltehtml
|
421
|
-
<
|
500
|
+
<script>
|
501
|
+
function logStreamMessage(event) {
|
502
|
+
console.log(event.detail.message)
|
503
|
+
}
|
504
|
+
</script>
|
505
|
+
<button class="counter-button" onclick="{logStreamMessage}">Show Contents</button>
|
422
506
|
```
|
423
507
|
|
424
|
-
within the svelte component
|
508
|
+
within the svelte component.
|
509
|
+
|
510
|
+
Then, call it by:
|
425
511
|
|
426
512
|
```ruby
|
427
513
|
SvelteOnRails::TurboStream.new.dispatch_event(
|
428
|
-
|
514
|
+
channel: 'my-custom-stream',
|
515
|
+
component: '/javascript/components/TurboStreamsChannel',
|
429
516
|
selector: '.counter-button',
|
430
|
-
|
517
|
+
event: 'click',
|
518
|
+
event_detail: { message: "Greetings from Server: äöü🤣🌴🌍漢字" }
|
431
519
|
)
|
432
520
|
```
|
433
521
|
|
434
522
|
|
523
|
+
|
435
524
|
## More rake tasks
|
436
525
|
|
437
526
|
This tasks are more for testing/playground purposes
|
data/lib/svelte-on-rails.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
module SvelteOnRails
|
2
|
+
class ActionCable
|
3
|
+
def dispatch_event(event: 'stream-action', event_detail: nil, selector: nil, component: nil, channel: "svelte_on_rails_channel")
|
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
|
8
|
+
|
9
|
+
args = {
|
10
|
+
eventDetail: event_detail,
|
11
|
+
component: component,
|
12
|
+
event: event,
|
13
|
+
selector: selector
|
14
|
+
}
|
15
|
+
|
16
|
+
#args_enc = Base64.strict_encode64(args.to_json)
|
17
|
+
|
18
|
+
ActionCable.server.broadcast(channel, args)
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def configs
|
25
|
+
@configs ||= begin
|
26
|
+
|
27
|
+
conf = SvelteOnRails::Configuration.instance
|
28
|
+
unless conf.configs[:turbo_stream]
|
29
|
+
raise '[svelte-on-rails] missing configuration: :turbo_stream'
|
30
|
+
end
|
31
|
+
unless conf.configs[:turbo_stream]['target_html_id']
|
32
|
+
raise '[svelte-on-rails] missing configuration: turbo_stream/target_html_id'
|
33
|
+
end
|
34
|
+
unless conf.configs[:turbo_stream]['channel']
|
35
|
+
raise '[svelte-on-rails] missing configuration: turbo_stream/channel'
|
36
|
+
end
|
37
|
+
|
38
|
+
conf.configs[:turbo_stream]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module SvelteOnRails
|
2
2
|
class TurboStream
|
3
|
-
def dispatch_event(event: 'stream-action', event_detail: nil, selector: nil, component: nil,
|
3
|
+
def dispatch_event(event: 'stream-action', event_detail: nil, selector: nil, component: 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
|
)
|
@@ -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,7 @@ 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
29
|
|
30
30
|
development:
|
31
31
|
watch_changes: true
|
data/templates/rails_vite_hello_world/app/controllers/svelte_on_rails_hello_world_controller.rb
CHANGED
@@ -9,17 +9,27 @@ class SvelteOnRailsHelloWorldController < ApplicationController
|
|
9
9
|
SvelteOnRails::TurboStream.new.dispatch_event(
|
10
10
|
event: 'click',
|
11
11
|
selector: '.counter-button',
|
12
|
-
component: '/javascript/components/
|
12
|
+
component: '/javascript/components/ReceiveFromChannel'
|
13
13
|
)
|
14
14
|
render plain: 'increase-action streamed'
|
15
|
+
elsif params['action_cable']
|
16
|
+
|
17
|
+
ActionCable.server.broadcast("svelte_on_rails_channel",
|
18
|
+
{
|
19
|
+
eventDetail: { message: "Sent by ActionCable: äöü🤣🌴🌍漢字" },
|
20
|
+
component: '/javascript/components/ReceiveFromChannel',
|
21
|
+
}
|
22
|
+
)
|
23
|
+
#SvelteOnRails::ActionCable.new.dispatch_event(channel: "svelte_on_rails_channel", event_detail: { message: "Hello from SvelteChannel!" })
|
24
|
+
|
25
|
+
render plain: 'ActionCable streaming'
|
15
26
|
else
|
16
27
|
SvelteOnRails::TurboStream.new.dispatch_event(
|
17
|
-
event_detail: { message: "
|
28
|
+
event_detail: { message: "Sent by TurboStream: äöü🤣🌴🌍漢字", user: "Müller" }
|
18
29
|
)
|
19
30
|
render plain: 'component-action streamed'
|
20
31
|
end
|
21
32
|
|
22
|
-
head :ok
|
23
33
|
end
|
24
34
|
|
25
35
|
end
|
@@ -7,7 +7,6 @@
|
|
7
7
|
let results = $state([])
|
8
8
|
let incrBtn
|
9
9
|
|
10
|
-
|
11
10
|
onMount(() => {
|
12
11
|
incrBtn.addEventListener('click', increaseCounter)
|
13
12
|
});
|
@@ -31,7 +30,7 @@
|
|
31
30
|
const handleCableEvent = (ev) => {
|
32
31
|
results.push(
|
33
32
|
{
|
34
|
-
text: `Message received from
|
33
|
+
text: `Message received from Server: ${JSON.stringify(ev.detail.message)}`,
|
35
34
|
class: 'stream-action-received'
|
36
35
|
}
|
37
36
|
)
|
@@ -49,6 +48,8 @@
|
|
49
48
|
|
50
49
|
<button class="call-channel-action" onclick="{callChannelAction}">Action</button>
|
51
50
|
|
51
|
+
<button onclick="{() => callChannelAction('action_cable=true')}">Call ActionCable Action</button>
|
52
|
+
|
52
53
|
<ul class="results">
|
53
54
|
{#each results as result}
|
54
55
|
<li class="{result.class}">{result.text}</li>
|
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.1.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,6 +54,7 @@ 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
|
@@ -61,9 +63,9 @@ files:
|
|
61
63
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/JpgImport.svelte
|
62
64
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/ParentWithChild.svelte
|
63
65
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/PngImport.svelte
|
66
|
+
- templates/rails_vite_hello_world/app/frontend/javascript/components/ReceiveFromChannel.svelte
|
64
67
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/SvelteOnRailsHelloWorld.svelte
|
65
68
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/SvgRawImport.svelte
|
66
|
-
- templates/rails_vite_hello_world/app/frontend/javascript/components/TurboStreamsChannel.svelte
|
67
69
|
- templates/rails_vite_hello_world/app/frontend/javascript/components/sub/NestedComponent.svelte
|
68
70
|
- templates/rails_vite_hello_world/app/frontend/javascript/nestedJavascript.js
|
69
71
|
- templates/rails_vite_hello_world/app/frontend/javascript/nestedJavascriptToggled.js
|