All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.7.0] - 2026-06-09

Changed

  • Published to Hex.pm. Lantern and its LiveCode dependency are now available as Hex packages. The livecode path dependency in mix.exs is replaced by {:livecode, "~> 0.1"}.

Added

  • Hosted demo. examples/demo now ships with an ephemeral sandbox flow: visitors get a read-only view of the shared database; clicking "Get sandbox" triggers a Cloudflare Turnstile challenge and, on success, spins up a fresh private Postgres database seeded with the demo data. The sandbox auto-expires after 5 minutes and is destroyed on disconnect.

[0.6.0] - 2026-06-08

Changed

  • Honest, struct-free error copy. Database and query errors now route through a single Lantern.Errors.humanize/1 chokepoint instead of being inspect/1-dumped into the UI. An unreachable/asleep database (a %DBConnection.ConnectionError{}, e.g. pool :queue_timeout) now reads "Couldn't connect to this database. It may be starting up or unreachable; try again in a moment." rather than a raw struct. The table browser, SQL workspace, row editors, and connection setup all share this path.

Added

  • Query errors carry a short plain-language hint under the Postgres message — the server's own HINT: when present, otherwise one derived from the SQLSTATE (undefined table/column, syntax error, insufficient privilege, unique/foreign key/not-null/check violations). .lt-error now honors newlines so the hint sits on its own line.

[0.5.0] - 2026-06-08

Added

  • Guarded SQL workspace mode (sql_mode: :guarded). A write-enabled middle ground between :trusted and :read_only: ordinary statements run, but a destructive one — DROP, TRUNCATE, or a DELETE/UPDATE with no WHERE clause — is held and surfaces a confirmation dialog (an alertdialog portal showing the exact statement) before it runs. confirm_sql / cancel_sql events drive it; destructive_sql?/1 is the (heuristic, word-boundary-aware) detector and is unit-tested. The Run button's client data-confirm is suppressed in guarded mode so the server dialog is the single prompt.

[0.4.0] - 2026-06-08

Changed

  • Reworked Lantern.Explorer into a single window frame. A top bar now carries the sidebar toggle, a schema / table breadcrumb, the Data/SQL view toggle, settings, and fullscreen, and the sidebar, grid, and footer share the frame's borders instead of floating as separate panels. The Data/SQL toggle no longer takes its own row, and Settings moved from the sidebar into the top bar.
  • Minimum phoenix_live_view is now ~> 1.1 (dialogs use Phoenix.Component.portal/1).

Added

  • :read_only option on Lantern.Explorer — a browse-only mode that hides every write affordance (inline edit, row insert, bulk delete, and all DDL) and refuses the matching events server-side, and restricts the SQL workspace to SELECT/EXPLAIN. Intended for public or untrusted-viewer deployments.
  • Themeable per-type cell tints (--lt-cell-number, --lt-cell-temporal, --lt-cell-boolean, --lt-cell-json) so a column's type reads at a glance, plus --lt-bg-code and --lt-shadow variables.
  • Row detail drawer — a row's expand button opens a side panel with the full record: every column labeled with its type, full (un-truncated) values, pretty-printed JSON, and clickable foreign keys.
  • Cell context menu — right-click a cell to copy its value, filter the grid by that value, or open a foreign-key reference. All three are reads, so they work in :read_only mode.
  • Grid browsing niceties: a type label under each data-grid column header, right-aligned tabular numerics, booleans as distinct true/false text, and a click-to-peek popover that pretty-prints JSON and expands truncated values.
  • Quick-chart Bar / Line / Pie selector. The SQL workspace chart (and a new "chart this column" affordance on numeric data-grid headers) can render as a horizontal bar chart, an inline-SVG line chart, or an inline-SVG pie chart with a legend — all dependency-free (no chart library) and fully available in :read_only mode. Pie slices cycle through the existing --lt-cell-* / --lt-accent tokens, so charts stay themed in light and dark.

Fixed

  • Dialogs render through a portal onto <body>, so a modal can no longer be clipped by a host page's overflow or transform.
  • The settings popover is no longer clipped by the sidebar's overflow.
  • Fullscreen fills the viewport even when the host page constrains the component's width (for example, a centered max-width container).

[0.3.0] - 2026-05-30

Changed

  • A table without a primary key is now insert-only rather than fully read-only. The "New row" affordance stays available so rows can be added, while inline edit and delete — which need a primary key to address an existing row — remain disabled. Lantern.Explorer now derives insertable (a table is loaded with columns) separately from editable (the table has a primary key), and the empty-state note reflects the new behavior.

[0.2.0] - 2026-05-29

Added

  • Table-level DDL on the Lantern facade: create_table/3, drop_table/2, add_column/3, drop_column/3, rename_column/4, and rename_table/3. Each validates names and builds (and type-checks) its statement before opening a connection, so a bad request never spends one.
  • Lantern.SQL DDL builders and a validate_type/1 allowlist. Since DDL can't parameterize identifiers or types, the safety boundary is quote_ident/1 for every identifier plus a curated type allowlist (simple + parameterized (n)/(n,m) types); injection attempts such as "text; drop table users" are rejected.
  • Lantern.Explorer table editor UI: a "New table" dialog (named columns, per-column type/nullable/primary-key, add/remove rows), and a per-table menu to edit columns (add/rename/drop), rename the table, or drop it. Destructive actions are guarded by confirmations.

[0.1.0] - 2026-05-28

Initial release.

Added

  • Lantern data layer: introspection (list_tables/1, columns/2, primary_keys/2, schema/2), reads with filter/sort/pagination (query/3), safe primary-key-scoped writes (insert/3, update/4, delete/3), and FK lookup options (reference_options/4). Values are always sent as cast text parameters; nothing is interpolated into SQL.
  • Lantern.Explorer LiveComponent: table sidebar, sortable/filterable grid, inline editing, row insertion, bulk delete, fixed-height shell with internal scroll, fullscreen mode (Esc to exit), and an inline filter help popover with click-to-apply examples.
  • Type-aware editors: dropdowns for booleans, enums, and single-column foreign keys; native date/time/datetime pickers; number inputs; a JSON textarea with live validation; a "set NULL" control on nullable fields. Arrays render as Postgres array literals and round-trip through the editor.
  • Connection-agnostic Lantern.Source: parses postgres:// URLs, keyword lists, maps, or any struct exposing host/port/username/password/database.
  • One-shot connections with Process.unlink + search_path pinned to public, so a Postgres disconnect can't kill the host LiveView and DML hits the same schema the introspection scanned.
  • :allow_raw_filter attribute (default false). The raw WHERE-fragment filter input is hidden unless explicitly opted in for trusted operators.
  • Composite-foreign-key safety: detected and excluded from FK dropdowns so a mis-paired option can't write the wrong column.
  • Standalone lantern.css (themeable via --lt-* variables, light + dark), an optional lantern.tailwind.css preset, and a LanternGrid JS hook (column resize with persistence, set-NULL, JSON validation; cleans up window listeners on destroyed() and supports touch via pointercancel).
  • Test suite: pure SQL/Source/Coercion unit tests, real-Postgres integration tests (introspection, read/write round-trips, UUID/bytea, enum, FK), and event-handler tests that exercise update/2 + handle_event/3 on a constructed socket. 80 tests + 6 doctests.