class

Analyzer::Php::Livewire

Inherits Analyzer::Php::PhpEngine < FileScanEngine < Analyzer < FileHelper < Reference < Object

Livewire components are reached through one endpoint, POST /livewire/update (v3; v2 posts to /livewire/message/<name>), whose JSON payload names the component, the property updates and the method calls. Every public method that is not a lifecycle hook is a callable action and every public property is client-writable unless #[Locked] / #[Reactive].

One endpoint per action, disambiguated by a URL fragment (/livewire/update#edit-post.save) the way OpenRPC and GraphQL do it — the optimizer dedupes on (method, url), so without the fragment every component would collapse into one endpoint. A component with no actions still gets #<component> for its writable properties.

Components: classes extending Livewire\Component (named from their namespace below …\Livewire\, kebab-cased: App\Livewire\Posts\EditPost → posts.edit-post) and class-based Volt single-file components (new class extends Component in a Blade view, named from the view path).

Constants

CLASS_RE = /(?<!::)\b(abstract\s+)?(?:(?:final|readonly)\s+)*class\s+([A-Za-z_]\w*)\s+extends\s+\\?(?:Livewire\\(?:Volt\\)?)?Component\b[^{;]*\{/
COMPUTED_RE = /#\[[^\]]*\bComputed\b/
DEFAULT_UPDATE_PATH = "/livewire/update"
IMPORT_RE = /Livewire\\(?:Volt\\)?Component\b/
LATER_MAJOR = /(?<![\d.])(?:[3-9]|\d\d)\./
LIFECYCLE_RE = /\A(?:render|placeholder|exception|rendering|rendered|(?:mount|boot|booted)(?:[A-Z]\w*)?|(?:hydrate|dehydrate|updating|updated)\w*|__\w+)\z/

Names Livewire refuses to call from the client: lifecycle hooks, their per-trait variants (mountWithTabs) and the hydrate/update wildcards.

LOCKED_RE = /#\[[^\]]*\b(?:Locked|Reactive)\b/
NAMESPACE_RE = /\bnamespace\s+([\w\\]+)\s*;/
UPDATE_ROUTE_RE = /setUpdateRoute\s*\([^;]*?Route::post\s*\(\s*['"]([^'"]+)['"]/
USE_RE = /^\s*use\s+\\?([\w\\]+)(?:\s+as\s+(\w+))?\s*;/m
V2_MAJOR = /(?<![\d.])2\./

A require constraint naming major 2 and no later one (^2.12, not ^2.0 || ^3.0).

V2_MESSAGE_PATH = "/livewire/message/"

Livewire 2 posts each component to its own /livewire/message/<name>.

VIEW_DIRS = ["views/livewire/", "views/"]
VOLT_RE = /\bnew\s+class\b[^{;]*?\bextends\s+\\?(?:Livewire\\(?:Volt\\)?)?Component\b[^{;]*\{/

Class methods

tech_name
Source

Instance methods

analyze
Source
analyze_file(path : String) : Array(Endpoint)
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source

Nested types