fix(data,export): collapse the STEP string escaper's two TS copies into one (#3300) - #3378
fix(data,export): collapse the STEP string escaper's two TS copies into one (#3300)#3378BIMvoice wants to merge 2 commits into
Conversation
…to one (#3300) @ifc-lite/data's step-serializers.ts and @ifc-lite/export's step-serialization.ts each kept a byte-identical escapeStepString (backslash/quote doubling, \X2\/\X4\ non-ASCII directives, one space per control char). export already depends on data with no cycle, so data now exports the function and export re-exports it instead of keeping its own body; every existing call site is unaffected. The rust implementation (ifc_lite_export::step_text::escape) stays separate -- a wasm adapter to share it is out of scope here -- and stays pinned by a hand-kept vector test rather than shared code. #3284's parity test, which asserted the two TS copies agreed with Rust, is gone from the export package (there is nothing left to duplicate there) and the coverage lives once in data's step-serializers.test.ts, which also gains direct tests of escapeStepString now that it is exported. Verified today's three implementations agree on backslash, apostrophe, non-ASCII, an already-escaped-looking sequence, and the empty string before collapsing. The encoding package's separate encodeIfcString is a genuinely different, partial implementation (whole-Latin-1 \X\HH range, no '' doubling) and is left alone per the issue. Claude-Session: https://claude.ai/code/session_01QPHChk3Ve9N519A4kY7436
|
Warning Review limit reached
This review includes 7 billable files and costs up to $1.75. Or wait 29 minutes for your next included review. View limit detailsLimit details: You’ve used all 2 included reviews currently available. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
Comment |
Viewer benchmark✅ No threshold regressions detected. 01_Snowdon_Towers_Sample_Structural(1).ifcBaseline recorded 2026-07-01T20:31:05.538Z on github-actions ubuntu-latest, viewer-benchmark-ci (headless Chrome, SwiftShader ANGLE), production build.
AC20-FZK-Haus.ifcBaseline recorded 2026-07-01T20:30:59.972Z on github-actions ubuntu-latest, viewer-benchmark-ci (headless Chrome, SwiftShader ANGLE), production build.
Refresh the baseline from a CI run: dispatch the Benchmark workflow with |
…dget `step-serializers.ts` sits at a 459-line budget and the #3300 note pushed it to 465, failing the 'Check TypeScript module size ratchet' step in Node tests. Trimmed the added comment rather than raising the budget: a reviewer flagged a budget raise on a sibling PR today, and the house rule treats a raise as a last resort needing written justification. The note still says what matters -- this is the one TS implementation, export re-exports it, and a vector test pins parity with the separate Rust escaper.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
Closes part of #3300.
The three sites, before this change
packages/data/src/step-serializers.tsescapeStepString, module-privatepackages/export/src/step-serialization.tsescapeStepString, exportedrust/export/src/step_text.rsescape(pub(crate))The two TypeScript bodies were byte-identical: same three-transform pipeline (backslash doubling, quote doubling, one-space-per-control-char), same
\X2\/\X4\non-ASCII directive thresholds, same 32–126 basic-graphic-range check.packages/export/package.jsonalready declares"@ifc-lite/data": "workspace:^"— one direction, no cycle — so there was no dependency reason for the second copy.Verified today's three implementations actually agree
Before collapsing anything, I ran the same awkward inputs — a bare backslash, an apostrophe, a BMP non-ASCII character, an already-
\X2\-looking sequence, control-char runs, and the empty string — through all three (TSdata, TSexport, and a temporary Rust unit test callingstep_text::escapedirectly). All three agreed on every case. No live divergence bug; this was pure duplication.What changed
@ifc-lite/data'sstep-serializers.tsnow exportsescapeStepString(was module-private) and is re-exported from the package'sindex.ts.@ifc-lite/export'sstep-serialization.tsdeletes its ownescapeStepString/encodeNonAsciiStepDirectivesbody and instead doesimport { escapeStepString } from '@ifc-lite/data'+export { escapeStepString }, so all five existing call sites (property-value-serialization.ts,step-georeferencing.ts,retype.ts,step-property-set-generators.ts,attribute-slot-types.ts) keep importing from./step-serialization.jsunchanged.scripts/api-surface.jsongains the one new@ifc-lite/dataexport entry (checked withcheck-api-surface.mjs, matches exactly).The Rust implementation is left alone: sharing it with TypeScript would need a wasm adapter, which is out of scope here, so the TS/Rust agreement stays pinned by a hand-kept vector test rather than shared code — same reasoning #3297 gave for the sibling lexical-rule issue (#3303).
#3284's parity test
A prior fix (#3284) added a
RUST_VECTORStable +it.eachblock in both TS test files, asserting each copy's control-character-run output matched Rust's observed output. With one TS implementation left:packages/export/src/step-serialization.test.ts's twodescribeblocks (non-ASCII directive tests + control-char-run parity table) are replaced by a single small "re-export resolves to a working function" smoke test — coverage of the actual behavior would otherwise be a second copy of the same assertions against the same underlying function.packages/data/src/step-serializers.test.tskeeps the fullRUST_VECTORSparity suite (comment updated to say it's the one remaining TS copy) and gains new direct tests ofescapeStepString(backslash, apostrophe, non-ASCII, already-escaped-looking text, empty string) now that the function is exported instead of reached only throughserializeValue/generateHeader.Mutation-checked: reverting the backslash-doubling regex to a no-op reds 3 tests in
data's suite and 2 inexport's re-export smoke test, restored cleanly by SHA.The fourth, partial copy — left alone
packages/encoding/src/ifc-string.ts'sencodeIfcStringis a genuinely different implementation, not a drop-in: it encodes the whole Latin-1 range as\X\HH(not\X2\HHHH\X0\), routes a backslash into that same arm as\X\5Cinstead of doubling it, and does no''quote-doubling or control-to-space mapping. It has no production call sites (only its ownifc-string.parity.test.ts). Folding it in is explicitly out of scope per the issue.Verification
🤖 Generated with Claude Code
https://claude.ai/code/session_01QPHChk3Ve9N519A4kY7436