TypeScript runtime for Interscript — interoperable script conversion systems.
A TypeScript-native port of the Ruby runtime, designed for modern Node.js, bundlers, and the browser. Consumes JSON IR (intermediate representation) emitted by the Ruby gem's Compiler::JsonIR.
🟡 v0.1 — preview. 4/5 sample maps achieve byte-exact Ruby parity. See TODO.complete/42 for the remaining gap.
npm install interscript-tsimport{transliterate,configure,bundledStrategy}from"interscript-ts"// Load IR maps from a JSON dictionary (e.g. fetched, bundled, or read from disk)configure({strategies: [bundledStrategy({"bgnpcgn-ukr-Cyrl-Latn-2019": {/* IR */},})],})transliterate("bgnpcgn-ukr-Cyrl-Latn-2019","Антон")// → "Anton"transliterate("bgnpcgn-deu-Latn-Latn-2000","Tschüß!")// → "Tschueß!"transliterate("odni-rus-Cyrl-Latn-2015","привет")// → "privet"transliterate("alalc-amh-Ethi-Latn-2011","ኢትዮጵያ")// → "ʼiteyop̣eyā"import{configure,transliterate,filesystemStrategy}from"interscript-ts"configure({strategies: [filesystemStrategy("./maps")]})// reads `./maps/<systemCode>.json` on demand, cachesnpx interscript-ts -s bgnpcgn-ukr-Cyrl-Latn-2019 -i input.txt --maps-dir ./mapsReads stdin if -i is omitted; writes stdout if -o is omitted.
| Principle | Implementation |
|---|---|
| OCP | Discriminated unions for AST; new node kinds add via variants + executor registry entries |
| MECE | One responsibility per module: errors, types, stdlib, loader, loaders, detector, runtime/{context,compile-item,executor,interpreter} |
| DRY | compileItem shared by all executors; ExecutionContext shared state |
| Model-driven | types.ts defines domain (Stage, Rule, Item); everything else references it |
| Performance | Trie-based parallel replace (O(n) single pass), cached maps, lazy alias resolution |
| Ruby | TypeScript |
|---|---|
Interscript.transliterate(systemCode, string) | transliterate(systemCode, input, stage?) |
Interscript.load(systemCode) | loadMap(systemCode) |
Interscript.detect(input, output) | detect(input, output, opts?) |
The Ruby gem ships Compiler::JsonIR (PR #757):
cd interscript-ruby
bundle exec rake compile:json_ir[target_directory]Or programmatically:
require"interscript/compiler/json_ir"Interscript::Compiler::JsonIR.call(Interscript.parse(map_name)).codenpm ci
npm test# 118 unit + property + edge tests
npm run test:coverage # 80% thresholds enforced
npm run test:bench # benchmark suite (regression detection)
npm run test:parity # Ruby parity tests (requires fixtures)
npm run lint
npm run buildGenerate fresh parity fixtures (requires Ruby + interscript gem):
npm run gen:parity- Unit: stdlib, interpreter, executor, compile-item, loader, errors, detector
- Property: deterministic PRNG; round-trip, idempotence, longest-match invariants
- Edge cases: empty input, 10k chars, astral plane, determinism
- Parity: byte-exact comparison with Ruby interpreter across 5 sample maps
- Bench: trie reuse, parallel replace, end-to-end transliteration
BSD-2-Clause — Ribose Inc.
- Interscript Ruby — reference runtime
- Interscript maps — map corpus
- Interscript.org — main site