Live wire response + component display with OOB swaps on all examples

- All 6 examples show Component and Wire response as placeholders that
  fill with actual content when the demo is triggered (via OOB swaps)
- Wire response shows full wire content including component definitions
  (when not cached) and CSS style block
- Component display only includes defs the client doesn't already have,
  matching real sx_response() behaviour
- Add "Clear component cache" button to reset localStorage + in-memory
  component env so next interaction shows component download
- Rebuild tw.css with Tailwind v3.4.19 including sx content paths
- Optimize sx_response() CSS scanning to only scan sent comp_defs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 01:54:45 +00:00
parent ea18a402d6
commit 8024fa5b13
6 changed files with 289 additions and 65 deletions

View File

@@ -132,58 +132,103 @@ def register(url_prefix: str = "/") -> Blueprint:
@bp.get("/examples/api/click")
async def api_click():
from shared.sx.helpers import sx_response
return sx_response('(~click-result)')
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
sx_src = f'(~click-result :time "{now}")'
comp_text = _component_source_text("click-result")
wire_text = _full_wire_text(sx_src, "click-result")
oob_wire = _oob_code("click-wire", wire_text)
oob_comp = _oob_code("click-comp", comp_text)
return sx_response(f'(<> {sx_src} {oob_wire} {oob_comp})')
@bp.post("/examples/api/form")
async def api_form():
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
form = await request.form
name = form.get("name", "")
escaped = name.replace('"', '\\"')
return sx_response(f'(~form-result :name "{escaped}")')
sx_src = f'(~form-result :name "{escaped}")'
comp_text = _component_source_text("form-result")
wire_text = _full_wire_text(sx_src, "form-result")
oob_wire = _oob_code("form-wire", wire_text)
oob_comp = _oob_code("form-comp", comp_text)
return sx_response(f'(<> {sx_src} {oob_wire} {oob_comp})')
_poll_count = {"n": 0}
@bp.get("/examples/api/poll")
async def api_poll():
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
_poll_count["n"] += 1
now = datetime.now().strftime("%H:%M:%S")
count = min(_poll_count["n"], 10)
return sx_response(f'(~poll-result :time "{now}" :count {count})')
sx_src = f'(~poll-result :time "{now}" :count {count})'
comp_text = _component_source_text("poll-result")
wire_text = _full_wire_text(sx_src, "poll-result")
oob_wire = _oob_code("poll-wire", wire_text)
oob_comp = _oob_code("poll-comp", comp_text)
return sx_response(f'(<> {sx_src} {oob_wire} {oob_comp})')
@bp.delete("/examples/api/delete/<item_id>")
async def api_delete(item_id: str):
# Return empty response — the row's outerHTML swap removes it
return Response("", status=200, content_type="text/sx")
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
# Empty primary response — outerHTML swap removes the row
# But send OOB swaps to show what happened
wire_text = _full_wire_text(f'(empty — row #{item_id} removed by outerHTML swap)')
comp_text = _component_source_text("delete-row")
oob_wire = _oob_code("delete-wire", wire_text)
oob_comp = _oob_code("delete-comp", comp_text)
return sx_response(f'(<> {oob_wire} {oob_comp})')
@bp.get("/examples/api/edit")
async def api_edit_form():
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
value = request.args.get("value", "")
escaped = value.replace('"', '\\"')
return sx_response(f'(~inline-edit-form :value "{escaped}")')
sx_src = f'(~inline-edit-form :value "{escaped}")'
comp_text = _component_source_text("inline-edit-form")
wire_text = _full_wire_text(sx_src, "inline-edit-form")
oob_wire = _oob_code("edit-wire", wire_text)
oob_comp = _oob_code("edit-comp", comp_text)
return sx_response(f'(<> {sx_src} {oob_wire} {oob_comp})')
@bp.post("/examples/api/edit")
async def api_edit_save():
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
form = await request.form
value = form.get("value", "")
escaped = value.replace('"', '\\"')
return sx_response(f'(~inline-view :value "{escaped}")')
sx_src = f'(~inline-view :value "{escaped}")'
comp_text = _component_source_text("inline-view")
wire_text = _full_wire_text(sx_src, "inline-view")
oob_wire = _oob_code("edit-wire", wire_text)
oob_comp = _oob_code("edit-comp", comp_text)
return sx_response(f'(<> {sx_src} {oob_wire} {oob_comp})')
@bp.get("/examples/api/edit/cancel")
async def api_edit_cancel():
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _component_source_text, _full_wire_text
value = request.args.get("value", "")
escaped = value.replace('"', '\\"')
return sx_response(f'(~inline-view :value "{escaped}")')
sx_src = f'(~inline-view :value "{escaped}")'
comp_text = _component_source_text("inline-view")
wire_text = _full_wire_text(sx_src, "inline-view")
oob_wire = _oob_code("edit-wire", wire_text)
oob_comp = _oob_code("edit-comp", comp_text)
return sx_response(f'(<> {sx_src} {oob_wire} {oob_comp})')
@bp.get("/examples/api/oob")
async def api_oob():
from shared.sx.helpers import sx_response
from sxc.sx_components import _oob_code, _full_wire_text
now = datetime.now().strftime("%H:%M:%S")
return sx_response(
sx_src = (
f'(<>'
f' (p :class "text-emerald-600 font-medium" "Box A updated!")'
f' (p :class "text-sm text-stone-500" "at {now}")'
@@ -191,6 +236,9 @@ def register(url_prefix: str = "/") -> Blueprint:
f' (p :class "text-violet-600 font-medium" "Box B updated via OOB!")'
f' (p :class "text-sm text-stone-500" "at {now}")))'
)
wire_text = _full_wire_text(sx_src)
oob_wire = _oob_code("oob-wire", wire_text)
return sx_response(f'(<> {sx_src} {oob_wire})')
# ------------------------------------------------------------------
# Essays