Migrate fjs/sul, fjs/media/html, fjs/crypto/sign, fjs/types/rtti to .f.mjs - #1485
Conversation
Splits the EncodeState<S>/Encode<S> types into a sibling types.ts, and converts the runtime implementation (emptyEncodeState, encode) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. No other module imports fjs/sul/module.f.ts, so updates only touch the README.md example.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
functionalscript | b57d53a | Commit Preview URL Branch Preview URL |
Aug 11 2026, 04:58 AM |
Splits the Element/Node types into a sibling types.ts, and converts the runtime implementation (element, html, htmlToString, htmlUtf8) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. Updates the sole dependent, fjs/website/module.f.ts, to import from the .f.mjs specifier, and fixes a stale line reference in fjs/text/todo/190.md.
Splits the All type into a sibling types.ts, and converts the runtime implementation (all, fromCurve, concat, computeK, sign) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. No other module imports fjs/crypto/sign/module.f.ts; fixes three stale doc references in fjs/crypto/sign/todo and fjs/crypto/todo.
o2alexanderfedin
left a comment
There was a problem hiding this comment.
Reviewed at 3024c8c against main (cbcc7ab). Three modules now — fjs/sul, fjs/media/html, fjs/crypto/sign. The migrations themselves are clean; one recurrence of the stale-link issue from #1484.
Runtime logic is provably unchanged
crypto/sign carries RFC6979 deterministic nonce generation, so "looks equivalent" isn't good enough. I compared main's compiled JavaScript (module.f.js from prepack) against the authored module.f.mjs on this branch, normalizing only the things TypeScript's emitter adds or an annotation removes — semicolons, and the parens left behind by dropped as const/type annotations:
TOKEN-IDENTICAL runtime: fjs/crypto/sign
TOKEN-IDENTICAL runtime: fjs/sul
TOKEN-IDENTICAL runtime: fjs/media/html
All three are token-for-token identical. The large computeK hunk in the diff is entirely re-indentation from the arrow chain changing shape — no expression moved.
Also verified
npx tscclean; 2356 pass / 0 fail.- Public type surface: 0 removed, 0 changed. No
anyas a type anywhere in the emitted declarations. - The
_prefix convention was applied on its own this time —_Attributes,_HashState, and_Signaturewere all non-exportedtypedeclarations onmainand all carry the prefix here. That is theByte/NodeListclass of issue not recurring, which is the outcome I was hoping for. - CHANGELOG has entries for all three, and their claims check out:
media/html/types.tsdoes exportElement/Node,sul/types.tsdoes exportEncodeState/Encode. - Both new
.f.mjsproofs import only.f.mjsruntime modules, so they satisfy §2 — no repeat of the revert that #1484 needed. - The
crypto/signcommit updated its owntodo/docs in the same change. That is the right instinct; it just wasn't applied to the other two.
Three doc references to files this PR renames are stale
Same check as last time — main has 49 broken references, this head has 52, and the three added are yours:
| Stale reference | Now | Where |
|---|---|---|
fjs/sul/module.f.ts |
module.f.mjs |
fjs/cas/todo/strategy-3-merkle-tree.md:61 |
fjs/sul/proof.f.ts |
proof.f.mjs |
fjs/emergent_testing/todo/65y-proof-asserteq-adoption.md:30,141, fjs/sul/todo/id-prefix-tag-factory.md:56, todo/camel-case-proof-keys.md:17 |
fjs/media/html/module.f.ts |
module.f.mjs |
fjs/text/sgr/todo/csi-edsl.md:6, fjs/media/nix/todo/serializer-validation-split.md:82 |
65y-proof-asserteq-adoption.md:141 is the same half-updated-line shape as last time, now from the other side: it reads fjs/sul/proof.f.ts:1, fjs/sul/level/hash/proof.f.mjs:1 — the hash half was fixed in #1484 and the sul half on the same line is now stale.
Since this is the second PR in a row, it may be worth a one-line grep in the migration checklist — grep -rn 'old/path\.f\.ts' --include='*.md' . after each rename — rather than catching it in review each time.
Minor
The summary describes only fjs/sul; fjs/media/html and fjs/crypto/sign arrived after it was written. The CHANGELOG covers all three correctly, so this is just the PR body.
No correctness objection — happy to approve once the three references are updated.
Splits the full type-level API (Const, ConstObject, Struct, Tuple, Primitive0, Tag0, Info0, Type, Type0, Boolean, Number, String, Bigint, Unknown, Tag1, Info1, Type1, MakeType1, Array, Record, Or) into a sibling types.ts, and converts the runtime implementation (tag0List, boolean, number, string, bigint, unknown, isTag1, array, record, or, option, never) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. TypeScript's JSDoc parser special-cases the identifiers Boolean/Number/String as aliases for the primitive types (a legacy Closure Compiler convention), so those three exported consts rely on inference from type0() rather than an explicit @type annotation naming the colliding type. Updates all 19 dependents (protocol/mcp, protocol/json_rpc, dev/package_json, ci/common, media/json, media/json/schema, media/revision, media, mcp/evo, mcp/cas, mcp, emergent_testing, and rtti's own common/parse/validate/ts submodules) to import runtime values from module.f.mjs and types from types.ts. Also addresses stale todo/ doc links flagged in review for the previous three migrations in this PR (fjs/sul, fjs/media/html) plus three more found for fjs/types/rtti itself.
|
Thanks for the token-diff verification — great to have that confirmed independently. All three stale references fixed in 936ce34, plus a fourth module (
Also refreshed the PR title/summary to cover all four migrated modules, and took your suggestion — worth checking
Generated by Claude Code |
Splits the full Ts<T> type-transformer API (Primitive, Unknown, Array, Object, Info0Ts, ConstTs, Info1Ts, ArrayTs, RecordTs, TupleTs, StructTs, Ts) into a sibling types.ts, and converts the sole runtime export (printer) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. Updates 11 dependents (protocol/mcp, protocol/json_rpc, dev/package_json, ci/common, media/json, media/json/schema, media/revision, media, emergent_testing, and rtti's own common/parse/validate submodules) to import the Ts type from types.ts. All were type-only imports of Ts/Unknown, so no runtime specifier changes were needed beyond the import path. Fixes two stale doc references to fjs/types/rtti/ts/module.f.ts and proof.f.ts.
Splits the shared kernel's type-level API (Path, ValidationError, Result, Validate, Visitor, IsContainer, Container, ResultE, ValidateE) into a sibling types.ts, and converts the runtime implementation (verror, prependPath, primitive0Validate, constPrimitiveValidate, isArray, isObject, eachEntry, orVisit, visit) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. Updates the three dependents (rtti/validate, rtti/parse, media/json/schema) to import runtime values from module.f.mjs and types from types.ts, splitting mixed import/export statements where needed. Fixes three stale doc references.
o2alexanderfedin
left a comment
There was a problem hiding this comment.
Reviewed at 93fdc6e. The three stale references from my last pass are fixed, and this round introduces none — main and this head have the same 49 broken doc refs, so the rename sweep is now clean. Six modules migrate here.
Runtime logic is unchanged
Same method as before — main's compiled module.f.js versus the authored module.f.mjs, normalizing only semicolons and annotation-parens:
TOKEN-IDENTICAL: fjs/crypto/sign
TOKEN-IDENTICAL: fjs/sul
TOKEN-IDENTICAL: fjs/media/html
TOKEN-IDENTICAL: fjs/types/rtti
TOKEN-IDENTICAL: fjs/types/rtti/ts
DIFFERS: fjs/types/rtti/common
The one difference is worth calling out because it is the migration working as designed, not a defect. main's emit begins with import {} from '../module.f.js'; — a bare side-effect import left behind because rtti/common/module.f.ts imported types from ../module.f.ts. Now those come through /** @import … from '../types.ts' */, so the runtime edge is gone. Strip that single import from main's emit and the two files are byte-identical. That is exactly the "type-only edge the migration wants gone" from #1483, and it is unobservable here since these modules are pure.
npx tsc clean, 2356 pass / 0 fail, no any as a type in any emitted declaration, public surface 0 removed.
1. Primitive0, Tag0, and Tag1 are no longer tied to their runtime lists
On main these were derived, so the list was the single source of truth:
const primitive0List = ['bigint', 'boolean', 'number', 'string'] as const
export type Primitive0 = typeof primitive0List[number]
export const tag0List = [...primitive0List, 'unknown'] as const
export type Tag0 = typeof tag0List[number]
const tag1List = ['array', 'record'] as const
export type Tag1 = typeof tag1List[number]In types.ts they are now hand-written unions, while the lists stay in module.f.mjs. They agree today, so nothing is broken — but the guarantee that they must agree is gone. I tested it rather than assuming, in clean trees (an earlier attempt of mine was contaminated by prepack artifacts shadowing the .mjs with its .d.mts, so these numbers are from trees with no emitted files). Adding 'symbol' to primitive0List:
| Tree | Errors after the edit |
|---|---|
main |
2 — the type follows the list |
| this branch | 0 — the type does not |
Both baselines are 0. My probe is a Assert<Equal<…>> that I negative-controlled first: asserting a deliberately false equality yields 2 errors, so silence means agreement rather than a probe that never ran.
Two fixes, both of which I verified compile and restore the guarantee:
Tag0is a one-liner, sincetag0Listis already exported.import type { tag0List } from './module.f.mjs'intypes.ts, thenexport type Tag0 = typeof tag0List[number]. Baseline stays clean; the'symbol'edit goes back to 2 errors. This is the same type-only import back intomodule.f.mjsthatfjs/asn.1already does.Primitive0/Tag1can't do that without exporting their lists, so instead pin them from insidemodule.f.mjs, which can see them:
/** @typedef {Assert<Equal<Primitive0, typeof primitive0List[number]>>} _Primitive0Pinned */
/** @typedef {Assert<Equal<Tag1, typeof tag1List[number]>>} _Tag1Pinned */Clean at baseline; drifting tag1List produces Type 'false' does not satisfy the constraint 'true'.
Worth noting this also confirms /** @type {const} */ ([…]) is behaving as a real as const — otherwise the derived form would not have matched the literal union at baseline.
2. Type0 and MakeType1 are newly public without the _ prefix
Both were non-exported on main (type Type0<T extends Tag0>, type MakeType1<K extends Tag1>) while appearing in the signatures of exported values like array: MakeType1<'array'>. They are now exported from types.ts unprefixed.
This is the Byte/NodeList case again, and the reason I raise it rather than assume it's deliberate is that the same PR gets it right five times — _Attributes, _HashState, _Signature, _Tests, _Entries all carry the prefix. So the convention was applied, just not to these two.
If Type0 is meant to be public now — it is documented and every exported Boolean/Number/String alias is built from it — that is a defensible call; it just deserves to be intentional rather than a side effect of the move.
No correctness objection; CI is green on the earlier commits and still running here. Happy to approve once these are settled.
Converts module.f.ts to JSDoc-typed module.f.mjs under the stage-1 TypeScript-to-mjs migration. This module has no new public types of its own (only re-exports from rtti/common), so no types.ts companion is needed. proof.f.ts stays TypeScript: it has a type-only dependency on djs's still-unmigrated Unknown type, and AGENTS.md requires such a type to be split into a types.ts before a migrated .f.mjs consumer can reference it — out of scope here. Updates the six dependents (protocol/mcp, protocol/json_rpc x2, dev/package_json, media, media/revision) to import validate from module.f.mjs and the re-exported types (Validate, ValidationError) directly from rtti/common/types.ts. Fixes two stale doc references.
Tag0 was hand-copied from tag0List rather than derived, silently dropping the compile-time guarantee that the union and the runtime list agree. Restores it via `export type Tag0 = typeof tag0List[number]`, importing the now-exported tag0List type-only from module.f.mjs (same pattern fjs/asn.1 already uses). Primitive0 and Tag1 can't do the same since their backing lists (primitive0List, tag1List) aren't exported, so instead pins them from inside module.f.mjs, which can see the lists, via `Assert<Equal<Primitive0, typeof primitive0List[number]>>` and the Tag1 equivalent. Verified both catch drift: adding a bogus 'symbol' literal to primitive0List reproduces the same 2-error count main's derived form produces, confirming the guarantee is restored rather than silently absent. Also renames Type0 and MakeType1 to _Type0/_MakeType1: both were non-exported on main despite appearing in exported signatures (array: MakeType1<'array'>), the same private-type-goes-public case as Byte/NodeList in earlier commits.
|
Great catch on the derived-type guarantee — thanks for negative-controlling it too. Both fixed in 439cf51, exactly as suggested:
Generated by Claude Code |
Splits the Result<T>/Parse<T> types into a sibling types.ts, and converts the runtime implementation (parse, and the container/const builders it composes) to JSDoc-typed module.f.mjs under the stage-1 TypeScript-to-mjs migration. proof.f.ts stays TypeScript: it has a type-only dependency on djs's still-unmigrated Unknown type, same as rtti/validate/proof.f.ts. Updates the four dependents (ci/common, mcp, mcp/evo, emergent_testing) to import parse from module.f.mjs. Fixes two stale doc references.
Splits the type-level API (Os, Architecture, Image, Step, Job, Jobs, GitHubAction, StepType, MetaStep) into a sibling types.ts, and converts the runtime implementation (os, architecture, stepSchema, jobSchema, jobsSchema, gitHubActionSchema, parseGitHubAction, uses, install, test, toSteps, ubuntu, ubuntuArm) to JSDoc-typed module.f.mjs under the stage-1 TypeScript-to-mjs migration. Updates the nine dependents (fjs/ci itself, and its node/rust/deno/bun/nix submodules) to import runtime values from module.f.mjs and types from types.ts. Fixes five stale doc references in fjs/ci/todo and AGENTS.md.
Converts module.f.ts to JSDoc-typed module.f.mjs under the stage-1 TypeScript-to-mjs migration; no public types, no proof file. Updates the sole dependent, fjs/ci/module.f.ts, to import from the .f.mjs specifier (missed by an initial substring grep since the relative import path './bun/module.f.ts' doesn't repeat the 'ci' directory name — caught via tsc and an exhaustive resolved-path scan). Fixes three stale doc references.
Converts module.f.ts and proof.f.ts to JSDoc-typed module.f.mjs and proof.f.mjs under the stage-1 TypeScript-to-mjs migration; no public types. Updates both dependents (fjs/ci/module.f.ts, fjs/ci/proof.f.ts) to import from the .f.mjs specifier. Fixes five stale doc references.
Converts module.f.ts to JSDoc-typed module.f.mjs under the stage-1 TypeScript-to-mjs migration; no public types, no proof file. Updates the sole dependent, fjs/ci/module.f.ts, to import from the .f.mjs specifier. Fixes six stale doc references.
Splits the Expression type and its private helper types (Binding, Reference, AttributeSet, NixList, Application, OpenSetPattern, Lambda, Let, IndentedString, AttributePath, Chunks — all _-prefixed as private cross-file types) into a sibling types.ts, and converts the runtime serializer (nix, nixToString, and the internal serialize* helpers) to JSDoc-typed module.f.mjs/proof.f.mjs under the stage-1 TypeScript-to-mjs migration. Updates the sole dependent, fjs/ci/nix/module.f.ts, to import nixToString from module.f.mjs and Expression from types.ts. Fixes three stale doc references.
o2alexanderfedin
left a comment
There was a problem hiding this comment.
Approving. Reviewed at b174648 against main (cbcc7ab). Thirteen modules.
Both prior findings are fixed, and the fix demonstrably works
439cf51 restores the derived-type guarantee and applies the prefixes. I re-ran the drift test rather than reading the diff — clean tree, no prepack artifacts:
| Edit | Result |
|---|---|
add 'symbol' to primitive0List |
2 errors — _Primitive0Pinned and the _AssertType in types.ts both fire |
add 'tuple' to tag1List |
1 error — _Tag1Pinned fires |
Baseline is clean, so the lists and the types can no longer drift apart silently. Tag0 is back to typeof tag0List[number] via the type-only import, and Type0/MakeType1 are now _Type0/_MakeType1.
Runtime logic across all thirteen modules
main's compiled module.f.js versus each authored module.f.mjs:
equivalent: 13 differing: 0
I discount only four things, each an artifact of the migration rather than a change: elided type-only imports (the bare import {} from … TypeScript leaves behind), .f.js → .f.mjs specifiers for modules co-migrated in this PR, trailing commas, and parens left by removed annotations. To make sure that normalization isn't so permissive as to be meaningless, I checked it two ways: it still reports ci/bun and ci/deno as different modules, and injecting a one-token change (--release → --debug in ci/rust) is caught.
Also verified
npx tscclean; 2356 pass / 0 fail.- Public type surface: 0 removed. 22 additions, every one
_-prefixed — the convention is now being applied without prompting, including on the newmedia/nixsplit. - The nine changed entries are all benign:
Boolean/Number/String/Bigint/Unknowndiffer only by theType0→_Type0rename,Expressiononly because its constituents gained the prefix,Primitive0/Tag1are the intended re-derivation, and_Mergeis my by-name comparison seeingbtree's_Merge<A, T>alongsidesul's unrelated module-scoped_Merge. - No
anyas a type in any emitted declaration. - Doc references are clean — 43 broken on
main, 43 here, none added. Themedia/nix,rtti, andcicommits each swept their owntodo/files as they went, which is the habit that closes this out.
One nit
The two newest CHANGELOG entries name the pre-migration file — "fjs/types/rtti/parse/module.f.ts migrates from…" — where the sibling entries in the same section name the module (fjs/types/object, fjs/ci/common). Naming the old path is defensible for a migration note; it is only an inconsistency within one section, and not worth a commit on its own.
To be explicit about one thing my sweep flags that should not be changed: CHANGELOG.md:377 references fjs/ci/common/module.f.ts inside the released 0.39.0 section. §8.3 says not to rewrite released sections from an unrelated PR, so leaving it is correct.
CI is green on the earlier commits and still finishing on b174648; I verified locally at b174648 directly.
Splits the type-level API (TerminalRange, Sequence, Variant, DataRule, LazyRule, Rule, RangeVariant, None, Option, Repeat0Plus, Repeat1Plus, Join1Plus, Join0Plus, Repeat) into a sibling types.ts, and converts the runtime implementation (rangeEncode, oneEncode, eof, fullRange, unicodeRange, unicodeMax, rangeDecode, toSequence, str, set, range, remove, not, notSet, none, option, repeat0Plus, repeat1Plus, join1Plus, join0Plus, commaJoin0Plus, repeat, isEmpty) to JSDoc-typed module.f.mjs under the stage-1 TypeScript-to-mjs migration. proof.f.ts and testlib.f.ts stay TypeScript: proof.f.ts has a runtime dependency on testlib.f.ts, which is a shared test-fixture library (not itself a proof/module file) still authored in TypeScript. Updates the nine other dependents (bnf/token_symbol, bnf/descent module+proof, bnf/ll1 module+proof, bnf/data module+proof, djs/tokenizer, fsc/json.f.ts, fsc/bnf.f.ts) to import runtime values from module.f.mjs and types from types.ts, splitting mixed import statements where needed. Fixes eleven stale doc references.
|
Thanks for the approval and the thorough runtime-equivalence verification across all thirteen modules! Noted the CHANGELOG naming nit for future entries. Landed one more module since your review — Generated by Claude Code |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5941c986a1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export type Image = typeof images[Os][Architecture] | ||
|
|
||
| export const stepSchema = { | ||
| export const stepSchema = /** @type {const} */ ({ |
There was a problem hiding this comment.
Preserve readonly schema properties in declaration emit
Preserve the previous readonly object shape when migrating these exported schemas. During declaration emit, this @type {const} form becomes an exported namespace whose properties are mutable (stepSchema.run = stepSchema.run type-checks), whereas the former .f.ts declaration rejected assignment because every property was readonly; gitHubActionSchema has the same regression. This weakens the public API for package consumers despite runtime behavior being unchanged.
AGENTS.md reference: AGENTS.md:L449-L454
Useful? React with 👍 / 👎.
|
|
||
| A function-free, serializable representation of `Type` in | ||
| [`fjs/types/rtti/module.f.ts`](../module.f.ts), modeled after | ||
| [`fjs/types/rtti/module.f.mjs`](../module.f.ts), modeled after |
There was a problem hiding this comment.
Point migrated documentation links at the new files
Update the Markdown target along with the displayed filename: this link still resolves to the deleted module.f.ts. The same stale destination appears in fjs/bnf/todo/bigint-symbols.md:267, terminal-range-representation.md:100, and unicode-rules.md:183; additionally, fjs/types/rtti/README.md:47 still tells readers to import the removed RTTI entry point, so following these migration docs now leads to missing files.
Useful? React with 👍 / 👎.
Several earlier commits updated a link's visible label text ([`fjs/bnf/module.f.mjs`]) but not its href, since the sed patterns matched the label's fuller path but not the relative href (e.g. ../module.f.ts, which lacks the bnf/ prefix the label carries) — the same relative-path substring-miss pattern that has recurred throughout this migration. Fixes all four affected links (three in fjs/bnf/todo, one in fjs/types/rtti/todo) plus fjs/types/rtti/README.md's code example, which still imported from the removed module.f.ts/ validate/module.f.ts/ts/module.f.ts entry points. Verified with a repo-wide scan for the [`*.f.mjs`](*.f.ts) mismatch pattern: none remain.
|
Checked both findings:
Generated by Claude Code |
|
@codex review |
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a035585300
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /** | ||
| * Full 24-bit symbol range packed into a single {@link TerminalRange}. | ||
| */ | ||
| export const fullRange = 0x000000_FFFFFF |
There was a problem hiding this comment.
Preserve the public range constant types
Annotate fullRange as TerminalRange during the migration; declaration emit now exposes the literal type 16777215 instead of the previous TerminalRange/number, so consumer code such as const range: typeof fullRange = rangeEncode(a, b) no longer type-checks. unicodeRange has the same narrowing regression.
AGENTS.md reference: AGENTS.md:L449-L454
Useful? React with 👍 / 👎.
| ```ts | ||
| // fjs/types/rtti/common/module.f.ts:124 | ||
| // fjs/types/rtti/common/module.f.mjs:124 | ||
| export const visit = <R>(v: Visitor<R>) => (rtti: Type): R => { |
There was a problem hiding this comment.
Refresh all migrated design references
Update the locations throughout this issue rather than only changing their extensions: common/module.f.mjs:124 and :99 now point away from visit and visitConst (currently lines 164 and 79), while the printer reference ts/module.f.mjs:118-145 is now at lines 41-61. The caveat at lines 182-183 also still instructs an implementer to import the deleted module.f.ts paths instead of the new runtime/type split, so following this concrete design leads to unrelated or nonexistent sources.
AGENTS.md reference: AGENTS.md:L337-L339
Useful? React with 👍 / 👎.
fullRange/unicodeRange lost their TerminalRange type in declaration emit without an explicit @type annotation. 662.md still cited deleted .f.ts paths and pre-migration line numbers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9bV7Civ4LaC6GPsjcgnJY
|
@codex review |
o2alexanderfedin
left a comment
There was a problem hiding this comment.
Reviewed at e11269a (14 modules now). a035585's claim checks out — I scanned every relative markdown link in the repo and there are 0 label/target extension mismatches left. tsc clean, 2356 pass / 0 fail, public type surface 0 removed, 23 additions all _-prefixed.
fjs/bnf reorders top-level declarations (fullRange/unicodeRange/unicodeMax move below eof), so it is the one module that isn't token-identical to main's compiled output. Reordering consts can bite through TDZ, so I checked it properly rather than reading it: imported both module versions and compared all 23 exports. Names match exactly, the 5 value exports are identical (eof, fullRange, none, unicodeMax, unicodeRange), and the 18 function exports return identical results on sampled inputs. The other 13 modules are token-identical as before. Safe.
Two one-line things.
1. Two markdown links still point at fjs/bnf/module.f.ts
fjs/bnf/README.md:5 - the functional representation [./module.f.ts](./module.f.ts),
fjs/bnf/todo/46.md:9 [../module.f.ts](../module.f.ts), serializable form in
fjs/bnf/module.f.ts no longer exists. These survived both a035585 and e11269a for a mechanical reason worth naming, because it is the third variant of this bug: the target is relative and has no fjs/ prefix, so a grep 'fjs/bnf/module\.f\.ts' never sees it, and both label and target say .f.ts, so the […mjs](….ts) mismatch scan does not see it either. The two sweeps were each looking for a shape this instance doesn't have.
A check that would end this class outright is resolving every relative markdown link against the filesystem rather than pattern-matching the text. Against main as baseline that comes out at 144 broken links before and 146 after, and the two added are exactly the ones above — no other regressions anywhere in the repo, and the pre-existing 144 stay out of scope.
2. eof lost the TerminalRange annotation its neighbours just regained
e11269a adds @type {TerminalRange} to fullRange and unicodeRange, but eof is annotated on main and isn't here:
// main
export declare const eof: TerminalRange;
// this branch
export declare const eof: number;TerminalRange is number, so nothing is weakened — assignability is unchanged in both directions and no caller can tell. It is purely that the declaration no longer says what the number means, and all three constants were consistent on main. One /** @type {TerminalRange} */ above export const eof restores it.
Not a finding, just so it's on record
The per-arrow @template/@param style emits the JSDoc block inside the parameter list of the shipped declaration:
export declare const option: <S extends Rule>(
/**
* @template {Rule} S
* @param {S} some
* @returns {Option<S>}
*/
some: S) => Option<S>;I checked before raising it and this is pre-existing — main already ships 14 of these from earlier migrations (types/array, types/sorted_list, types/sorted_set, range_map, bit_vec, list, sul/level/hash). This branch adds 7 more (bnf's three, sul::encode, and rtti/common's three), consistent with how the repo already does it. The types are correct; only the rendered declaration is noisy. Not this PR's job to fix, and I would not change the style here — worth a separate look someday if the emit ever matters.
CI green on the earlier commits, still finishing on e11269a; verified locally at e11269a. Happy to approve once the two above are in.
… type Two relative markdown links (no fjs/ prefix, both label and target saying .f.ts) escaped the earlier link-mismatch sweeps. eof was missing the TerminalRange annotation its two neighbours regained. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9bV7Civ4LaC6GPsjcgnJY
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e11269a87c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| * @module | ||
| */ | ||
| import type { Type } from '../types.ts' | ||
| import type { Result as CommonValidateResult, Validate } from '../common/types.ts' |
There was a problem hiding this comment.
Restore parse error-type re-exports
When consumers update the migrated type import to rtti/parse/types.ts, Path and ValidationError are no longer available: the former parse/module.f.ts explicitly re-exported both, while this companion only imports common types and exports Result and Parse. Downstream code using the parse module as its error-type entry point therefore fails to type-check; re-export the two common types here.
AGENTS.md reference: AGENTS.md:L449-L454
Useful? React with 👍 / 👎.
| export { | ||
| constPrimitiveValidate, | ||
| prependPath, | ||
| primitive0Validate, | ||
| verror, |
There was a problem hiding this comment.
Restore validate's type-level entry point
The former validate module publicly re-exported Path, Result, Validate, and ValidationError, but the migrated module now re-exports only runtime helpers and there is no validate/types.ts companion anywhere in the repository. Consumers importing those validation types lose the entire entry point after migration and fail to type-check; add a companion that preserves these re-exports.
AGENTS.md reference: AGENTS.md:L449-L454
Useful? React with 👍 / 👎.
parse/module.f.ts and validate/module.f.ts each re-exported Path/ ValidationError (and validate additionally Result/Validate) from common as their type-level entry point. The migrated modules dropped these; restore them via types.ts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9bV7Civ4LaC6GPsjcgnJY
|
@codex review |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Migrates four modules from authored TypeScript (
.f.ts) to JSDoc-typedJavaScript (
.f.mjs) under the stage-1 TypeScript-to-mjs migration(
todo/migrate-typescript-to-mjs.md), following thetypes.tsconvention introduced by #1481/#1483:
fjs/sul— splitsEncodeState<S>/Encode<S>intotypes.ts.No other module imports it; only
README.md's example updates.fjs/media/html— splitsElement/Nodeintotypes.ts.Updates the sole dependent,
fjs/website.fjs/crypto/sign— splits theAlltype intotypes.ts. Noother module imports it. Its 592-line proof is mostly RFC6979 test
vectors.
fjs/types/rtti— splits the full schema type-level API (Const,Type,Tag0,Tag1,Info0,Info1,Type0,Type1,MakeType1,Boolean,Number,String,Bigint,Unknown,Array,Record,Or,Struct,Tuple,ConstObject,Primitive0)into
types.ts. Updates 19 dependents acrossprotocol/mcp,protocol/json_rpc,dev/package_json,ci/common,media/json,media/json/schema,media/revision,media,mcp/evo,mcp/cas,mcp,emergent_testing, andrtti's owncommon/parse/validate/tssubmodules. Note: TypeScript's JSDoc parser special-cases the
identifiers
Boolean/Number/Stringas aliases for the primitivetypes (a legacy Closure Compiler convention), so the three runtime
consts of those names rely on inference rather than an explicit
@typeannotation naming the colliding type.Also fixes stale
todo/doc links to paths this PR renamed, includingseveral flagged in review for the
fjs/sul/fjs/media/htmlmigrations.Test plan
npx tsc --noEmit— clean, 0 errors, matchingmainnode ./fjs/module.ts t— all 2356 tests pass, 0 failures**BREAKING CHANGES:**entry for eachof the four migrations