@clean-jsdoc-theme/bhasha
v5.0.3
Published
Pure, browser-safe i18n core for clean-jsdoc-theme (catalog, t, provider, key scheme, validation)
Readme
@clean-jsdoc-theme/bhasha
The pure, browser-safe i18n runtime. The disk-bound extract/translate/build pipeline lives in
@clean-jsdoc-theme/aadesh.
The internationalization core for clean-jsdoc-theme. bhasha is isomorphic —
zero node:* — because rang bundles it into the browser. It holds the
translatable chrome catalog, the t translator and its fallback chain, the
LanguageProvider static carrier, the API-slot key scheme, and the validation
primitives. setu and aadesh import its key/hash helpers so they agree on slot
identity + staleness. The full localization walkthrough is in
Localize your docs.
What's here
Chrome catalog
EN_CHROME is the canonical list of UI strings, authored as a nested object and
flattened to dotted chrome.* keys. The key union is derived from the
catalog, so every t('chrome.…') call is compile-checked.
import { EN_CHROME, EN_CHROME_FLAT, type ChromeKey } from '@clean-jsdoc-theme/bhasha';t + provider
LanguageProvider is a static carrier — an immutable per-render value, no
setter (locale is a build dimension, not a runtime toggle). With no provider, t
returns exact English (the byte-identical no-locale baseline).
import { LanguageProvider, useTranslation, createI18n } from '@clean-jsdoc-theme/bhasha';
function ThemeButton() {
const { t } = useTranslation();
return <button title={t('chrome.theme.toggleTitle')}>{t('chrome.theme.switchTo', { mode: 'dark' })}</button>;
}
// Seed an island root (browser) or a page render (SSR):
const i18n = createI18n({ locale: 'fr', messages: { 'chrome.theme.toggleTitle': 'Basculer le thème' } });
<LanguageProvider value={i18n}>{/* … */}</LanguageProvider>;Fallback chain: active locale → default locale → the key (chrome) or the
source text (translateSlot, API slots). An empty value counts as
untranslated and falls through.
Interpolation is simple named {token} substitution (t(key, { count: 3 }));
ICU plurals are deferred.
API slot keys + staleness
import { apiSlotKey, sourceHash } from '@clean-jsdoc-theme/bhasha';
apiSlotKey('Foo#bar', ['params', '0', 'description']); // 'api.Foo#bar#params.0.description'
sourceHash('The Foo class.'); // '9d6177d6' — FNV-1a; changes when source text changesValidation primitives
Built on the theme's diagnostics spine (DiagnosticBag / suggestKey from
@clean-jsdoc-theme/utils). A gap warns; a malformation errors, reported
against the key.
import {
validateCatalogShape, // missing → warn, unknown → error (+ "did you mean?")
catalogCoverage, // { translated, total, ratio }
lintSlotMarkdown, // unbalanced fence / {@link} / braces → error
validateTokenParity, // dropped/added {token} → error
} from '@clean-jsdoc-theme/bhasha';License
MIT.
