@sveltekit-i18n/base 1.3.7 → 3.0.0-next.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.
- package/README.md +357 -82
- package/dist/I18n.svelte.d.ts +80 -0
- package/dist/I18n.svelte.js +486 -0
- package/dist/exports/utils.d.ts +2 -0
- package/dist/exports/utils.js +1 -0
- package/dist/index.d.ts +2 -227
- package/dist/index.js +1 -1
- package/dist/logger.d.ts +5 -0
- package/dist/logger.js +35 -0
- package/dist/types.d.ts +461 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +25 -0
- package/dist/utils.js +237 -0
- package/package.json +40 -25
- package/dist/index.cjs +0 -1
package/README.md
CHANGED
|
@@ -1,126 +1,401 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
2
|
[](https://badge.fury.io/js/@sveltekit-i18n%2Fbase) 
|
|
4
3
|
|
|
5
4
|
# @sveltekit-i18n/base
|
|
6
|
-
This repository contains the base functionality of [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) and provides support for external message [parsers](https://github.com/sveltekit-i18n/parsers).
|
|
7
5
|
|
|
6
|
+
Core i18n functionality for SvelteKit with support for custom message parsers. This package provides the foundation for [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) and can be used standalone when you need maximum flexibility with custom parsers.
|
|
7
|
+
|
|
8
|
+
## When to use @sveltekit-i18n/base
|
|
9
|
+
|
|
10
|
+
**Use this package if you:**
|
|
11
|
+
- Need a custom message parser (like ICU, Fluent, or your own format)
|
|
12
|
+
- Want full control over message interpolation
|
|
13
|
+
- Are building a custom i18n solution
|
|
14
|
+
|
|
15
|
+
**Use [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) if you:**
|
|
16
|
+
- Want the quickest setup with sensible defaults
|
|
17
|
+
- Are happy with the default placeholder/modifier syntax
|
|
18
|
+
- Don't need custom parsers
|
|
19
|
+
|
|
20
|
+
## Key Features
|
|
21
|
+
|
|
22
|
+
✅ **Svelte 5 runes** – One reactive instance, no stores
|
|
23
|
+
✅ **Framework ready** – Full SSR and CSR support
|
|
24
|
+
✅ **Parser-agnostic** – Use any message syntax you need
|
|
25
|
+
✅ **Custom data sources** – Load translations from anywhere (files, APIs, databases)
|
|
26
|
+
✅ **Module-based** – Translations load only for visited pages
|
|
27
|
+
✅ **Route-aware** – Automatic loading based on SvelteKit routes
|
|
28
|
+
✅ **Component-scoped** – Multiple translation instances with custom definitions
|
|
29
|
+
✅ **Extensible** – Pipe the instance through [extensions](#extensions) to reshape or augment its surface
|
|
30
|
+
✅ **TypeScript** – Locales inferred from your config, keys and payloads from a [`schema`](#schema)
|
|
31
|
+
✅ **Zero dependencies** – Lightweight and fast
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @sveltekit-i18n/base
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
You'll also need a parser:
|
|
8
40
|
|
|
9
|
-
|
|
41
|
+
```bash
|
|
42
|
+
# Choose one:
|
|
43
|
+
npm install @sveltekit-i18n/parser-default
|
|
44
|
+
npm install @sveltekit-i18n/parser-icu
|
|
45
|
+
# or create your own
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### 1. Create translation files
|
|
10
51
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
✅ No external dependencies
|
|
52
|
+
```jsonc
|
|
53
|
+
// src/lib/translations/en/common.json
|
|
54
|
+
{
|
|
55
|
+
"greeting": "Hello, {{name}}!",
|
|
56
|
+
"farewell": "Goodbye!"
|
|
57
|
+
}
|
|
58
|
+
```
|
|
19
59
|
|
|
20
|
-
|
|
60
|
+
### 2. Setup with a parser
|
|
21
61
|
|
|
22
|
-
Setup `translations.js` in your lib folder...
|
|
23
62
|
```javascript
|
|
24
|
-
|
|
25
|
-
|
|
63
|
+
// src/lib/translations/index.js
|
|
64
|
+
import { I18n } from '@sveltekit-i18n/base';
|
|
26
65
|
import parser from '@sveltekit-i18n/parser-default';
|
|
27
|
-
// import parser from '@sveltekit-i18n/parser-icu';
|
|
28
66
|
|
|
29
|
-
/** @type {import('@sveltekit-i18n/
|
|
30
|
-
const config =
|
|
31
|
-
parser: parser({/*
|
|
67
|
+
/** @type {import('@sveltekit-i18n/base').Config.T} */
|
|
68
|
+
const config = {
|
|
69
|
+
parser: parser({ /* parser options */ }),
|
|
32
70
|
loaders: [
|
|
33
71
|
{
|
|
34
72
|
locale: 'en',
|
|
35
73
|
key: 'common',
|
|
36
|
-
loader: async () => (
|
|
37
|
-
await import('./en/common.json')
|
|
38
|
-
).default,
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
locale: 'en',
|
|
42
|
-
key: 'home',
|
|
43
|
-
routes: ['/'], // you can use regexes as well!
|
|
44
|
-
loader: async () => (
|
|
45
|
-
await import('./en/home.json')
|
|
46
|
-
).default,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
locale: 'en',
|
|
50
|
-
key: 'about',
|
|
51
|
-
routes: ['/about'],
|
|
52
|
-
loader: async () => (
|
|
53
|
-
await import('./en/about.json')
|
|
54
|
-
).default,
|
|
74
|
+
loader: async () => (await import('./en/common.json')).default,
|
|
55
75
|
},
|
|
56
76
|
{
|
|
57
77
|
locale: 'cs',
|
|
58
78
|
key: 'common',
|
|
59
|
-
loader: async () => (
|
|
60
|
-
await import('./cs/common.json')
|
|
61
|
-
).default,
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
locale: 'cs',
|
|
65
|
-
key: 'home',
|
|
66
|
-
routes: ['/'],
|
|
67
|
-
loader: async () => (
|
|
68
|
-
await import('./cs/home.json')
|
|
69
|
-
).default,
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
locale: 'cs',
|
|
73
|
-
key: 'about',
|
|
74
|
-
routes: ['/about'],
|
|
75
|
-
loader: async () => (
|
|
76
|
-
await import('./cs/about.json')
|
|
77
|
-
).default,
|
|
79
|
+
loader: async () => (await import('./cs/common.json')).default,
|
|
78
80
|
},
|
|
79
81
|
],
|
|
80
|
-
}
|
|
82
|
+
};
|
|
81
83
|
|
|
82
|
-
|
|
84
|
+
// One reactive instance. Do NOT destructure its value properties — reading
|
|
85
|
+
// them off the instance is what makes templates reactive. (`t`/`l` are
|
|
86
|
+
// functions and stay reactive even when destructured, since the tracked reads
|
|
87
|
+
// happen at call time. In a component, `const { loading } = $derived(i18n)`
|
|
88
|
+
// destructures value reads without losing reactivity.)
|
|
89
|
+
export const i18n = new I18n(config);
|
|
83
90
|
```
|
|
84
91
|
|
|
85
|
-
|
|
92
|
+
### 3. Load translations in your layout
|
|
86
93
|
|
|
87
|
-
```
|
|
88
|
-
|
|
94
|
+
```javascript
|
|
95
|
+
// src/routes/+layout.js
|
|
96
|
+
import { i18n } from '$lib/translations';
|
|
89
97
|
|
|
90
|
-
/** @type {import('
|
|
98
|
+
/** @type {import('./$types').LayoutLoad} */
|
|
91
99
|
export const load = async ({ url }) => {
|
|
92
100
|
const { pathname } = url;
|
|
101
|
+
const initLocale = 'en';
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
await loadTranslations(initLocale, pathname); // keep this just before the `return`
|
|
103
|
+
await i18n.loadTranslations(initLocale, pathname);
|
|
97
104
|
|
|
98
105
|
return {};
|
|
99
|
-
}
|
|
106
|
+
};
|
|
100
107
|
```
|
|
101
108
|
|
|
102
|
-
|
|
109
|
+
> **Rendering per-visitor locales on the server?** The instance above is a
|
|
110
|
+
> module-level singleton — on the server it is shared by every request in the
|
|
111
|
+
> process, so concurrent visitors overwrite each other's locale. Use one
|
|
112
|
+
> instance per request and hand its data to the client with `snapshot()`:
|
|
113
|
+
> see [Server-Side Rendering](./docs/README.md#server-side-rendering).
|
|
114
|
+
|
|
115
|
+
### 4. Use in components
|
|
103
116
|
|
|
104
117
|
```svelte
|
|
105
118
|
<script>
|
|
106
|
-
import {
|
|
107
|
-
|
|
108
|
-
const pageName = 'This page is Home page!';
|
|
119
|
+
import { i18n } from '$lib/translations';
|
|
109
120
|
</script>
|
|
110
121
|
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
<p>{i18n.t('common.greeting', { name: 'World' })}</p>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The call reads the reactive translation table and locale, so the text updates
|
|
126
|
+
automatically when either changes — no stores, no `$` prefix.
|
|
127
|
+
|
|
128
|
+
## Using Different Parsers
|
|
129
|
+
|
|
130
|
+
### ICU Message Format
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
import i18n from '@sveltekit-i18n/base';
|
|
134
|
+
import parser from '@sveltekit-i18n/parser-icu';
|
|
135
|
+
|
|
136
|
+
const config = {
|
|
137
|
+
parser: parser(),
|
|
138
|
+
loaders: [/* ... */],
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"items": "You have {count, plural, =0 {no items} one {# item} other {# items}}."
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Custom Parser
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
import i18n from '@sveltekit-i18n/base';
|
|
152
|
+
|
|
153
|
+
const customParser = () => ({
|
|
154
|
+
parse: (value, params) => {
|
|
155
|
+
// Your custom interpolation logic
|
|
156
|
+
return value.replace(/\{(\w+)\}/g, (_, key) => params[0]?.[key] ?? key);
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const config = {
|
|
161
|
+
parser: customParser(),
|
|
162
|
+
loaders: [/* ... */],
|
|
163
|
+
};
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Learn more about [creating custom parsers](https://github.com/sveltekit-i18n/parsers#creating-custom-parsers).
|
|
167
|
+
|
|
168
|
+
## Configuration Options
|
|
169
|
+
|
|
170
|
+
### `parser` (required)
|
|
171
|
+
|
|
172
|
+
Message parser instance. See [Parsers](https://github.com/sveltekit-i18n/parsers).
|
|
173
|
+
|
|
174
|
+
### `loaders`
|
|
175
|
+
|
|
176
|
+
Array of loader configurations:
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
loaders: [
|
|
180
|
+
{
|
|
181
|
+
locale: 'en', // Required: locale identifier
|
|
182
|
+
key: 'common', // Required: translation namespace
|
|
183
|
+
loader: async () => {}, // Required: async function returning translations
|
|
184
|
+
routes: ['/about'], // Optional: load only for specific routes
|
|
185
|
+
},
|
|
186
|
+
]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Both `loaders` and a loader's `routes` accept readonly arrays, so a whole-config `as const` is fine.
|
|
190
|
+
|
|
191
|
+
### `translations`
|
|
192
|
+
|
|
193
|
+
Synchronous translations loaded immediately:
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
translations: {
|
|
197
|
+
en: {
|
|
198
|
+
'app.name': 'My App',
|
|
199
|
+
},
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### `initLocale`
|
|
204
|
+
|
|
205
|
+
Initialize with a specific locale immediately:
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
initLocale: 'en'
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### `fallbackLocale`
|
|
212
|
+
|
|
213
|
+
Fallback when translation is missing:
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
fallbackLocale: 'en'
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Note:** This loads translations for both current locale and fallback locale, which may impact performance.
|
|
220
|
+
|
|
221
|
+
### `fallbackValue`
|
|
222
|
+
|
|
223
|
+
Default return value when translation key is not found:
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
fallbackValue: '...' // Default: returns the key itself
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### `preprocess`
|
|
230
|
+
|
|
231
|
+
Transform translations after loading:
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
preprocess: 'full' // 'full' | 'preserveArrays' | 'none' | custom function
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
- `'full'` (default): Flattens all nested objects to dot notation
|
|
238
|
+
- `'preserveArrays'`: Flattens objects but preserves arrays
|
|
239
|
+
- `'none'`: No preprocessing
|
|
240
|
+
- Custom function: `(input) => transformedOutput`
|
|
241
|
+
|
|
242
|
+
### `schema`
|
|
243
|
+
|
|
244
|
+
A map of translation key to the payload its message expects (`never` for a message that takes none). Supplying it types `t`/`l` — keys autocomplete, an unknown key is a type error, and the payload argument is checked. Only its type is read, so the value can stay empty at runtime:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
type TranslationSchema = {
|
|
248
|
+
'common.greeting': { name: string };
|
|
249
|
+
'common.farewell': never;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const i18n = new I18n({ ...config, schema: {} as TranslationSchema });
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Hand-write it for a small set of messages, or point the slot at a generated artifact. A schema whose keys are not a closed set is ignored, and keys stay plain strings. See [`schema`](./docs/README.md#schema) for the full rules.
|
|
256
|
+
|
|
257
|
+
### `cache`
|
|
258
|
+
|
|
259
|
+
Time in milliseconds the loaded translations stay fresh for. By default, loaded translations never expire — loaders run once per locale and key (a loader's `routes` only decide whether a load trigger considers it, not how often it runs).
|
|
260
|
+
|
|
261
|
+
Set a finite value when your loaders fetch from a source that can change at runtime (e.g. a CMS):
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
cache: 3600000 // Translations older than 1 hour refetch on the next load
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Set to `0` to treat translations as always stale (refetch on every load trigger). You can also drop the loaded state manually at any time with [`invalidate()`](#methods).
|
|
268
|
+
|
|
269
|
+
### `extensions`
|
|
270
|
+
|
|
271
|
+
Pipes the constructed instance through extension functions, left to right. Each extension receives the surface produced so far (the raw instance for the first one) and returns the surface handed on — `new I18n(config)` evaluates to the last extension's output:
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
import stores from '@sveltekit-i18n/extension-stores';
|
|
275
|
+
|
|
276
|
+
const { t, locale, loading } = new I18n({
|
|
277
|
+
...config,
|
|
278
|
+
extensions: [stores],
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
An extension may augment the instance in place, or replace the surface entirely (like the store adapter above). Official extensions live in the [extensions](https://github.com/sveltekit-i18n/extensions) repository; a custom extension is just a function:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
const withGreeting = (i18n) => Object.assign(i18n, {
|
|
286
|
+
greet: (name) => i18n.t('common.greeting', { name }),
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
export const i18n = new I18n({ ...config, extensions: [withGreeting] });
|
|
290
|
+
|
|
291
|
+
i18n.greet('World');
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Notes:**
|
|
295
|
+
- Applied at construction time only — a later `loadConfig()` call ignores this property.
|
|
296
|
+
- When an extension returns a new object, the result is no longer `instanceof I18n`; the original instance stays reachable through whatever the extension exposes (the official extensions expose it as `instance`).
|
|
297
|
+
|
|
298
|
+
### `log`
|
|
299
|
+
|
|
300
|
+
Logging configuration:
|
|
301
|
+
|
|
302
|
+
```javascript
|
|
303
|
+
log: {
|
|
304
|
+
level: 'warn', // 'error' | 'warn' | 'debug'
|
|
305
|
+
prefix: '[i18n]: ', // Log prefix
|
|
306
|
+
logger: console, // Custom logger
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## API Reference
|
|
311
|
+
|
|
312
|
+
### Reactive properties
|
|
313
|
+
|
|
314
|
+
- `t(key, ...params)` – translate for the active locale (reactive function)
|
|
315
|
+
- `l(locale, key, ...params)` – translate for an explicit locale
|
|
316
|
+
- `locale` – the ACTIVE locale; assignment is a fire-and-forget `setLocale()`
|
|
317
|
+
- `locales` – available locales
|
|
318
|
+
- `loading` – `true` while any load is in flight
|
|
319
|
+
- `initialized` – locale and route set, translations present
|
|
320
|
+
- `translations` / `rawTranslations` – the (pre/post-preprocess) tables
|
|
321
|
+
|
|
322
|
+
### Methods
|
|
323
|
+
|
|
324
|
+
Load-triggering methods return the promise of the matching load — concurrent duplicate triggers share one in-flight load (and its promise) instead of fetching twice.
|
|
325
|
+
|
|
326
|
+
- `loadTranslations(locale, route?)` – load translations for locale and route; `route` defaults to the current one
|
|
327
|
+
- `setLocale(locale)` – request a locale; loads once a route is known
|
|
328
|
+
- `setRoute(route)` – update the current route
|
|
329
|
+
- `loadConfig(config)` – (re)configure the instance
|
|
330
|
+
- `addTranslations(translations)` – add synchronous translations
|
|
331
|
+
- `snapshot()` – serialize the active locale (and the fallback) for the current route, shaped like `config.translations` so the receiving instance hydrates from it
|
|
332
|
+
- `invalidate(locale?)` – mark loaded translations stale (one locale, or all); loaders run again on the next load trigger, and a load still in flight for an invalidated locale settles with its data discarded
|
|
333
|
+
- `destroy()` – detach a per-request or per-component instance: in-flight loads settle discarded, further load and mutation calls are ignored, reads keep working
|
|
334
|
+
|
|
335
|
+
### Utilities
|
|
336
|
+
|
|
337
|
+
Two helpers the instance uses internally ship from a separate subpath, for code that has to match the library's own behavior:
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
import { sanitizeLocales, toDotNotation } from '@sveltekit-i18n/base/utils';
|
|
115
341
|
```
|
|
116
342
|
|
|
343
|
+
- `toDotNotation(input, preserveArrays?)` – the flattening behind [`preprocess`](#preprocess), for a custom `preprocess` that still wants dot notation
|
|
344
|
+
- `sanitizeLocales(...locales)` – normalizes a locale from a URL, cookie or `Accept-Language` header the way the instance does, so it can be compared against `locale`
|
|
345
|
+
|
|
346
|
+
Full API documentation: [docs/README.md](./docs/README.md)
|
|
347
|
+
|
|
348
|
+
## Documentation
|
|
349
|
+
|
|
350
|
+
- 📖 [Full API Documentation](./docs/README.md) – Complete reference
|
|
351
|
+
- 📚 [Main Library Docs](https://github.com/sveltekit-i18n/lib/tree/master/docs/INDEX.md) – Guides, tutorials, and best practices
|
|
352
|
+
- 🎨 [Parsers](https://github.com/sveltekit-i18n/parsers) – Available parsers and how to create your own
|
|
353
|
+
- 💡 [Examples](https://github.com/sveltekit-i18n/lib/tree/master/examples) – Real-world usage examples
|
|
354
|
+
|
|
355
|
+
## TypeScript Support
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import { I18n, type Config } from '@sveltekit-i18n/base';
|
|
359
|
+
import parser from '@sveltekit-i18n/parser-default';
|
|
360
|
+
|
|
361
|
+
// The parser's params – the rest parameters of `t`/`l`. Annotate only when the
|
|
362
|
+
// config lives on its own; `new I18n({ ... })` infers them.
|
|
363
|
+
type Params = [payload?: Record<string, unknown>];
|
|
364
|
+
|
|
365
|
+
const config: Config.T<Params> = {
|
|
366
|
+
parser: parser(),
|
|
367
|
+
loaders: [/* ... */],
|
|
368
|
+
};
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Two more things are inferred from the config itself. [`schema`](#schema) types the keys and payloads of `t`/`l`, and every locale the config names — loader locales, `initLocale`, `fallbackLocale` and the keys of `translations` — completes the locale arguments and reads (`setLocale`, `loadTranslations`, `invalidate`, `l`, `locale`, `locales`):
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
const i18n = new I18n({ parser: parser(), initLocale: 'en', fallbackLocale: 'de' });
|
|
375
|
+
|
|
376
|
+
i18n.setLocale('en'); // 'en' | 'de' autocomplete here
|
|
377
|
+
i18n.setLocale('sv'); // still accepted — the union is a hint, not a constraint
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
The locales survive only when the config reaches the constructor as a literal — inline, as above, or a separate object with `as const`. An annotated or separately widened config, and any config with one dynamic locale source (`loaders: locales.map(...)`), leaves them plain `string`. See [TypeScript](./docs/README.md#typescript) for both.
|
|
381
|
+
|
|
382
|
+
## Related Packages
|
|
383
|
+
|
|
384
|
+
- [sveltekit-i18n](https://github.com/sveltekit-i18n/lib) – Complete solution with default parser
|
|
385
|
+
- [@sveltekit-i18n/parser-default](https://github.com/sveltekit-i18n/parsers/tree/master/parser-default) – Default message parser
|
|
386
|
+
- [@sveltekit-i18n/parser-icu](https://github.com/sveltekit-i18n/parsers/tree/master/parser-icu) – ICU message format parser
|
|
387
|
+
- [Extensions](https://github.com/sveltekit-i18n/extensions) – Official extensions for the `config.extensions` pipe
|
|
388
|
+
|
|
389
|
+
## Contributing
|
|
390
|
+
|
|
391
|
+
For general contribution guidelines, see the [Contributing Guide](https://github.com/sveltekit-i18n/lib/blob/master/CONTRIBUTING.md) in the main library repository.
|
|
392
|
+
|
|
393
|
+
For issues specific to base functionality, create a ticket [here](https://github.com/sveltekit-i18n/lib/issues).
|
|
394
|
+
|
|
395
|
+
## Changelog
|
|
117
396
|
|
|
118
|
-
|
|
119
|
-
[Parsers](https://github.com/sveltekit-i18n/parsers)\
|
|
120
|
-
[Docs](https://github.com/sveltekit-i18n/base/tree/master/docs/README.md)\
|
|
121
|
-
[Examples](https://github.com/sveltekit-i18n/lib/tree/master/examples#parsers)\
|
|
122
|
-
[Changelog](https://github.com/sveltekit-i18n/base/releases)
|
|
397
|
+
See [Releases](https://github.com/sveltekit-i18n/base/releases) for version history.
|
|
123
398
|
|
|
399
|
+
## License
|
|
124
400
|
|
|
125
|
-
|
|
126
|
-
If you are facing some issues related to the base functionality, create a ticket [here](https://github.com/sveltekit-i18n/lib/issues).
|
|
401
|
+
MIT
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Config, Extension, Parser, Schema, Translations } from './types.js';
|
|
2
|
+
declare class I18nCore<ParserParams extends Parser.Params = any, ParserOutput = string, TranslationSchema = never, LocaleUnion extends string = string> {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(config?: Config.T<ParserParams, ParserOutput>);
|
|
5
|
+
/**
|
|
6
|
+
* The active locale. Reading it is reactive; assigning it is a shorthand for
|
|
7
|
+
* a fire-and-forget `setLocale()` — the value therefore updates once the
|
|
8
|
+
* locale's translations resolved, not synchronously on assignment.
|
|
9
|
+
*/
|
|
10
|
+
get locale(): Config.LocaleInput<LocaleUnion> | undefined;
|
|
11
|
+
set locale(value: Config.LocaleInput<LocaleUnion> | undefined);
|
|
12
|
+
get translations(): Translations.SerializedTranslations;
|
|
13
|
+
get rawTranslations(): Translations.SerializedTranslations;
|
|
14
|
+
loading: boolean;
|
|
15
|
+
locales: Config.LocaleInput<LocaleUnion>[];
|
|
16
|
+
initialized: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Translates `key` for the active locale. Reactive wherever reads are
|
|
19
|
+
* tracked: the call reads the translation table and locale, so a component
|
|
20
|
+
* using `{i18n.t('key')}` re-renders when either changes.
|
|
21
|
+
*/
|
|
22
|
+
t: Translations.TranslationFunction<ParserParams, ParserOutput, TranslationSchema>;
|
|
23
|
+
/** Like `t`, for an explicit locale. */
|
|
24
|
+
l: Translations.LocalTranslationFunction<ParserParams, ParserOutput, TranslationSchema, LocaleUnion>;
|
|
25
|
+
/**
|
|
26
|
+
* Applies a config. Overridable extension seam — `sveltekit-i18n` wires its
|
|
27
|
+
* default parser by extending this method.
|
|
28
|
+
*/
|
|
29
|
+
configLoader(config: Config.T<ParserParams, ParserOutput>): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Public entry for (re)configuration. The failure is reported here and the
|
|
32
|
+
* promise marked handled, so a fire-and-forget call cannot become an
|
|
33
|
+
* unhandled rejection; an awaiting caller still receives it.
|
|
34
|
+
*/
|
|
35
|
+
loadConfig: (config: Config.T<ParserParams, ParserOutput>) => Promise<void>;
|
|
36
|
+
setLocale: (locale?: Config.LocaleInput<LocaleUnion>) => Promise<void>;
|
|
37
|
+
setRoute: (route: string) => Promise<void>;
|
|
38
|
+
loadTranslations: (locale: Config.LocaleInput<LocaleUnion>, route?: string) => Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Marks loaded translations stale — for one locale, or all of them. Loaders
|
|
41
|
+
* run again on the NEXT load trigger; the call itself starts no load and
|
|
42
|
+
* keeps the currently displayed translations in place. A load still in
|
|
43
|
+
* flight for an invalidated locale is severed: it settles, but its data is
|
|
44
|
+
* discarded — it predates the invalidation.
|
|
45
|
+
*/
|
|
46
|
+
invalidate: (locale?: Config.LocaleInput<LocaleUnion>) => void;
|
|
47
|
+
addTranslations: (translations?: Translations.SerializedTranslations) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Serializes what this instance holds for the active locale and the fallback
|
|
50
|
+
* locale, narrowed to the current route: a key owned only by loaders that do
|
|
51
|
+
* not match the route is left out. The result is shaped like
|
|
52
|
+
* `config.translations`, so a client hydrates by handing it back to the
|
|
53
|
+
* constructor — the bookkeeping derived from it then keeps the matching
|
|
54
|
+
* loaders from fetching the same data again.
|
|
55
|
+
*/
|
|
56
|
+
snapshot: () => Translations.SerializedTranslations;
|
|
57
|
+
/**
|
|
58
|
+
* Detaches the instance from its loading lifecycle: in-flight loads settle
|
|
59
|
+
* with their data discarded, `loading` drops to `false`, and every further
|
|
60
|
+
* load or mutation call is ignored with a warning. Reads (`t`, `l`, `locale`,
|
|
61
|
+
* `translations`, `snapshot`) keep working, so a component still tearing down
|
|
62
|
+
* renders its last state instead of breaking. Idempotent.
|
|
63
|
+
*/
|
|
64
|
+
destroy: () => void;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A class declaration cannot annotate its constructor's return type, so the
|
|
68
|
+
* extension pipe's construction-time type lives on this construct signature
|
|
69
|
+
* instead: parser params and output are inferred from `config.parser`, locales
|
|
70
|
+
* are narrowed to the ones the config names, and the returned surface is the
|
|
71
|
+
* instance type folded through the `config.extensions` tuple
|
|
72
|
+
* (`const` keeps it a tuple without `as const` at the call site).
|
|
73
|
+
*/
|
|
74
|
+
interface I18nConstructor {
|
|
75
|
+
new <const C extends Config.T<any, any> = Config.T<any, any>>(config?: C): Extension.Piped<I18nCore<Parser.FromConfig<C>, Parser.OutputFromConfig<C>, Schema.FromConfig<C>, Config.LocalesFromConfig<C>>, Extension.FromConfig<C>>;
|
|
76
|
+
}
|
|
77
|
+
declare const I18n: I18nConstructor;
|
|
78
|
+
type I18n<ParserParams extends Parser.Params = any, ParserOutput = string, TranslationSchema = never, LocaleUnion extends string = string> = I18nCore<ParserParams, ParserOutput, TranslationSchema, LocaleUnion>;
|
|
79
|
+
export { I18n };
|
|
80
|
+
export default I18n;
|