reactive-actions 0.1.0.pre.alpha.1
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 +7 -0
- data/MIT-LICENSE +21 -0
- data/README.md +714 -0
- data/Rakefile +15 -0
- data/app/assets/javascripts/reactive_actions.js +100 -0
- data/app/controllers/reactive_actions/application_controller.rb +10 -0
- data/app/controllers/reactive_actions/reactive_actions_controller.rb +183 -0
- data/config/initializers/reactive_actions_logger.rb +4 -0
- data/config/routes.rb +5 -0
- data/lib/generators/reactive_actions/install/install_generator.rb +261 -0
- data/lib/generators/reactive_actions/install/templates/README +32 -0
- data/lib/generators/reactive_actions/install/templates/example_action.rb +26 -0
- data/lib/generators/reactive_actions/install/templates/initializer.rb +13 -0
- data/lib/reactive-actions.rb +3 -0
- data/lib/reactive_actions/configuration.rb +33 -0
- data/lib/reactive_actions/engine.rb +64 -0
- data/lib/reactive_actions/errors.rb +24 -0
- data/lib/reactive_actions/reactive_action.rb +67 -0
- data/lib/reactive_actions/version.rb +5 -0
- data/lib/reactive_actions.rb +19 -0
- metadata +93 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# ReactiveActions module provides functionality for creating and executing reactive actions in Rails applications
|
4
|
+
module ReactiveActions
|
5
|
+
# Configuration class for ReactiveActions
|
6
|
+
# Manages settings for controller method delegation and instance variable delegation
|
7
|
+
class Configuration
|
8
|
+
attr_accessor :delegated_controller_methods, :delegated_instance_variables
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
# Default methods to delegate
|
12
|
+
@delegated_controller_methods = %i[
|
13
|
+
render redirect_to head params
|
14
|
+
session cookies flash request response
|
15
|
+
]
|
16
|
+
|
17
|
+
# Default instance variables to delegate
|
18
|
+
@delegated_instance_variables = []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_writer :configuration
|
24
|
+
|
25
|
+
def configuration
|
26
|
+
@configuration ||= Configuration.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def configure
|
30
|
+
yield(configuration)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'reactive_actions'
|
4
|
+
|
5
|
+
module ReactiveActions
|
6
|
+
# Rails engine for the ReactiveActions gem
|
7
|
+
# Handles asset inclusion, autoloading, and namespace management
|
8
|
+
class Engine < ::Rails::Engine
|
9
|
+
isolate_namespace ReactiveActions
|
10
|
+
|
11
|
+
config.generators do |g|
|
12
|
+
g.test_framework :rspec
|
13
|
+
g.fixture_replacement :factory_bot
|
14
|
+
g.factory_bot dir: 'spec/factories'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Tell Zeitwerk to ignore the bridge file specifically
|
18
|
+
initializer 'reactive_actions.zeitwerk_ignore' do
|
19
|
+
Rails.autoloaders.main.ignore("#{root}/lib/reactive-actions.rb")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Configure assets for both Sprockets and Propshaft compatibility
|
23
|
+
initializer 'reactive_actions.assets' do |app|
|
24
|
+
# Add the JavaScript file to asset paths for Propshaft
|
25
|
+
app.config.assets.paths << root.join('app/assets/javascripts') if defined?(Propshaft)
|
26
|
+
|
27
|
+
# For Sprockets compatibility (if still being used)
|
28
|
+
app.config.assets.precompile += %w[reactive_actions.js] if defined?(Sprockets)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Load and namespace action classes properly
|
32
|
+
initializer 'reactive_actions.load_actions', after: :load_config_initializers do |app|
|
33
|
+
actions_path = "#{app.root}/app/reactive_actions"
|
34
|
+
next unless Dir.exist?(actions_path)
|
35
|
+
|
36
|
+
# Find all action files
|
37
|
+
Dir.glob("#{actions_path}/**/*_action.rb").each do |file_path|
|
38
|
+
# Get relative path and class name
|
39
|
+
file_path.sub("#{actions_path}/", '')
|
40
|
+
class_name = File.basename(file_path, '.rb').camelize
|
41
|
+
|
42
|
+
# Skip if already defined in ReactiveActions namespace
|
43
|
+
next if ReactiveActions.const_defined?(class_name, false)
|
44
|
+
|
45
|
+
begin
|
46
|
+
# Load the file to ensure the class is defined
|
47
|
+
require_dependency file_path
|
48
|
+
|
49
|
+
# Try to find the class in global namespace
|
50
|
+
if Object.const_defined?(class_name, false)
|
51
|
+
original_class = Object.const_get(class_name)
|
52
|
+
|
53
|
+
# Create an alias in the ReactiveActions namespace
|
54
|
+
ReactiveActions.const_set(class_name, original_class)
|
55
|
+
|
56
|
+
Rails.logger.debug { "ReactiveActions: Aliased #{class_name} to ReactiveActions::#{class_name}" }
|
57
|
+
end
|
58
|
+
rescue StandardError => e
|
59
|
+
Rails.logger.warn "ReactiveActions: Failed to load action #{file_path}: #{e.message}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ReactiveActions
|
4
|
+
# Base error class for all ReactiveActions errors
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
# Raised when an action is not found
|
8
|
+
class ActionNotFoundError < Error; end
|
9
|
+
|
10
|
+
# Raised when an action fails to execute properly
|
11
|
+
class ActionExecutionError < Error; end
|
12
|
+
|
13
|
+
# Raised when parameters are invalid
|
14
|
+
class InvalidParametersError < Error; end
|
15
|
+
|
16
|
+
# Raised when a required parameter is missing
|
17
|
+
class MissingParameterError < InvalidParametersError; end
|
18
|
+
|
19
|
+
# Raised when a parameter has an invalid type or format
|
20
|
+
class ParameterTypeError < InvalidParametersError; end
|
21
|
+
|
22
|
+
# Raised when the user is not authorized to perform the action
|
23
|
+
class UnauthorizedError < Error; end
|
24
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ReactiveActions
|
4
|
+
# Base class for reactive actions
|
5
|
+
# Provides common functionality for executing actions and handling responses
|
6
|
+
class ReactiveAction
|
7
|
+
attr_reader :action_params, :result, :controller
|
8
|
+
|
9
|
+
# Initialize a new reactive action
|
10
|
+
#
|
11
|
+
# @param [ActionController::Base] controller The controller instance
|
12
|
+
# @param [Hash] action_params Parameters to be used in the action
|
13
|
+
def initialize(controller = nil, **action_params)
|
14
|
+
@controller = controller
|
15
|
+
@action_params = action_params
|
16
|
+
|
17
|
+
# Delegate instance variables from controller to actions class
|
18
|
+
ReactiveActions.configuration.delegated_instance_variables.each do |instance_variable|
|
19
|
+
instance_variable_set("@#{instance_variable}", controller.instance_variable_get("@#{instance_variable}"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Execute the action and handle the response through the controller
|
24
|
+
def run
|
25
|
+
ReactiveActions.logger.info "Running action #{self.class.name} with params: #{action_params.inspect}"
|
26
|
+
|
27
|
+
begin
|
28
|
+
# Run the action
|
29
|
+
controller.instance_exec(&method(:action))
|
30
|
+
# Run the response
|
31
|
+
controller.instance_exec(&method(:response))
|
32
|
+
rescue ReactiveActions::Error => e
|
33
|
+
# Let ReactiveActions errors bubble up without modification
|
34
|
+
raise e
|
35
|
+
rescue StandardError => e
|
36
|
+
# Modify all other errors
|
37
|
+
ReactiveActions.logger.error "Error in action #{self.class.name}: #{e.message}"
|
38
|
+
raise ReactiveActions::ActionExecutionError, "Error executing #{self.class.name}: #{e.message}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# The action to be implemented by subclasses
|
43
|
+
def action
|
44
|
+
raise NotImplementedError, "#{self.class.name} must implement the 'action' method"
|
45
|
+
end
|
46
|
+
|
47
|
+
# The response to be implemented by subclasses
|
48
|
+
def response
|
49
|
+
controller.head :ok
|
50
|
+
end
|
51
|
+
|
52
|
+
# Make class methods private
|
53
|
+
class << self
|
54
|
+
# This hook runs when ReactiveAction is subclassed
|
55
|
+
def inherited(subclass)
|
56
|
+
# Call super
|
57
|
+
super
|
58
|
+
# Apply controller method delegations from configuration
|
59
|
+
ReactiveActions.configuration.delegated_controller_methods.each do |method_name|
|
60
|
+
subclass.delegate method_name, to: :controller, allow_nil: true if ActionController::Base.instance_methods.include?(method_name.to_sym)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private :inherited
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'reactive_actions/version'
|
4
|
+
require 'reactive_actions/configuration'
|
5
|
+
require 'reactive_actions/engine'
|
6
|
+
require 'reactive_actions/reactive_action'
|
7
|
+
require 'reactive_actions/errors'
|
8
|
+
|
9
|
+
# Main namespace for the ReactiveActions gem
|
10
|
+
# Provides functionality for creating and executing reactive actions in Rails applications
|
11
|
+
module ReactiveActions
|
12
|
+
class << self
|
13
|
+
attr_writer :logger
|
14
|
+
|
15
|
+
def logger
|
16
|
+
@logger ||= Rails.logger
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reactive-actions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre.alpha.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Istvan Meszaros
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-05-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '7.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '9.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '7.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '9.0'
|
33
|
+
description: A modern framework for creating HTTP API endpoints that execute server-side
|
34
|
+
actions in Rails applications with automatic JavaScript client integration.
|
35
|
+
email:
|
36
|
+
- meszarosistvan97@gmail.com
|
37
|
+
executables: []
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- MIT-LICENSE
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- app/assets/javascripts/reactive_actions.js
|
45
|
+
- app/controllers/reactive_actions/application_controller.rb
|
46
|
+
- app/controllers/reactive_actions/reactive_actions_controller.rb
|
47
|
+
- config/initializers/reactive_actions_logger.rb
|
48
|
+
- config/routes.rb
|
49
|
+
- lib/generators/reactive_actions/install/install_generator.rb
|
50
|
+
- lib/generators/reactive_actions/install/templates/README
|
51
|
+
- lib/generators/reactive_actions/install/templates/example_action.rb
|
52
|
+
- lib/generators/reactive_actions/install/templates/initializer.rb
|
53
|
+
- lib/reactive-actions.rb
|
54
|
+
- lib/reactive_actions.rb
|
55
|
+
- lib/reactive_actions/configuration.rb
|
56
|
+
- lib/reactive_actions/engine.rb
|
57
|
+
- lib/reactive_actions/errors.rb
|
58
|
+
- lib/reactive_actions/reactive_action.rb
|
59
|
+
- lib/reactive_actions/version.rb
|
60
|
+
homepage: https://github.com/IstvanMs/reactive-actions
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata:
|
64
|
+
homepage_uri: https://github.com/IstvanMs/reactive-actions
|
65
|
+
source_code_uri: https://github.com/IstvanMs/reactive-actions
|
66
|
+
changelog_uri: https://github.com/IstvanMs/reactive-actions/blob/main/CHANGELOG.md
|
67
|
+
rubygems_mfa_required: 'true'
|
68
|
+
post_install_message: |2
|
69
|
+
Thank you for installing ReactiveActions!
|
70
|
+
|
71
|
+
To complete the setup, please run:
|
72
|
+
rails generate reactive_actions:install
|
73
|
+
|
74
|
+
This will add the necessary routes to your application.
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.0.0
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 1.3.1
|
88
|
+
requirements: []
|
89
|
+
rubygems_version: 3.4.19
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: ReactiveActions for Rails applications
|
93
|
+
test_files: []
|