Commit Graph

14 Commits

Author SHA1 Message Date
bfe4727edf Hyperscript gallery: index page for gallery/
Adds the top-level gallery/index.sx that links into the one-per-file
gallery pages committed in the prior commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 09:09:08 +00:00
1a9c8d61b5 Hyperscript gallery: one-per-file page migration (76 pages)
Migrates hyperscript demo/reference pages from grouped index files into
one-per-page directory layout. Each gallery-<topic>/index.sx is a single
defpage with its own demo, matching the one-per-file convention used
elsewhere in sx/sx/applications/.

Covers: control (call/go/if/log/repeat/settle), dom (add/append/empty/
focus/hide/measure/morph/put/remove/reset/scroll/set/show/swap/take/
toggle), events (asyncError/bootstrap/dialog/fetch/halt/init/on/pick/
send/socket/tell/wait/when), expressions (asExpression/attributeRef/
closest/collectionExpressions/comparisonOperator/default/in/increment/
logicalOperator/mathOperator/no/objectLiteral/queryRef/select/splitJoin),
language (askAnswer/assignableElements/component/cookies/def/dom-scope/
evalStatically/js/parser/relativePositionalExpression/scoping), and
reactivity (bind/live/liveTemplate/reactive-properties/resize/transition).

Adds _islands/hs-test-card.sx — a shared island for hyperscript demos.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 09:08:30 +00:00
fc24cc704d GraphQL: query/mutation/fragments/vars/executor + parser spec + tests
New graphql application. 676-line test-graphql.sx covers parser, executor,
fetch-gql integration. lib/graphql.sx (686L) is the core parser/AST;
lib/graphql-exec.sx (219L) runs resolvers. applications/graphql/spec.sx
declares the application. sx/sx/applications/graphql/ provides the doc
pages (parser, queries, mutation, fragments, vars, fetch-gql, executor).

Includes rebuilt sx_browser.bc.js / sx_browser.bc.wasm.js bundles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 09:08:00 +00:00
b5387c069f Test runner: increase wait times for iframe htmx activation
- reload-frame: wait 1500ms after wait-boot (was 500ms)
- wait-for-el: poll up to 25 tries / 5s (was 15 / 3s)
- Added log after wait-boot confirming iframe ready

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 06:58:38 +00:00
84996d74e2 Test runner: return-value error handling, no guard/cek-try/throws
guard and cek-try both create CEK frames that don't survive async
perform/resume. Instead, run-action returns nil on success and an
error string on failure. The for-each loop checks the return value
and sets fail-msg. No exceptions cross async boundaries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 23:09:38 +00:00
0410812420 Async error handler: dispatch Eval_error to VM handler_stack in resume_vm
When an error occurs during resumed VM execution (after perform/hs-wait),
resume_vm now checks the VM's handler_stack. If a handler exists (from a
compiled guard form's OP_PUSH_HANDLER), it unwinds frames and jumps to
the catch block — exactly like OP_RAISE. This enables try/catch across
async perform/resume boundaries.

The guard form compiles to OP_PUSH_HANDLER which lives on the vm struct
and survives across setTimeout-based async resume. Previously, errors
during resume escaped to the JS console as unhandled exceptions.

Also restored guard in the test runner (was cek-try which doesn't survive
async) and restored error-throwing assertions in run-action.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 22:54:37 +00:00
25db89a96c Add console.log tracing to test runner for debugging
Logs at every step: run-all start, test name, reload-frame, wait-for-el,
actions done, PASS/FAIL, run-all complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 22:32:26 +00:00
017451370f Fix letrec structure: wait-for-el as proper binding, not begin-wrapped
The previous insert wrapped reload-frame and wait-for-el in a begin
block instead of making them separate letrec bindings. This made
reload-frame invisible to later bindings. Fixed by inserting
wait-for-el at index 3 in the letrec bindings list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 22:16:13 +00:00
cc9975aaf0 Add wait-for-el polling to test runner for element readiness
wait-for-el polls the iframe doc for a CSS selector up to max-tries
times with 200ms intervals. Used before running test actions to ensure
the target elements exist in the iframe after page load.

Also restores reload-frame timing and keeps cek-try error handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 21:45:38 +00:00
b12ec746a2 Fix: replace guard with cek-try in test runner, clear stale reuse_stack
The guard form (call/cc + handler-bind expansion) doesn't survive async
IO suspension — the CEK continuation from guard's call/cc captures frames
that become invalid after the VM resumes from hs-wait. Replacing guard
with cek-try (which compiles to VM-native OP_PUSH_HANDLER/OP_POP_HANDLER)
avoids the CEK boundary crossing.

The test runner now executes: suspends on hs-wait, resumes, runs test
actions, and test assertions fire correctly. The "Not callable: nil"
error is eliminated. Remaining: test assertion errors from iframe content
not loading fast enough (timing issue, not a framework bug).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 18:10:10 +00:00
fec3194464 Island body: letrec instead of define (fixes render-to-dom), host-object JS fns
runner.sx: Converted define forms inside island body to letrec. Multiple
define forms in a let body cause render-to-dom to fall back to eval-expr
for the whole body, which evaluates (div ...) as a list instead of
rendering it to DOM. letrec keeps the last body expression (div) as the
render target.

sx_browser.ml: js_to_value now stores plain JS functions as host objects
(Dict with __host_handle) instead of wrapping as NativeFn. This preserves
the original JS function identity through the SX→JS round-trip, keeping
_driveAsync wrappers from host-callback intact when passed to
addEventListener via host-call.

Remaining: IO suspension in click handler is caught as "IO suspension in
non-IO context" instead of being driven by _driveAsync. The host-callback
wrapper creates the right JS function, but the event dispatch path doesn't
go through K.callFn.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 15:45:06 +00:00
1e42451252 Test runner: SX island for (test.(applications.(htmx))), header test link
- Test runner island (~test-runner) with 8 test definitions as SX data
- SSR renders test list with expandable deftest source
- Island body has run-all/run-action/reload-frame/wait-boot helpers
- Header: "test" link on every page, derives test URL from current path
- _test added to skip_dirs in sx_server.ml (both load_dir locations)
- Handler names: ex-{slug} convention for dispatch compatibility
- JS fallback runner updated with data-role selectors

Next: wire island hydration so browser re-evaluates the island body
(component bundler needs to include ~test-runner in page scripts)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 12:20:21 +00:00
4aa49e42e8 htmx demos working: activation, fetch, swap, OOB filtering, test runner page
- htmx-boot-subtree! wired into process-elements for auto-activation
- Fixed cond compilation bug in hx-verb-info (Clojure-style flat cond)
- Platform io-fetch upgraded: method/body/headers support, full response dict
- Replaced perform IO ops with browser primitives (set-timeout, browser-confirm, etc)
- SX→HTML rendering in hx-do-swap with OOB section filtering
- hx-collect-params: collects input name/value for all methods
- Handler naming: ex-{slug} convention, removed perform IO dependencies
- Test runner page at (test.(applications.(htmx))) with iframe-based runner
- Header "test" link on every page linking to test URL
- Page file restructure: 285 files moved to URL-matching paths (a/b/c/index.sx)
- page-functions.sx: ~100 component name references updated
- _test added to skip_dirs, test- file prefix convention for test files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:56:15 +00:00
4f02f82f4e HS parser: fix number+comparison keyword collision, eval-hs uses hs-compile
Parser: skip unit suffix when next ident is a comparison keyword
(starts, ends, contains, matches, is, does, in, precedes, follows).
Fixes "123 starts with '12'" returning "123starts" instead of true.

eval-hs: use hs-compile directly instead of hs-to-sx-from-source with
"return " prefix, which was causing the parser to consume the comparison
as a string suffix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:29:01 +00:00