{"_id":"@burojs/i18n-core","_rev":"2-72bf731920a9a9c3ca465215ada067bf","name":"@burojs/i18n-core","dist-tags":{"latest":"0.4.0"},"versions":{"0.2.0":{"name":"@burojs/i18n-core","version":"0.2.0","license":"MIT","_id":"@burojs/i18n-core@0.2.0","maintainers":[{"name":"maksimkuznetsov","email":"mak.kooz@gmail.com"}],"dist":{"shasum":"be51f82810d7cab48a6f19cccd673940ccbea4c2","tarball":"https://registry.npmjs.org/@burojs/i18n-core/-/i18n-core-0.2.0.tgz","fileCount":9,"integrity":"sha512-fMwLpDjeyMth374kj6TfD92hwpFPDxdwxuJSlEwbFwqu5qMDZD0mpbvE6zXmlcJ3VrdSMCDjMWN95Jur+ta+mg==","signatures":[{"sig":"MEUCIBsCssvcDx2h2RkaGEp7rtZYZqGabdm1CHVgXJquS8vGAiEAqovEipUYi1UtFLSNyAqipJ231nVyGcz1gqYTe6TJlu4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102337},"main":"./dist/index.cjs","type":"module","_from":"file:burojs-i18n-core-0.2.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"scripts":{"dev":"tsup --watch","build":"tsup","typecheck":"tsc --noEmit","typecheck:tests":"tsc -p tsconfig.test.json"},"_npmUser":{"name":"maksimkuznetsov","email":"mak.kooz@gmail.com"},"_resolved":"/tmp/25e9ef07c96a459ed80ed8147a338b2b/burojs-i18n-core-0.2.0.tgz","_integrity":"sha512-fMwLpDjeyMth374kj6TfD92hwpFPDxdwxuJSlEwbFwqu5qMDZD0mpbvE6zXmlcJ3VrdSMCDjMWN95Jur+ta+mg==","_npmVersion":"10.9.8","description":"Buro: hierarchical i18n with fallback chain over i18next","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@burojs/core":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","vitest":"^2.1.0","i18next":"^24.0.0","typescript":"^5.5.0","expect-type":"^1.1.0","@burojs/tooling-eslint":"0.0.0","@burojs/tooling-tsconfig":"0.0.0"},"peerDependencies":{"i18next":">=23 <27"},"_npmOperationalInternal":{"tmp":"tmp/i18n-core_0.2.0_1786820376203_0.8060208847987023","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@burojs/i18n-core@0.4.0","dist":{"shasum":"c9746df88b8b472eefc55ac59aa25e650d37a08e","tarball":"https://registry.npmjs.org/@burojs/i18n-core/-/i18n-core-0.4.0.tgz","fileCount":9,"integrity":"sha512-Eyx+5WPolW1wtKRkhjS9qUsWu6nB3HSqVqS8thIedQdPv7tnvkA+w8iAY+nZIv8Z60Oj1da/3R9dMqjV4gCQwQ==","signatures":[{"sig":"MEYCIQCNVl4mqOg+tEaOFfqj1M7npRMWur9uHBZJbpbwKyaD7AIhAO74v71uG3f3X/dhdYV+B8h88JJJCpbG+R/0djZlhzw6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCxIE+1PVxk7YQku1y7zm85NoUA2Wx49HNpvTGoFdZ0+QIgD0fTAIRJOFpaK44nQyTaWFMxuayNVJFgEfe+aM/N2LY="}],"unpackedSize":95906},"main":"./dist/index.cjs","name":"@burojs/i18n-core","type":"module","_from":"file:burojs-i18n-core-0.4.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./package.json":"./package.json"},"license":"MIT","scripts":{"dev":"tsdown --watch","build":"tsdown","typecheck":"tsc --noEmit","typecheck:tests":"tsc -p tsconfig.test.json"},"version":"0.4.0","_npmUser":{"name":"maksimkuznetsov","email":"mak.kooz@gmail.com"},"_resolved":"/tmp/de6b68cbf0879af6583645e33a3f50be/burojs-i18n-core-0.4.0.tgz","_integrity":"sha512-Eyx+5WPolW1wtKRkhjS9qUsWu6nB3HSqVqS8thIedQdPv7tnvkA+w8iAY+nZIv8Z60Oj1da/3R9dMqjV4gCQwQ==","_npmVersion":"10.9.8","description":"Buro: hierarchical i18n with fallback chain over i18next","directories":{},"maintainers":[{"name":"maksimkuznetsov","email":"mak.kooz@gmail.com"}],"_nodeVersion":"22.23.2","dependencies":{"@burojs/core":"0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.0","i18next":"^24.0.0","typescript":"^5.5.0","expect-type":"^1.1.0","@burojs/tooling-eslint":"0.0.0","@burojs/tooling-tsconfig":"0.0.0"},"peerDependencies":{"i18next":">=23 <27"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/i18n-core_0.4.0_1790626270241_0.5116354998807975"}}},"time":{"created":"2026-08-15T18:59:36.044Z","modified":"2026-09-28T20:11:10.507Z","0.2.0":"2026-08-15T18:59:36.382Z","0.4.0":"2026-09-28T20:11:10.319Z"},"license":"MIT","description":"Buro: hierarchical i18n with fallback chain over i18next","maintainers":[{"name":"maksimkuznetsov","email":"mak.kooz@gmail.com"}],"readme":"# @burojs/i18n-core\n\nHierarchical i18n for [buro](https://github.com/buro/buro), with a per-resource fallback chain over [i18next](https://www.i18next.com).\n\nTranslation happens at **render time**, so switching language updates the whole UI live — no reload, no refetch.\n\n## Install\n\n```bash\npnpm add @burojs/i18n-core\n```\n\n## Usage\n\n```ts\nimport { createI18n, createI18nextAdapter } from '@burojs/i18n-core';\n\nconst i18n = createI18n({\n  adapter: createI18nextAdapter({\n    defaultLocale: 'ru',\n    locales: ['ru', 'en'],\n    resources: { ru: ruBundle, en: enBundle },\n    fallbackLocale: 'en',\n  }),\n});\n```\n\n## Key resolution\n\nA key is resolved against the most specific namespace first and falls back outward, so a resource can override a shared string without copying the rest:\n\n```\nresources.<resource>.fields.<field>.label   →   fields.<field>.label   →   <the key itself>\n```\n\n`resolveKey` implements that chain and is exported for callers that need to know *which* key won.\n\n## Locale registry\n\nMost apps assemble their `resources` from more than one place: the framework\nships a base dictionary, the app adds its own chrome strings, a domain module\nadds its enum labels. Printing that as one literal object means adding a\nlanguage is a code change. `createLocaleRegistry` instead lets each source\n**register** a contribution — the registry merges them:\n\n```ts\nimport {\n  createLocaleRegistry,\n  localeContributionsFromGlob,\n  createI18nFromRegistry,\n} from '@burojs/i18n-core';\nimport { en as frameworkEn } from '@burojs/react';\n\nconst registry = createLocaleRegistry();\nregistry.register({ locale: 'en', priority: 0, source: '@burojs/react', bundle: frameworkEn });\n\n// One file per locale, globbed by the bundler — dropping in `es.ts` is the\n// entire mechanism for adding Spanish. Nothing here lists locale codes.\nconst glob = import.meta.glob('./locales/*.ts', { eager: true });\nfor (const c of localeContributionsFromGlob(glob, { source: 'app', priority: 10 })) {\n  registry.register(c);\n}\n\nconst i18n = await createI18nFromRegistry(registry, {\n  defaultLocale: 'en',\n  fallbackLocale: 'en', // or a per-locale chain: { fr: ['en'], default: ['en'] }\n});\n```\n\nA key collision within one (locale, namespace) resolves by the higher\nDECLARED `priority`, never by which contribution happened to register last.\n`localeContributionsFromGlob` is bundler-agnostic (same reasoning as\n`@burojs/core`'s `docsFromGlob`): it accepts whatever flat `path → module`\nmap `import.meta.glob` or an equivalent walk produces, and the caller — not\nthis package — is the one that actually calls the bundler API.\n\n## Main exports\n\n- **`createI18n` / `I18nFacade`** — the facade the React layer consumes.\n- **`createI18nextAdapter`** — the default backend; swap it to use another i18n runtime.\n- **`createResourceI18n` / `ResourceI18n`** — a resource-scoped view of the facade.\n- **`resolveKey`** — the fallback-chain resolver, usable standalone.\n- **`createLocaleRegistry` / `LocaleRegistry`** — merges per-source locale contributions by declared priority.\n- **`localeContributionsFromGlob`** — turns a bundler glob of per-locale files into contributions.\n- **`createI18nFromRegistry`** — wires a `LocaleRegistry` straight into `createI18nextAdapter` + `createI18n`.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}