@vireocodedev/localization 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/package.json +52 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vireocodedev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # @vireocodedev/localization
2
+
3
+ Framework-free localization resources and tooling shared by the Starter
4
+ packages. It is the single owner of the `platform`, `queryengine`, and `history`
5
+ i18next namespaces.
6
+
7
+ The package owns translation resources, namespace constants, resource
8
+ factories, imperative registration, deep-merge utilities, and locale-neutral
9
+ number formatting. It deliberately does not own React hooks, providers,
10
+ i18next initialization, locale detection, persistence, or application locale
11
+ policy.
12
+
13
+ The package has no React dependency and is safe to load in Node and Web Workers.
14
+ React consumers import namespace hooks from
15
+ `@vireocodedev/ui/react-i18next`.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @vireocodedev/localization i18next
21
+ ```
22
+
23
+ The package is published publicly on npm; installation requires no registry
24
+ authentication.
25
+
26
+ `i18next` is the only peer dependency. The package runs against the consuming
27
+ application's instance and never bundles its own copy.
28
+
29
+ TypeScript declarations are verified from the packed artifact with TypeScript
30
+ 6, `moduleResolution: "Bundler"`, and `skipLibCheck: false`. Relative source
31
+ maps with embedded source content are published intentionally for debugging.
32
+
33
+ ## Primary workflow
34
+
35
+ Create every Starter namespace for the locales your app supports, add the
36
+ application's own namespace, then pass the combined resources to an app-owned
37
+ i18next instance:
38
+
39
+ ```ts
40
+ import { createStarterResources } from "@vireocodedev/localization";
41
+ import { createInstance } from "i18next";
42
+
43
+ const locales = ["en", "hr"] as const;
44
+ const starterResources = createStarterResources({ locales });
45
+ const resources = {
46
+ en: { app: { home: { title: "Overview" } }, ...starterResources.en },
47
+ hr: { app: { home: { title: "Pregled" } }, ...starterResources.hr },
48
+ };
49
+
50
+ const i18next = createInstance();
51
+ await i18next.init({
52
+ defaultNS: "app",
53
+ initAsync: false,
54
+ lng: "hr",
55
+ fallbackLng: "en",
56
+ resources,
57
+ });
58
+ ```
59
+
60
+ Locales not shipped by Starter are seeded from English by default. Partial
61
+ overrides are deeply merged, so untranslated keys retain the seed value. Set
62
+ `seedFrom: "hr"` to use Croatian as the seed instead.
63
+
64
+ Every generated locale owns an isolated resource tree. Mutating one result does
65
+ not mutate the shipped base resources or another locale.
66
+
67
+ ## Registering resources after initialization
68
+
69
+ Use `registerStarterResources` when an initialized instance needs the resources
70
+ later in its lifecycle:
71
+
72
+ ```ts
73
+ import { registerStarterResources } from "@vireocodedev/localization";
74
+
75
+ registerStarterResources(i18next, {
76
+ locales: ["en", "hr"],
77
+ });
78
+ ```
79
+
80
+ The function registers every Starter namespace. Per-namespace factories remain
81
+ available when a consumer intentionally needs only one namespace.
82
+
83
+ ## React consumption
84
+
85
+ React adapters belong to Starter UI. In a React application, install
86
+ `initReactI18next` on the same app-owned instance **before its single call to
87
+ `init`**, then expose that instance through `I18nextProvider`; Starter UI's
88
+ hooks read that provider:
89
+
90
+ ```tsx
91
+ import type { PropsWithChildren } from "react";
92
+ import { I18nextProvider, initReactI18next } from "react-i18next";
93
+ import { usePlatformTranslation } from "@vireocodedev/ui/react-i18next";
94
+
95
+ const reactI18next = createInstance();
96
+ void reactI18next.use(initReactI18next).init({
97
+ defaultNS: "app",
98
+ fallbackLng: "en",
99
+ initAsync: false,
100
+ lng: "en",
101
+ resources,
102
+ });
103
+
104
+ export function AppLocalizationProvider({ children }: PropsWithChildren) {
105
+ return <I18nextProvider i18n={reactI18next}>{children}</I18nextProvider>;
106
+ }
107
+
108
+ export function SaveButton() {
109
+ const { t } = usePlatformTranslation();
110
+ return <button>{t("common.save")}</button>;
111
+ }
112
+ ```
113
+
114
+ `useQueryEngineTranslation` and `useHistoryTranslation` are available from the
115
+ same UI subpath. This package itself remains usable without React.
116
+
117
+ ## Type safety
118
+
119
+ Augment i18next with the exported namespace resource types for strict keys and
120
+ autocomplete:
121
+
122
+ ```ts
123
+ import type { HistoryResources, PlatformResources, QueryEngineResources } from "@vireocodedev/localization";
124
+
125
+ declare module "i18next" {
126
+ interface CustomTypeOptions {
127
+ resources: {
128
+ platform: PlatformResources;
129
+ queryengine: QueryEngineResources;
130
+ history: HistoryResources;
131
+ };
132
+ }
133
+ }
134
+ ```
135
+
136
+ ## Public API
137
+
138
+ | Export | Purpose |
139
+ | --------------------------------------------------------------------------- | ------------------------------------------------------------------- |
140
+ | `createStarterResources` | Build every Starter namespace for requested locales. |
141
+ | `registerStarterResources` | Register every namespace on a caller-owned i18next instance. |
142
+ | `createPlatformResources` | Build only the `platform` namespace. |
143
+ | `createQueryEngineResources` | Build only the `queryengine` namespace. |
144
+ | `createHistoryResources` | Build only the `history` namespace. |
145
+ | `STARTER_TRANSLATION_NAMESPACES`, `STARTER_BASE_LOCALES` | Shipped namespace and locale contracts. |
146
+ | `*_TRANSLATION_NAMESPACE`, `*_BASE_LOCALES` | Per-namespace constants. |
147
+ | `platformBaseResources`, `queryEngineBaseResources`, `historyBaseResources` | Shipped resource maps. |
148
+ | `createNamespaceResources` | Build a complete custom namespace from shipped seeds and overrides. |
149
+ | `deepMerge` | Immutable, prototype-safe merge used by resource factories. |
150
+ | `formatIntlNumber` | Format a number with caller-owned locale and fallback policy. |
151
+ | Resource/configuration utility types | Type namespace shapes, overrides, and custom factories. |
152
+
153
+ ## Failure and versioning policy
154
+
155
+ Resource factories reject blank namespaces, empty locale sets, blank or
156
+ duplicate locale identifiers, missing seed locales, and overrides targeting a
157
+ locale that was not requested. Prototype-mutating override keys are ignored.
158
+
159
+ Translation keys and base locales are versioned contracts:
160
+
161
+ - adding a key, namespace, or locale is a minor release;
162
+ - renaming/removing a key or dropping a base locale is breaking;
163
+ - changing a shipped translation value is reviewed as user-visible behavior.
164
+
165
+ Explicit contract tests guard namespace keys and locale parity.
166
+
167
+ ## Live documentation
168
+
169
+ The shared Vireo Starter Storybook contains the package's executable primary
170
+ workflow, late-registration path, custom-namespace toolkit, number formatting,
171
+ and failure semantics. Every displayed example imports this package through its
172
+ published entry point, is typechecked with the package, and executes from the
173
+ same source shown to readers.
174
+
175
+ ## Scripts
176
+
177
+ - `npm run build` — build the ESM runtime and bundled declarations.
178
+ - `npm run typecheck` — typecheck source and tests without emitting.
179
+ - `npm run test` — run behavior, workflow, resource-contract, and architecture tests.
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@vireocodedev/localization",
3
+ "version": "0.2.0",
4
+ "description": "Foundation i18n toolkit and shared platform translations for the vireocodedev starter product.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/vireocodedev/starter.git",
11
+ "directory": "packages/localization"
12
+ },
13
+ "keywords": [
14
+ "i18n",
15
+ "i18next",
16
+ "localization",
17
+ "starter"
18
+ ],
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "main": "./dist/index.js",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "scripts": {
32
+ "build": "vite build",
33
+ "dev": "vite build --watch --mode watch",
34
+ "typecheck": "tsc --noEmit -p tsconfig.json",
35
+ "test": "vitest run"
36
+ },
37
+ "peerDependencies": {
38
+ "i18next": ">=26 <27"
39
+ },
40
+ "devDependencies": {
41
+ "i18next": "^26.4.0",
42
+ "typescript": "npm:@typescript/typescript6@^6.0.2",
43
+ "vite": "^8.2.2",
44
+ "vite-plugin-dts": "^5.0.3",
45
+ "vitest": "^4.1.11"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "provenance": true,
50
+ "registry": "https://registry.npmjs.org"
51
+ }
52
+ }