Files
sk-react-toolkit/README.md
T

5.5 KiB

sk-react-toolkit

The shared code of the web tools built as a Fastify server in TypeScript and a React application with MUI built by Vite, such as azure-platform's manage-ui and sql-query-webui. It is TypeScript source: Node 26 runs the server helpers, and the application's Vite build compiles the web code.

Using it

The package is @koszewscy/sk-react-toolkit, published to the npm registry of Gitea, https://gitea.koszewscy.waw.pl/api/packages/koszewscy/npm/. An application imports it as sk-react-toolkit, by an alias. Its .npmrc names the registry of the scope:

@koszewscy:registry=https://gitea.koszewscy.waw.pl/api/packages/koszewscy/npm/
{ "dependencies": { "sk-react-toolkit": "npm:@koszewscy/sk-react-toolkit@^0.1.0" } }

While the toolkit and an application change together, the application depends on the checkout next to its own repository instead, the TypeScript source:

{ "dependencies": { "sk-react-toolkit": "file:../sk-react-toolkit" } }

npm links the checkout into node_modules, and npm ci keeps the link. The web application adds the toolkit's resolve options and font plugin to its vite.config.ts, so React, MUI and Emotion come from its own node_modules, and allows the dev server to read the checkout:

import { font, fontChoice, TOOLKIT_RESOLVE } from 'sk-react-toolkit/vite'
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ mode }) => ({
  plugins: [react(), font(fontChoice(loadEnv(mode, import.meta.dirname)))],
  resolve: TOOLKIT_RESOLVE,
  server: { fs: { allow: ['..', '../../sk-react-toolkit'] } },
}))

The peer dependencies are the application's: fastify and @fastify/static for the server helpers; react, react-dom, @mui/material, @mui/icons-material and Emotion for the web code; vite for the Vite helpers.

sk-react-toolkit/server

Export Purpose
HttpError an error answered with its status and { error }, with problems and a detail message for a refused write
strict(properties) the JSON schema of an object with exactly these properties, all required
errorHandler(log) Fastify's error handler: { error }, or { error, problems, message }; unexpected 5xx errors logged with their stack
notFoundHandler(webDir, buildHint) 404 for /api paths, index.html for the others, 503 with the hint while the frontend is not built
createLog, timestampsOn, QUIET, Log the log of a server, with optional timestamps and requests; QUIET for tests
fail(message) prints the error in red and ends the process with status 2
gitVersion(dir, variable) git describe of the checkout, else the environment variable, else dev
exitOnSignals(close) closes the server on Ctrl-C and SIGTERM, ending the process after 5 seconds at most
readJsonObject(path, options) a JSON object file and its version, the SHA-256 of its bytes; optionally {} for a missing file

sk-react-toolkit/web

Export Purpose
request, ApiError, Validation a JSON call to the backend, its error with the problems of a refused write, and the answer of a validate endpoint
appTheme(colorSchemes?), renderApp(options) the theme (light, dark and system, Regular font, small text fields) and the startup that retries the first call while showing Connecting
REGULAR, MONOSPACED, verbatim the font styles and the attributes of inputs the browser must not change
Card a centered panel with a title and a message
ThemeMenu the button cycling light, dark and system theme
SwitcherMenu, SwitcherItem a button naming the item chosen, whose menu chooses another, such as a page or a connection
TextInput a text field with clear and show/hide buttons
RowDialog, useValidation a dialog that edits a value validated by the server as it changes, and the validation hook
createBrowserSettings(keys, event) switches kept in localStorage and followed across tabs

sk-react-toolkit/vite

Export Purpose
font(choice), fontChoice(env), FONTS the font plugin of VITE_FONT: cdn (Google Fonts links, the default), bundled (@fontsource/roboto, a dependency of the application) or none
TOOLKIT_RESOLVE the resolve options that keep one copy of React, MUI and Emotion

Development

npm install installs the peer dependencies as development dependencies; npm run typecheck and npm run lint check the code. npm run build (build.mjs) builds the published package in dist/: the code compiled to JavaScript with its declarations, README.md, CHANGELOG.md and a package.json whose exports name the compiled files.

Releases

./release.mjs commits, tags the version of the newest CHANGELOG.md entry and pushes main with the tag; -n prints the git commands instead. The version of a release of the code, x.y.z, is that of package.json, so a release raises both. A tag x.y.z-n releases changes that are not code changes; its version is already published, so its run publishes nothing.

The Release workflow, .gitea/workflows/release.yml, builds and publishes the package on Gitea Actions for each tag and on demand: it installs the dependencies, typechecks and lints the code, builds the package and publishes dist/ to the npm registry of the owner CI_OWNER on the server CI_URL, with CI_TOKEN, a token with the package scope; all three are secrets of the repository. A version already published is skipped, as the registry refuses the same version again.