Metadata-Version: 2.4
Name: streamlit-timetravel
Version: 0.1.0
Summary: Undo/redo + per-user session resume for Streamlit apps, backed by SQLite.
Author-email: sm2026jul <sm2026jul@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/smahable/streamlit-timetravel
Project-URL: Repository, https://github.com/smahable/streamlit-timetravel
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: streamlit>=1.31
Dynamic: license-file

# streamlit-timetravel

Undo/Redo and per-user "resume a previous session" for Streamlit apps —
backed by a plain SQLite (or swap-in any) database.

- Every real state change is snapshotted with a sequential number and a
  timestamp.
- Undo / Redo just move a pointer through existing snapshots — navigating
  never creates new history rows.
- Making a new edit after undoing correctly discards the abandoned "future"
  (standard branching undo-history behavior), and Redo becomes unavailable
  again until you undo further.
- Optional per-`login_user` session picker: on login, show a modal listing
  the user's past sessions (grouped, newest-active first) and let them
  resume one — same session id, same pointer, same tracked variables.

## Install

```bash
pip install streamlit-timetravel   # if/once published to PyPI
# or, for now:
pip install git+https://github.com/yourname/streamlit-timetravel.git
```

## Quick start

```python
import streamlit as st
from state_manager import init_state, get_state, set_state, undo_redo_widget

init_state("total", 0)

if st.button("+1"):
    set_state("total", get_state("total") + 1)

st.metric("Total", get_state("total"))
undo_redo_widget()
```

See `demo_app.py` in this repo for a fuller example covering:
- plain values (`set_state` / `get_state`)
- widget-bound values via `key=` + `commit_on_change(key)` (multiselect, text_input, etc.)
- form submits batched into a single history row via `set_states({...})`
- the per-user session picker (`login_session_picker`)

## Known limitations — read before deploying

- **This is not an authentication system.** `login_session_picker` takes
  whatever `login_user` string you give it after *your own* auth check
  succeeds. Bring your own login (e.g. `streamlit-authenticator`, your
  org's SSO) — do not use the demo's plain text box as real auth.
- **SQLite + Streamlit Community Cloud:** Community Cloud containers can
  be recycled (redeploys, sleep after inactivity), and the local
  filesystem is not guaranteed to persist across that. For a durable
  deployment, point `configure(db_path=...)` at an external database
  instead of a local file, or swap the connection layer for one
  (Postgres, Turso/libSQL, etc.).
- Values you track must be JSON-serializable (numbers, strings, lists,
  dicts of the above). Anything else falls back to `str()` on save and
  won't round-trip to its original type on load.
- Not stress-tested for very high write concurrency; WAL mode helps but
  this is a small-to-medium-traffic-app tool, not a distributed system.

## Credits

Design and implementation developed in collaboration with
[Claude](https://claude.ai) (Anthropic), from an original idea and set of
requirements by [sm2026jul].

## License

MIT — see `LICENSE`.
