@intlayer/lingui 9.0.0-canary.11 → 9.0.0-canary.13
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/dist/esm/I18nClass.mjs +22 -0
- package/dist/esm/I18nClass.mjs.map +1 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/plugin/index.mjs +3 -42
- package/dist/esm/plugin/index.mjs.map +1 -1
- package/dist/esm/useDictionary.mjs +34 -0
- package/dist/esm/useDictionary.mjs.map +1 -0
- package/dist/esm/useDictionaryDynamic.mjs +28 -0
- package/dist/esm/useDictionaryDynamic.mjs.map +1 -0
- package/dist/types/I18nClass.d.ts +14 -0
- package/dist/types/I18nClass.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/useDictionary.d.ts +20 -0
- package/dist/types/useDictionary.d.ts.map +1 -0
- package/dist/types/useDictionaryDynamic.d.ts +15 -0
- package/dist/types/useDictionaryDynamic.d.ts.map +1 -0
- package/package.json +9 -9
package/dist/esm/I18nClass.mjs
CHANGED
|
@@ -63,6 +63,12 @@ var I18nClass = class extends EventEmitter {
|
|
|
63
63
|
*/
|
|
64
64
|
_catalogs = {};
|
|
65
65
|
_loadFallbackWarned = false;
|
|
66
|
+
/**
|
|
67
|
+
* Pre-resolved `messages` dictionary content bound by the build-optimized
|
|
68
|
+
* `useDictionary` / `useDictionaryDynamic` variants. Checked before the
|
|
69
|
+
* runtime registry so lookups stay tree-shakeable.
|
|
70
|
+
*/
|
|
71
|
+
_dictionaryContent;
|
|
66
72
|
constructor({ locale = "en", locales, messages } = {}) {
|
|
67
73
|
super();
|
|
68
74
|
this._locale = typeof locale === "string" ? locale : "en";
|
|
@@ -77,6 +83,7 @@ var I18nClass = class extends EventEmitter {
|
|
|
77
83
|
}
|
|
78
84
|
get messages() {
|
|
79
85
|
const dictionary = {};
|
|
86
|
+
if (this._dictionaryContent !== void 0) Object.assign(dictionary, unwrapLinguiCatalog(this._dictionaryContent));
|
|
80
87
|
for (const key of getDictionaryKeys()) try {
|
|
81
88
|
Object.assign(dictionary, unwrapLinguiCatalog(getIntlayer(key, this._locale)));
|
|
82
89
|
} catch {}
|
|
@@ -131,6 +138,17 @@ var I18nClass = class extends EventEmitter {
|
|
|
131
138
|
this.activate(locale, locales);
|
|
132
139
|
}
|
|
133
140
|
/**
|
|
141
|
+
* Binds pre-resolved `messages` dictionary content, checked before the
|
|
142
|
+
* runtime registry.
|
|
143
|
+
*
|
|
144
|
+
* @internal Used by the build-optimized `useDictionary` /
|
|
145
|
+
* `useDictionaryDynamic` variants — not part of the lingui API surface.
|
|
146
|
+
*/
|
|
147
|
+
bindDictionaryContent(content) {
|
|
148
|
+
this._dictionaryContent = content;
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
134
152
|
* Sets the active locale and emits `'change'` to notify React consumers.
|
|
135
153
|
*/
|
|
136
154
|
activate(locale, locales) {
|
|
@@ -146,6 +164,10 @@ var I18nClass = class extends EventEmitter {
|
|
|
146
164
|
* 2. runtime fallback catalog (constructor / `load()` / `loadAndActivate()`)
|
|
147
165
|
*/
|
|
148
166
|
resolveTemplate(id) {
|
|
167
|
+
if (this._dictionaryContent !== void 0) {
|
|
168
|
+
const boundValue = navigateLinguiCatalog(this._dictionaryContent, id);
|
|
169
|
+
if (boundValue !== void 0) return linguiMessageToIcu(boundValue);
|
|
170
|
+
}
|
|
149
171
|
const fromDictionary = lookupDictionaryMessage(id, this._locale);
|
|
150
172
|
if (fromDictionary !== void 0) return fromDictionary;
|
|
151
173
|
const catalog = this._catalogs[this._locale];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"I18nClass.mjs","names":[],"sources":["../../src/I18nClass.ts"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport { resolveMessage } from '@intlayer/core/messageFormat';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n AllMessages,\n Locale,\n Locales,\n MessageDescriptor,\n MessageId,\n MessageOptions,\n Messages,\n} from '@lingui/core';\nimport { EventEmitter } from './eventEmitter';\nimport {\n linguiMessageToIcu,\n navigateLinguiCatalog,\n unwrapLinguiCatalog,\n} from './linguiCatalog';\n\n/** Mirrors the unexported `Values` type from `@lingui/core`. */\ntype Values = Record<string, unknown>;\n\n/** Mirrors the unexported `MessageCompiler` type from `@lingui/core`. */\ntype MessageCompiler = (message: string) => unknown;\n\n/** Mirrors the unexported `Events` type from `@lingui/core`. */\ntype LinguiEvents = {\n change: () => void;\n missing: (event: { locale: Locale; id: MessageId }) => void;\n};\n\n/** Mirrors the unexported `I18nProps` type from `@lingui/core`. */\ntype I18nProps = {\n locale?: Locale;\n locales?: Locales;\n messages?: AllMessages;\n missing?: string | ((locale: string, id: string) => string);\n};\n\n/**\n * Keys of every intlayer dictionary available at runtime (the namespaces).\n *\n * The bundler-injected `@intlayer/dictionaries-entry` exposes the full registry;\n * outside a bundle (e.g. unit tests) it resolves to an empty map, in which case\n * resolution falls back to the runtime catalogs loaded via `load()`.\n */\nconst getDictionaryKeys = (): DictionaryKeys[] => {\n try {\n return Object.keys(getDictionaries()) as DictionaryKeys[];\n } catch {\n return [];\n }\n};\n\n/**\n * Looks up a lingui message across every intlayer dictionary.\n *\n * lingui ids are flat, namespace-less keys (`'hero.title'`), but the matching\n * content may live in any dictionary — a single centralized catalog, or one of\n * many namespaced catalogs (`home`, `shared`, …) produced by `syncJSON` from\n * split lingui catalogs. Each dictionary is searched in turn, supporting both\n * the flat/nested key shapes and the lingui `{ messages: {…} }` wrapper. The\n * first match wins.\n */\nconst lookupDictionaryMessage = (\n id: string,\n locale: LocalesValues\n): string | undefined => {\n for (const key of getDictionaryKeys()) {\n let dictionary: unknown;\n try {\n dictionary = getIntlayer(key, locale);\n } catch {\n continue;\n }\n const value = navigateLinguiCatalog(dictionary, id);\n if (value !== undefined) return linguiMessageToIcu(value);\n }\n return undefined;\n};\n\n/**\n * Intlayer-backed implementation of `@lingui/core`'s `I18n` class.\n *\n * - Messages are read from the `messages` intlayer dictionary.\n * - ICU MessageFormat syntax is resolved via `@intlayer/core/messageFormat`.\n * - `load()` / `loadAndActivate()` / `setMessagesCompiler()` are no-ops —\n * messages are served by intlayer's compiled dictionaries.\n * - `activate(locale)` emits `'change'` so that React consumers re-render.\n */\nexport class I18nClass extends EventEmitter<LinguiEvents> {\n private _locale: string;\n private _locales?: Locales;\n /**\n * Per-locale catalogs supplied at runtime via the constructor, `load()` or\n * `loadAndActivate()`. Used as a fallback when a key is absent from the\n * compiled intlayer `messages` dictionary, so an unmodified lingui codebase\n * (which loads its compiled `.mjs`/`.json` catalogs) keeps working as a\n * drop-in. For optimal bundle size, compile catalogs into intlayer\n * dictionaries instead — see the dev warning emitted by `load()`.\n */\n private _catalogs: Record<string, Messages> = {};\n private _loadFallbackWarned = false;\n\n constructor({ locale = 'en', locales, messages }: I18nProps = {}) {\n super();\n this._locale = typeof locale === 'string' ? locale : 'en';\n this._locales = locales;\n if (messages) this.mergeAllCatalogs(messages);\n }\n\n get locale(): string {\n return this._locale;\n }\n\n get locales(): Locales | undefined {\n return this._locales;\n }\n\n get messages(): Messages {\n // Merge every intlayer dictionary (namespace) for the active locale into a\n // single flat catalog, unwrapping the lingui `{ messages: {…} }` wrapper.\n const dictionary: Messages = {};\n for (const key of getDictionaryKeys()) {\n try {\n Object.assign(\n dictionary,\n unwrapLinguiCatalog(getIntlayer(key, this._locale as LocalesValues))\n );\n } catch {\n // Skip dictionaries that fail to resolve for this locale.\n }\n }\n // The compiled dictionaries win over the runtime fallback catalog.\n return { ...(this._catalogs[this._locale] ?? {}), ...dictionary };\n }\n\n /** Merges a single-locale catalog into the in-memory fallback store. */\n private mergeLocaleCatalog(locale: string, catalog: Messages) {\n this._catalogs[locale] = { ...this._catalogs[locale], ...catalog };\n }\n\n /**\n * Merges a `{ [locale]: catalog }` map (lingui's `AllMessages`) into the\n * in-memory fallback store.\n */\n private mergeAllCatalogs(messages: AllMessages) {\n for (const [locale, catalog] of Object.entries(messages)) {\n if (catalog && typeof catalog === 'object') {\n this.mergeLocaleCatalog(locale, catalog as Messages);\n }\n }\n }\n\n /**\n * No-op: intlayer handles message compilation at build time.\n */\n setMessagesCompiler(_compiler: MessageCompiler): this {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n '@intlayer/lingui: i18n.setMessagesCompiler() is a no-op — ' +\n 'message compilation is handled at build time by intlayer.'\n );\n }\n return this;\n }\n\n /**\n * Loads message catalogs into the runtime fallback store, supporting both\n * lingui signatures: `load(locale, messages)` and `load(allMessages)`.\n *\n * These messages are a compatibility fallback — keys present in the compiled\n * intlayer `messages` dictionary take precedence, and only those keys can be\n * pruned/optimized at build time.\n */\n load(localeOrAll: Locale | AllMessages, messages?: Messages): void {\n if (typeof localeOrAll === 'string') {\n this.mergeLocaleCatalog(localeOrAll, messages ?? {});\n } else {\n this.mergeAllCatalogs(localeOrAll);\n }\n\n if (process.env.NODE_ENV === 'development' && !this._loadFallbackWarned) {\n this._loadFallbackWarned = true;\n console.warn(\n '@intlayer/lingui: i18n.load() messages are used as a runtime ' +\n 'fallback. For optimal bundle size, compile your catalogs into ' +\n 'intlayer dictionaries instead of importing lingui locale files.'\n );\n }\n }\n\n /**\n * Loads the given catalog (fallback store) and activates the locale\n * (emits `'change'`).\n */\n loadAndActivate({\n locale,\n locales,\n messages,\n }: {\n locale: Locale;\n locales?: Locales;\n messages?: Messages;\n }): void {\n if (messages) this.mergeLocaleCatalog(locale, messages);\n this.activate(locale, locales);\n }\n\n /**\n * Sets the active locale and emits `'change'` to notify React consumers.\n */\n activate(locale: Locale, locales?: Locales): void {\n this._locale = locale;\n this._locales = locales;\n this.emit('change');\n }\n\n /**\n * Resolves the raw message template for an id (before interpolation).\n *\n * Resolution order:\n * 1. compiled intlayer `messages` dictionary\n * 2. runtime fallback catalog (constructor / `load()` / `loadAndActivate()`)\n */\n private resolveTemplate(id: string): string | undefined {\n const fromDictionary = lookupDictionaryMessage(\n id,\n this._locale as LocalesValues\n );\n if (fromDictionary !== undefined) return fromDictionary;\n\n const catalog = this._catalogs[this._locale];\n if (catalog) {\n const raw = navigateLinguiCatalog(catalog, id);\n if (raw !== undefined) return linguiMessageToIcu(raw);\n }\n\n return undefined;\n }\n\n /**\n * Translates a message descriptor or a plain ID.\n *\n * Resolution order:\n * 1. `messages` intlayer dictionary (flat dotted key or nested path)\n * 2. runtime fallback catalog loaded via `load()` / `loadAndActivate()`\n * 3. `descriptor.message` or `options.message` (original source string)\n * 4. The raw `id` as fallback\n */\n _(descriptor: MessageDescriptor): string;\n _(id: MessageId, values?: Values, options?: MessageOptions): string;\n _(\n descriptorOrId: MessageDescriptor | MessageId,\n values?: Values,\n options?: MessageOptions\n ): string {\n const isDescriptor =\n typeof descriptorOrId === 'object' && descriptorOrId !== null;\n const id = isDescriptor\n ? (descriptorOrId as MessageDescriptor).id\n : (descriptorOrId as MessageId);\n const defaultMessage = isDescriptor\n ? ((descriptorOrId as MessageDescriptor).message ?? options?.message)\n : options?.message;\n const resolvedValues: Values = isDescriptor\n ? {\n ...((descriptorOrId as MessageDescriptor).values ?? {}),\n ...(values ?? {}),\n }\n : (values ?? {});\n\n const rawValue = this.resolveTemplate(id);\n const template = rawValue ?? defaultMessage ?? id;\n\n return (\n resolveMessage(\n template,\n resolvedValues as Record<string, string | number>,\n this._locale as LocalesValues,\n 'icu'\n ) ?? id\n );\n }\n\n /**\n * Alias for `_`. Provided for lingui API compatibility.\n */\n t = (\n descriptorOrId: MessageDescriptor | MessageId,\n values?: Values,\n options?: MessageOptions\n ): string => this._(descriptorOrId as MessageId, values, options);\n\n /**\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\n date(\n value?: string | Date | number,\n format?: Intl.DateTimeFormatOptions\n ): string {\n if (value === undefined || value === null) return '';\n const dateValue =\n value instanceof Date\n ? value\n : new Date(typeof value === 'string' ? value : value);\n return new Intl.DateTimeFormat(this._locale, format).format(dateValue);\n }\n\n /**\n * @deprecated Use `Intl.NumberFormat` directly.\n */\n number(value: number | bigint, format?: Intl.NumberFormatOptions): string {\n return new Intl.NumberFormat(this._locale, format).format(value);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"I18nClass.mjs","names":[],"sources":["../../src/I18nClass.ts"],"sourcesContent":["import { getIntlayer } from '@intlayer/core/interpreter';\nimport { resolveMessage } from '@intlayer/core/messageFormat';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n AllMessages,\n Locale,\n Locales,\n MessageDescriptor,\n MessageId,\n MessageOptions,\n Messages,\n} from '@lingui/core';\nimport { EventEmitter } from './eventEmitter';\nimport {\n linguiMessageToIcu,\n navigateLinguiCatalog,\n unwrapLinguiCatalog,\n} from './linguiCatalog';\n\n/** Mirrors the unexported `Values` type from `@lingui/core`. */\ntype Values = Record<string, unknown>;\n\n/** Mirrors the unexported `MessageCompiler` type from `@lingui/core`. */\ntype MessageCompiler = (message: string) => unknown;\n\n/** Mirrors the unexported `Events` type from `@lingui/core`. */\ntype LinguiEvents = {\n change: () => void;\n missing: (event: { locale: Locale; id: MessageId }) => void;\n};\n\n/** Mirrors the unexported `I18nProps` type from `@lingui/core`. */\ntype I18nProps = {\n locale?: Locale;\n locales?: Locales;\n messages?: AllMessages;\n missing?: string | ((locale: string, id: string) => string);\n};\n\n/**\n * Keys of every intlayer dictionary available at runtime (the namespaces).\n *\n * The bundler-injected `@intlayer/dictionaries-entry` exposes the full registry;\n * outside a bundle (e.g. unit tests) it resolves to an empty map, in which case\n * resolution falls back to the runtime catalogs loaded via `load()`.\n */\nconst getDictionaryKeys = (): DictionaryKeys[] => {\n try {\n return Object.keys(getDictionaries()) as DictionaryKeys[];\n } catch {\n return [];\n }\n};\n\n/**\n * Looks up a lingui message across every intlayer dictionary.\n *\n * lingui ids are flat, namespace-less keys (`'hero.title'`), but the matching\n * content may live in any dictionary — a single centralized catalog, or one of\n * many namespaced catalogs (`home`, `shared`, …) produced by `syncJSON` from\n * split lingui catalogs. Each dictionary is searched in turn, supporting both\n * the flat/nested key shapes and the lingui `{ messages: {…} }` wrapper. The\n * first match wins.\n */\nconst lookupDictionaryMessage = (\n id: string,\n locale: LocalesValues\n): string | undefined => {\n for (const key of getDictionaryKeys()) {\n let dictionary: unknown;\n try {\n dictionary = getIntlayer(key, locale);\n } catch {\n continue;\n }\n const value = navigateLinguiCatalog(dictionary, id);\n if (value !== undefined) return linguiMessageToIcu(value);\n }\n return undefined;\n};\n\n/**\n * Intlayer-backed implementation of `@lingui/core`'s `I18n` class.\n *\n * - Messages are read from the `messages` intlayer dictionary.\n * - ICU MessageFormat syntax is resolved via `@intlayer/core/messageFormat`.\n * - `load()` / `loadAndActivate()` / `setMessagesCompiler()` are no-ops —\n * messages are served by intlayer's compiled dictionaries.\n * - `activate(locale)` emits `'change'` so that React consumers re-render.\n */\nexport class I18nClass extends EventEmitter<LinguiEvents> {\n private _locale: string;\n private _locales?: Locales;\n /**\n * Per-locale catalogs supplied at runtime via the constructor, `load()` or\n * `loadAndActivate()`. Used as a fallback when a key is absent from the\n * compiled intlayer `messages` dictionary, so an unmodified lingui codebase\n * (which loads its compiled `.mjs`/`.json` catalogs) keeps working as a\n * drop-in. For optimal bundle size, compile catalogs into intlayer\n * dictionaries instead — see the dev warning emitted by `load()`.\n */\n private _catalogs: Record<string, Messages> = {};\n private _loadFallbackWarned = false;\n /**\n * Pre-resolved `messages` dictionary content bound by the build-optimized\n * `useDictionary` / `useDictionaryDynamic` variants. Checked before the\n * runtime registry so lookups stay tree-shakeable.\n */\n private _dictionaryContent: unknown;\n\n constructor({ locale = 'en', locales, messages }: I18nProps = {}) {\n super();\n this._locale = typeof locale === 'string' ? locale : 'en';\n this._locales = locales;\n if (messages) this.mergeAllCatalogs(messages);\n }\n\n get locale(): string {\n return this._locale;\n }\n\n get locales(): Locales | undefined {\n return this._locales;\n }\n\n get messages(): Messages {\n // Merge every intlayer dictionary (namespace) for the active locale into a\n // single flat catalog, unwrapping the lingui `{ messages: {…} }` wrapper.\n const dictionary: Messages = {};\n if (this._dictionaryContent !== undefined) {\n Object.assign(dictionary, unwrapLinguiCatalog(this._dictionaryContent));\n }\n for (const key of getDictionaryKeys()) {\n try {\n Object.assign(\n dictionary,\n unwrapLinguiCatalog(getIntlayer(key, this._locale as LocalesValues))\n );\n } catch {\n // Skip dictionaries that fail to resolve for this locale.\n }\n }\n // The compiled dictionaries win over the runtime fallback catalog.\n return { ...(this._catalogs[this._locale] ?? {}), ...dictionary };\n }\n\n /** Merges a single-locale catalog into the in-memory fallback store. */\n private mergeLocaleCatalog(locale: string, catalog: Messages) {\n this._catalogs[locale] = { ...this._catalogs[locale], ...catalog };\n }\n\n /**\n * Merges a `{ [locale]: catalog }` map (lingui's `AllMessages`) into the\n * in-memory fallback store.\n */\n private mergeAllCatalogs(messages: AllMessages) {\n for (const [locale, catalog] of Object.entries(messages)) {\n if (catalog && typeof catalog === 'object') {\n this.mergeLocaleCatalog(locale, catalog as Messages);\n }\n }\n }\n\n /**\n * No-op: intlayer handles message compilation at build time.\n */\n setMessagesCompiler(_compiler: MessageCompiler): this {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n '@intlayer/lingui: i18n.setMessagesCompiler() is a no-op — ' +\n 'message compilation is handled at build time by intlayer.'\n );\n }\n return this;\n }\n\n /**\n * Loads message catalogs into the runtime fallback store, supporting both\n * lingui signatures: `load(locale, messages)` and `load(allMessages)`.\n *\n * These messages are a compatibility fallback — keys present in the compiled\n * intlayer `messages` dictionary take precedence, and only those keys can be\n * pruned/optimized at build time.\n */\n load(localeOrAll: Locale | AllMessages, messages?: Messages): void {\n if (typeof localeOrAll === 'string') {\n this.mergeLocaleCatalog(localeOrAll, messages ?? {});\n } else {\n this.mergeAllCatalogs(localeOrAll);\n }\n\n if (process.env.NODE_ENV === 'development' && !this._loadFallbackWarned) {\n this._loadFallbackWarned = true;\n console.warn(\n '@intlayer/lingui: i18n.load() messages are used as a runtime ' +\n 'fallback. For optimal bundle size, compile your catalogs into ' +\n 'intlayer dictionaries instead of importing lingui locale files.'\n );\n }\n }\n\n /**\n * Loads the given catalog (fallback store) and activates the locale\n * (emits `'change'`).\n */\n loadAndActivate({\n locale,\n locales,\n messages,\n }: {\n locale: Locale;\n locales?: Locales;\n messages?: Messages;\n }): void {\n if (messages) this.mergeLocaleCatalog(locale, messages);\n this.activate(locale, locales);\n }\n\n /**\n * Binds pre-resolved `messages` dictionary content, checked before the\n * runtime registry.\n *\n * @internal Used by the build-optimized `useDictionary` /\n * `useDictionaryDynamic` variants — not part of the lingui API surface.\n */\n bindDictionaryContent(content: unknown): this {\n this._dictionaryContent = content;\n return this;\n }\n\n /**\n * Sets the active locale and emits `'change'` to notify React consumers.\n */\n activate(locale: Locale, locales?: Locales): void {\n this._locale = locale;\n this._locales = locales;\n this.emit('change');\n }\n\n /**\n * Resolves the raw message template for an id (before interpolation).\n *\n * Resolution order:\n * 1. compiled intlayer `messages` dictionary\n * 2. runtime fallback catalog (constructor / `load()` / `loadAndActivate()`)\n */\n private resolveTemplate(id: string): string | undefined {\n if (this._dictionaryContent !== undefined) {\n const boundValue = navigateLinguiCatalog(this._dictionaryContent, id);\n if (boundValue !== undefined) return linguiMessageToIcu(boundValue);\n }\n\n const fromDictionary = lookupDictionaryMessage(\n id,\n this._locale as LocalesValues\n );\n if (fromDictionary !== undefined) return fromDictionary;\n\n const catalog = this._catalogs[this._locale];\n if (catalog) {\n const raw = navigateLinguiCatalog(catalog, id);\n if (raw !== undefined) return linguiMessageToIcu(raw);\n }\n\n return undefined;\n }\n\n /**\n * Translates a message descriptor or a plain ID.\n *\n * Resolution order:\n * 1. `messages` intlayer dictionary (flat dotted key or nested path)\n * 2. runtime fallback catalog loaded via `load()` / `loadAndActivate()`\n * 3. `descriptor.message` or `options.message` (original source string)\n * 4. The raw `id` as fallback\n */\n _(descriptor: MessageDescriptor): string;\n _(id: MessageId, values?: Values, options?: MessageOptions): string;\n _(\n descriptorOrId: MessageDescriptor | MessageId,\n values?: Values,\n options?: MessageOptions\n ): string {\n const isDescriptor =\n typeof descriptorOrId === 'object' && descriptorOrId !== null;\n const id = isDescriptor\n ? (descriptorOrId as MessageDescriptor).id\n : (descriptorOrId as MessageId);\n const defaultMessage = isDescriptor\n ? ((descriptorOrId as MessageDescriptor).message ?? options?.message)\n : options?.message;\n const resolvedValues: Values = isDescriptor\n ? {\n ...((descriptorOrId as MessageDescriptor).values ?? {}),\n ...(values ?? {}),\n }\n : (values ?? {});\n\n const rawValue = this.resolveTemplate(id);\n const template = rawValue ?? defaultMessage ?? id;\n\n return (\n resolveMessage(\n template,\n resolvedValues as Record<string, string | number>,\n this._locale as LocalesValues,\n 'icu'\n ) ?? id\n );\n }\n\n /**\n * Alias for `_`. Provided for lingui API compatibility.\n */\n t = (\n descriptorOrId: MessageDescriptor | MessageId,\n values?: Values,\n options?: MessageOptions\n ): string => this._(descriptorOrId as MessageId, values, options);\n\n /**\n * @deprecated Use `Intl.DateTimeFormat` directly.\n */\n date(\n value?: string | Date | number,\n format?: Intl.DateTimeFormatOptions\n ): string {\n if (value === undefined || value === null) return '';\n const dateValue =\n value instanceof Date\n ? value\n : new Date(typeof value === 'string' ? value : value);\n return new Intl.DateTimeFormat(this._locale, format).format(dateValue);\n }\n\n /**\n * @deprecated Use `Intl.NumberFormat` directly.\n */\n number(value: number | bigint, format?: Intl.NumberFormatOptions): string {\n return new Intl.NumberFormat(this._locale, format).format(value);\n }\n}\n"],"mappings":"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"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -7,5 +7,7 @@ import { formats } from "./formats.mjs";
|
|
|
7
7
|
import { I18nProvider } from "./I18nProvider.mjs";
|
|
8
8
|
import { Trans } from "./Trans.mjs";
|
|
9
9
|
import { i18n, setupI18n } from "./setupI18n.mjs";
|
|
10
|
+
import { useDictionaryDynamic } from "./useDictionaryDynamic.mjs";
|
|
11
|
+
import { useDictionary } from "./useDictionary.mjs";
|
|
10
12
|
|
|
11
|
-
export { I18nClass as I18n, I18nProvider, LinguiContext, Trans, formats, i18n, setupI18n, useLingui };
|
|
13
|
+
export { I18nClass as I18n, I18nProvider, LinguiContext, Trans, formats, i18n, setupI18n, useDictionary, useDictionaryDynamic, useLingui };
|
|
@@ -1,52 +1,13 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { LINGUI_CALLERS } from "@intlayer/config/callers";
|
|
3
3
|
import * as ANSIColors from "@intlayer/config/colors";
|
|
4
4
|
import { colorize, getAppLogger } from "@intlayer/config/logger";
|
|
5
5
|
import { getConfiguration } from "@intlayer/config/node";
|
|
6
|
+
import { runOnce } from "@intlayer/engine/utils";
|
|
6
7
|
import { intlayer } from "vite-intlayer";
|
|
7
8
|
|
|
8
9
|
//#region src/plugin/index.ts
|
|
9
10
|
/**
|
|
10
|
-
* Caller configurations for lingui.
|
|
11
|
-
*
|
|
12
|
-
* After `@lingui/babel-plugin-lingui-macro` / `@lingui/swc-plugin` compiles
|
|
13
|
-
* macros (`` t`Hello ${name}` `` → `i18n._(id, values)`) the intlayer field
|
|
14
|
-
* usage analyser sees these method calls and records which top-level fields of
|
|
15
|
-
* the `messages` dictionary are consumed, enabling accurate pruning.
|
|
16
|
-
*
|
|
17
|
-
* Two call forms are tracked:
|
|
18
|
-
* - `i18n._('home.title', values)` — string id
|
|
19
|
-
* - `i18n._({ id: 'home.title', message: '...' }, values)` — descriptor
|
|
20
|
-
* - `i18n.t('home.title', values)` — alias for `_`
|
|
21
|
-
*
|
|
22
|
-
* Because lingui projects may also use hashed IDs (generated from the default
|
|
23
|
-
* message string) that cannot be statically mapped to dictionary keys, a
|
|
24
|
-
* separate `'all'`-mode caller is not needed here: when the first argument is
|
|
25
|
-
* not a static string or descriptor, the `'self'` handler falls back to `'all'`
|
|
26
|
-
* automatically.
|
|
27
|
-
*/
|
|
28
|
-
const LINGUI_COMPAT_CALLERS = [{
|
|
29
|
-
callerName: "_",
|
|
30
|
-
importSources: ["@lingui/core", "@intlayer/lingui"],
|
|
31
|
-
matchAsMethod: true,
|
|
32
|
-
namespace: {
|
|
33
|
-
from: "fixed",
|
|
34
|
-
value: "messages"
|
|
35
|
-
},
|
|
36
|
-
translationFunction: "self",
|
|
37
|
-
flatKey: true
|
|
38
|
-
}, {
|
|
39
|
-
callerName: "t",
|
|
40
|
-
importSources: ["@lingui/core", "@intlayer/lingui"],
|
|
41
|
-
matchAsMethod: true,
|
|
42
|
-
namespace: {
|
|
43
|
-
from: "fixed",
|
|
44
|
-
value: "messages"
|
|
45
|
-
},
|
|
46
|
-
translationFunction: "self",
|
|
47
|
-
flatKey: true
|
|
48
|
-
}];
|
|
49
|
-
/**
|
|
50
11
|
* A Vite plugin for the lingui compat adapter.
|
|
51
12
|
*
|
|
52
13
|
* Wraps `vite-intlayer` and adds resolve aliases so that both
|
|
@@ -71,7 +32,7 @@ const lingui = (options) => {
|
|
|
71
32
|
}, { cacheTimeoutMs: 1e3 * 60 * 60 });
|
|
72
33
|
const basePlugins = intlayer({
|
|
73
34
|
...options,
|
|
74
|
-
compatCallers: [...options?.compatCallers ?? [], ...
|
|
35
|
+
compatCallers: [...options?.compatCallers ?? [], ...LINGUI_CALLERS]
|
|
75
36
|
});
|
|
76
37
|
const compatPlugin = {
|
|
77
38
|
name: "vite-lingui-compat-plugin",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugin/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { LINGUI_CALLERS } from '@intlayer/config/callers';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { runOnce } from '@intlayer/engine/utils';\nimport type { PluginOption } from 'vite';\nimport { intlayer } from 'vite-intlayer';\n\n/**\n * A Vite plugin for the lingui compat adapter.\n *\n * Wraps `vite-intlayer` and adds resolve aliases so that both\n * `@lingui/core` **and** `@lingui/react` are redirected to\n * `@intlayer/lingui` at bundle time.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { lingui } from '@intlayer/lingui/plugin';\n *\n * export default defineConfig({\n * plugins: [lingui()],\n * });\n * ```\n */\nexport const lingui = (\n options?: Parameters<typeof intlayer>[0]\n): PluginOption[] => {\n const intlayerConfig = getConfiguration();\n const appLogger = getAppLogger(intlayerConfig);\n\n runOnce(\n join(\n intlayerConfig.system.baseDir,\n '.intlayer',\n 'cache',\n 'intlayer-issues-invitation.lock'\n ),\n () => {\n appLogger([\n colorize(\n 'Please report any issues you met on GitHub:',\n ANSIColors.GREY\n ),\n colorize(\n 'https://github.com/aymericzip/intlayer/issues',\n ANSIColors.GREY_LIGHT\n ),\n ]);\n },\n {\n cacheTimeoutMs: 1000 * 60 * 60, // 1 hour\n }\n );\n\n const basePlugins = intlayer({\n ...options,\n compatCallers: [...(options?.compatCallers ?? []), ...LINGUI_CALLERS],\n });\n\n const compatPlugin: PluginOption = {\n name: 'vite-lingui-compat-plugin',\n config: () => ({\n resolve: {\n alias: {\n '@lingui/core': '@intlayer/lingui',\n '@lingui/react': '@intlayer/lingui',\n },\n },\n }),\n };\n\n return [\n ...(Array.isArray(basePlugins) ? basePlugins : [basePlugins]),\n compatPlugin,\n ];\n};\n\n/**\n * Backwards-compatible alias for {@link lingui}, matching the naming used by the\n * other compat adapters' Vite plugins (e.g. `i18nextVitePlugin`).\n */\nexport const linguiVitePlugin = lingui;\n\nexport default lingui;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,UACX,YACmB;CACnB,MAAM,iBAAiB,iBAAiB;CACxC,MAAM,YAAY,aAAa,cAAc;CAE7C,QACE,KACE,eAAe,OAAO,SACtB,aACA,SACA,iCACF,SACM;EACJ,UAAU,CACR,SACE,+CACA,WAAW,IACb,GACA,SACE,iDACA,WAAW,UACb,CACF,CAAC;CACH,GACA,EACE,gBAAgB,MAAO,KAAK,GAC9B,CACF;CAEA,MAAM,cAAc,SAAS;EAC3B,GAAG;EACH,eAAe,CAAC,GAAI,SAAS,iBAAiB,CAAC,GAAI,GAAG,cAAc;CACtE,CAAC;CAED,MAAM,eAA6B;EACjC,MAAM;EACN,eAAe,EACb,SAAS,EACP,OAAO;GACL,gBAAgB;GAChB,iBAAiB;EACnB,EACF,EACF;CACF;CAEA,OAAO,CACL,GAAI,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,WAAW,GAC3D,YACF;AACF;;;;;AAMA,MAAa,mBAAmB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { I18nClass } from "./I18nClass.mjs";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { useDictionary as useDictionary$1, useLocale } from "react-intlayer";
|
|
6
|
+
|
|
7
|
+
//#region src/useDictionary.ts
|
|
8
|
+
/**
|
|
9
|
+
* Dictionary-accepting variant of `useLingui`.
|
|
10
|
+
*
|
|
11
|
+
* Used internally by the build-time optimization: instead of resolving the
|
|
12
|
+
* single-catalog `messages` dictionary at runtime, the babel/swc plugin
|
|
13
|
+
* pre-imports the dictionary JSON at build time and passes it directly here.
|
|
14
|
+
* This enables tree-shaking of unused locale content.
|
|
15
|
+
*
|
|
16
|
+
* @example (generated by the plugin, not written manually)
|
|
17
|
+
* import _abc from '.intlayer/dictionaries/messages.json' with { type: 'json' };
|
|
18
|
+
* const { _ } = useDictionary(_abc);
|
|
19
|
+
*/
|
|
20
|
+
const useDictionary = (dictionary) => {
|
|
21
|
+
const content = useDictionary$1(dictionary);
|
|
22
|
+
const { locale } = useLocale();
|
|
23
|
+
return useMemo(() => {
|
|
24
|
+
const instance = new I18nClass({ locale }).bindDictionaryContent(content);
|
|
25
|
+
return {
|
|
26
|
+
i18n: instance,
|
|
27
|
+
_: instance._.bind(instance)
|
|
28
|
+
};
|
|
29
|
+
}, [locale, content]);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { useDictionary };
|
|
34
|
+
//# sourceMappingURL=useDictionary.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDictionary.mjs","names":["useDictionaryBase"],"sources":["../../src/useDictionary.ts"],"sourcesContent":["'use client';\n\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { I18nContext } from '@lingui/react';\nimport { useMemo } from 'react';\nimport { useDictionary as useDictionaryBase, useLocale } from 'react-intlayer';\nimport { I18nClass } from './I18nClass';\n\n/**\n * Dictionary-accepting variant of `useLingui`.\n *\n * Used internally by the build-time optimization: instead of resolving the\n * single-catalog `messages` dictionary at runtime, the babel/swc plugin\n * pre-imports the dictionary JSON at build time and passes it directly here.\n * This enables tree-shaking of unused locale content.\n *\n * @example (generated by the plugin, not written manually)\n * import _abc from '.intlayer/dictionaries/messages.json' with { type: 'json' };\n * const { _ } = useDictionary(_abc);\n */\nexport const useDictionary = <T extends Dictionary>(\n dictionary: T\n): I18nContext => {\n const content = useDictionaryBase(dictionary);\n const { locale } = useLocale();\n\n return useMemo(() => {\n const instance = new I18nClass({\n locale: locale as string,\n }).bindDictionaryContent(content);\n\n return {\n i18n: instance as unknown as I18nContext['i18n'],\n _: instance._.bind(instance) as I18nContext['_'],\n } as I18nContext;\n }, [locale, content]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,MAAa,iBACX,eACgB;CAChB,MAAM,UAAUA,gBAAkB,UAAU;CAC5C,MAAM,EAAE,WAAW,UAAU;CAE7B,OAAO,cAAc;EACnB,MAAM,WAAW,IAAI,UAAU,EACrB,OACV,CAAC,CAAC,CAAC,sBAAsB,OAAO;EAEhC,OAAO;GACL,MAAM;GACN,GAAG,SAAS,EAAE,KAAK,QAAQ;EAC7B;CACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AACtB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { I18nClass } from "./I18nClass.mjs";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { useDictionaryDynamic as useDictionaryDynamic$1, useLocale } from "react-intlayer";
|
|
6
|
+
|
|
7
|
+
//#region src/useDictionaryDynamic.ts
|
|
8
|
+
/**
|
|
9
|
+
* Dynamic dictionary-accepting variant of `useLingui`.
|
|
10
|
+
*
|
|
11
|
+
* Counterpart to {@link useDictionary} for dictionaries imported lazily per
|
|
12
|
+
* locale. Used internally by the build-time optimization.
|
|
13
|
+
*/
|
|
14
|
+
const useDictionaryDynamic = (dictionaryPromise, key) => {
|
|
15
|
+
const content = useDictionaryDynamic$1(dictionaryPromise, key);
|
|
16
|
+
const { locale } = useLocale();
|
|
17
|
+
return useMemo(() => {
|
|
18
|
+
const instance = new I18nClass({ locale }).bindDictionaryContent(content);
|
|
19
|
+
return {
|
|
20
|
+
i18n: instance,
|
|
21
|
+
_: instance._.bind(instance)
|
|
22
|
+
};
|
|
23
|
+
}, [locale, content]);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { useDictionaryDynamic };
|
|
28
|
+
//# sourceMappingURL=useDictionaryDynamic.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.mjs","names":["useDictionaryDynamicBase"],"sources":["../../src/useDictionaryDynamic.ts"],"sourcesContent":["'use client';\n\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { StrictModeLocaleMap } from '@intlayer/types/module_augmentation';\nimport type { I18nContext } from '@lingui/react';\nimport { useMemo } from 'react';\nimport {\n useDictionaryDynamic as useDictionaryDynamicBase,\n useLocale,\n} from 'react-intlayer';\nimport { I18nClass } from './I18nClass';\n\n/**\n * Dynamic dictionary-accepting variant of `useLingui`.\n *\n * Counterpart to {@link useDictionary} for dictionaries imported lazily per\n * locale. Used internally by the build-time optimization.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends string,\n>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n key: K\n): I18nContext => {\n const content = useDictionaryDynamicBase<T, K>(dictionaryPromise, key);\n const { locale } = useLocale();\n\n return useMemo(() => {\n const instance = new I18nClass({\n locale: locale as string,\n }).bindDictionaryContent(content);\n\n return {\n i18n: instance as unknown as I18nContext['i18n'],\n _: instance._.bind(instance) as I18nContext['_'],\n } as I18nContext;\n }, [locale, content]);\n};\n"],"mappings":";;;;;;;;;;;;;AAkBA,MAAa,wBAIX,mBACA,QACgB;CAChB,MAAM,UAAUA,uBAA+B,mBAAmB,GAAG;CACrE,MAAM,EAAE,WAAW,UAAU;CAE7B,OAAO,cAAc;EACnB,MAAM,WAAW,IAAI,UAAU,EACrB,OACV,CAAC,CAAC,CAAC,sBAAsB,OAAO;EAEhC,OAAO;GACL,MAAM;GACN,GAAG,SAAS,EAAE,KAAK,QAAQ;EAC7B;CACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AACtB"}
|
|
@@ -43,6 +43,12 @@ declare class I18nClass extends EventEmitter<LinguiEvents> {
|
|
|
43
43
|
*/
|
|
44
44
|
private _catalogs;
|
|
45
45
|
private _loadFallbackWarned;
|
|
46
|
+
/**
|
|
47
|
+
* Pre-resolved `messages` dictionary content bound by the build-optimized
|
|
48
|
+
* `useDictionary` / `useDictionaryDynamic` variants. Checked before the
|
|
49
|
+
* runtime registry so lookups stay tree-shakeable.
|
|
50
|
+
*/
|
|
51
|
+
private _dictionaryContent;
|
|
46
52
|
constructor({
|
|
47
53
|
locale,
|
|
48
54
|
locales,
|
|
@@ -84,6 +90,14 @@ declare class I18nClass extends EventEmitter<LinguiEvents> {
|
|
|
84
90
|
locales?: Locales;
|
|
85
91
|
messages?: Messages;
|
|
86
92
|
}): void;
|
|
93
|
+
/**
|
|
94
|
+
* Binds pre-resolved `messages` dictionary content, checked before the
|
|
95
|
+
* runtime registry.
|
|
96
|
+
*
|
|
97
|
+
* @internal Used by the build-optimized `useDictionary` /
|
|
98
|
+
* `useDictionaryDynamic` variants — not part of the lingui API surface.
|
|
99
|
+
*/
|
|
100
|
+
bindDictionaryContent(content: unknown): this;
|
|
87
101
|
/**
|
|
88
102
|
* Sets the active locale and emits `'change'` to notify React consumers.
|
|
89
103
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"I18nClass.d.ts","names":[],"sources":["../../src/I18nClass.ts"],"mappings":";;;;;KAwBK,MAAA,GAAS,MAAM;AAR0B;AAAA,KAWzC,eAAA,IAAmB,OAAe;;KAGlC,YAAA;EACH,MAAA;EACA,OAAA,GAAU,KAAA;IAAS,MAAA,EAAQ,MAAA;IAAQ,EAAA,EAAI,SAAS;EAAA;AAAA;AALX;AAAA,KASlC,SAAA;EACH,MAAA,GAAS,MAAA;EACT,OAAA,GAAU,OAAA;EACV,QAAA,GAAW,WAAA;EACX,OAAA,cAAqB,MAAA,UAAgB,EAAA;AAAA;;;;;;AARa;AAAA;;;cA8DvC,SAAA,SAAkB,YAAA,CAAa,YAAA;EAAA,QAClC,OAAA;EAAA,QACA,QAAA;EAzDc;;;;;;;;EAAA,QAkEd,SAAA;EAAA,QACA,mBAAA;;IAEM,MAAA;IAAe,OAAA;IAAS;EAAA,IAAY,SAAA;EAAA,IAO9C,MAAA;EAAA,IAIA,OAAA,IAAW,OAAA;EAAA,IAIX,QAAA,IAAY,QAAA;
|
|
1
|
+
{"version":3,"file":"I18nClass.d.ts","names":[],"sources":["../../src/I18nClass.ts"],"mappings":";;;;;KAwBK,MAAA,GAAS,MAAM;AAR0B;AAAA,KAWzC,eAAA,IAAmB,OAAe;;KAGlC,YAAA;EACH,MAAA;EACA,OAAA,GAAU,KAAA;IAAS,MAAA,EAAQ,MAAA;IAAQ,EAAA,EAAI,SAAS;EAAA;AAAA;AALX;AAAA,KASlC,SAAA;EACH,MAAA,GAAS,MAAA;EACT,OAAA,GAAU,OAAA;EACV,QAAA,GAAW,WAAA;EACX,OAAA,cAAqB,MAAA,UAAgB,EAAA;AAAA;;;;;;AARa;AAAA;;;cA8DvC,SAAA,SAAkB,YAAA,CAAa,YAAA;EAAA,QAClC,OAAA;EAAA,QACA,QAAA;EAzDc;;;;;;;;EAAA,QAkEd,SAAA;EAAA,QACA,mBAAA;EAlE6B;;AAAU;AAsDjD;;EAtDuC,QAwE7B,kBAAA;;IAEM,MAAA;IAAe,OAAA;IAAS;EAAA,IAAY,SAAA;EAAA,IAO9C,MAAA;EAAA,IAIA,OAAA,IAAW,OAAA;EAAA,IAIX,QAAA,IAAY,QAAA;EAfkC;EAAA,QAqC1C,kBAAA;EAtBQ;;;;EAAA,QA8BR,gBAAA;EAmDN;;;EAxCF,mBAAA,CAAoB,SAAA,EAAW,eAAA;EA6CnB;;;;;;;;EA3BZ,IAAA,CAAK,WAAA,EAAa,MAAA,GAAS,WAAA,EAAa,QAAA,GAAW,QAAA;EAmIb;;;;EA9GtC,eAAA;IACE,MAAA;IACA,OAAA;IACA;EAAA;IAEA,MAAA,EAAQ,MAAA;IACR,OAAA,GAAU,OAAA;IACV,QAAA,GAAW,QAAA;EAAA;EA1HgB;;;;;;;EAuI7B,qBAAA,CAAsB,OAAA;EAnHR;;;EA2Hd,QAAA,CAAS,MAAA,EAAQ,MAAA,EAAQ,OAAA,GAAU,OAAA;EA3HG;;;;;;;EAAA,QAwI9B,eAAA;EAnGA;;;;;;;;;EAiIR,CAAA,CAAE,UAAA,EAAY,iBAAA;EACd,CAAA,CAAE,EAAA,EAAI,SAAA,EAAW,MAAA,GAAS,MAAA,EAAQ,OAAA,GAAU,cAAA;EAxE5C;;;EA6GA,CAAA,GACE,cAAA,EAAgB,iBAAA,GAAoB,SAAA,EACpC,MAAA,GAAS,MAAA,EACT,OAAA,GAAU,cAAA;EA9GV;;;EAoHF,IAAA,CACE,KAAA,YAAiB,IAAA,WACjB,MAAA,GAAS,IAAA,CAAK,qBAAA;EAnHN;;;EAgIV,MAAA,CAAO,KAAA,mBAAwB,MAAA,GAAS,IAAA,CAAK,mBAAA;AAAA"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ import { LinguiContext } from "./LinguiContext.js";
|
|
|
4
4
|
import { Trans } from "./Trans.js";
|
|
5
5
|
import { formats } from "./formats.js";
|
|
6
6
|
import { i18n, setupI18n } from "./setupI18n.js";
|
|
7
|
+
import { useDictionary } from "./useDictionary.js";
|
|
8
|
+
import { useDictionaryDynamic } from "./useDictionaryDynamic.js";
|
|
7
9
|
import { useLingui } from "./useLingui.js";
|
|
8
10
|
import { AllMessages, Locale, Locales, MessageDescriptor, MessageId, MessageOptions, Messages, Register } from "@lingui/core";
|
|
9
11
|
import { I18nContext, I18nProviderProps, TransProps, TransRenderCallbackOrComponent, TransRenderProps } from "@lingui/react";
|
|
10
|
-
export { type AllMessages, I18nClass as I18n, type I18nContext, I18nProvider, type I18nProviderProps, LinguiContext, type Locale, type Locales, type MessageDescriptor, type MessageId, type MessageOptions, type Messages, type Register, Trans, type TransProps, type TransRenderCallbackOrComponent, type TransRenderProps, formats, i18n, setupI18n, useLingui };
|
|
12
|
+
export { type AllMessages, I18nClass as I18n, type I18nContext, I18nProvider, type I18nProviderProps, LinguiContext, type Locale, type Locales, type MessageDescriptor, type MessageId, type MessageOptions, type Messages, type Register, Trans, type TransProps, type TransRenderCallbackOrComponent, type TransRenderProps, formats, i18n, setupI18n, useDictionary, useDictionaryDynamic, useLingui };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/plugin/index.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/plugin/index.ts"],"mappings":";;;;;;AA0BA;;;;;;;;;;;;;AAEe;AAuDf;cAzDa,MAAA,GACX,OAAA,GAAU,UAAA,QAAkB,QAAA,SAC3B,YAAA;;;;;cAuDU,gBAAA,GAAgB,OAAA,GAxDjB,UAAA,QAAkB,QAAA,SAC3B,YAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { I18nContext } from "@lingui/react";
|
|
2
|
+
import { Dictionary } from "@intlayer/types/dictionary";
|
|
3
|
+
|
|
4
|
+
//#region src/useDictionary.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Dictionary-accepting variant of `useLingui`.
|
|
7
|
+
*
|
|
8
|
+
* Used internally by the build-time optimization: instead of resolving the
|
|
9
|
+
* single-catalog `messages` dictionary at runtime, the babel/swc plugin
|
|
10
|
+
* pre-imports the dictionary JSON at build time and passes it directly here.
|
|
11
|
+
* This enables tree-shaking of unused locale content.
|
|
12
|
+
*
|
|
13
|
+
* @example (generated by the plugin, not written manually)
|
|
14
|
+
* import _abc from '.intlayer/dictionaries/messages.json' with { type: 'json' };
|
|
15
|
+
* const { _ } = useDictionary(_abc);
|
|
16
|
+
*/
|
|
17
|
+
declare const useDictionary: <T extends Dictionary>(dictionary: T) => I18nContext;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { useDictionary };
|
|
20
|
+
//# sourceMappingURL=useDictionary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDictionary.d.ts","names":[],"sources":["../../src/useDictionary.ts"],"mappings":";;;;;;AAoBA;;;;;;;;;;cAAa,aAAA,aAA2B,UAAA,EACtC,UAAA,EAAY,CAAA,KACX,WAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { I18nContext } from "@lingui/react";
|
|
2
|
+
import { Dictionary } from "@intlayer/types/dictionary";
|
|
3
|
+
import { StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
|
|
4
|
+
|
|
5
|
+
//#region src/useDictionaryDynamic.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Dynamic dictionary-accepting variant of `useLingui`.
|
|
8
|
+
*
|
|
9
|
+
* Counterpart to {@link useDictionary} for dictionaries imported lazily per
|
|
10
|
+
* locale. Used internally by the build-time optimization.
|
|
11
|
+
*/
|
|
12
|
+
declare const useDictionaryDynamic: <const T extends Dictionary, const K extends string>(dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>, key: K) => I18nContext;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { useDictionaryDynamic };
|
|
15
|
+
//# sourceMappingURL=useDictionaryDynamic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.d.ts","names":[],"sources":["../../src/useDictionaryDynamic.ts"],"mappings":";;;;;;;AAkBA;;;;cAAa,oBAAA,mBACK,UAAA,0BAGhB,iBAAA,EAAmB,mBAAA,OAA0B,OAAA,CAAQ,CAAA,IACrD,GAAA,EAAK,CAAA,KACJ,WAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/lingui",
|
|
3
|
-
"version": "9.0.0-canary.
|
|
3
|
+
"version": "9.0.0-canary.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "lingui API adapter for intlayer — drop-in compatibility layer",
|
|
6
6
|
"keywords": [
|
|
@@ -74,13 +74,13 @@
|
|
|
74
74
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@intlayer/
|
|
78
|
-
"@intlayer/
|
|
79
|
-
"@intlayer/
|
|
80
|
-
"@intlayer/
|
|
81
|
-
"@intlayer/types": "9.0.0-canary.
|
|
82
|
-
"react-intlayer": "9.0.0-canary.
|
|
83
|
-
"vite-intlayer": "9.0.0-canary.
|
|
77
|
+
"@intlayer/config": "9.0.0-canary.13",
|
|
78
|
+
"@intlayer/core": "9.0.0-canary.13",
|
|
79
|
+
"@intlayer/dictionaries-entry": "9.0.0-canary.13",
|
|
80
|
+
"@intlayer/engine": "9.0.0-canary.13",
|
|
81
|
+
"@intlayer/types": "9.0.0-canary.13",
|
|
82
|
+
"react-intlayer": "9.0.0-canary.13",
|
|
83
|
+
"vite-intlayer": "9.0.0-canary.13"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@lingui/core": "^6.3.0",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"rimraf": "6.1.3",
|
|
94
94
|
"tsdown": "0.22.2",
|
|
95
95
|
"typescript": "6.0.3",
|
|
96
|
-
"vite": "8.1.
|
|
96
|
+
"vite": "8.1.3",
|
|
97
97
|
"vitest": "4.1.9"
|
|
98
98
|
},
|
|
99
99
|
"peerDependencies": {
|