Class: Weft::Registry
- Inherits:
-
Object
- Object
- Weft::Registry
- Defined in:
- lib/weft/registry.rb,
lib/weft/registry/eligibility.rb
Overview
Stores registered Weft::Component and Weft::Page classes for the Router to consume at request time.
Components and Pages are stored separately because their lookup costs differ:
-
Components route at static paths (derived from the class name). Stored in
@components; looked up via@path_index, a lazily-built hash keyed on the resolved path. O(1) lookup, invalidated when new components register. -
Pages route at user-declared patterns that may include
:paramsegments (e.g./orders/:order_id). Stored in@pages; matched by walking the set and pattern-matching eachpage_pathagainst the request path. O(n) match, but n is typically small (one entry per user-declared Page).
Because pages aren't in @path_index, register_page does not
invalidate it. Unifying the two storage shapes would force pages-without-
params into the linear walk OR invent two parallel code paths; keeping
them separate is the simplest honest answer.
Defined Under Namespace
Modules: Eligibility
Instance Method Summary collapse
-
#any_sse_components? ⇒ Boolean
True if any registered component declares
pushes(i.e. participates in SSE streaming). -
#clear ⇒ Object
Empty the registry.
- #components ⇒ Object
-
#evict(klass) ⇒ Object
Remove one class from the registry, invalidating route lookup so a fresh same-path registration serves cleanly.
-
#initialize ⇒ Registry
constructor
A new instance of Registry.
- #lookup(path) ⇒ Object
-
#match_page(path) ⇒ Object
Match a request path against registered page patterns.
- #pages ⇒ Object
- #register(component_class) ⇒ Object
-
#register_page(page_class) ⇒ Object
No @path_index invalidation: pages aren't indexed there (see the class comment above).
Constructor Details
#initialize ⇒ Registry
Returns a new instance of Registry.
36 37 38 39 40 41 42 |
# File 'lib/weft/registry.rb', line 36 def initialize @components = Set.new @pages = Set.new @path_index = nil @sse_present = nil @routes_validated = false end |
Instance Method Details
#any_sse_components? ⇒ Boolean
True if any registered component declares pushes (i.e. participates in
SSE streaming). Used by Weft::Page to decide whether to emit the
htmx-ext-sse script tag automatically. One-way memoized: recomputed while
still false, so components registered after an earlier render are picked
up; once true it sticks, so the typical load-everything-then-serve pattern
pays no steady-state recompute cost.
116 117 118 119 120 |
# File 'lib/weft/registry.rb', line 116 def any_sse_components? return true if @sse_present @sse_present = @components.any?(&:push_config) end |
#clear ⇒ Object
Empty the registry. The evict-everything reset for hand-rolled reload integrations and for tests; per-class eviction is #evict.
60 61 62 63 64 65 66 |
# File 'lib/weft/registry.rb', line 60 def clear @components.clear @pages.clear @path_index = nil @sse_present = nil @routes_validated = false end |
#components ⇒ Object
106 107 108 |
# File 'lib/weft/registry.rb', line 106 def components @components.to_a end |
#evict(klass) ⇒ Object
Remove one class from the registry, invalidating route lookup so a fresh same-path registration serves cleanly. This is the reload-eviction primitive: Weft.configure_autoloading wires it to Zeitwerk's on_unload callback, and hand-rolled reloaders should call it (or #clear) as classes unload. Safe to call with any object — non-registered classes (models, service objects) fall through untouched. Returns true if evicted.
74 75 76 77 78 79 80 81 |
# File 'lib/weft/registry.rb', line 74 def evict(klass) # rubocop:disable Naming/PredicateMethod -- a command with a did-evict status return return false unless @components.delete?(klass) || @pages.delete?(klass) @path_index = nil @sse_present = nil @routes_validated = false true end |
#lookup(path) ⇒ Object
101 102 103 104 |
# File 'lib/weft/registry.rb', line 101 def lookup(path) validate_routes! path_index[path] end |
#match_page(path) ⇒ Object
Match a request path against registered page patterns. Non-routable pages (abstract bases, classes without a resolvable path) are skipped. Returns [page_class, extracted_params] or nil.
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/weft/registry.rb', line 90 def match_page(path) validate_routes! @pages.each do |page_class| next unless page_class.routable? params = match_pattern(resolved_page_pattern(page_class), path) return [page_class, params] if params end nil end |
#pages ⇒ Object
83 84 85 |
# File 'lib/weft/registry.rb', line 83 def pages @pages.to_a end |
#register(component_class) ⇒ Object
44 45 46 47 48 |
# File 'lib/weft/registry.rb', line 44 def register(component_class) @components.add(component_class) @path_index = nil @routes_validated = false end |
#register_page(page_class) ⇒ Object
No @path_index invalidation: pages aren't indexed there (see the class comment above). Pages do participate in collision detection, so the route-validation memo is cleared.
53 54 55 56 |
# File 'lib/weft/registry.rb', line 53 def register_page(page_class) @pages.add(page_class) @routes_validated = false end |