Files
sk-react-toolkit/ADR.md
T

3.0 KiB

Architecture Decision Records

ADR-1: The toolkit is TypeScript source, linked into the applications

Status: Accepted

Context: manage-ui and sql-query-webui share their server helpers and web components. The applications run their servers with Node's type stripping and build their web code with Vite. The toolkit is to be published to Gitea later; until then it is developed next to them.

Decision: The toolkit ships its .ts and .tsx files without a build, with three entry points: ./server, ./web and ./vite. The applications depend on the checkout by a file: path, which npm links; Node runs the server helpers from the checkout's real path, where type stripping applies, and Vite compiles the web code. The server helpers import only Node's modules at run time, and types of Fastify; the Vite helpers import only types of Vite, taking loadEnv's answer from the application. The web code's React, MUI and Emotion come from the application, which dedupes them with TOOLKIT_RESOLVE. The peer dependencies are optional, as an application uses only some of the entry points, and are development dependencies for the toolkit's own checks.

Consequences: The applications need the checkout at ../sk-react-toolkit, and their container builds cannot install it until it is published. Node refuses type stripping in node_modules, so the published package is compiled (ADR-2).

ADR-2: The published package is built in dist/ and published to Gitea by a tag

Status: Accepted

Context: An installed package lives in node_modules, where Node does not strip types, so the published package has to be JavaScript, while the linked checkout stays TypeScript source. The repository is on Gitea, which has an npm registry per owner and Actions mostly compatible with GitHub's.

Decision: build.mjs compiles the toolkit with tsconfig.build.json, which rewrites the .ts import extensions to .js, into dist/ with declarations, and writes dist/package.json with exports of the compiled files and declarations; the package published is dist/, while the source package.json stays private with exports of the source. The name is @koszewscy/sk-react-toolkit, scoped to the owner, so an application takes only this scope from Gitea; it imports it as sk-react-toolkit by an npm alias, so the switch from the checkout to the published package changes only the dependency. The package is built and published only by the Release workflow, which follows linux-cloud-router's: it runs for each tag and on demand, with the secrets CI_URL, CI_OWNER and CI_TOKEN, and skips a version already published. actions/setup-node gives npm the registry of the package's scope and the token, so the package carries no registry; release.mjs refuses a tag x.y.z that is not the version of package.json.

Consequences: A release raises the version in both CHANGELOG.md and package.json, and a re-run, or a tag x.y.z-n, publishes nothing. The declarations of renderApp reference the declaration of the virtual:font module, which build.mjs copies into dist/.