Hyperscript compiler/runtime:
- query target support in set/fire/put commands
- hs-set-prolog-hook! / hs-prolog-hook / hs-prolog in runtime
- runtime log-capture cleanup
Scripts: sx-loops-up/down, sx-hs-e-up/down, sx-primitives-down
Plans: datalog, elixir, elm, go, koka, minikanren, ocaml, hs-bucket-f,
designs (breakpoint, null-safety, step-limit, tell, cookies, eval,
plugin-system)
lib/prolog/hs-bridge.sx: initial hook-based bridge draft
lib/common-lisp/tests/runtime.sx: CL runtime tests
WASM: regenerate sx_browser.bc.js from updated hs sources
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
69 lines
3.3 KiB
Markdown
69 lines
3.3 KiB
Markdown
# F1 — Null Safety Reporting (+7)
|
||
|
||
**Suite:** `hs-upstream-core/runtimeErrors`
|
||
**Target:** 7 currently-failing tests (decrement, default, increment, put, remove, settle, transition commands)
|
||
|
||
## 1. Failing tests
|
||
|
||
The suite has 18 tests total; 11 already pass. The 7 failures all share the pattern:
|
||
|
||
```
|
||
Expected '#doesntExist' is null, got
|
||
```
|
||
|
||
The `eval-hs-error` helper already exists (landed in null-safety piece 1). It compiles and runs a HS snippet and returns the error string. The problem is that the listed commands don't guard against null targets before operating, so they produce no error (or a cryptic one) instead of `"'#doesntExist' is null"`.
|
||
|
||
| Test | Command | Null target expression |
|
||
|------|---------|----------------------|
|
||
| decrement | `decrement #doesntExist's innerHTML` | `#doesntExist` |
|
||
| default | `default #doesntExist's innerHTML to 'foo'` | `#doesntExist` |
|
||
| increment | `increment #doesntExist's innerHTML` | `#doesntExist` |
|
||
| put | `put 'foo' into/before/after/at start of/at end of #doesntExist` | `#doesntExist` |
|
||
| remove | `remove .foo/.@foo/#doesntExist from #doesntExist` | `#doesntExist` |
|
||
| settle | `settle #doesntExist` | `#doesntExist` |
|
||
| transition | `transition #doesntExist's *visibility to 0` | `#doesntExist` |
|
||
|
||
Note: add, hide, measure, send, sets, show, toggle, trigger already pass — they already guard.
|
||
|
||
## 2. Required error format
|
||
|
||
```
|
||
'#doesntExist' is null
|
||
```
|
||
|
||
The apostrophe-quoted selector string followed by ` is null`. The selector text is the original source text of the element expression (e.g. `#doesntExist`, not a stringified DOM node).
|
||
|
||
This is the same format already used by passing commands. The null-safety piece 1 commit added `eval-hs-error` and `hs-null-error` helper — just need to call it at the right point in each missing command.
|
||
|
||
## 3. Where to add guards
|
||
|
||
All in `lib/hyperscript/runtime.sx`. Pattern for each command:
|
||
|
||
```
|
||
(when (nil? target)
|
||
(hs-null-error target-source-text))
|
||
```
|
||
|
||
Where `hs-null-error` (or equivalent) raises with the formatted message.
|
||
|
||
### Per-command location
|
||
|
||
- **decrement / increment** — after resolving the target element, before reading/writing innerHTML
|
||
- **default** — after resolving target element, before reading current value
|
||
- **put** — after resolving destination element (covers all put variants: into, before, after, at start, at end)
|
||
- **remove** — after resolving the `from` target element
|
||
- **settle** — after resolving target element, before starting transition poll
|
||
- **transition** — after resolving target element, before reading/setting style
|
||
|
||
## 4. Implementation checklist
|
||
|
||
1. Find each failing command's runtime function in `lib/hyperscript/runtime.sx` using `sx_find_all`.
|
||
2. For each: `sx_read_subtree` on the function body, locate where target is resolved, insert null guard calling `hs-null-error` (or the equivalent raise form already used by passing commands).
|
||
3. After all 7: run `hs_test_run suite="hs-upstream-core/runtimeErrors"` — expect 18/18.
|
||
4. Run smoke range 0–195 — expect no regressions.
|
||
5. Commit: `HS: null-safety guards on decrement/default/increment/put/remove/settle/transition (+7)`
|
||
|
||
## 5. Risk
|
||
|
||
Low. The pattern is established by the 11 already-passing tests. The only risk is finding the correct point in each command where the element is resolved and before it's first used.
|