# Changelog

## [0.2.0] - 2026-03-15

### ⚠️ Deprecated

**PhoenixDatastar is deprecated.** Use [Dstar](https://hex.pm/packages/dstar) instead.
Dstar is a lighter, pure-functions library for Datastar + Plug/Phoenix apps without the
LiveView-like GenServer abstraction. This is the final release of PhoenixDatastar.

### Changed
- **SSE stream connection now uses `@post` instead of `@get`** — `DefaultHTML` now renders
  `data-init="@post(..., {retryMaxCount: Infinity})"` instead of
  `data-init__once="@get(..., {openWhenHidden: true})"`. This sends signals with the
  SSE connection request (the Datastar-idiomatic approach) and retries forever on disconnect.
- **Auto-reconnect on network recovery** — Added `data-on:online__window` attribute to
  `DefaultHTML` so the SSE connection is re-established when the browser comes back online.
- **Stream route changed from GET to POST** — The `/__datastar/stream` route should now be
  defined as `post "/stream"` in your router. The stream is authenticated via a signed token,
  so it does not require CSRF protection — place it in a scope with only `:fetch_session`.

### Added
- **`PhoenixDatastar.Plugs.RenameCsrfParam`** — New plug that copies a non-prefixed CSRF
  signal (default `"csrf"`) to `conn.body_params["_csrf_token"]` so `Plug.CSRFProtection`
  can find it. Useful for mixed SSE + form routes where Datastar's `_`-prefixed signals
  are never included in the request body.

### Migration

If upgrading from 0.1.x, update your router:

```elixir
# Before (0.1.x)
scope "/__datastar" do
  pipe_through [:fetch_session, :protect_from_forgery]
  get "/stream", PhoenixDatastar.StreamPlug, :stream
  post "/nav", PhoenixDatastar.NavPlug, :navigate
end

# After (0.2.0)
scope "/__datastar" do
  pipe_through [:fetch_session]
  post "/stream", PhoenixDatastar.StreamPlug, :stream
end

scope "/__datastar" do
  pipe_through [:fetch_session, :protect_from_forgery]
  post "/nav", PhoenixDatastar.NavPlug, :navigate
end
```

If you have a custom `html_module`, update it to use `data-init` with `@post` and
add `data-on:online__window` (see `PhoenixDatastar.DefaultHTML` for the updated example).

## [0.1.16] - 2026-03-06

### Added
- **Datastar attributes skill**: Added pre-built `usage_rules` package skill at `usage-rules/skills/datastar-attributes/SKILL.md` with complete Datastar attribute reference (all 16 attribute plugins, actions, modifier syntax). Users can pull it in via `package_skills: [:phoenix_datastar]`.
- **Datastar syntax gotchas in usage rules**: Added critical warnings about colon syntax (`data-on:click` not `data-on-click`), double-underscore modifiers (`data-init__once`), and `data-bind` taking a bare signal name (not `$name`).

### Fixed
- Fixed incorrect `data-bind:value="$name"` example in `usage-rules.md` — `data-bind` takes a signal name without the `$` prefix.

## [0.1.15] - 2026-03-05

### Added
- Export `locals_without_parens` for `datastar` and `datastar_session` macros in `.formatter.exs`, so the Elixir formatter preserves the parenthesis-free style consistent with other Phoenix router macros like `get`, `post`, and `live`.
- Installer now adds `:phoenix_datastar` to `import_deps` in the project's `.formatter.exs` via `Igniter.Project.Formatter.import_dep/2`.

## [0.1.14] - 2026-03-05

### Changed
- Installer now adds the global `/__datastar` scope with `StreamPlug` and `NavPlug` routes automatically. Previously this was a manual step.
- Installer notice now shows `datastar_session` usage example.

## [0.1.13] - 2026-02-27

### Added
- In-session soft navigation via SSE stream (`navigate/2`, `<.ds_link>`, `NavPlug`)
- `datastar_session/3` router macro for grouping Datastar routes under shared session navigation settings
- `PhoenixDatastar.StreamPlug` for global stream endpoint support (`GET /__datastar/stream`)
- `PhoenixDatastar.NavPlug` for in-session soft navigation (`POST /__datastar/nav`)
- Signed stream/nav token generation and verification (`StreamToken`)
- `PhoenixDatastar.RouteRegistry` for session-aware route matching
- `navigate/1,2` action helper and `<.ds_link navigate="...">` component for soft navigation links

### Changed
- Live mount now emits global stream URL + signed nav metadata signals (`nav_path`, `nav_token`)
- Default HTML wrapper now includes `nav_path` and `nav_token` in framework signals
- Cleaned up unused functions
- Improved documentation
- Streamlined test suite
- Live session server supports in-place route transitions via `Server.navigate/5`.
- Stream token payload now contains only `session_id` and `session_name`, keeping SSE stream URLs short regardless of params/assigns size.
- `stream_guard`/`nav_guard` options on `datastar_session` are now documented as metadata-only (reserved for future use). Use pipeline plugs for authorization.
- `stream_token_max_age` application config option (default: 3600s) controls how long stream/nav tokens remain valid.

## [0.1.12] - 2026-02-13

### Changed
- **`event/1,2` no longer requires assigns** — converted from a macro accessing `var!(assigns)` to a plain function that emits `$session_id` and `$event_path` Datastar signal references. This means `event/1,2` works in any component regardless of nesting depth, without passing `session_id` or `event_path` through as attributes.
- `DefaultHTML` now injects `event_path` alongside `session_id` into `data-signals`. Custom `html_module` implementations should update their `data-signals` to include `event_path` (see `DefaultHTML` docs for the updated example).
- `build_event/4` is deprecated in favour of `build_event/2`.

## [0.1.11] - 2026-02-12

### Changed
- Consolidated socket construction into `Socket.new/4`, eliminating duplication between `PageController` and `Server`.
- Stringified `conn.assigns` keys in session map for consistent `mount/3` pattern matching with Plug session keys.

### Fixed
- Removed hardcoded "Datastar" from page title.

## [0.1.10] - 2026-02-12

### Fixed
- Fixed SSE stream and event URLs when using dynamic route segments (e.g., `/:workspace_slug`) by using `conn.request_path` instead of the compile-time route pattern.

## [0.1.9] - 2026-02-11

### Changed
- **Assigns vs Signals separation**: Assigns (`assign/2,3`, `update/3`) are now server-side only and never sent to the client. Signals (`put_signal/2,3`, `update_signal/3`) are the explicit API for Datastar reactive state sent via SSE. Client signals arrive in the `handle_event/3` payload.
- **Unified events list**: Merged `patches` and `scripts` socket fields into a single `events` list, preserving user-intended ordering.
- **README overhaul**: Fully rewritten to document the assigns/signals separation, `put_signal`, `update_signal`, `execute_script`, `redirect`, `console_log`, and both rendering patterns (signals vs server-rendered patches).

### Fixed
- Stateless views now correctly re-run `mount/3` before `handle_event/3` so assigns are available.
- Compiler now recompiles when a view module changes.
- Fixed stale `@initial_signals` doc in `DefaultHTML`.

## [0.1.8] - 2026-02-09

### Added
- **Usage rules**: Added `usage-rules.md` for AI agent integration via the `usage_rules` package.

## [0.1.6] - 2026-02-09

### Changed
- **Simplified scoped alias resolution**: `datastar/3` now always delegates to `Phoenix.Router.scoped_alias/2`, matching Phoenix's own convention for controllers. Previously, single-segment vs multi-segment module names were special-cased; now all view modules are treated uniformly. Fully-qualified modules still work as before.

### Fixed
- `live?/1` now calls `Code.ensure_compiled!/1` before inspecting module attributes, preventing false negatives when the module hasn't been loaded yet.
- Removed stray "bump" entry from 0.1.5 changelog.
- Updated LICENSE copyright year to 2026.

## [0.1.5] - 2026-02-07

### Added
- **Built-in mount template**: The HTML wrapper (`DefaultHTML`) is now shipped inside the package. You no longer need to create a `DatastarHTML` module in your app — it works out of the box. To customize, configure `html_module` globally or per-route (see README).
- Installer no longer generates a `DatastarHTML` module — the built-in `DefaultHTML` is used by default.
- **Auto-injected initial signals**: Assigns set in `mount/3` are now automatically initialized as Datastar signals on the wrapper element. No more manually adding `data-signals={Jason.encode!(%{count: @count})}` in your `render/1` — just `assign(socket, :count, 0)` in `mount/3` and use `$count` in your template.
- `@initial_signals` assign is now available in custom HTML modules (see `DefaultHTML` docs).
- New tests for initial signal injection and internal assign filtering.

### Fixed
- `event_path` was leaking as a user signal — added it to `internal_assigns` filter list.

## [0.1.3] - 2026-02-04

### Added
- Stateless views can now handle events synchronously (no GenServer required).
- New `event/2` macro replaces `post/2` and `get/2` for triggering server events.
- `event_path` assign is now set for all views (live and stateless).
- CSRF token is now read from meta tag automatically (no signal setup required).

### Changed
- **Breaking**: Removed `datastar_events()` macro - all event routes are now per-page.
- **Breaking**: Replaced `post/2` and `get/2` macros with single `event/2` macro.
- **Breaking**: Event route path changed from `/path/event/:event` to `/path/_event/:event`.
- Simplified routing - `datastar/3` macro now generates event routes for all views.
- Installer no longer adds `datastar_events()` to router.

### Fixed
- Root path "/" now generates correct URLs (was creating double slashes like `//_event`).

### Removed
- Removed dead `:datastar_update` code path from SSE loop.
- Removed unnecessary `id` attribute from DatastarHTML wrapper (was only used by dead code).

## [0.1.2] - 2026-02-01

### Added
- Installer: adds `datastar/0` to my_app_web.ex

### Fixed
- conditional check to check if it should stablish a sse connection or not


## [0.1.1] - 2026-02-01

### Added
- Installer: Created mix installer (`mix phoenix_datastar.install`).
- Router: Added `PhoenixDatastar.Router` and "sse" option support.
- Config: Added option to remove debug annotations.
- Web: Added `:live_sse` to `_web` module.
- Layout: Added script tag generation for `<head>`.

### Fixed
- Signals: Fixed prepending of scope.
- Patches: Fix to ensure both patches and signals are sent correctly.
