stimulus_reflex 3.5.0.rc3 → 3.5.3
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.lock +144 -101
- data/README.md +2 -2
- data/app/assets/javascripts/stimulus_reflex.js +15 -13
- data/app/assets/javascripts/stimulus_reflex.umd.js +15 -12
- data/app/channels/stimulus_reflex/channel.rb +49 -53
- data/lib/generators/stimulus_reflex/stimulus_reflex_generator.rb +2 -2
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/cable_ready.js.tt +1 -1
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/index.js.tt +1 -1
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/stimulus_reflex.js.tt +1 -1
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/%file_name%_controller.js.tt +1 -1
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/application.js.tt +1 -1
- data/lib/install/action_cable.rb +30 -30
- data/lib/install/broadcaster.rb +11 -11
- data/lib/install/bundle.rb +9 -9
- data/lib/install/compression.rb +5 -5
- data/lib/install/config.rb +22 -22
- data/lib/install/development.rb +19 -19
- data/lib/install/esbuild.rb +28 -28
- data/lib/install/example.rb +3 -3
- data/lib/install/importmap.rb +29 -29
- data/lib/install/initializers.rb +3 -3
- data/lib/install/mrujs.rb +25 -25
- data/lib/install/npm_packages.rb +7 -7
- data/lib/install/reflexes.rb +2 -2
- data/lib/install/shakapacker.rb +23 -23
- data/lib/install/spring.rb +7 -7
- data/lib/install/updatable.rb +7 -7
- data/lib/install/vite.rb +22 -22
- data/lib/install/webpacker.rb +27 -27
- data/lib/install/yarn.rb +9 -9
- data/lib/stimulus_reflex/html/document_fragment.rb +5 -3
- data/lib/stimulus_reflex/installer.rb +305 -277
- data/lib/stimulus_reflex/reflex.rb +14 -29
- data/lib/stimulus_reflex/reflex_data.rb +17 -17
- data/lib/stimulus_reflex/reflex_factory.rb +49 -26
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/stimulus_reflex.rb +2 -0
- data/lib/tasks/stimulus_reflex/stimulus_reflex.rake +8 -8
- data/package.json +10 -10
- data/stimulus_reflex.gemspec +10 -8
- data/web-test-runner.config.mjs +14 -0
- data/yarn.lock +1278 -830
- metadata +34 -42
@@ -3,20 +3,6 @@
|
|
3
3
|
require "stimulus_reflex/cable_readiness"
|
4
4
|
require "stimulus_reflex/version_checker"
|
5
5
|
|
6
|
-
# TODO remove xpath_controller and xpath_element for v4
|
7
|
-
ClientAttributes = Struct.new(
|
8
|
-
:id,
|
9
|
-
:tab_id,
|
10
|
-
:reflex_controller,
|
11
|
-
:xpath_controller,
|
12
|
-
:xpath_element,
|
13
|
-
:permanent_attribute_name,
|
14
|
-
:version,
|
15
|
-
:npm_version,
|
16
|
-
:suppress_logging,
|
17
|
-
keyword_init: true
|
18
|
-
)
|
19
|
-
|
20
6
|
class StimulusReflex::Reflex
|
21
7
|
prepend StimulusReflex::CableReadiness
|
22
8
|
include StimulusReflex::VersionChecker
|
@@ -26,32 +12,27 @@ class StimulusReflex::Reflex
|
|
26
12
|
include CableReady::Identifiable
|
27
13
|
|
28
14
|
attr_accessor :payload, :headers
|
29
|
-
attr_reader :channel, :
|
30
|
-
|
31
|
-
alias_method :action_name, :method_name # for compatibility with controller libraries like Pundit that expect an action name
|
15
|
+
attr_reader :channel, :reflex_data, :broadcaster
|
32
16
|
|
33
17
|
delegate :connection, :stream_name, to: :channel
|
34
18
|
delegate :controller_class, :flash, :session, to: :request
|
35
19
|
delegate :broadcast, :broadcast_halt, :broadcast_forbid, :broadcast_error, to: :broadcaster
|
20
|
+
|
36
21
|
# TODO remove xpath_controller and xpath_element for v4
|
37
|
-
delegate :id, :tab_id, :reflex_controller, :xpath_controller, :xpath_element, :permanent_attribute_name, :version, :npm_version, :suppress_logging, to: :
|
22
|
+
delegate :url, :element, :selectors, :method_name, :id, :tab_id, :reflex_controller, :xpath_controller, :xpath_element, :permanent_attribute_name, :version, :npm_version, :suppress_logging, to: :reflex_data
|
23
|
+
# END TODO: remove
|
38
24
|
|
39
|
-
|
25
|
+
alias_method :action_name, :method_name # for compatibility with controller libraries like Pundit that expect an action name
|
26
|
+
alias_method :data, :reflex_data
|
27
|
+
|
28
|
+
def initialize(channel, reflex_data:)
|
40
29
|
@channel = channel
|
41
|
-
@
|
42
|
-
@element = element
|
43
|
-
@selectors = selectors
|
44
|
-
@method_name = method_name
|
45
|
-
@params = params
|
46
|
-
@client_attributes = ClientAttributes.new(client_attributes)
|
30
|
+
@reflex_data = reflex_data
|
47
31
|
@broadcaster = StimulusReflex::PageBroadcaster.new(self)
|
48
|
-
@logger = suppress_logging ? nil : StimulusReflex::Logger.new(self)
|
49
32
|
@payload = {}
|
50
33
|
@headers = {}
|
51
34
|
|
52
35
|
check_version!
|
53
|
-
|
54
|
-
self.params
|
55
36
|
end
|
56
37
|
|
57
38
|
# TODO: remove this for v4
|
@@ -61,6 +42,10 @@ class StimulusReflex::Reflex
|
|
61
42
|
end
|
62
43
|
# END TODO: remove
|
63
44
|
|
45
|
+
def logger
|
46
|
+
@logger ||= StimulusReflex::Logger.new(self) unless suppress_logging
|
47
|
+
end
|
48
|
+
|
64
49
|
def request
|
65
50
|
@request ||= begin
|
66
51
|
uri = URI.parse(url)
|
@@ -91,7 +76,7 @@ class StimulusReflex::Reflex
|
|
91
76
|
req = ActionDispatch::Request.new(env)
|
92
77
|
|
93
78
|
# fetch path params (controller, action, ...) and apply them
|
94
|
-
request_params = StimulusReflex::RequestParameters.new(params:
|
79
|
+
request_params = StimulusReflex::RequestParameters.new(params: reflex_data.params, req: req, url: url)
|
95
80
|
req = request_params.apply!
|
96
81
|
|
97
82
|
req
|
@@ -4,7 +4,7 @@ class StimulusReflex::ReflexData
|
|
4
4
|
attr_reader :data
|
5
5
|
|
6
6
|
def initialize(data)
|
7
|
-
@data = data
|
7
|
+
@data = data.deep_merge(data.deep_transform_keys { |k| k.to_s.underscore }).with_indifferent_access
|
8
8
|
end
|
9
9
|
|
10
10
|
def reflex_name
|
@@ -14,13 +14,13 @@ class StimulusReflex::ReflexData
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def selectors
|
17
|
-
selectors = (data[
|
18
|
-
selectors = data[
|
17
|
+
selectors = (data[:selectors] || []).select(&:present?)
|
18
|
+
selectors = data[:selectors] = ["body"] if selectors.blank?
|
19
19
|
selectors
|
20
20
|
end
|
21
21
|
|
22
22
|
def target
|
23
|
-
data[
|
23
|
+
data[:target].to_s
|
24
24
|
end
|
25
25
|
|
26
26
|
def method_name
|
@@ -28,11 +28,11 @@ class StimulusReflex::ReflexData
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def arguments
|
31
|
-
(data[
|
31
|
+
(data[:args] || []).map { |arg| object_with_indifferent_access arg } || []
|
32
32
|
end
|
33
33
|
|
34
34
|
def url
|
35
|
-
data[
|
35
|
+
data[:url].to_s
|
36
36
|
end
|
37
37
|
|
38
38
|
def element
|
@@ -40,15 +40,15 @@ class StimulusReflex::ReflexData
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def permanent_attribute_name
|
43
|
-
data[
|
43
|
+
data[:permanent_attribute_name]
|
44
44
|
end
|
45
45
|
|
46
46
|
def suppress_logging
|
47
|
-
data[
|
47
|
+
data[:suppress_logging]
|
48
48
|
end
|
49
49
|
|
50
50
|
def form_data
|
51
|
-
Rack::Utils.parse_nested_query(data[
|
51
|
+
Rack::Utils.parse_nested_query(data[:form_data])
|
52
52
|
end
|
53
53
|
|
54
54
|
def params
|
@@ -56,7 +56,7 @@ class StimulusReflex::ReflexData
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def form_params
|
59
|
-
form_data.deep_merge(data[
|
59
|
+
form_data.deep_merge(data[:params] || {})
|
60
60
|
end
|
61
61
|
|
62
62
|
def url_params
|
@@ -64,33 +64,33 @@ class StimulusReflex::ReflexData
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def id
|
67
|
-
data[
|
67
|
+
data[:id]
|
68
68
|
end
|
69
69
|
|
70
70
|
def tab_id
|
71
|
-
data[
|
71
|
+
data[:tab_id]
|
72
72
|
end
|
73
73
|
|
74
74
|
# TODO: remove this in v4
|
75
75
|
def xpath_controller
|
76
|
-
data[
|
76
|
+
data[:xpath_controller]
|
77
77
|
end
|
78
78
|
|
79
79
|
def xpath_element
|
80
|
-
data[
|
80
|
+
data[:xpath_element]
|
81
81
|
end
|
82
82
|
# END TODO remove
|
83
83
|
|
84
84
|
def reflex_controller
|
85
|
-
data[
|
85
|
+
data[:reflex_controller]
|
86
86
|
end
|
87
87
|
|
88
88
|
def npm_version
|
89
|
-
data[
|
89
|
+
data[:version].to_s
|
90
90
|
end
|
91
91
|
|
92
92
|
def version
|
93
|
-
|
93
|
+
npm_version.gsub("-pre", ".pre").gsub("-rc", ".rc")
|
94
94
|
end
|
95
95
|
|
96
96
|
private
|
@@ -1,36 +1,59 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class StimulusReflex::ReflexFactory
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
4
|
+
attr_reader :channel, :data
|
5
|
+
|
6
|
+
delegate :reflex_name, :method_name, to: :data
|
7
|
+
|
8
|
+
def initialize(channel, data)
|
9
|
+
@channel = channel
|
10
|
+
@data = StimulusReflex::ReflexData.new(data)
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
verify_method_name!
|
15
|
+
reflex_class.new(channel, reflex_data: data)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def verify_method_name!
|
21
|
+
return if default_reflex?
|
22
|
+
|
23
|
+
argument_error = ArgumentError.new("Reflex method '#{method_name}' is not defined on class '#{reflex_name}' or on any of its ancestors")
|
24
|
+
|
25
|
+
if reflex_method.nil?
|
26
|
+
raise argument_error
|
26
27
|
end
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
if !safe_ancestors.include?(reflex_method.owner)
|
30
|
+
raise argument_error
|
30
31
|
end
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
def reflex_class
|
35
|
+
@reflex_class ||= reflex_name.constantize.tap do |klass|
|
36
|
+
unless klass.ancestors.include?(StimulusReflex::Reflex)
|
37
|
+
raise ArgumentError.new("#{reflex_name} is not a StimulusReflex::Reflex")
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
41
|
+
|
42
|
+
def reflex_method
|
43
|
+
if reflex_class.public_instance_methods.include?(method_name.to_sym)
|
44
|
+
reflex_class.public_instance_method(method_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_reflex?
|
49
|
+
method_name == "default_reflex" && reflex_method.owner == ::StimulusReflex::Reflex
|
50
|
+
end
|
51
|
+
|
52
|
+
def safe_ancestors
|
53
|
+
# We want to include every class and module up to the `StimulusReflex::Reflex` class,
|
54
|
+
# but not the StimulusReflex::Reflex itself
|
55
|
+
reflex_class_index = reflex_class.ancestors.index(StimulusReflex::Reflex) - 1
|
56
|
+
|
57
|
+
reflex_class.ancestors.to(reflex_class_index)
|
58
|
+
end
|
36
59
|
end
|
data/lib/stimulus_reflex.rb
CHANGED
@@ -3,11 +3,13 @@
|
|
3
3
|
require "uri"
|
4
4
|
require "open-uri"
|
5
5
|
require "rack"
|
6
|
+
require "ostruct"
|
6
7
|
require "active_support/all"
|
7
8
|
require "action_dispatch"
|
8
9
|
require "action_cable"
|
9
10
|
require "action_view"
|
10
11
|
require "nokogiri"
|
12
|
+
require "nokogiri/html5/inference"
|
11
13
|
require "cable_ready"
|
12
14
|
require "stimulus_reflex/version"
|
13
15
|
require "stimulus_reflex/open_struct_fix"
|
@@ -53,8 +53,8 @@ end
|
|
53
53
|
namespace :stimulus_reflex do
|
54
54
|
desc "✨ Install StimulusReflex and CableReady ✨"
|
55
55
|
task :install do
|
56
|
-
create_dir_if_not_exists(Rails.root.join("tmp/stimulus_reflex_installer/templates"))
|
57
|
-
create_dir_if_not_exists(Rails.root.join("tmp/stimulus_reflex_installer/working"))
|
56
|
+
StimulusReflex::Installer.create_dir_if_not_exists(Rails.root.join("tmp/stimulus_reflex_installer/templates"))
|
57
|
+
StimulusReflex::Installer.create_dir_if_not_exists(Rails.root.join("tmp/stimulus_reflex_installer/working"))
|
58
58
|
|
59
59
|
install_complete = Rails.root.join("tmp/stimulus_reflex_installer/complete")
|
60
60
|
|
@@ -93,8 +93,8 @@ namespace :stimulus_reflex do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
# if there is an installation in progress, continue where we left off
|
96
|
-
if installer_entrypoint_path.exist?
|
97
|
-
entrypoint = installer_entrypoint_path.read
|
96
|
+
if StimulusReflex::Installer.installer_entrypoint_path.exist?
|
97
|
+
entrypoint = StimulusReflex::Installer.installer_entrypoint_path.read
|
98
98
|
|
99
99
|
puts "✨ Resuming \e[38;5;220mStimulusReflex\e[0m and \e[38;5;220mCableReady\e[0m installation ✨"
|
100
100
|
puts
|
@@ -118,18 +118,18 @@ namespace :stimulus_reflex do
|
|
118
118
|
entrypoint = if options.key? "entrypoint"
|
119
119
|
options["entrypoint"]
|
120
120
|
else
|
121
|
-
auto_detect_entrypoint
|
121
|
+
StimulusReflex::Installer.auto_detect_entrypoint
|
122
122
|
end
|
123
123
|
|
124
|
-
installer_entrypoint_path.write(entrypoint)
|
124
|
+
StimulusReflex::Installer.installer_entrypoint_path.write(entrypoint)
|
125
125
|
end
|
126
126
|
|
127
127
|
# verify their bundler before starting, unless they explicitly specified on CLI
|
128
128
|
if !used_bundler
|
129
|
-
used_bundler = bundler
|
129
|
+
used_bundler = StimulusReflex::Installer.bundler
|
130
130
|
end
|
131
131
|
|
132
|
-
installer_bundler_path.write(used_bundler)
|
132
|
+
StimulusReflex::Installer.installer_bundler_path.write(used_bundler)
|
133
133
|
|
134
134
|
FileUtils.touch("tmp/stimulus_reflex_installer/backups")
|
135
135
|
File.write("tmp/stimulus_reflex_installer/template_src", File.expand_path("../../generators/stimulus_reflex/templates/", __dir__))
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "stimulus_reflex",
|
3
|
-
"version": "3.5.
|
3
|
+
"version": "3.5.3",
|
4
4
|
"description": "Build reactive applications with the Rails tooling you already know and love.",
|
5
5
|
"keywords": [
|
6
6
|
"ruby",
|
@@ -57,18 +57,18 @@
|
|
57
57
|
"dependencies": {
|
58
58
|
"@hotwired/stimulus": "^3",
|
59
59
|
"@rails/actioncable": "^6 || ^7",
|
60
|
-
"cable_ready": "^5.0.
|
60
|
+
"cable_ready": "^5.0.6"
|
61
61
|
},
|
62
62
|
"devDependencies": {
|
63
|
-
"@open-wc/testing": "^
|
64
|
-
"@rollup/plugin-json": "^6.
|
65
|
-
"@rollup/plugin-node-resolve": "^15.0
|
66
|
-
"@rollup/plugin-terser": "^0.4.
|
67
|
-
"@web/dev-server-esbuild": "^0.
|
68
|
-
"@web/dev-server-rollup": "^0.
|
69
|
-
"@web/test-runner": "^0.
|
63
|
+
"@open-wc/testing": "^4.0.0",
|
64
|
+
"@rollup/plugin-json": "^6.1.0",
|
65
|
+
"@rollup/plugin-node-resolve": "^15.3.0",
|
66
|
+
"@rollup/plugin-terser": "^0.4.4",
|
67
|
+
"@web/dev-server-esbuild": "^1.0.2",
|
68
|
+
"@web/dev-server-rollup": "^0.6.4",
|
69
|
+
"@web/test-runner": "^0.19.0",
|
70
70
|
"prettier-standard": "^16.4.1",
|
71
|
-
"rollup": "^
|
71
|
+
"rollup": "^4.22.4",
|
72
72
|
"toastify-js": "^1.12.0",
|
73
73
|
"vitepress": "^1.0.0-beta.1"
|
74
74
|
}
|
data/stimulus_reflex.gemspec
CHANGED
@@ -37,24 +37,26 @@ Gem::Specification.new do |gem|
|
|
37
37
|
"[A-Z]*"
|
38
38
|
]
|
39
39
|
|
40
|
-
gem.required_ruby_version = ">=
|
40
|
+
gem.required_ruby_version = ">= 3.0.0"
|
41
41
|
|
42
|
-
rails_version =
|
43
|
-
gem.add_dependency "actioncable",
|
44
|
-
gem.add_dependency "actionpack",
|
45
|
-
gem.add_dependency "actionview",
|
46
|
-
gem.add_dependency "activesupport",
|
47
|
-
gem.add_dependency "railties",
|
42
|
+
rails_version = ">= 5.2"
|
43
|
+
gem.add_dependency "actioncable", rails_version
|
44
|
+
gem.add_dependency "actionpack", rails_version
|
45
|
+
gem.add_dependency "actionview", rails_version
|
46
|
+
gem.add_dependency "activesupport", rails_version
|
47
|
+
gem.add_dependency "railties", rails_version
|
48
48
|
|
49
49
|
gem.add_dependency "cable_ready", "~> 5.0"
|
50
50
|
gem.add_dependency "nokogiri", "~> 1.0"
|
51
51
|
gem.add_dependency "rack", ">= 2", "< 4"
|
52
52
|
gem.add_dependency "redis", ">= 4.0", "< 6.0"
|
53
|
+
gem.add_dependency "nokogiri-html5-inference", "~> 0.3"
|
53
54
|
|
54
55
|
gem.add_development_dependency "bundler", "~> 2.0"
|
55
56
|
gem.add_development_dependency "magic_frozen_string_literal", "~> 1.2"
|
56
57
|
gem.add_development_dependency "mocha", "~> 1.13"
|
57
|
-
gem.add_development_dependency "rails",
|
58
|
+
gem.add_development_dependency "rails", rails_version
|
58
59
|
gem.add_development_dependency "rake", "~> 13.0"
|
59
60
|
gem.add_development_dependency "standard", "~> 1.24"
|
61
|
+
gem.add_development_dependency "minitest", "5.18.1"
|
60
62
|
end
|
data/web-test-runner.config.mjs
CHANGED
@@ -3,8 +3,22 @@ import { fromRollup } from '@web/dev-server-rollup'
|
|
3
3
|
|
4
4
|
const json = fromRollup(rollupJson)
|
5
5
|
|
6
|
+
const filteredLogs = [
|
7
|
+
'Lit is in dev mode. Not recommended for production! See https://lit.dev/msg/dev-mode for more information.'
|
8
|
+
]
|
9
|
+
|
10
|
+
const filterBrowserLogs = (log) => {
|
11
|
+
for (const arg of log.args) {
|
12
|
+
if (typeof arg === 'string' && filteredLogs.some(l => arg.includes(l))) {
|
13
|
+
return false
|
14
|
+
}
|
15
|
+
}
|
16
|
+
return true
|
17
|
+
}
|
18
|
+
|
6
19
|
export default {
|
7
20
|
nodeResolve: true,
|
21
|
+
filterBrowserLogs,
|
8
22
|
mimeTypes: {
|
9
23
|
'**/*.json': 'js'
|
10
24
|
},
|