solder 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/app/controllers/solder/ui_state_controller.rb +3 -1
- data/lib/generators/solder/initializer/USAGE +8 -0
- data/lib/generators/solder/initializer/USAGE~ +8 -0
- data/lib/generators/solder/initializer/initializer_generator.rb +7 -0
- data/lib/generators/solder/initializer/initializer_generator.rb~ +3 -0
- data/lib/generators/solder/initializer/templates/solder.rb +10 -0
- data/lib/generators/solder/initializer/templates/solder.rb~ +0 -0
- data/lib/generators/solder/stimulus/USAGE +8 -0
- data/lib/generators/solder/stimulus/USAGE~ +8 -0
- data/lib/generators/solder/stimulus/stimulus_generator.rb +7 -0
- data/lib/generators/solder/stimulus/stimulus_generator.rb~ +3 -0
- data/lib/generators/solder/stimulus/templates/solder_controller.js.tt +41 -0
- data/lib/install/install.rb +36 -0
- data/lib/install/install.rb~ +17 -0
- data/lib/install/templates/solder_controller.js.tt +41 -0
- data/lib/solder/engine.rb +23 -2
- data/lib/solder/engine.rb~ +5 -2
- data/lib/solder/version.rb +1 -1
- data/lib/solder/version.rb~ +1 -1
- data/lib/tasks/solder_tasks.rake +6 -4
- metadata +17 -20
- data/app/controllers/solder/ui_state_controller.rb~ +0 -25
- data/app/helpers/solder/application_helper.rb~ +0 -37
- data/config/routes.rb~ +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00c285939bae079a1349a896571e8b315752b813715081d4d29d043a25d0c27a
|
4
|
+
data.tar.gz: '092845396d182c4082c4915a12fd9a9087666557c95cca1cae4a6be1e9078420'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: adb71a8e89b6c6730250dd0ba23b5ad0390822ba6d35afd130fd655a37ab6cecbcd45f1c443ece71d8e199a8fce984d6070d8dd0dcab4e6444041f0089e402bf
|
7
|
+
data.tar.gz: ea5f579f47725c9d5f148ca0f1e9dca34e2f98a81b6575595442266b36c3e264577ef96fcff94487dbc3fef0390d7c1c891c8f00b9196023ff796d02cde216dc
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Solder
|
2
2
|
class UiStateController < ApplicationController
|
3
|
+
include ActionView::Helpers::SanitizeHelper
|
4
|
+
|
3
5
|
before_action :set_ui_state, only: :show
|
4
6
|
around_action Solder.config[:around_action]
|
5
7
|
|
@@ -29,7 +31,7 @@ module Solder
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def parsed_attributes
|
32
|
-
JSON.parse(ui_state_params[:attributes])
|
34
|
+
JSON.parse(ui_state_params[:attributes]).deep_transform_values { sanitize(_1) }
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Solder.configure do |config|
|
2
|
+
# Specify a global around action for Solder's UIStateController
|
3
|
+
# This is useful for any assumptions your app makes, e.g. instance
|
4
|
+
# variables being present, headers being checked, or multitenancy
|
5
|
+
# (see example below)
|
6
|
+
#
|
7
|
+
# config[:around_action] = ->(_controller, action) do
|
8
|
+
# ActsAsTenant.without_tenant { action.call }
|
9
|
+
# end
|
10
|
+
end
|
File without changes
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
2
|
+
import { get, patch } from '@rails/request.js'
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static values = {
|
6
|
+
key: String
|
7
|
+
}
|
8
|
+
|
9
|
+
async connect () {
|
10
|
+
this.mutationObserver = new MutationObserver(this.mutateState.bind(this))
|
11
|
+
|
12
|
+
this.mutationObserver.observe(this.element, { attributes: true })
|
13
|
+
}
|
14
|
+
|
15
|
+
disconnect () {
|
16
|
+
this.mutationObserver?.disconnect()
|
17
|
+
}
|
18
|
+
|
19
|
+
mutateState (mutationList, observer) {
|
20
|
+
mutationList
|
21
|
+
.filter(mutation => mutation.attributeName !== 'data-solder-touch')
|
22
|
+
.forEach(async mutation => {
|
23
|
+
const body = new FormData()
|
24
|
+
|
25
|
+
const attributes = {}
|
26
|
+
this.element
|
27
|
+
.getAttributeNames()
|
28
|
+
.filter(name => name !== 'data-controller')
|
29
|
+
.map(name => {
|
30
|
+
attributes[name] = this.element.getAttribute(name)
|
31
|
+
})
|
32
|
+
|
33
|
+
body.append('key', this.keyValue)
|
34
|
+
body.append('attributes', JSON.stringify(attributes))
|
35
|
+
|
36
|
+
await patch('/solder/ui_state/update', {
|
37
|
+
body
|
38
|
+
})
|
39
|
+
})
|
40
|
+
}
|
41
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# install @rails/request.js
|
2
|
+
if Rails.root.join("config/importmap.rb").exist?
|
3
|
+
say "Pin @rails/request.js"
|
4
|
+
append_to_file "config/importmap.rb", %(pin "@rails/request.js", preload: true\n)
|
5
|
+
else
|
6
|
+
say "Install @rails/request.js"
|
7
|
+
run "yarn add @rails/request.js"
|
8
|
+
end
|
9
|
+
|
10
|
+
gemfile = Rails.root.join("Gemfile").read
|
11
|
+
|
12
|
+
# install stimulus-rails, if not already present
|
13
|
+
if !gemfile.include? "stimulus-rails"
|
14
|
+
gem "stimulus-rails"
|
15
|
+
rails_command "stimulus:install"
|
16
|
+
say "✅ stimulus-rails has been installed"
|
17
|
+
else
|
18
|
+
say "⏩ stimulus-rails is already installed. Skipping."
|
19
|
+
end
|
20
|
+
|
21
|
+
# copy stimulus controller template
|
22
|
+
generate "solder:stimulus"
|
23
|
+
|
24
|
+
# turn on development caching
|
25
|
+
if Rails.root.join("tmp", "caching-dev.txt").exist?
|
26
|
+
say "⏩ Already caching in development. Skipping."
|
27
|
+
else
|
28
|
+
system "rails dev:cache"
|
29
|
+
say "✅ Enabled caching in development"
|
30
|
+
end
|
31
|
+
|
32
|
+
# mount engine
|
33
|
+
route 'mount Solder::Engine, at: "/solder"'
|
34
|
+
|
35
|
+
# copy initializer template
|
36
|
+
generate "solder:initializer" if yes?("Do you want to install the solder initializer template?")
|
@@ -0,0 +1,17 @@
|
|
1
|
+
if Rails.root.join("config/importmap.rb").exist?
|
2
|
+
say "Pin @rails/request.js"
|
3
|
+
append_to_file "config/importmap.rb", %(pin "@rails/request.js", preload: true\n)
|
4
|
+
else
|
5
|
+
say "Install @rails/request.js"
|
6
|
+
run "yarn add @rails/request.js"
|
7
|
+
end
|
8
|
+
|
9
|
+
# if stimulus isn't present
|
10
|
+
# bundle add stimulus-rails
|
11
|
+
# bin/rails stimulus:install
|
12
|
+
gemfile = Rails.root.join("Gemfile").read
|
13
|
+
binding.irb
|
14
|
+
|
15
|
+
say "Installing Stimulus"
|
16
|
+
gem "stimulus-rails"
|
17
|
+
rails_command "stimulus:install"
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
2
|
+
import { get, patch } from '@rails/request.js'
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static values = {
|
6
|
+
key: String
|
7
|
+
}
|
8
|
+
|
9
|
+
async connect () {
|
10
|
+
this.mutationObserver = new MutationObserver(this.mutateState.bind(this))
|
11
|
+
|
12
|
+
this.mutationObserver.observe(this.element, { attributes: true })
|
13
|
+
}
|
14
|
+
|
15
|
+
disconnect () {
|
16
|
+
this.mutationObserver?.disconnect()
|
17
|
+
}
|
18
|
+
|
19
|
+
mutateState (mutationList, observer) {
|
20
|
+
mutationList
|
21
|
+
.filter(mutation => mutation.attributeName !== 'data-solder-touch')
|
22
|
+
.forEach(async mutation => {
|
23
|
+
const body = new FormData()
|
24
|
+
|
25
|
+
const attributes = {}
|
26
|
+
this.element
|
27
|
+
.getAttributeNames()
|
28
|
+
.filter(name => name !== 'data-controller')
|
29
|
+
.map(name => {
|
30
|
+
attributes[name] = this.element.getAttribute(name)
|
31
|
+
})
|
32
|
+
|
33
|
+
body.append('key', this.keyValue)
|
34
|
+
body.append('attributes', JSON.stringify(attributes))
|
35
|
+
|
36
|
+
await patch('/solder/ui_state/update', {
|
37
|
+
body
|
38
|
+
})
|
39
|
+
})
|
40
|
+
}
|
41
|
+
}
|
data/lib/solder/engine.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
module Solder
|
2
|
-
|
3
|
-
|
2
|
+
class << self
|
3
|
+
def config
|
4
|
+
Rails.application.config.solder
|
5
|
+
end
|
6
|
+
|
7
|
+
def configure
|
8
|
+
yield config
|
9
|
+
end
|
4
10
|
end
|
5
11
|
|
6
12
|
class Engine < ::Rails::Engine
|
@@ -10,6 +16,9 @@ module Solder
|
|
10
16
|
config.solder[:around_action] = ->(_controller, action) { action.call }
|
11
17
|
|
12
18
|
initializer "solder.check_caching" do |app|
|
19
|
+
next if called_by_installer?
|
20
|
+
next if called_by_generator?
|
21
|
+
|
13
22
|
unless app.config.action_controller.perform_caching && app.config.cache_store != :null_store
|
14
23
|
puts <<~WARN
|
15
24
|
🧑🏭 Solder uses the Rails cache store to provide UI state persistence. Therefore, please make sure caching is enabled in your environment.
|
@@ -28,5 +37,17 @@ module Solder
|
|
28
37
|
helper Solder::Engine.helpers
|
29
38
|
end
|
30
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def called_by_installer?
|
44
|
+
Rake.application.top_level_tasks.include? "app:template"
|
45
|
+
rescue
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
def called_by_generator?
|
50
|
+
ARGV.any? { _1.include? "solder:" }
|
51
|
+
end
|
31
52
|
end
|
32
53
|
end
|
data/lib/solder/engine.rb~
CHANGED
@@ -22,8 +22,11 @@ module Solder
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
initializer "solder.helpers" do
|
26
|
+
ActiveSupport.on_load(:action_controller_base) do
|
27
|
+
include Solder::ApplicationHelper
|
28
|
+
helper Solder::Engine.helpers
|
29
|
+
end
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
data/lib/solder/version.rb
CHANGED
data/lib/solder/version.rb~
CHANGED
data/lib/tasks/solder_tasks.rake
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
#
|
1
|
+
namespace :solder do
|
2
|
+
desc "Install Solder into the app"
|
3
|
+
task :install do
|
4
|
+
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/install.rb", __dir__)}"
|
5
|
+
end
|
6
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Rubisch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 7.0.4
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: stimulus-rails
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.1'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.1'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: mocha
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,15 +107,26 @@ files:
|
|
121
107
|
- app/assets/stylesheets/solder/application.css
|
122
108
|
- app/controllers/solder/application_controller.rb
|
123
109
|
- app/controllers/solder/ui_state_controller.rb
|
124
|
-
- app/controllers/solder/ui_state_controller.rb~
|
125
110
|
- app/helpers/solder/application_helper.rb
|
126
|
-
- app/helpers/solder/application_helper.rb~
|
127
111
|
- app/jobs/solder/application_job.rb
|
128
112
|
- app/mailers/solder/application_mailer.rb
|
129
113
|
- app/models/solder/application_record.rb
|
130
114
|
- app/views/layouts/solder/application.html.erb
|
131
115
|
- config/routes.rb
|
132
|
-
-
|
116
|
+
- lib/generators/solder/initializer/USAGE
|
117
|
+
- lib/generators/solder/initializer/USAGE~
|
118
|
+
- lib/generators/solder/initializer/initializer_generator.rb
|
119
|
+
- lib/generators/solder/initializer/initializer_generator.rb~
|
120
|
+
- lib/generators/solder/initializer/templates/solder.rb
|
121
|
+
- lib/generators/solder/initializer/templates/solder.rb~
|
122
|
+
- lib/generators/solder/stimulus/USAGE
|
123
|
+
- lib/generators/solder/stimulus/USAGE~
|
124
|
+
- lib/generators/solder/stimulus/stimulus_generator.rb
|
125
|
+
- lib/generators/solder/stimulus/stimulus_generator.rb~
|
126
|
+
- lib/generators/solder/stimulus/templates/solder_controller.js.tt
|
127
|
+
- lib/install/install.rb
|
128
|
+
- lib/install/install.rb~
|
129
|
+
- lib/install/templates/solder_controller.js.tt
|
133
130
|
- lib/solder.rb
|
134
131
|
- lib/solder/engine.rb
|
135
132
|
- lib/solder/engine.rb~
|
@@ -156,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
153
|
- !ruby/object:Gem::Version
|
157
154
|
version: '0'
|
158
155
|
requirements: []
|
159
|
-
rubygems_version: 3.3.
|
156
|
+
rubygems_version: 3.3.22
|
160
157
|
signing_key:
|
161
158
|
specification_version: 4
|
162
159
|
summary: Simplistic UI State Management for Rails Apps using Hotwire and Caching
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Solder
|
2
|
-
class UiStateController < ApplicationController
|
3
|
-
before_action :set_ui_state
|
4
|
-
|
5
|
-
def show
|
6
|
-
render json: @ui_state.value
|
7
|
-
end
|
8
|
-
|
9
|
-
def update
|
10
|
-
@ui_state.value = JSON.parse(params[:attributes])
|
11
|
-
|
12
|
-
head :ok
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def ui_state_params
|
18
|
-
params.permit(:attributes, :key)
|
19
|
-
end
|
20
|
-
|
21
|
-
def set_ui_state
|
22
|
-
@ui_state = Kredis.json params[:key]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Solder
|
2
|
-
module ApplicationHelper
|
3
|
-
def solder_onto(name, touch: [], attribute_safelist: ["class"], &block)
|
4
|
-
soldered_html = capture(&block).to_s.strip
|
5
|
-
fragment = Nokogiri::HTML.fragment(soldered_html)
|
6
|
-
|
7
|
-
first_fragment_child = fragment.first_element_child
|
8
|
-
|
9
|
-
# rehydrate
|
10
|
-
ui_state = Rails.cache.read "solder/#{solder_key(name)}"
|
11
|
-
|
12
|
-
ui_state&.select { attribute_safelist.include?(_1) }&.each do |attribute_name, value|
|
13
|
-
first_fragment_child[attribute_name] = sanitize value
|
14
|
-
end
|
15
|
-
|
16
|
-
# add stimulus controller and create unique key
|
17
|
-
first_fragment_child["data-controller"] = "#{first_fragment_child["data-controller"]} solder".strip
|
18
|
-
first_fragment_child["data-solder-key-value"] = solder_key(name)
|
19
|
-
|
20
|
-
first_fragment_child["data-solder-touch"] ||= Array(touch).map(&:to_sgid).map(&:to_s).join(":")
|
21
|
-
|
22
|
-
first_fragment_child.to_html.html_safe
|
23
|
-
end
|
24
|
-
|
25
|
-
def solder_key(name)
|
26
|
-
key = cache_fragment_name(name, skip_digest: true)
|
27
|
-
.flatten
|
28
|
-
.compact
|
29
|
-
.map(&:cache_key)
|
30
|
-
.join(":")
|
31
|
-
|
32
|
-
key += ":#{caller.find { _1 =~ /html/ }}"
|
33
|
-
|
34
|
-
ActiveSupport::Digest.hexdigest(key)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/config/routes.rb~
DELETED