Skip to content

chore: γ-fallback strip TS types from Node-bound packages#14

Merged
hyperpolymath merged 2 commits intomainfrom
js-strip-types
May 4, 2026
Merged

chore: γ-fallback strip TS types from Node-bound packages#14
hyperpolymath merged 2 commits intomainfrom
js-strip-types

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Step (d) of the migration plan: pure type-stripping for the 5 Node-bound packages, since AffineScript Node-target (affinescript#35) is mid-flight and these packages need to keep working today.

19 .ts/.tsx files → .js/.jsx via ts-blank-space (positions preserved verbatim, types replaced with whitespace, no JSX/target transpilation). Equivalent JS, no semantic changes.

  • ✅ React (@accessibility-everywhere/react) not touched — goes to AffineScript next (step c).
  • ✅ Test files stripped too — they run on jest now without ts-jest.
  • ✅ All 5 tsconfig.json removed.
  • ✅ TypeScript / @types / ts-node / ts-node-dev dropped from devDependencies.
  • ✅ `main` repointed from `dist/` → `src/.js` (no transpile step in the runtime path).

Caveats

  • Workspace deps still broken at runtime@accessibility-everywhere/{core,scanner} aren't on the npm registry; root package.json's workspaces: ["packages/*", "tools/*"] glob doesn't reach tools/stale/packages/*. Same problem the TS build had pre-strip; not a regression. Fix is a workspace config change, separate concern.
  • Scanner bodies still stubbed — original TS had `// ... [Implementation]` placeholders; the strip preserved them. Not runnable.

Next on this migration

  • (c) AffineScript pilot: port React components per migration-playbook.adoc — separate PR
  • (a) Write AffineScript .affine sources alongside these .js files for the Node packages, locking in the re-decomposition design while context is fresh — separate PR, won't run until #35 lands

Test plan

  • All 19 files stripped without errors (ts-blank-space exit 0)
  • `npm install` per package + smoke-run `npm test` to confirm jest still picks up the new .js test files

🤖 Generated with Claude Code

Per the AffineScript-or-strip-types policy: where AffineScript Node-target isn't
yet ready (issue affinescript#35 still mid-flight), Node-bound TS packages take
the γ fallback — pure type-stripping via ts-blank-space, producing equivalent
JS at the same source positions.

Stripped (19 files, .ts → .js / .tsx → .jsx):
- tools/cli/{src/cli, tests/cli_test}
- tools/github-action/{src/index, tests/action_test}
- tools/monitoring-api/src/{server, routes/{badge,dashboard,leaderboard,scan,stats,violations}}
- tools/monitoring-api/tests/{aspect/security_test, benches/api_bench, e2e/api_test, property/scanner_properties_test}
- tools/stale/packages/core/src/{index, database/arangodb}
- tools/stale/packages/scanner/src/{index, scanner}

Per-package package.json:
- typescript / ts-node / ts-node-dev / @types/* dropped from devDependencies
- main repointed from dist/*.js → src/*.js (no transpile step needed)
- "type": "module" added (ESM, matches the strip-types output)
- "build": "tsc" removed where it had no remaining purpose
- tools/cli bin paths updated dist → src/cli.js

tsconfig.json removed in all 5 Node-bound packages.

React component package (@accessibility-everywhere/react) NOT touched —
that one is browser/wasm-targetable today and goes to AffineScript next.

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 hyperpolymath merged commit 8a8966c into main May 4, 2026
18 of 34 checks passed
@hyperpolymath hyperpolymath deleted the js-strip-types branch May 4, 2026 07:40
hyperpolymath added a commit that referenced this pull request May 4, 2026
…#16)

## Summary

Step **(a)** of the migration plan: AffineScript `.affine` design files
for all 5 Node-bound packages, written alongside the JS fallback ([PR
#14](#14)).
Bodies remain TODO until the Node-target lands
([affinescript#35](hyperpolymath/affinescript#35))
— the type-level contract is the design lock-in.

**Conformance**: every file follows the locked AffineScript conventions
(see `feedback_affinescript_conventions.md` resolution log).
Q1=canonical face, Q2=`.affine` extension, Q3=domain-specific effect
names, Q4=per-package `Externs.affine` shim (interim, pending `.affex`
compatibility filesystem).

## What's in this PR

14 new `.affine` files across the 5 Node-bound packages:

| Package | Files | Effects declared |
|---|---|---|
| `scanner` | Externs, Scanner, Index | `Browser`, `Fs`, `Clock` |
| `core` | Externs, Arangodb, Index | `Db`, `Process` |
| `github-action` | Externs, Action, Index | `Action`, `Github` |
| `cli` | Externs, Cli, Index | `IO`, `Process`, `Fs`, `Path`,
`Commander`, `Spinner`, `Style`, `TableBuilder` |
| `monitoring-api` | Externs, Server | `Net`, `Joi`, `Dotenv`, `IO`,
`Process`, `Clock` (+ re-declared `Db` / `Scanner` from cross-pkg shims)
|

## Key playbook re-decompositions captured at the type level

Per the [migration
playbook](https://github.com/hyperpolymath/affinescript/blob/main/docs/guides/migration-playbook.adoc)
Cardinal Rule (*re-decompose, don't transliterate*):

- **Module-level singletons** (`server.ts`'s top-level `db` / `scanner`)
→ owned `AppState` threaded as `ref` parameter through route handlers —
kills the service-locator pattern the playbook flags.
- **`try/catch` around every handler** → handler effect rows (`Net + Db
+ Joi + Clock + …`) make impurity visible at the signature.
- **Tagged-template `aql\`…\`` queries** → bind-vars-form
`Db.query[B](db, str, bindVars) -> Cursor` per the playbook
recommendation.
- **`'A' | 'AA' | 'AAA'` literal-string unions** → AffineScript sum
types (`A | AA | AAA`).
- **TS class with private fields + methods** (e.g. `ArangoDBService`) →
owned `Service` record + standalone fns taking `ref Service` / `mut
Service`.
- **`React.forwardRef` class** (in [PR
#15](#15))
→ standalone `make_button` fn returning `own Element`.

## Caveats

- **Bodies are stubs.** Each fn has the right signature + effect row but
the body is `// TODO: implement when Node-target lands` plus `let _ = …;
()`-style placeholders. This is the agreed shape of "step (a) design
lock-in" — type-level contract captured, runtime impl a separate
session.
- **Cross-package types** (e.g. monitoring-api consuming core's
`Service` and `Db` effect, or scanner's `ScanResult`) are currently
re-declared as opaque `extern type` + a slim re-declared effect in each
consumer. When `.affex` lands, those re-decls collapse to `use Core` /
`use Scanner` and the duplication disappears.
- **Stdlib-style helpers** (`String.join`, `List.fold`, `Int.to_string`,
etc.) are referenced but not yet pinned to a specific stdlib path — to
settle when the language's stdlib path scheme is finalised.
- **`pub` visibility on top-level `let` / `type`** is used per
`stdlib/Core.affine` precedent; if the canonical face has different
export semantics in some constructs, those are renamings.

## How this fits the four PRs

| Step | Branch | PR | What it gives |
|---|---|---|---|
| (d) | `js-strip-types` |
[#14](#14)
| TS → JS via ts-blank-space; Node packages run today |
| (c) | `react-affinescript-pilot` |
[#15](#15)
| Button.affine pilot; Modal deferred |
| **(a)** | `affinescript-node-design` | this PR | `.affine` design for
the 5 Node-bound packages |

PR #14 keeps the runtime working today; PR #15 + this PR capture the
AffineScript design while context is fresh. The two layers (`.js` +
`.affine`) coexist until the Node-target lands; at that point the `.js`
files retire and `.affine` becomes canonical.

## Test plan

- [ ] AffineScript compile-check via `affinescript check <file>` once a
working environment is set up — couldn't run in this session
- [ ] Specify `.affex` per the parking-lot entry; collapse cross-package
type re-decls
- [ ] Implement TODO-bodies once Node-target lands (multi-session)
- [ ] Modal port (deferred from PR #15)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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