i18n-keyless-react 2.2.0 → 2.3.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/dist/I18nKeylessText.js +6 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/request-scope.d.ts +22 -3
- package/dist/request-scope.js +43 -5
- package/dist/store.js +4 -1
- package/package.json +2 -2
package/dist/I18nKeylessText.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import React, { useEffect, useMemo } from "react";
|
|
3
3
|
import { useI18nKeyless, getTranslation } from "./store.js";
|
|
4
4
|
import { useI18nKeylessContext } from "./I18nKeylessProvider.js";
|
|
5
|
-
import { getRequestScope } from "./request-scope.js";
|
|
5
|
+
import { getRequestScope, recordUsedKey } from "./request-scope.js";
|
|
6
6
|
const warnAboutWhitespace = (text) => {
|
|
7
7
|
if (process.env.NODE_ENV === "development" && text !== text.trim()) {
|
|
8
8
|
console.warn(`I18nKeylessText received text with leading/trailing whitespace: "${text}". ` +
|
|
@@ -29,9 +29,11 @@ export const I18nKeylessText = ({ children, replace, context, debug = false, for
|
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
getTranslation(sourceText, { context, debug, forceTemporary });
|
|
31
31
|
}, [sourceText, currentLanguage, context, debug, forceTemporary]);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const storageKey = context ? `${sourceText}__${context}` : sourceText;
|
|
33
|
+
// Record the key for the per-page SSR snapshot (no-op off-server; pure Set.add, no
|
|
34
|
+
// setState, so no render-time update warning). See docs/SSR.md.
|
|
35
|
+
recordUsedKey(storageKey);
|
|
36
|
+
const translatedText = currentLanguage === config.languages.primary ? sourceText : translations[storageKey] || sourceText;
|
|
35
37
|
const finalText = useMemo(() => {
|
|
36
38
|
if (!replace) {
|
|
37
39
|
return translatedText;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { clearI18nKeylessStorage, validateLanguage, createMemoryStorage } from "
|
|
|
4
4
|
export { I18nKeylessProvider, useI18nKeylessContext } from "./I18nKeylessProvider.tsx";
|
|
5
5
|
export type { I18nKeylessProviderProps } from "./I18nKeylessProvider.tsx";
|
|
6
6
|
export { getServerTranslations, clearServerTranslationsCache } from "./server.ts";
|
|
7
|
-
export { runWithI18nKeyless, getRequestScope } from "./request-scope.ts";
|
|
7
|
+
export { runWithI18nKeyless, getRequestScope, getUsedTranslationsSnapshot } from "./request-scope.ts";
|
|
8
8
|
export type { I18nRequestScope } from "./request-scope.ts";
|
|
9
9
|
export { clearI18nKeylessStorageAndStore } from "./store.ts";
|
|
10
10
|
export type { I18nKeylessTextProps } from "./I18nKeylessText.tsx";
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,6 @@ export { init, hydrateFromServer, setCurrentLanguage, useCurrentLanguage, getTra
|
|
|
3
3
|
export { clearI18nKeylessStorage, validateLanguage, createMemoryStorage } from "./utils.js";
|
|
4
4
|
export { I18nKeylessProvider, useI18nKeylessContext } from "./I18nKeylessProvider.js";
|
|
5
5
|
export { getServerTranslations, clearServerTranslationsCache } from "./server.js";
|
|
6
|
-
export { runWithI18nKeyless, getRequestScope } from "./request-scope.js";
|
|
6
|
+
export { runWithI18nKeyless, getRequestScope, getUsedTranslationsSnapshot } from "./request-scope.js";
|
|
7
7
|
export { clearI18nKeylessStorageAndStore } from "./store.js";
|
|
8
8
|
export { AVAILABLE_LANGS, getAllTranslationsFromLanguage, queue } from "i18n-keyless-core";
|
package/dist/request-scope.d.ts
CHANGED
|
@@ -29,8 +29,27 @@ export interface I18nRequestScope {
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function runWithI18nKeyless<R>(scope: I18nRequestScope, fn: () => R): Promise<R>;
|
|
31
31
|
/**
|
|
32
|
-
* Returns the active per-request scope,
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Returns the active per-request scope (`{ lang, translations }` with the FULL set
|
|
33
|
+
* available for resolution), or `undefined` when none is set (browser, or outside
|
|
34
|
+
* `runWithI18nKeyless`). Read internally by `getTranslation` and `<I18nKeylessText>`;
|
|
35
|
+
* exported for advanced/server use.
|
|
35
36
|
*/
|
|
36
37
|
export declare function getRequestScope(): I18nRequestScope | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Records that `key` (the storage key, i.e. `key` or `key__context`) was used in the
|
|
40
|
+
* current render. No-op outside a `runWithI18nKeyless` scope (browser / SPA). Pure
|
|
41
|
+
* `Set.add` — no store write, no setState. Internal: called by `getTranslation` and
|
|
42
|
+
* `<I18nKeylessText>`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function recordUsedKey(key: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Returns a snapshot containing ONLY the keys used during the current render (∩ the keys
|
|
47
|
+
* actually available in the scope's translations), for serializing a per-page subset into
|
|
48
|
+
* the SSR HTML instead of the full language set. Use it at the serialization site in
|
|
49
|
+
* place of `getRequestScope()` when the language set is large.
|
|
50
|
+
*
|
|
51
|
+
* The full set is still used for resolution during render; only the serialized snapshot is
|
|
52
|
+
* narrowed. Pair it with `init()`'s background full fetch on the client so subsequent
|
|
53
|
+
* client-side navigation has every key. Returns `undefined` outside a scope. See docs/SSR.md.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getUsedTranslationsSnapshot(): I18nRequestScope | undefined;
|
package/dist/request-scope.js
CHANGED
|
@@ -51,13 +51,51 @@ async function ensureALS() {
|
|
|
51
51
|
*/
|
|
52
52
|
export async function runWithI18nKeyless(scope, fn) {
|
|
53
53
|
await ensureALS();
|
|
54
|
-
|
|
54
|
+
if (!als) {
|
|
55
|
+
return fn();
|
|
56
|
+
}
|
|
57
|
+
// Each run gets its own `used` Set, isolated to this request's async context.
|
|
58
|
+
return als.run({ lang: scope.lang, translations: scope.translations, used: new Set() }, fn);
|
|
55
59
|
}
|
|
56
60
|
/**
|
|
57
|
-
* Returns the active per-request scope,
|
|
58
|
-
*
|
|
59
|
-
*
|
|
61
|
+
* Returns the active per-request scope (`{ lang, translations }` with the FULL set
|
|
62
|
+
* available for resolution), or `undefined` when none is set (browser, or outside
|
|
63
|
+
* `runWithI18nKeyless`). Read internally by `getTranslation` and `<I18nKeylessText>`;
|
|
64
|
+
* exported for advanced/server use.
|
|
60
65
|
*/
|
|
61
66
|
export function getRequestScope() {
|
|
62
|
-
|
|
67
|
+
const s = als?.getStore();
|
|
68
|
+
return s ? { lang: s.lang, translations: s.translations } : undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Records that `key` (the storage key, i.e. `key` or `key__context`) was used in the
|
|
72
|
+
* current render. No-op outside a `runWithI18nKeyless` scope (browser / SPA). Pure
|
|
73
|
+
* `Set.add` — no store write, no setState. Internal: called by `getTranslation` and
|
|
74
|
+
* `<I18nKeylessText>`.
|
|
75
|
+
*/
|
|
76
|
+
export function recordUsedKey(key) {
|
|
77
|
+
als?.getStore()?.used.add(key);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns a snapshot containing ONLY the keys used during the current render (∩ the keys
|
|
81
|
+
* actually available in the scope's translations), for serializing a per-page subset into
|
|
82
|
+
* the SSR HTML instead of the full language set. Use it at the serialization site in
|
|
83
|
+
* place of `getRequestScope()` when the language set is large.
|
|
84
|
+
*
|
|
85
|
+
* The full set is still used for resolution during render; only the serialized snapshot is
|
|
86
|
+
* narrowed. Pair it with `init()`'s background full fetch on the client so subsequent
|
|
87
|
+
* client-side navigation has every key. Returns `undefined` outside a scope. See docs/SSR.md.
|
|
88
|
+
*/
|
|
89
|
+
export function getUsedTranslationsSnapshot() {
|
|
90
|
+
const s = als?.getStore();
|
|
91
|
+
if (!s) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const translations = {};
|
|
95
|
+
for (const key of s.used) {
|
|
96
|
+
if (key in s.translations) {
|
|
97
|
+
translations[key] = s.translations[key];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { lang: s.lang, translations };
|
|
63
101
|
}
|
package/dist/store.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { queue, getAllTranslationsFromLanguage, getTranslationCore, sendTranslationsUsageToI18nKeyless, } from "i18n-keyless-core";
|
|
2
2
|
import { create } from "zustand";
|
|
3
3
|
import { storeKeys, setItem, getItem, clearI18nKeylessStorage, validateLanguage, createMemoryStorage } from "./utils.js";
|
|
4
|
-
import { getRequestScope } from "./request-scope.js";
|
|
4
|
+
import { getRequestScope, recordUsedKey } from "./request-scope.js";
|
|
5
5
|
/**
|
|
6
6
|
* True when running without a DOM (server-side rendering). On the server the lib is
|
|
7
7
|
* read-only: usage analytics are neither recorded nor sent. Evaluated at call time so
|
|
@@ -294,6 +294,9 @@ export function getTranslation(key, options) {
|
|
|
294
294
|
if (!isServerEnv() && !base.config.ssr) {
|
|
295
295
|
queueMicrotask(() => base.setTranslationUsage(key, options?.context));
|
|
296
296
|
}
|
|
297
|
+
// Record the key for the per-page SSR snapshot (no-op off-server). Pure Set.add — no
|
|
298
|
+
// store write. Use the storage key (with context) so it matches the translations map.
|
|
299
|
+
recordUsedKey(options?.context ? `${key}__${options.context}` : key);
|
|
297
300
|
// SSR: if a per-request scope is active (set by runWithI18nKeyless), translate against
|
|
298
301
|
// that request's language/translations instead of the process-global store — so
|
|
299
302
|
// getTranslation, like <T>, renders the right language without leaking across
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18n-keyless-react",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"postpublish": "rm -rf ./dist && rm *.tgz"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"i18n-keyless-core": "2.
|
|
27
|
+
"i18n-keyless-core": "2.3.0",
|
|
28
28
|
"zustand": "^5.0.3"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|