PhoenixVapor.Hybrid.Classifier (PhoenixVapor v0.3.0)

Copy Markdown View Source

Classifies bindings from a parsed <script setup> into server-owned, client-owned, and mixed categories using AST-based dataflow analysis.

Given the output of PhoenixVapor.ScriptSetup.parse/1, determines:

  • Which props the client needs (for serialization)
  • Which functions are server actions vs client handlers
  • Which computeds are pure-client vs mixed (depend on server props)

Summary

Functions

Classify all bindings and handlers from a parsed script setup.

Extract free variables from a JavaScript expression string.

Extract property names accessed via props.X pattern in a JS expression.

Types

binding_kind()

@type binding_kind() ::
  :server_prop
  | {:client_ref, initial :: String.t()}
  | :client_computed
  | {:mixed_computed, server_deps :: [String.t()], client_deps :: [String.t()]}

classification()

@type classification() :: %{
  bindings: %{required(String.t()) => binding_kind()},
  handlers: %{required(String.t()) => handler_kind()},
  client_props: [String.t()],
  server_only_props: [String.t()]
}

handler_kind()

@type handler_kind() :: :client_handler | {:server_action, body :: String.t()}

Functions

classify(refs, computeds, functions, function_bodies, props)

@spec classify(
  refs :: %{required(String.t()) => String.t()},
  computeds :: %{required(String.t()) => String.t()},
  functions :: [String.t()],
  function_bodies :: %{required(String.t()) => String.t()},
  props :: [String.t()]
) :: classification()

Classify all bindings and handlers from a parsed script setup.

Accepts the tuple returned by PhoenixVapor.ScriptSetup.parse/1.

free_variables(source)

@spec free_variables(String.t()) :: [String.t()]

Extract free variables from a JavaScript expression string.

prop_references(source)

@spec prop_references(String.t()) :: [String.t()]

Extract property names accessed via props.X pattern in a JS expression.

Handles props.contacts, props.users, etc. — common when using const props = defineProps([...]) in Vue script setup.