Skip to content

feat(safe-dom): add minimal SafeDOM package and runnable example#26

Merged
hyperpolymath merged 2 commits into
mainfrom
feat/safe-dom-package
May 13, 2026
Merged

feat(safe-dom): add minimal SafeDOM package and runnable example#26
hyperpolymath merged 2 commits into
mainfrom
feat/safe-dom-package

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

  • New workspace package tools/safe-dom/ implementing the SafeDOM surface that the orphaned examples/SafeDOMExample.res already assumed (ProvenSelector / ProvenHTML, mount, mountSafe, mountWhenReady, mountBatch).
  • Moves the example into the package so the build now actually verifies it. Fixes three latent bugs in the example revealed by the first compile:
    1. mountWithValidation was missing one } (outer switch never closed).
    2. Multi-arg Console.log("label", value) was JS-style; switched to RescriptCore's Console.log2 / Console.error2.
    3. Template literal with Array.length(...) needed ->Int.toString (no implicit int→string in ReScript).
  • Root package-lock.json is committed because npm hoisted the workspace on install — it locks the resolved tree across all members.

Why this matters

Closes the last gap in the TS→ReScript migration: every .res source in the repo now builds. Previously examples/SafeDOMExample.res referenced open SafeDOM with no implementation anywhere — aspirational code masquerading as a runnable example.

Test plan

  • rescript build in tools/safe-dom succeeds (no warnings).
  • All other ReScript packages still build (cli, github-action, monitoring-api, stale/core, stale/scanner, stale/components/react — exit=0 each).
  • find . -name "*.ts" -not -path "*/node_modules/*" -not -path "*/.git/*" returns 0 results — antipattern check trivially passes.
  • Reviewer: confirm the safety story for mountBatch (documented in-source: validation is atomic, mutation phase is best-effort and not transactionally reversible).

🤖 Generated with Claude Code

hyperpolymath and others added 2 commits May 13, 2026 20:38
Introduces tools/safe-dom/ as a standalone ReScript workspace package
implementing the SafeDOM surface the orphaned examples/SafeDOMExample.res
already assumed:

- ProvenSelector / ProvenHTML: validated-input wrappers (boundary check is
  carried in the type so mount cannot fail on input shape).
- mount: proven-input mounting that returns mountResult variant.
- mountSafe / mountWhenReady: string-input helpers that validate at the
  boundary and dispatch via callbacks.
- mountBatch: two-phase (validate + existence check, then mutate) for
  best-effort atomic batch mounting; the trade-off (innerHTML mutations are
  not transactionally reversible if the DOM races mid-batch) is documented
  in-source.

Moves examples/SafeDOMExample.res into the package so the build verifies the
surface. Fixes three latent bugs in the example uncovered by the first build:

  1. mountWithValidation had 6 opening braces and 5 closing - outer switch
     was never closed.
  2. Console.log("label", value) used JS-style varargs; switched to
     RescriptCore's Console.log2 / Console.error2.
  3. Template literal interpolating Array.length(...) needed ->Int.toString
     (no implicit int-to-string in ReScript).

package-lock.json appears at the repo root because npm hoisted the workspace
on install - committing it locks the resolved tree across the workspace.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hyperpolymath
hyperpolymath merged commit 38b8c3a into main May 13, 2026
16 of 34 checks passed
@hyperpolymath
hyperpolymath deleted the feat/safe-dom-package branch May 13, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant