tailmix 0.4.7 → 0.4.8

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +46 -205
  4. data/app/javascript/tailmix/runtime/action_dispatcher.js +132 -0
  5. data/app/javascript/tailmix/runtime/component.js +130 -0
  6. data/app/javascript/tailmix/runtime/index.js +130 -0
  7. data/app/javascript/tailmix/runtime/plugins.js +35 -0
  8. data/app/javascript/tailmix/runtime/updater.js +140 -0
  9. data/docs/01_getting_started.md +0 -81
  10. data/examples/_modal_component.arb +17 -25
  11. data/examples/modal_component.rb +31 -155
  12. data/lib/tailmix/definition/builders/action_builder.rb +39 -0
  13. data/lib/tailmix/definition/{contexts → builders}/actions/element_builder.rb +1 -1
  14. data/lib/tailmix/definition/{contexts → builders}/attribute_builder.rb +1 -1
  15. data/lib/tailmix/definition/builders/component_builder.rb +81 -0
  16. data/lib/tailmix/definition/{contexts → builders}/dimension_builder.rb +2 -2
  17. data/lib/tailmix/definition/builders/element_builder.rb +83 -0
  18. data/lib/tailmix/definition/builders/reactor_builder.rb +43 -0
  19. data/lib/tailmix/definition/builders/rule_builder.rb +58 -0
  20. data/lib/tailmix/definition/builders/state_builder.rb +21 -0
  21. data/lib/tailmix/definition/{contexts → builders}/variant_builder.rb +17 -2
  22. data/lib/tailmix/definition/context_builder.rb +17 -12
  23. data/lib/tailmix/definition/payload_proxy.rb +16 -0
  24. data/lib/tailmix/definition/result.rb +17 -19
  25. data/lib/tailmix/dev/docs.rb +3 -9
  26. data/lib/tailmix/dev/tools.rb +0 -5
  27. data/lib/tailmix/dsl.rb +3 -5
  28. data/lib/tailmix/engine.rb +11 -1
  29. data/lib/tailmix/html/attributes.rb +22 -12
  30. data/lib/tailmix/middleware/registry_cleaner.rb +17 -0
  31. data/lib/tailmix/registry.rb +37 -0
  32. data/lib/tailmix/runtime/action_proxy.rb +29 -0
  33. data/lib/tailmix/runtime/attribute_builder.rb +102 -0
  34. data/lib/tailmix/runtime/attribute_cache.rb +23 -0
  35. data/lib/tailmix/runtime/context.rb +51 -62
  36. data/lib/tailmix/runtime/facade_builder.rb +8 -5
  37. data/lib/tailmix/runtime/state.rb +36 -0
  38. data/lib/tailmix/runtime/state_proxy.rb +34 -0
  39. data/lib/tailmix/runtime.rb +0 -1
  40. data/lib/tailmix/version.rb +1 -1
  41. data/lib/tailmix/view_helpers.rb +49 -0
  42. data/lib/tailmix.rb +4 -2
  43. metadata +26 -20
  44. data/app/javascript/tailmix/finder.js +0 -15
  45. data/app/javascript/tailmix/index.js +0 -7
  46. data/app/javascript/tailmix/mutator.js +0 -28
  47. data/app/javascript/tailmix/runner.js +0 -7
  48. data/app/javascript/tailmix/stimulus_adapter.js +0 -37
  49. data/docs/02_dsl_reference.md +0 -266
  50. data/docs/03_advanced_usage.md +0 -88
  51. data/docs/04_client_side_bridge.md +0 -119
  52. data/docs/05_cookbook.md +0 -249
  53. data/lib/tailmix/definition/contexts/action_builder.rb +0 -31
  54. data/lib/tailmix/definition/contexts/element_builder.rb +0 -55
  55. data/lib/tailmix/definition/contexts/stimulus_builder.rb +0 -101
  56. data/lib/tailmix/dev/stimulus_generator.rb +0 -124
  57. data/lib/tailmix/runtime/stimulus/compiler.rb +0 -59
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ require_relative "../payload_proxy"
3
+
4
+ module Tailmix
5
+ module Definition
6
+ module Builders
7
+ class ActionBuilder
8
+ def initialize
9
+ @transitions = []
10
+ end
11
+
12
+ def set(state_key, value)
13
+ processed_value = if value.is_a?(PayloadValue)
14
+ { __type: 'payload_value', key: value.key }
15
+ else
16
+ value
17
+ end
18
+ @transitions << { type: :set, payload: { key: state_key.to_sym, value: processed_value } }
19
+ end
20
+
21
+ def toggle(state_key)
22
+ @transitions << { type: :toggle, payload: { key: state_key.to_sym } }
23
+ end
24
+
25
+ def refresh(state_key, params: {})
26
+ @transitions << { type: :refresh, payload: { key: state_key.to_sym, params: params } }
27
+ end
28
+
29
+ def dispatch(event_name, detail: {})
30
+ @transitions << { type: :dispatch, payload: { name: event_name, detail: detail } }
31
+ end
32
+
33
+ def build_definition
34
+ Result::Action.new(transitions: @transitions.freeze)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Tailmix
4
4
  module Definition
5
- module Contexts
5
+ module Builders
6
6
  module Actions
7
7
  class ElementBuilder
8
8
  def initialize(default_method)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Tailmix
4
4
  module Definition
5
- module Contexts
5
+ module Builders
6
6
  class AttributeBuilder
7
7
  def initialize
8
8
  @classes = []
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "action_builder"
4
+ require_relative "element_builder"
5
+ require_relative "reactor_builder"
6
+ require_relative "../payload_proxy"
7
+
8
+ module Tailmix
9
+ module Definition
10
+ module Builders
11
+ class ComponentBuilder
12
+ attr_reader :component_name
13
+
14
+ def initialize(component_name:)
15
+ @states = {}
16
+ @actions = {}
17
+ @elements = {}
18
+ @component_name = component_name
19
+ @plugins = {}
20
+ @reactions = {}
21
+ end
22
+
23
+ def state(name, default: nil, endpoint: nil, toggle: false)
24
+ @states[name.to_sym] = { default: default, endpoint: endpoint }.compact
25
+ if toggle
26
+ action_name = :"toggle_#{name}"
27
+ action(action_name) { toggle name }
28
+ end
29
+ end
30
+
31
+ def action(name, &block)
32
+ builder = ActionBuilder.new
33
+ builder.instance_exec(PayloadProxy.new, &block)
34
+ @actions[name.to_sym] = builder
35
+ end
36
+
37
+ def element(name, classes = "", &block)
38
+ builder = ElementBuilder.new(name)
39
+ builder.attributes.classes(classes.split)
40
+ builder.instance_eval(&block) if block
41
+ @elements[name.to_sym] = builder
42
+ end
43
+
44
+ def plugin(name, options = {})
45
+ plugin_name = name.to_s.gsub(/_([a-z])/) { $1.upcase }
46
+ @plugins[plugin_name] = options
47
+ end
48
+
49
+ def react(on:, run: nil, **options, &block)
50
+ watched_states = Array(on)
51
+
52
+ # Processing the short form: `react on: :query, run: :search`
53
+ if run
54
+ builder = ReactorBuilder.new(watched_states.first)
55
+ builder.run(run, **options)
56
+ watched_states.each { |state| (@reactions[state] ||= []).concat(builder.build_rules) }
57
+ return
58
+ end
59
+
60
+ # Processing the full form with the block.
61
+ if block
62
+ builder = ReactorBuilder.new(watched_states.first)
63
+ builder.instance_eval(&block) # `instance_eval` чтобы не писать `r.`
64
+ watched_states.each { |state| (@reactions[state] ||= []).concat(builder.build_rules) }
65
+ end
66
+ end
67
+
68
+ def build_definition
69
+ Result::Context.new(
70
+ name: component_name,
71
+ states: @states.freeze,
72
+ actions: @actions.transform_values(&:build_definition).freeze,
73
+ elements: @elements.transform_values(&:build_definition).freeze,
74
+ reactions: @reactions.freeze,
75
+ plugins: @plugins.freeze
76
+ )
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -4,7 +4,7 @@ require_relative "variant_builder"
4
4
 
5
5
  module Tailmix
6
6
  module Definition
7
- module Contexts
7
+ module Builders
8
8
  class DimensionBuilder
9
9
  def initialize(default: nil)
10
10
  @variants = {}
@@ -13,12 +13,12 @@ module Tailmix
13
13
 
14
14
  def variant(name, classes = "", data: {}, aria: {}, &block)
15
15
  builder = VariantBuilder.new
16
+
16
17
  builder.classes(classes) if classes && !classes.empty?
17
18
  builder.data(data)
18
19
  builder.aria(aria)
19
20
 
20
21
  builder.instance_eval(&block) if block
21
-
22
22
  @variants[name] = builder.build_variant
23
23
  end
24
24
 
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "attribute_builder"
4
+ require_relative "dimension_builder"
5
+ require_relative "variant_builder"
6
+
7
+ module Tailmix
8
+ module Definition
9
+ module Builders
10
+ class ElementBuilder
11
+ def initialize(name)
12
+ @name = name
13
+ @default_attributes = {}
14
+ @dimensions = {}
15
+ @compound_variants = []
16
+ @event_bindings = []
17
+ @attribute_bindings = {}
18
+ @model_bindings = {}
19
+ end
20
+
21
+ def attributes
22
+ @attributes_builder ||= AttributeBuilder.new
23
+ end
24
+
25
+ def method_missing(name, *args, &block)
26
+ attribute_name = name.to_s.chomp("=").to_sym
27
+ @default_attributes[attribute_name] = args.first
28
+ end
29
+
30
+ def respond_to_missing?(*_args)
31
+ true
32
+ end
33
+
34
+ def on(event_name, action_name, with: nil, **options)
35
+ # `with` mapping: `{ payload_key => state_key }`
36
+ @event_bindings << { event: event_name, action: action_name, with: with, options: options }
37
+ end
38
+
39
+ def bind(attribute_name, to:)
40
+ @attribute_bindings[attribute_name.to_sym] = to.to_sym
41
+ end
42
+
43
+ def model(attribute_name, to:, on: :input, action: nil, debounce: nil)
44
+ @model_bindings[attribute_name.to_sym] = {
45
+ state: to.to_sym,
46
+ event: on,
47
+ action: action,
48
+ debounce: debounce
49
+ }.compact
50
+ end
51
+
52
+ def dimension(name, &block)
53
+ builder = DimensionBuilder.new
54
+ builder.instance_eval(&block)
55
+ @dimensions[name.to_sym] = builder.build_dimension
56
+ end
57
+
58
+ def compound_variant(on:, &block)
59
+ builder = VariantBuilder.new
60
+ builder.instance_eval(&block)
61
+
62
+ @compound_variants << {
63
+ on: on,
64
+ modifications: builder.build_variant
65
+ }
66
+ end
67
+
68
+ def build_definition
69
+ Result::Element.new(
70
+ name: @name,
71
+ attributes: attributes.build_definition,
72
+ default_attributes: @default_attributes.freeze,
73
+ dimensions: @dimensions.freeze,
74
+ compound_variants: @compound_variants.freeze,
75
+ event_bindings: @event_bindings.freeze,
76
+ attribute_bindings: @attribute_bindings.freeze,
77
+ model_bindings: @model_bindings.freeze
78
+ )
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ require_relative "rule_builder"
3
+
4
+ module Tailmix
5
+ module Definition
6
+ module Builders
7
+ class ReactorBuilder
8
+ def initialize(watched_state)
9
+ @watched_state = watched_state
10
+ @rules = []
11
+ end
12
+
13
+ # Start a method for the rule chain: r.value("commercial")
14
+ def value(expected_value)
15
+ rule_builder = RuleBuilder.new(@watched_state)
16
+ rule_builder.value(expected_value)
17
+ @rules << rule_builder
18
+ rule_builder
19
+ end
20
+
21
+ # Alternative startup method: r.state(:zip_code)
22
+ def state(state_key)
23
+ rule_builder = RuleBuilder.new(state_key)
24
+ @rules << rule_builder
25
+ rule_builder
26
+ end
27
+
28
+ # Unconditional effect (always triggers on change)
29
+ def run(action_name, with: nil)
30
+ # We create an "empty" rule with a condition that is always true.
31
+ rule_builder = RuleBuilder.new(nil)
32
+ rule_builder.instance_variable_set(:@rule, { condition: { type: :always_true } })
33
+ rule_builder.run(action_name, with: with)
34
+ @rules << rule_builder
35
+ end
36
+
37
+ def build_rules
38
+ @rules.map(&:build_rule)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailmix
4
+ module Definition
5
+ module Builders
6
+ class RuleBuilder
7
+ def initialize(source_state_key)
8
+ @rule = { condition: { type: :eql, source: { type: :state, key: source_state_key } } }
9
+ end
10
+
11
+ def value(expected_value)
12
+ @rule[:condition][:value] = expected_value
13
+ self
14
+ end
15
+ alias_method :is, :value
16
+
17
+ def is_not(expected_value)
18
+ @rule[:condition][:type] = :not_eql
19
+ @rule[:condition][:value] = expected_value
20
+ self
21
+ end
22
+
23
+ def is_truthy
24
+ @rule[:condition][:type] = :truthy
25
+ self
26
+ end
27
+
28
+ def set_state(payload)
29
+ add_effect(:set_state, payload: payload)
30
+ end
31
+
32
+ def run(action_name, with: nil)
33
+ add_effect(:run_action, name: action_name, with: with)
34
+ end
35
+
36
+ def dispatch(event_name, detail: {})
37
+ add_effect(:dispatch_event, name: event_name, detail: detail)
38
+ end
39
+
40
+ def call(element_name, method_name, *args)
41
+ add_effect(:call_method, element: element_name, method: method_name, args: args)
42
+ end
43
+
44
+ def build_rule
45
+ @rule
46
+ end
47
+
48
+ private
49
+
50
+ def add_effect(type, **payload)
51
+ @rule[:effects] ||= []
52
+ @rule[:effects] << { type: type, payload: payload }
53
+ self
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailmix
4
+ module Definition
5
+ module Builders
6
+ class StateBuilder
7
+ def initialize
8
+ @data_source = {}
9
+ end
10
+
11
+ def endpoint(method, url:)
12
+ @data_source = { method: method, url: url }
13
+ end
14
+
15
+ def build_data_source
16
+ @data_source.empty? ? nil : @data_source.freeze
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,12 +2,13 @@
2
2
 
3
3
  module Tailmix
4
4
  module Definition
5
- module Contexts
5
+ module Builders
6
6
  class VariantBuilder
7
7
  def initialize
8
8
  @class_groups = []
9
9
  @data = {}
10
10
  @aria = {}
11
+ @attributes = {}
11
12
  end
12
13
 
13
14
  def classes(class_string, options = {})
@@ -22,11 +23,25 @@ module Tailmix
22
23
  @aria.merge!(hash)
23
24
  end
24
25
 
26
+ def method_missing(name, *args, &block)
27
+ # `disabled true` -> { disabled: true }
28
+ # `placeholder "text"` -> { placeholder: "text" }
29
+ # `type "password"` -> { type: "password" }
30
+ attribute_name = name.to_s.chomp("=").to_sym
31
+ value = args.first
32
+ @attributes[attribute_name] = value
33
+ end
34
+
35
+ def respond_to_missing?(*_args)
36
+ true
37
+ end
38
+
25
39
  def build_variant
26
40
  Definition::Result::Variant.new(
27
41
  class_groups: @class_groups.freeze,
28
42
  data: @data.freeze,
29
- aria: @aria.freeze
43
+ aria: @aria.freeze,
44
+ attributes: @attributes.freeze
30
45
  )
31
46
  end
32
47
  end
@@ -1,36 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "contexts/action_builder"
4
- require_relative "contexts/element_builder"
5
- require_relative "contexts/variant_builder"
3
+ require_relative "builders/action_builder"
4
+ require_relative "builders/element_builder"
5
+ require_relative "builders/variant_builder"
6
+ require_relative "payload_proxy"
6
7
 
7
8
  module Tailmix
8
9
  module Definition
9
10
  class ContextBuilder
10
- attr_reader :elements, :actions
11
+ attr_reader :elements, :actions, :component_name
11
12
 
12
- def initialize
13
+ def initialize(component_name:)
13
14
  @elements = {}
14
15
  @actions = {}
16
+ @component_name = component_name
15
17
  end
16
18
 
17
- def element(name, base_classes = "", &block)
18
- builder = Contexts::ElementBuilder.new(name)
19
- builder.attributes.classes(base_classes.split)
19
+ def element(name, classes = "", &block)
20
+ builder = Builders::ElementBuilder.new(name)
21
+ builder.attributes.classes(classes.split)
20
22
 
21
23
  builder.instance_eval(&block) if block
22
-
23
24
  @elements[name.to_sym] = builder
25
+
26
+ @actions.merge!(builder.auto_actions)
24
27
  end
25
28
 
26
- def action(name, method:, &block)
27
- builder = Contexts::ActionBuilder.new(method)
28
- builder.instance_eval(&block) if block
29
+ def action(name, &block)
30
+ builder = Builders::ActionBuilder.new
31
+ proxy = Builders::PayloadProxy.new
32
+ builder.instance_exec(proxy, &block)
29
33
  @actions[name.to_sym] = builder
30
34
  end
31
35
 
32
36
  def build_definition
33
37
  Definition::Result::Context.new(
38
+ name: component_name,
34
39
  elements: @elements.transform_values(&:build_definition).freeze,
35
40
  actions: @actions.transform_values(&:build_definition).freeze,
36
41
  )
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tailmix
4
+ module Definition
5
+ # A marker indicating that the value should be taken from the runtime payload.
6
+ PayloadValue = Struct.new(:key)
7
+
8
+ # A proxy object that is passed to the `action do |payload|` block.
9
+ # It creates PayloadValue markers instead of containing the actual data.
10
+ class PayloadProxy
11
+ def [](key)
12
+ PayloadValue.new(key.to_sym)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -3,20 +3,25 @@
3
3
  module Tailmix
4
4
  module Definition
5
5
  module Result
6
- Context = Struct.new(:elements, :actions, keyword_init: true) do
6
+ Context = Struct.new(:name, :states, :actions, :elements, :plugins, :reactions, keyword_init: true) do
7
7
  def to_h
8
8
  {
9
- elements: elements.transform_values(&:to_h),
9
+ name: name,
10
+ states: states,
10
11
  actions: actions.transform_values(&:to_h),
12
+ elements: elements.transform_values(&:to_h),
13
+ plugins: plugins,
14
+ reactions: reactions
11
15
  }
12
16
  end
13
17
  end
14
18
 
15
- Element = Struct.new(:name, :attributes, :dimensions, :stimulus, :compound_variants, keyword_init: true) do
19
+ Element = Struct.new(:name, :attributes, :dimensions, :compound_variants, :event_bindings, :attribute_bindings, :model_bindings, :default_attributes, keyword_init: true) do
16
20
  def to_h
17
21
  {
18
22
  name: name,
19
23
  attributes: attributes.to_h,
24
+ default_attributes: default_attributes,
20
25
  dimensions: dimensions.transform_values do |dimension|
21
26
  dimension.transform_values do |value|
22
27
  case value
@@ -29,13 +34,14 @@ module Tailmix
29
34
  end
30
35
  end
31
36
  end,
32
- stimulus: stimulus.to_h,
33
- compound_variants: compound_variants
37
+ compound_variants: compound_variants,
38
+ attribute_bindings: attribute_bindings,
39
+ model_bindings: model_bindings,
34
40
  }
35
41
  end
36
42
  end
37
43
 
38
- Variant = Struct.new(:class_groups, :data, :aria, keyword_init: true) do
44
+ Variant = Struct.new(:class_groups, :data, :aria, :attributes, keyword_init: true) do
39
45
  def classes
40
46
  class_groups.flat_map { |group| group[:classes] }
41
47
  end
@@ -45,7 +51,8 @@ module Tailmix
45
51
  classes: classes,
46
52
  class_groups: class_groups,
47
53
  data: data,
48
- aria: aria
54
+ aria: aria,
55
+ attributes: attributes
49
56
  }
50
57
  end
51
58
  end
@@ -58,22 +65,13 @@ module Tailmix
58
65
  end
59
66
  end
60
67
 
61
- Stimulus = Struct.new(:definitions, keyword_init: true) do
62
- def to_h
63
- {
64
- definitions: definitions
65
- }
66
- end
67
- end
68
-
69
- Action = Struct.new(:action, :mutations, keyword_init: true) do
68
+ Action = Struct.new(:transitions, keyword_init: true) do
70
69
  def to_h
71
70
  {
72
- action: action,
73
- mutations: mutations
71
+ transitions: transitions,
74
72
  }
75
73
  end
76
74
  end
77
75
  end
78
76
  end
79
- end
77
+ end
@@ -18,12 +18,8 @@ module Tailmix
18
18
  output << ""
19
19
 
20
20
  output << generate_dimensions_docs
21
- output << ""
22
- output << generate_compound_variants_docs # <-- Наш новый метод
23
- output << ""
21
+ output << generate_compound_variants_docs
24
22
  output << generate_actions_docs
25
- output << ""
26
- output << generate_stimulus_docs
27
23
 
28
24
  output.join("\n")
29
25
  end
@@ -70,6 +66,7 @@ module Tailmix
70
66
  end
71
67
 
72
68
  if compound_variants_by_element.any?
69
+ output << ""
73
70
  output << "Compound Variants:"
74
71
  compound_variants_by_element.each do |element|
75
72
  output << " - on element `:#{element.name}`:"
@@ -86,6 +83,7 @@ module Tailmix
86
83
  output << " - aria: #{modifications.aria.inspect}" if modifications.aria.any?
87
84
  end
88
85
  end
86
+ output << ""
89
87
  end
90
88
 
91
89
  output.join("\n")
@@ -107,10 +105,6 @@ module Tailmix
107
105
  output.join("\n")
108
106
  end
109
107
 
110
- def generate_stimulus_docs
111
- @tools.stimulus.scaffold(show_docs: true)
112
- end
113
-
114
108
  def all_dimensions
115
109
  @_all_dimensions ||= @definition.elements.values.flat_map(&:dimensions).reduce({}, :merge)
116
110
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "stimulus_generator"
4
3
  require_relative "docs"
5
4
 
6
5
  module Tailmix
@@ -18,10 +17,6 @@ module Tailmix
18
17
  end
19
18
  alias_method :help, :docs
20
19
 
21
- def stimulus
22
- StimulusGenerator.new(@definition, @component_class.name)
23
- end
24
-
25
20
  def elements
26
21
  @definition.elements.values.map(&:name)
27
22
  end
data/lib/tailmix/dsl.rb CHANGED
@@ -1,15 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "definition/context_builder"
3
+ require_relative "definition/builders/component_builder"
4
4
  require_relative "definition/merger"
5
5
  require_relative "dev/tools"
6
6
 
7
7
  module Tailmix
8
- # The main DSL for defining component styles and behaviors.
9
- # This module is extended into any class that includes Tailmix.
10
8
  module DSL
11
9
  def tailmix(&block)
12
- child_context = Definition::ContextBuilder.new
10
+ child_context = Definition::Builders::ComponentBuilder.new(component_name: self)
13
11
  child_context.instance_eval(&block)
14
12
  child_definition = child_context.build_definition
15
13
 
@@ -32,4 +30,4 @@ module Tailmix
32
30
  Dev::Tools.new(self)
33
31
  end
34
32
  end
35
- end
33
+ end
@@ -6,12 +6,22 @@ module Tailmix
6
6
  Rails.application.config.assets.paths << Engine.root.join("app/javascript")
7
7
  end
8
8
 
9
- PRECOMPILE_ASSETS = %w[ index.js runner.js finder.js mutator.js stimulus_adapter.js ]
9
+ PRECOMPILE_ASSETS = %w[ runtime/action_dispatcher.js runtime/component.js runtime/updater.js runtime/index.js runtime/plugins.js ]
10
10
 
11
11
  initializer "tailmix.assets" do
12
12
  if Rails.application.config.respond_to?(:assets)
13
13
  Rails.application.config.assets.precompile += PRECOMPILE_ASSETS
14
14
  end
15
15
  end
16
+
17
+ initializer "tailmix.add_middleware" do |app|
18
+ app.middleware.use Tailmix::Middleware::RegistryCleaner
19
+ end
20
+
21
+ initializer "tailmix.helpers" do
22
+ ActiveSupport.on_load(:action_controller_base) do
23
+ helper Tailmix::ViewHelpers
24
+ end
25
+ end
16
26
  end
17
27
  end