Skip to content

TS→ReScript migration (session 1: stale/{scanner,react})#13

Closed
hyperpolymath wants to merge 3 commits intomainfrom
rescript-migration
Closed

TS→ReScript migration (session 1: stale/{scanner,react})#13
hyperpolymath wants to merge 3 commits intomainfrom
rescript-migration

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

@hyperpolymath hyperpolymath commented May 3, 2026

Summary

Full TS→ReScript src migration mandated by .claude/CLAUDE.md's language policy (TypeScript banned; ReScript primary).

All 6 TS-bearing packages now ported and compiling under rescript@11:

Package Files TS LOC Status
tools/stale/packages/stale/components/react/ Button + Modal + Index 304 ✅ compiles
tools/stale/packages/scanner/ Scanner + Index 83 ✅ compiles (TODO bodies match TS stubs)
tools/stale/packages/core/ Arangodb + Index 420 ✅ compiles, full impl
tools/github-action/ Action 151 ✅ compiles
tools/cli/ Cli 246 ✅ compiles
tools/monitoring-api/ Server + Db + Express + Joi 659 ✅ compiles

Total: ~1863 LOC of TS source converted to ReScript + extensive hand-rolled FFI bindings.

FFI surface written

  • React DOM (focus, querySelectorAll, key/mouse events, addEventListener, body.style)
  • puppeteer / playwright / axe-core / fs (scanner)
  • arangojs (Database, Collection.{save,update,document,byExample,count,ensureIndex}, Cursor, AQL via bind-vars)
  • @actions/core (getInput, info, warning, setFailed, setOutput, summary)
  • @actions/github (context, getOctokit, octokit.rest.issues.createComment)
  • commander, chalk, ora, cli-table3, fs-extra, path
  • express (Router, middleware, req/res, error handler)
  • cors, helmet, compression, express-rate-limit, dotenv
  • joi (schema, validator)

Deferred (separate sessions)

  • 6 test files (~1988 LOC):
    • tools/cli/tests/cli_test.ts (299 LOC, Deno.test)
    • tools/github-action/tests/action_test.ts (376 LOC, jest)
    • tools/monitoring-api/tests/{e2e,property,aspect,benches}/*.ts (1313 LOC, jest)
  • Scanner runtime bodies — original TS was already stubbed; mine carries the same failwith("TODO") placeholders
  • Workspace deps — root package.json workspaces glob tools/* doesn't reach tools/stale/packages/*; cross-package npm refs (@accessibility-everywhere/scanner, @accessibility-everywhere/core) currently resolve only via @module(...) externals at compile time. To make the runtime imports work, set up a workspaces config that includes the nested package paths.
  • Deno alignment — CLAUDE.md says runtime deps belong in deno.json, not package.json. All packages still use package.json for npm-distributed deps. Migrating to deno.json import maps with npm: specifiers is a separate cleanup.

Caveats / known rough edges

  1. Modal.res uses one Obj.magic for JsxEvent.Mouse.targetDom.element (an upstream rescript-react typing gap).
  2. Server.res uses %raw(...) blocks for process.exit(1) and a couple of process.env defaults — typed wrappers exist but plain %raw was faster.
  3. Each package's npm install needed --no-workspaces because the root workspace glob doesn't see the nested tools/stale/packages/* packages, and one of them references @accessibility-everywhere/core@^1.0.0 which isn't on the npm registry. Once the workspace structure is fixed, this flag won't be needed.

Test plan

  • tools/stale/packages/stale/components/react: npx rescript build — clean
  • tools/stale/packages/scanner: npx rescript build — clean
  • tools/stale/packages/core: npx rescript build — clean
  • tools/github-action: npx rescript build — clean
  • tools/cli: npx rescript build — clean
  • tools/monitoring-api: npx rescript build — clean
  • Runtime smoke-test: spin up the API and hit each route
  • Implement scanner bodies (TS was stubbed; needs a real puppeteer/playwright/axe orchestration)
  • Port test suites
  • Set up npm workspaces correctly so cross-package deps resolve at runtime

🤖 Generated with Claude Code

Per the ReScript-and-Deno language policy in .claude/CLAUDE.md.

- @accessibility-everywhere/react: Button + Modal (forwardRef, focus trap, portal,
  WCAG-compliant ARIA) with hand-rolled DOM FFI; React.useId replaces @reach/auto-id.
- @accessibility-everywhere/scanner: Scanner module with typed FFI to puppeteer/
  playwright/axe-core/fs. Method bodies preserved as TODOs to mirror the TS stubs.
- Per-package rescript.json with esmodule output, in-source .mjs.
- Root rescript.json stub (pointed at non-existent src/) removed.
- gitignore extended for nested ReScript build dirs.

Both packages compile cleanly with rescript@11. Remaining TS to port:
core/arangodb (409 LOC), cli, github-action, monitoring-api.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

hyperpolymath and others added 2 commits May 3, 2026 18:23
- @accessibility-everywhere/core (Arangodb.res): full port of arangodb.ts (409 LOC)
  including all type interfaces, DB initialization, index creation, WCAG 2.1 criteria
  data, and 7 query methods (getSiteByUrl, getRecentScansForSite, getViolationsForScan,
  getTopSites, getCommonViolations, getSiteViolationTrend, getOrganizationSites).
  Tagged-template aql queries converted to bind-vars-form db.query() for cleaner FFI.
- @accessibility-everywhere/github-action (Action.res): full port of src/index.ts.
  FFI for @actions/core (getInput, info, warning, setFailed, setOutput, summary)
  and @actions/github (context, getOctokit, octokit.rest.issues.createComment).
- @accessibility-everywhere/cli (Cli.res): full port of src/cli.ts.
  FFI for commander, chalk, ora, cli-table3, fs-extra, path. All three subcommands
  (scan, ci, batch) ported with the same UX as the TS original.

Workspace dep "@accessibility-everywhere/scanner" referenced via @module externals;
package.json runtime dep dropped pending workspace setup.

Tests deferred: action_test.ts, cli_test.ts (Deno.test rewrite separate session).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces 7 TS files (server + 6 routes, 659 LOC) with a single Server.res that
mounts all six routers, plus shared FFI modules:

- Express.res — Router, app, req/res accessors, middleware (cors, helmet,
  compression, rate-limit, json-parser).
- Joi.res — schema builder + validator.
- Db.res — service + collection methods (save/update/document/byExample/count)
  and scanner FFI, both backed by @module externals to the workspace packages.

All six route surfaces preserved with the same paths:
- POST /v1/scan, GET /v1/scan/:scanId
- POST /v1/violations, GET /v1/violations/common, GET /v1/violations/site/:k,
  PATCH /v1/violations/:id/fixed
- GET /v1/leaderboard, GET /v1/leaderboard/category/:c
- GET /v1/badge/:domain (json + svg formats; SVG template inlined)
- GET /v1/stats, GET /v1/stats/site/:k
- GET /v1/dashboard/:orgId

Tests deferred: 4 jest-style suites (e2e, property, aspect, benches; 1313 LOC).

This completes the ReScript src migration for all 6 TS-bearing packages.
Test ports across cli/github-action/monitoring-api remain.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath
Copy link
Copy Markdown
Owner Author

Discarded — TS deletions cherry-picked to ts-removal branch (PR forthcoming). Replacement port will use AffineScript per the actual hyperpolymath language policy (the .claude/CLAUDE.md prescription of ReScript was stale).

@hyperpolymath hyperpolymath deleted the rescript-migration branch May 4, 2026 16:15
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