turbo_live 0.2.0 → 0.3.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 +50 -2
- data/examples/countdown_component.rb +2 -2
- data/examples/counter_component.rb +3 -3
- data/examples/flappy_bird_component.rb +2 -2
- data/examples/showcase_component.rb +4 -1
- data/examples/tic_tac_toe_component.rb +2 -2
- data/lib/turbo_live/serializer.rb +19 -0
- data/lib/turbo_live/version.rb +1 -1
- data/lib/turbo_live.rb +8 -2
- metadata +4 -3
- /data/app/channels/{components_channel.rb → turbo_live/components_channel.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f35b2977f8f91c94aa92547a23facedec57a0fe96c10b497a9ee4f0583ee3aa6
|
4
|
+
data.tar.gz: b2d82cbcc93d640fd1dee6a32753fe93d5ef7e509e2e6db569d74b24c84cb651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3108716f45050495efcb80b7c5d7b8ea0ba0fe1712ffa72165299dc31ad9e0a7443e3e961323ed33dbcb35f4fb4f65c52d1a530f5b2e8e537028d7fec612f91a
|
7
|
+
data.tar.gz: 1118bcb7d3bcbd573265edaff2be2b3d5590614a7018d68e8ecb4e628404c6eec24f4ce00d1f6260ecf078e717d6ff8741e1dbc603389395b22eb4539971d541
|
data/README.md
CHANGED
@@ -6,6 +6,10 @@ TurboLive is a Ruby gem that enables the creation of async, progressively enhanc
|
|
6
6
|
|
7
7
|
- [Installation](#installation)
|
8
8
|
- [Setup](#setup)
|
9
|
+
- [Rails Routes](#rails-routes)
|
10
|
+
- [Stimulus Controller](#stimulus-controller)
|
11
|
+
- [ActionCable (Optional)](#actioncable-optional)
|
12
|
+
- [Serializer Configuration](#serializer-configuration)
|
9
13
|
- [Usage](#usage)
|
10
14
|
- [Creating a Component](#creating-a-component)
|
11
15
|
- [Model State](#model-state)
|
@@ -46,7 +50,13 @@ For importmaps:
|
|
46
50
|
bin/importmap pin @radioactive-labs/turbo-live
|
47
51
|
```
|
48
52
|
|
49
|
-
For
|
53
|
+
For yarn:
|
54
|
+
|
55
|
+
```console
|
56
|
+
yarn add @radioactive-labs/turbo-live
|
57
|
+
```
|
58
|
+
|
59
|
+
Or YAR:
|
50
60
|
|
51
61
|
```console
|
52
62
|
npm install @radioactive-labs/turbo-live
|
@@ -54,6 +64,21 @@ npm install @radioactive-labs/turbo-live
|
|
54
64
|
|
55
65
|
## Setup
|
56
66
|
|
67
|
+
### Rails Routes
|
68
|
+
|
69
|
+
In your rails routes, mount the engine:
|
70
|
+
|
71
|
+
```diff
|
72
|
+
Rails.application.routes.draw do
|
73
|
+
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
|
74
|
+
|
75
|
+
+ mount TurboLive::Engine => "/turbo_live"
|
76
|
+
|
77
|
+
# Defines the root path route ("/")
|
78
|
+
root "index#index"
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
57
82
|
### Stimulus Controller
|
58
83
|
|
59
84
|
TurboLive uses a Stimulus controller to manage interactions. In your `app/javascript/controllers/index.js`:
|
@@ -61,9 +86,10 @@ TurboLive uses a Stimulus controller to manage interactions. In your `app/javasc
|
|
61
86
|
```diff
|
62
87
|
import { application } from "controllers/application"
|
63
88
|
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
|
64
|
-
+import * as turboLive from "@radioactive-labs/turbo-live"
|
65
89
|
|
66
90
|
eagerLoadControllersFrom("controllers", application)
|
91
|
+
|
92
|
+
+import * as turboLive from "@radioactive-labs/turbo-live"
|
67
93
|
+turboLive.registerControllers(application)
|
68
94
|
```
|
69
95
|
|
@@ -88,6 +114,28 @@ import "controllers"
|
|
88
114
|
+import "channels"
|
89
115
|
```
|
90
116
|
|
117
|
+
### Serializer Configuration
|
118
|
+
|
119
|
+
TurboLive requires a serializer for state management.
|
120
|
+
|
121
|
+
The default serializer (`TurboLive::Serializer`) simply wraps YAML, which handles primitive objects and basic collections.
|
122
|
+
If you need to serialize complex objects, you can provide your own serializer implementation or customize the in-built.
|
123
|
+
|
124
|
+
You can configure the serializer in an initializer:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
# config/initializers/turbo_live.rb
|
128
|
+
|
129
|
+
# Optional - defaults to TurboLive::Serializer
|
130
|
+
TurboLive.serializer = YourCustomSerializer
|
131
|
+
|
132
|
+
# (Optional) You can set a custom verifier key for security
|
133
|
+
TurboLive.verifier_key = Rails.application.secret_key_base
|
134
|
+
|
135
|
+
# pass extra permitted classes to the underlying YAML serializer
|
136
|
+
TurboLive::Serializer.permitted_classes << BigDecimal
|
137
|
+
```
|
138
|
+
|
91
139
|
## Usage
|
92
140
|
|
93
141
|
A TurboLive component is a self-contained, interactive unit of a web application that can update in real-time without full page reloads. Components follow [The Elm Architecture](https://guide.elm-lang.org/architecture/) pattern.
|
@@ -15,11 +15,11 @@ class CounterComponent < TurboLive::Component
|
|
15
15
|
|
16
16
|
def update(input)
|
17
17
|
case input
|
18
|
-
in
|
18
|
+
in :decrement
|
19
19
|
self.count -= 1
|
20
|
-
in
|
20
|
+
in :increment
|
21
21
|
self.count += 1
|
22
|
-
in
|
22
|
+
in :reset
|
23
23
|
self.count = 0
|
24
24
|
end
|
25
25
|
end
|
@@ -75,14 +75,14 @@ class FlappyBirdComponent < TurboLive::Component
|
|
75
75
|
|
76
76
|
def update(input)
|
77
77
|
case input
|
78
|
-
in
|
78
|
+
in :jump
|
79
79
|
if game_over
|
80
80
|
reset_game
|
81
81
|
else
|
82
82
|
self.nonce = NONCES[live_id] = NONCES[live_id] + 1
|
83
83
|
self.bird_velocity = JUMP_STRENGTH
|
84
84
|
end
|
85
|
-
in
|
85
|
+
in :tick
|
86
86
|
norender! if nonce < NONCES[live_id]
|
87
87
|
update_game_state
|
88
88
|
end
|
@@ -12,6 +12,7 @@ class ShowcaseComponent < TurboLive::Component
|
|
12
12
|
li { button(**on(click: [:change_component, :countdown])) { "Countdown" } }
|
13
13
|
li { button(**on(click: [:change_component, :tic_tac_toe])) { "TicTacToe" } }
|
14
14
|
li { button(**on(click: [:change_component, :flappy_bird])) { "Flappy Bird" } }
|
15
|
+
li { button(**on(click: [:change_component, :form])) { "Form" } }
|
15
16
|
end
|
16
17
|
end
|
17
18
|
div class: "right-column" do
|
@@ -24,7 +25,7 @@ class ShowcaseComponent < TurboLive::Component
|
|
24
25
|
|
25
26
|
def update(input)
|
26
27
|
case input
|
27
|
-
in [
|
28
|
+
in [:change_component, component]
|
28
29
|
self.component = component
|
29
30
|
end
|
30
31
|
end
|
@@ -41,6 +42,8 @@ class ShowcaseComponent < TurboLive::Component
|
|
41
42
|
TicTacToeComponent
|
42
43
|
when :flappy_bird
|
43
44
|
FlappyBirdComponent
|
45
|
+
when :form
|
46
|
+
FormComponent
|
44
47
|
end
|
45
48
|
end
|
46
49
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TurboLive
|
4
|
+
class Serializer
|
5
|
+
class << self
|
6
|
+
def dump(obj)
|
7
|
+
YAML.dump(obj)
|
8
|
+
end
|
9
|
+
|
10
|
+
def load(obj)
|
11
|
+
YAML.safe_load(obj, permitted_classes: permitted_classes)
|
12
|
+
end
|
13
|
+
|
14
|
+
def permitted_classes
|
15
|
+
@permitted_classes ||= []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/turbo_live/version.rb
CHANGED
data/lib/turbo_live.rb
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
require_relative "turbo_live/version"
|
4
4
|
require_relative "turbo_live/component"
|
5
5
|
require_relative "turbo_live/renderer"
|
6
|
+
require_relative "turbo_live/serializer"
|
6
7
|
|
7
8
|
require_relative "turbo_live/engine" if defined?(Rails)
|
8
|
-
require_relative "../app/channels/components_channel" if defined?(ActionCable)
|
9
|
+
require_relative "../app/channels/turbo_live/components_channel" if defined?(ActionCable::Channel::Base)
|
9
10
|
|
10
11
|
module TurboLive
|
11
12
|
class Error < StandardError; end
|
@@ -17,13 +18,18 @@ module TurboLive
|
|
17
18
|
|
18
19
|
class << self
|
19
20
|
attr_writer :verifier_key
|
21
|
+
attr_writer :serializer
|
20
22
|
|
21
23
|
def verifier
|
22
|
-
@verifier ||= ActiveSupport::MessageVerifier.new(verifier_key, digest: "SHA256", serializer:
|
24
|
+
@verifier ||= ActiveSupport::MessageVerifier.new(verifier_key, digest: "SHA256", serializer: serializer)
|
23
25
|
end
|
24
26
|
|
25
27
|
def verifier_key
|
26
28
|
@verifier_key or raise ArgumentError, "Turbo requires a verifier_key"
|
27
29
|
end
|
30
|
+
|
31
|
+
def serializer
|
32
|
+
@serializer ||= TurboLive::Serializer
|
33
|
+
end
|
28
34
|
end
|
29
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo_live
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TheDumbTechGuy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex-rails
|
@@ -52,7 +52,7 @@ files:
|
|
52
52
|
- LICENSE.txt
|
53
53
|
- README.md
|
54
54
|
- Rakefile
|
55
|
-
- app/channels/components_channel.rb
|
55
|
+
- app/channels/turbo_live/components_channel.rb
|
56
56
|
- app/controllers/turbo_live/components_controller.rb
|
57
57
|
- config/routes.rb
|
58
58
|
- examples/countdown_component.rb
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- lib/turbo_live/component.rb
|
65
65
|
- lib/turbo_live/engine.rb
|
66
66
|
- lib/turbo_live/renderer.rb
|
67
|
+
- lib/turbo_live/serializer.rb
|
67
68
|
- lib/turbo_live/version.rb
|
68
69
|
- package-lock.json
|
69
70
|
- package.json
|
File without changes
|