vident 1.0.2 → 2.0.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/CHANGELOG.md +43 -0
- data/README.md +45 -17
- data/lib/vident/caching.rb +4 -110
- data/lib/vident/capabilities/caching.rb +98 -0
- data/lib/vident/capabilities/child_element_rendering.rb +92 -0
- data/lib/vident/capabilities/class_list_building.rb +23 -0
- data/lib/vident/capabilities/declarable.rb +39 -0
- data/lib/vident/capabilities/identifiable.rb +54 -0
- data/lib/vident/capabilities/inspectable.rb +17 -0
- data/lib/vident/capabilities/root_element_rendering.rb +31 -0
- data/lib/vident/capabilities/stimulus_data_emitting.rb +98 -0
- data/lib/vident/capabilities/stimulus_declaring.rb +79 -0
- data/lib/vident/capabilities/stimulus_draft.rb +51 -0
- data/lib/vident/capabilities/stimulus_mutation.rb +60 -0
- data/lib/vident/capabilities/stimulus_parsing.rb +144 -0
- data/lib/vident/capabilities/tailwind.rb +18 -0
- data/lib/vident/component.rb +14 -76
- data/lib/vident/engine.rb +6 -5
- data/lib/vident/error.rb +16 -0
- data/lib/{vident2 → vident}/internals/action_builder.rb +18 -22
- data/lib/vident/internals/attribute_writer.rb +17 -0
- data/lib/{vident2 → vident}/internals/class_list_builder.rb +5 -22
- data/lib/vident/internals/declaration.rb +13 -0
- data/lib/{vident2 → vident}/internals/declarations.rb +6 -18
- data/lib/{vident2 → vident}/internals/draft.rb +3 -16
- data/lib/{vident2 → vident}/internals/dsl.rb +6 -32
- data/lib/vident/internals/plan.rb +9 -0
- data/lib/vident/internals/registry.rb +37 -0
- data/lib/{vident2 → vident}/internals/resolver.rb +101 -91
- data/lib/{vident2 → vident}/internals/target_builder.rb +1 -7
- data/lib/vident/stable_id.rb +3 -3
- data/lib/{vident2 → vident}/stimulus/action.rb +11 -24
- data/lib/vident/stimulus/base.rb +26 -0
- data/lib/{vident2 → vident}/stimulus/class_map.rb +6 -18
- data/lib/{vident2 → vident}/stimulus/collection.rb +6 -8
- data/lib/vident/stimulus/combinable.rb +30 -0
- data/lib/vident/stimulus/controller.rb +45 -0
- data/lib/vident/stimulus/naming.rb +9 -9
- data/lib/vident/stimulus/null.rb +7 -0
- data/lib/{vident2 → vident}/stimulus/outlet.rb +12 -32
- data/lib/{vident2 → vident}/stimulus/param.rb +5 -11
- data/lib/{vident2 → vident}/stimulus/target.rb +5 -14
- data/lib/vident/stimulus/value.rb +57 -0
- data/lib/vident/stimulus_null.rb +4 -8
- data/lib/vident/tailwind.rb +4 -17
- data/lib/vident/types.rb +28 -0
- data/lib/vident/version.rb +1 -6
- data/lib/vident.rb +44 -36
- data/skills/vident/SKILL.md +122 -19
- data/skills/vident/api-reference.md +259 -115
- data/skills/vident/examples.md +23 -10
- metadata +38 -60
- data/lib/vident/child_element_helper.rb +0 -64
- data/lib/vident/class_list_builder.rb +0 -112
- data/lib/vident/component_attribute_resolver.rb +0 -106
- data/lib/vident/component_class_lists.rb +0 -37
- data/lib/vident/stimulus/primitive.rb +0 -38
- data/lib/vident/stimulus.rb +0 -31
- data/lib/vident/stimulus_action.rb +0 -133
- data/lib/vident/stimulus_action_collection.rb +0 -11
- data/lib/vident/stimulus_attribute_base.rb +0 -67
- data/lib/vident/stimulus_attributes.rb +0 -129
- data/lib/vident/stimulus_builder.rb +0 -136
- data/lib/vident/stimulus_class.rb +0 -59
- data/lib/vident/stimulus_class_collection.rb +0 -11
- data/lib/vident/stimulus_collection_base.rb +0 -51
- data/lib/vident/stimulus_component.rb +0 -75
- data/lib/vident/stimulus_controller.rb +0 -41
- data/lib/vident/stimulus_controller_collection.rb +0 -14
- data/lib/vident/stimulus_data_attribute_builder.rb +0 -32
- data/lib/vident/stimulus_helper.rb +0 -66
- data/lib/vident/stimulus_outlet.rb +0 -90
- data/lib/vident/stimulus_outlet_collection.rb +0 -11
- data/lib/vident/stimulus_param.rb +0 -42
- data/lib/vident/stimulus_param_collection.rb +0 -11
- data/lib/vident/stimulus_target.rb +0 -47
- data/lib/vident/stimulus_target_collection.rb +0 -18
- data/lib/vident/stimulus_value.rb +0 -39
- data/lib/vident/stimulus_value_collection.rb +0 -11
- data/lib/vident2/caching.rb +0 -93
- data/lib/vident2/component.rb +0 -538
- data/lib/vident2/engine.rb +0 -18
- data/lib/vident2/error.rb +0 -30
- data/lib/vident2/internals/attribute_writer.rb +0 -22
- data/lib/vident2/internals/declaration.rb +0 -17
- data/lib/vident2/internals/plan.rb +0 -12
- data/lib/vident2/internals/registry.rb +0 -41
- data/lib/vident2/phlex/html.rb +0 -84
- data/lib/vident2/phlex.rb +0 -9
- data/lib/vident2/stimulus/controller.rb +0 -59
- data/lib/vident2/stimulus/naming.rb +0 -26
- data/lib/vident2/stimulus/null.rb +0 -16
- data/lib/vident2/stimulus/value.rb +0 -77
- data/lib/vident2/tailwind.rb +0 -19
- data/lib/vident2/version.rb +0 -5
- data/lib/vident2/view_component/base.rb +0 -124
- data/lib/vident2/view_component.rb +0 -9
- data/lib/vident2.rb +0 -50
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Vident
|
|
4
|
-
class StimulusOutlet < StimulusAttributeBase
|
|
5
|
-
attr_reader :controller, :outlet_name, :selector
|
|
6
|
-
|
|
7
|
-
def initialize(*args, implied_controller:, component_id: nil)
|
|
8
|
-
@component_id = component_id
|
|
9
|
-
super(*args, implied_controller: implied_controller)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def to_s = @selector
|
|
13
|
-
|
|
14
|
-
def data_attribute_name = "#{@controller}-#{@outlet_name}-outlet"
|
|
15
|
-
|
|
16
|
-
def data_attribute_value = @selector
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def parse_arguments(*args)
|
|
21
|
-
case args.size
|
|
22
|
-
when 1
|
|
23
|
-
parse_single_argument(args[0])
|
|
24
|
-
when 2
|
|
25
|
-
parse_two_arguments(args[0], args[1])
|
|
26
|
-
when 3
|
|
27
|
-
parse_three_arguments(args[0], args[1], args[2])
|
|
28
|
-
else
|
|
29
|
-
raise ArgumentError, "Invalid number of arguments: #{args.size}"
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def parse_single_argument(arg)
|
|
34
|
-
@controller = implied_controller_name
|
|
35
|
-
if arg.is_a?(Symbol)
|
|
36
|
-
# Single symbol: outlet name on implied controller with auto-generated selector
|
|
37
|
-
outlet_identifier = arg.to_s.dasherize
|
|
38
|
-
@outlet_name = outlet_identifier
|
|
39
|
-
@selector = build_outlet_selector(outlet_identifier)
|
|
40
|
-
elsif arg.is_a?(String)
|
|
41
|
-
# Single string: outlet identifier with auto-generated selector
|
|
42
|
-
@outlet_name = arg.dasherize
|
|
43
|
-
@selector = build_outlet_selector(arg)
|
|
44
|
-
elsif arg.is_a?(Array) && arg.size == 2
|
|
45
|
-
# Array format: [outlet_identifier, css_selector]
|
|
46
|
-
@outlet_name = arg[0].to_s.dasherize
|
|
47
|
-
@selector = arg[1]
|
|
48
|
-
elsif arg.respond_to?(:stimulus_identifier)
|
|
49
|
-
# Component with stimulus_identifier
|
|
50
|
-
identifier = arg.stimulus_identifier
|
|
51
|
-
@outlet_name = identifier
|
|
52
|
-
@selector = build_outlet_selector(identifier)
|
|
53
|
-
elsif arg.respond_to?(:implied_controller_name)
|
|
54
|
-
# RootComponent with implied_controller_name
|
|
55
|
-
identifier = arg.implied_controller_name
|
|
56
|
-
@outlet_name = identifier
|
|
57
|
-
@selector = build_outlet_selector(identifier)
|
|
58
|
-
else
|
|
59
|
-
raise ArgumentError, "Invalid argument type: #{arg.class}"
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def parse_two_arguments(arg1, arg2)
|
|
64
|
-
if (arg1.is_a?(Symbol) || arg1.is_a?(String)) && arg2.is_a?(String)
|
|
65
|
-
@controller = implied_controller_name
|
|
66
|
-
@outlet_name = arg1.to_s.dasherize
|
|
67
|
-
@selector = arg2
|
|
68
|
-
else
|
|
69
|
-
raise ArgumentError, "Invalid argument types: #{arg1.class}, #{arg2.class}"
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def parse_three_arguments(controller, outlet_name, selector)
|
|
74
|
-
if controller.is_a?(String) && outlet_name.is_a?(Symbol) && selector.is_a?(String)
|
|
75
|
-
# controller path + outlet name + selector
|
|
76
|
-
@controller = stimulize_path(controller)
|
|
77
|
-
@outlet_name = outlet_name.to_s.dasherize
|
|
78
|
-
@selector = selector
|
|
79
|
-
else
|
|
80
|
-
raise ArgumentError, "Invalid argument types: #{controller.class}, #{outlet_name.class}, #{selector.class}"
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Build outlet selector following the same pattern as RootComponent
|
|
85
|
-
def build_outlet_selector(outlet_selector)
|
|
86
|
-
prefix = @component_id ? "##{@component_id} " : ""
|
|
87
|
-
"#{prefix}[data-controller~=#{outlet_selector}]"
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Vident
|
|
4
|
-
# `data-<controller>-<name>-param="..."` — readable on the JS side as
|
|
5
|
-
# `event.params.<camelName>`. Element-scoped: every action on the element
|
|
6
|
-
# sees the same params.
|
|
7
|
-
class StimulusParam < StimulusAttributeBase
|
|
8
|
-
attr_reader :controller, :param_name, :value
|
|
9
|
-
|
|
10
|
-
def to_s = @value.to_s
|
|
11
|
-
|
|
12
|
-
def data_attribute_name = "#{@controller}-#{@param_name}-param"
|
|
13
|
-
|
|
14
|
-
def data_attribute_value = @value
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
def parse_arguments(*args)
|
|
19
|
-
case args.size
|
|
20
|
-
when 2 then parse_two_arguments(*args)
|
|
21
|
-
when 3 then parse_three_arguments(*args)
|
|
22
|
-
else raise ArgumentError, "Invalid number of arguments: #{args.size} (#{args.inspect}). Did you pass an array of hashes?"
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def parse_two_arguments(param_name, value)
|
|
27
|
-
raise ArgumentError, "Invalid argument types: #{param_name.class}, #{value.class}" unless param_name.is_a?(Symbol)
|
|
28
|
-
@controller = implied_controller_name
|
|
29
|
-
@param_name = param_name.to_s.dasherize
|
|
30
|
-
@value = serialize_value(value)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def parse_three_arguments(controller, param_name, value)
|
|
34
|
-
unless controller.is_a?(String) && param_name.is_a?(Symbol)
|
|
35
|
-
raise ArgumentError, "Invalid argument types: #{controller.class}, #{param_name.class}, #{value.class}"
|
|
36
|
-
end
|
|
37
|
-
@controller = stimulize_path(controller)
|
|
38
|
-
@param_name = param_name.to_s.dasherize
|
|
39
|
-
@value = serialize_value(value)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Vident
|
|
4
|
-
class StimulusTarget < StimulusAttributeBase
|
|
5
|
-
attr_reader :controller, :name
|
|
6
|
-
|
|
7
|
-
def to_s = @name
|
|
8
|
-
|
|
9
|
-
# Returns the data attribute name for this target
|
|
10
|
-
def data_attribute_name = "#{@controller}-target"
|
|
11
|
-
|
|
12
|
-
# Returns the target name value for the data attribute
|
|
13
|
-
def data_attribute_value = @name
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def parse_arguments(*args)
|
|
18
|
-
case args.size
|
|
19
|
-
when 1
|
|
20
|
-
parse_single_argument(args[0])
|
|
21
|
-
when 2
|
|
22
|
-
parse_two_arguments(args[0], args[1])
|
|
23
|
-
else
|
|
24
|
-
raise ArgumentError, "Invalid number of arguments: #{args.size}"
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def parse_single_argument(arg)
|
|
29
|
-
@controller = implied_controller_name
|
|
30
|
-
@name = case arg
|
|
31
|
-
when Symbol then js_name(arg) # name of target on implied controller
|
|
32
|
-
when String then arg # target name on implied controller
|
|
33
|
-
else raise ArgumentError, "Invalid argument type: #{arg.class}"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def parse_two_arguments(part1, part2)
|
|
38
|
-
if part1.is_a?(String) && part2.is_a?(Symbol)
|
|
39
|
-
# 1 string arg, 1 symbol = controller + target
|
|
40
|
-
@controller = stimulize_path(part1)
|
|
41
|
-
@name = js_name(part2)
|
|
42
|
-
else
|
|
43
|
-
raise ArgumentError, "Invalid argument types: #{part1.class}, #{part2.class}"
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Vident
|
|
4
|
-
class StimulusTargetCollection < StimulusCollectionBase
|
|
5
|
-
def to_h
|
|
6
|
-
return {} if items.empty?
|
|
7
|
-
|
|
8
|
-
merged = {}
|
|
9
|
-
items.each do |target|
|
|
10
|
-
target.to_h.each do |key, value|
|
|
11
|
-
# Merge space-separated values for same target attribute
|
|
12
|
-
merged[key] = merged.key?(key) ? "#{merged[key]} #{value}" : value
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
merged
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Vident
|
|
4
|
-
class StimulusValue < StimulusAttributeBase
|
|
5
|
-
attr_reader :controller, :value_name, :value
|
|
6
|
-
|
|
7
|
-
def to_s = @value.to_s
|
|
8
|
-
|
|
9
|
-
def data_attribute_name = "#{@controller}-#{@value_name}-value"
|
|
10
|
-
|
|
11
|
-
def data_attribute_value = @value
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
def parse_arguments(*args)
|
|
16
|
-
case args.size
|
|
17
|
-
when 2 then parse_two_arguments(*args)
|
|
18
|
-
when 3 then parse_three_arguments(*args)
|
|
19
|
-
else raise ArgumentError, "Invalid number of arguments: #{args.size} (#{args.inspect}). Did you pass an array of hashes?"
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def parse_two_arguments(value_name, value)
|
|
24
|
-
raise ArgumentError, "Invalid argument types: #{value_name.class}, #{value.class}" unless value_name.is_a?(Symbol)
|
|
25
|
-
@controller = implied_controller_name
|
|
26
|
-
@value_name = value_name.to_s.dasherize
|
|
27
|
-
@value = serialize_value(value)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def parse_three_arguments(controller, value_name, value)
|
|
31
|
-
unless controller.is_a?(String) && value_name.is_a?(Symbol)
|
|
32
|
-
raise ArgumentError, "Invalid argument types: #{controller.class}, #{value_name.class}, #{value.class}"
|
|
33
|
-
end
|
|
34
|
-
@controller = stimulize_path(controller)
|
|
35
|
-
@value_name = value_name.to_s.dasherize
|
|
36
|
-
@value = serialize_value(value)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
data/lib/vident2/caching.rb
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "digest/sha1"
|
|
4
|
-
|
|
5
|
-
module Vident2
|
|
6
|
-
# Fragment-caching opt-in. Include into a component to get `cacheable?`,
|
|
7
|
-
# `cache_key`, and the `with_cache_key` / `depends_on` class helpers.
|
|
8
|
-
#
|
|
9
|
-
# `cache_component_modified_time` lives on the adapter base class
|
|
10
|
-
# (Phlex: `.rb` mtime; VC: sidecar template + `.rb` mtime).
|
|
11
|
-
module Caching
|
|
12
|
-
extend ActiveSupport::Concern
|
|
13
|
-
|
|
14
|
-
class_methods do
|
|
15
|
-
def inherited(subclass)
|
|
16
|
-
subclass.instance_variable_set(:@named_cache_key_attributes, @named_cache_key_attributes&.clone)
|
|
17
|
-
super
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def with_cache_key(*attrs, name: :_collection)
|
|
21
|
-
attrs << :component_modified_time
|
|
22
|
-
attrs << :to_h if respond_to?(:to_h)
|
|
23
|
-
named_cache_key_includes(name, *attrs.uniq)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
attr_reader :named_cache_key_attributes
|
|
27
|
-
|
|
28
|
-
def depends_on(*klasses)
|
|
29
|
-
@component_dependencies ||= []
|
|
30
|
-
@component_dependencies += klasses
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
attr_reader :component_dependencies
|
|
34
|
-
|
|
35
|
-
def component_modified_time
|
|
36
|
-
return @component_modified_time if defined?(::Rails) && ::Rails.env.production? && @component_modified_time
|
|
37
|
-
|
|
38
|
-
raise StandardError, "Must implement cache_component_modified_time" unless respond_to?(:cache_component_modified_time)
|
|
39
|
-
|
|
40
|
-
deps = component_dependencies&.map(&:component_modified_time)&.join("-") || ""
|
|
41
|
-
@component_modified_time = deps + cache_component_modified_time
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
def named_cache_key_includes(name, *attrs)
|
|
47
|
-
define_cache_key_method unless @named_cache_key_attributes
|
|
48
|
-
@named_cache_key_attributes ||= {}
|
|
49
|
-
@named_cache_key_attributes[name] = attrs
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def define_cache_key_method
|
|
53
|
-
define_method :cache_key do |n = :_collection|
|
|
54
|
-
@cache_key ||= {}
|
|
55
|
-
return @cache_key[n] if @cache_key.key?(n)
|
|
56
|
-
generate_cache_key(n)
|
|
57
|
-
@cache_key[n]
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def component_modified_time = self.class.component_modified_time
|
|
63
|
-
|
|
64
|
-
def cacheable? = respond_to?(:cache_key)
|
|
65
|
-
|
|
66
|
-
def cache_key_modifier = ENV["RAILS_CACHE_ID"]
|
|
67
|
-
|
|
68
|
-
def cache_keys_for_sources(key_attributes)
|
|
69
|
-
sources = key_attributes.flat_map { |n| n.is_a?(Proc) ? instance_eval(&n) : send(n) }
|
|
70
|
-
sources.compact.filter_map { |item| generate_item_cache_key_from(item) unless item == self }
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def generate_item_cache_key_from(item)
|
|
74
|
-
if item.respond_to? :cache_key_with_version
|
|
75
|
-
item.cache_key_with_version
|
|
76
|
-
elsif item.respond_to? :cache_key
|
|
77
|
-
item.cache_key
|
|
78
|
-
elsif item.is_a?(String)
|
|
79
|
-
Digest::SHA1.hexdigest(item)
|
|
80
|
-
else
|
|
81
|
-
Digest::SHA1.hexdigest(Marshal.dump(item))
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def generate_cache_key(index)
|
|
86
|
-
key_attributes = self.class.named_cache_key_attributes[index]
|
|
87
|
-
return nil unless key_attributes
|
|
88
|
-
key = "#{self.class.name}/#{cache_keys_for_sources(key_attributes).join("/")}"
|
|
89
|
-
raise StandardError, "Cache key for key #{key} is blank!" if key.blank?
|
|
90
|
-
@cache_key[index] = cache_key_modifier.present? ? "#{key}/#{cache_key_modifier}" : key
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|