You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix(optimistic): apply optimistic UI patch client-side (closes#16)
The optimistic-UI protocol was implemented server-side and the client
defined applyOptimistic(), but dispatch() never called it — the patch
shipped in the same response as the full render, so the UI only ever
reflected the authoritative server state after the round-trip.
applyOptimistic was dead code and the docstrings promised instant
feedback the runtime never delivered.
Implements Option A from the issue (declarative client-side prediction):
- dispatch() accepts an options.optimistic patch and applies it
synchronously before the fetch, reconciling on success and rolling
back on error.
- Triggers declare predictions via data-optimistic='{...}' or the
data-optimistic-toggle="field" shorthand; the bind handler computes the
patch and passes it to dispatch().
- applyOptimistic() now also exposes data-optimistic and
data-optimistic-<field> attributes as CSS styling hooks.
- Ship component-framework.css with [data-loading] / [data-optimistic]
default styles (reduced-motion aware).
- Correct the docstrings on dispatch(), applyOptimistic(),
get_optimistic_patch(), and the .d.ts to describe actual behavior.
- Add node:test coverage (tests/js/optimistic.test.mjs) proving the
prediction is applied before the response and reconciled/rolled back.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hdmTV88wAXU8ew1rorMjt
* fix(optimistic): address review — wire JS tests into CI, clear stale markers
Review of #17 surfaced three gaps:
- JS tests were orphaned: `just test` runs pytest only and CI had no Node
step, so the suite never ran automatically. Add a `test-js` justfile
recipe (+ `test-all`) and a `test-js` CI job (Node 22).
- The documented run command was a bare directory, which Node 25 treats as
a module path and fails; use a node-expanded glob instead, and fix the
in-file run instructions (avoiding `*/` inside the block comment).
- `update()` left `data-optimistic*` markers stuck on the element when the
server returned empty HTML (element not replaced). Add `_clearOptimistic()`
and call it on that early-return path; covered by a new test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hdmTV88wAXU8ew1rorMjt
* chore: normalize trailing whitespace and EOF across tracked files
These files (spec-kit scaffolding, docs, an issue template) carried
trailing-whitespace / missing-final-newline that the hand-rolled CI lint
never checked. Running the pre-commit hooks via prek in CI surfaces them,
so normalize once. Mechanical only — no content changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hdmTV88wAXU8ew1rorMjt
* ci(lint): run pinned hooks via prek; pin ty to a known-good version
CI's lint job hand-rolled `ruff`/`ty` calls, which could (and did) diverge
from local pre-commit. ty is pre-1.0 and a version after 0.0.25 changed its
exit code to fail on warnings, turning the intentionally warn-level Django
mixin/ORM diagnostics into a red build.
- Pin `ty==0.0.25` in the dev deps so CI matches the local/working version
that exits 0 on warn-level diagnostics; bump deliberately.
- Replace the lint job's manual ruff/ty steps with `prek run --all-files`
so CI runs the exact pinned hooks from .pre-commit-config.yaml (single
source of truth with local pre-commit). Add `prek` to dev deps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hdmTV88wAXU8ew1rorMjt
* ci: use uv instead of pip (project standard)
The CI jobs hand-rolled `pip install -e .[dev]`, but the project
standardizes on uv with a committed uv.lock. Switch all Python jobs to
`astral-sh/setup-uv` + `uv sync --extra dev --locked` + `uv run`, so CI
installs the exact locked dependency set and matches local workflow.
Refresh uv.lock for the pyproject changes (adds prek, pins ty==0.0.25).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hdmTV88wAXU8ew1rorMjt
* ci: install via uv pip --system (uv.lock is gitignored)
uv.lock is gitignored, so `uv sync --locked` has no lockfile to resolve
against in a clean CI checkout. Use `uv pip install --system -e .[dev]`
instead — still uv (project standard), resolves fresh like a library, and
needs no committed lock. Commands run directly on the runner's Python.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hdmTV88wAXU8ew1rorMjt
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments