mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 22:07:15 +01:00
`Clock` and a seeded mulberry32 RNG had each been reimplemented across the game and web repos -- Clock twice (konbini-67, iron-and-anvil, doc comments near-verbatim), the RNG four times. None of it is UI, so no existing shared package owned it: `web_ui` ships `tokens.css` and React components, and a game importing a UI package to get a seeded RNG is exactly the coupling that makes people vendor their own copy instead. The RNG deliberately exports **two** interfaces rather than reconciling them into one. konbini-67 threaded mutable state through free functions; sims3-clone and europe-county-map returned an object of closures. The sequence is the contract here -- these repos have seeded tests and "same seed -> identical world" guarantees, so changing how many times a helper advances the generator silently re-rolls every saved world. A shared package that did that would be worse than the duplication it replaces. The core is shared, so both interfaces yield the same float sequence; that is asserted, not assumed. `rng.test.ts` pins the first five floats for seed 12345, captured from the pre-extraction konbini-67 implementation rather than from this one -- a golden test generated from the code under test only asserts that the code matches itself. It earned its place immediately: the first constants I wrote came from a truncated `toFixed(9)` probe and the test failed, which is precisely the class of silent precision drift it exists to catch. `hotline3d` is not a consumer and should not become one. Its generator uses `%` and `Math.trunc` where mulberry32 uses `>>>`/`>>`; measured, it emits a different sequence, so adopting this package would change its output. 29 tests, 100% branch/function/line/statement coverage, type-aware eslint, and a committed dist/ with a CI freshness check -- the same bar web_ui holds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U4Rj3s7K2qzrLNgJqqPhno
43 lines
1.3 KiB
JSON
43 lines
1.3 KiB
JSON
{
|
|
"compilerOptions": {
|
|
"target": "ES2023",
|
|
// DOM is here only for `performance.now()` in clock.ts -- the package
|
|
// ships no DOM *code*. Without it the build fails while the lint config
|
|
// (which adds @types/node) passes, so the two must not be trusted to
|
|
// agree by accident.
|
|
"lib": ["ESNext", "DOM"],
|
|
"module": "ESNext",
|
|
"moduleResolution": "bundler",
|
|
|
|
/* Strictness: everything on, matching the consumers so a file that
|
|
compiles here compiles there. */
|
|
"strict": true,
|
|
"noUncheckedIndexedAccess": true,
|
|
"noImplicitOverride": true,
|
|
"noImplicitReturns": true,
|
|
"noFallthroughCasesInSwitch": true,
|
|
"noUnusedLocals": true,
|
|
"noUnusedParameters": true,
|
|
"exactOptionalPropertyTypes": true,
|
|
"useUnknownInCatchVariables": true,
|
|
"verbatimModuleSyntax": true,
|
|
"isolatedModules": true,
|
|
"erasableSyntaxOnly": true,
|
|
|
|
/* Ships a prebuilt dist/ (ESM + .d.ts) because consumers use Vite, which
|
|
does not transpile dependencies. */
|
|
"rewriteRelativeImportExtensions": true,
|
|
"allowImportingTsExtensions": true,
|
|
"declaration": true,
|
|
"declarationMap": true,
|
|
"sourceMap": true,
|
|
"outDir": "dist",
|
|
"rootDir": "src",
|
|
|
|
"skipLibCheck": true,
|
|
"forceConsistentCasingInFileNames": true
|
|
},
|
|
"include": ["src"],
|
|
"exclude": ["src/**/*.test.ts"]
|
|
}
|