Changelog

Copy Markdown

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Added

Changed

Deprecated

Removed

Fixed

Security

[0.2.1] - 2026-05-07

Changed

  • The project license has changed from Apache-2.0 to MIT.

Fixed

  • ~F formatter now preserves <script> block content verbatim. Previously, JavaScript inside colocated <script :type={ColocatedHook}> blocks was re-indented as if it were HTML, corrupting indentation-sensitive code.

[0.2.0] - 2026-05-06

Added

  • use_observable/2 now accepts a positional projection fn as its second argument. The fn receives :disconnected when the server is unavailable, or the raw server state otherwise, and its return value becomes the hook's result:

    count = use_observable(CartServer, fn
      :disconnected -> 0
      state -> Cart.State.item_count(state)
    end)
  • static_subscribe option on Filament.LiveView (default: true) controls whether the HTTP render pass subscribes to observables. Set to false on a live view to prevent double-counting presence or other mount side effects on page reload — subscriptions are then established only once the WebSocket session connects.

  • Support for <script :type={Phoenix.LiveView.ColocatedHook}> in ~F templates. Modules using use Filament.Component now correctly register colocated JS hooks alongside those from use Phoenix.Component.

Changed

  • Projection fns now run client-side at render time rather than server-side at broadcast time. This means a projection fn can close over local component state (filters, selections, etc.) so changing that local state correctly re-projects without a new server broadcast. The server sends raw state; change-or-bust comparison is new_raw_state !== last_raw_state per subscriber.

  • handle_subscribe/3handle_subscribe/2: the request argument has been removed. Update your Observable.GenServer implementations:

    # before
    def handle_subscribe(_request, _subscriber, state), do: {:ok, state, state}
    
    # after
    def handle_subscribe(_subscriber, state), do: {:ok, state, state}
  • Observable.subscribe/3Observable.subscribe/2: the request argument has been removed.

  • Observable.remove_projection/5Observable.remove_projection/4: the request argument has been removed.

  • Subscriber struct: request and projections fields replaced by proj_keys and last_raw.

  • ~F templates no longer accept @foo assign syntax — use bare lexical variables from destructured function arguments instead. @foo in a ~F template now raises a compile error. {if … do}, {for … do}, {else}, and {end} are handled natively by the tag engine rather than via a regex preprocessing pass (no behaviour change for existing templates).

Removed

  • The request parameter has been removed from the entire observable stack (handle_subscribe, Observable.subscribe, Observable.remove_projection, Subscriber struct).

Fixed

  • Fixed keyed_list removal leaking observable projection keys, causing stale subscriptions when list items are removed.

[0.1.0] - 2026-05-01

Added

  • Initial project scaffold
  • Mix project structure with Elixir 1.17+ and OTP 26+ support
  • GitHub Actions CI with matrix testing
  • ExDoc configuration for documentation
  • Basic supervision tree structure