All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m56s
- 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>
266 lines
11 KiB
Python
266 lines
11 KiB
Python
"""SX docs page routes."""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from quart import Blueprint, Response, make_response, request
|
|
|
|
|
|
def register(url_prefix: str = "/") -> Blueprint:
|
|
bp = Blueprint("pages", __name__, url_prefix=url_prefix)
|
|
|
|
def _is_sx_request() -> bool:
|
|
return bool(request.headers.get("SX-Request") or request.headers.get("HX-Request"))
|
|
|
|
# ------------------------------------------------------------------
|
|
# Home
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/")
|
|
async def index():
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import home_oob_sx
|
|
return sx_response(await home_oob_sx())
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_home_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_home_page_sx(ctx)
|
|
return await make_response(html, 200)
|
|
|
|
# ------------------------------------------------------------------
|
|
# Docs
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/docs/")
|
|
async def docs_index():
|
|
from quart import redirect
|
|
return redirect("/docs/introduction")
|
|
|
|
@bp.get("/docs/<slug>")
|
|
async def docs_page(slug: str):
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import docs_oob_sx
|
|
return sx_response(await docs_oob_sx(slug))
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_docs_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_docs_page_sx(ctx, slug)
|
|
return await make_response(html, 200)
|
|
|
|
# ------------------------------------------------------------------
|
|
# Reference
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/reference/")
|
|
async def reference_index():
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import reference_oob_sx
|
|
return sx_response(await reference_oob_sx(""))
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_reference_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_reference_page_sx(ctx, "")
|
|
return await make_response(html, 200)
|
|
|
|
@bp.get("/reference/<slug>")
|
|
async def reference_page(slug: str):
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import reference_oob_sx
|
|
return sx_response(await reference_oob_sx(slug))
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_reference_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_reference_page_sx(ctx, slug)
|
|
return await make_response(html, 200)
|
|
|
|
# ------------------------------------------------------------------
|
|
# Protocols
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/protocols/")
|
|
async def protocols_index():
|
|
from quart import redirect
|
|
return redirect("/protocols/wire-format")
|
|
|
|
@bp.get("/protocols/<slug>")
|
|
async def protocol_page(slug: str):
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import protocol_oob_sx
|
|
return sx_response(await protocol_oob_sx(slug))
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_protocol_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_protocol_page_sx(ctx, slug)
|
|
return await make_response(html, 200)
|
|
|
|
# ------------------------------------------------------------------
|
|
# Examples
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/examples/")
|
|
async def examples_index():
|
|
from quart import redirect
|
|
return redirect("/examples/click-to-load")
|
|
|
|
@bp.get("/examples/<slug>")
|
|
async def examples_page(slug: str):
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import examples_oob_sx
|
|
return sx_response(await examples_oob_sx(slug))
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_examples_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_examples_page_sx(ctx, slug)
|
|
return await make_response(html, 200)
|
|
|
|
# ------------------------------------------------------------------
|
|
# Example API endpoints (for live demos)
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/examples/api/click")
|
|
async def api_click():
|
|
from shared.sx.helpers import sx_response
|
|
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('"', '\\"')
|
|
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)
|
|
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):
|
|
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('"', '\\"')
|
|
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('"', '\\"')
|
|
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('"', '\\"')
|
|
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")
|
|
sx_src = (
|
|
f'(<>'
|
|
f' (p :class "text-emerald-600 font-medium" "Box A updated!")'
|
|
f' (p :class "text-sm text-stone-500" "at {now}")'
|
|
f' (div :id "oob-box-b" :sx-swap-oob "innerHTML"'
|
|
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
|
|
# ------------------------------------------------------------------
|
|
|
|
@bp.get("/essays/")
|
|
async def essays_index():
|
|
from quart import redirect
|
|
return redirect("/essays/sx-sucks")
|
|
|
|
@bp.get("/essays/<slug>")
|
|
async def essay_page(slug: str):
|
|
if _is_sx_request():
|
|
from shared.sx.helpers import sx_response
|
|
from sxc.sx_components import essay_oob_sx
|
|
return sx_response(await essay_oob_sx(slug))
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sxc.sx_components import render_essay_page_sx
|
|
ctx = await get_template_context()
|
|
html = await render_essay_page_sx(ctx, slug)
|
|
return await make_response(html, 200)
|
|
|
|
return bp
|