intor 2.3.5 → 2.3.6
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/core/export/index.js +1 -0
- package/dist/core/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +2 -5
- package/dist/core/src/shared/utils/deep-merge.js +4 -9
- package/dist/next/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +2 -5
- package/dist/next/src/shared/utils/deep-merge.js +4 -9
- package/dist/react/src/client/react/contexts/messages/utils/use-refetch-messages.js +1 -1
- package/dist/react/src/client/react/contexts/translator/provider.js +9 -1
- package/dist/react/src/shared/utils/deep-merge.js +4 -9
- package/dist/types/export/index.d.ts +1 -1
- package/dist/types/src/shared/utils/deep-merge.d.ts +4 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { PREFIX_PLACEHOLDER } from '../src/shared/constants/prefix-placeholder.js';
|
|
2
|
+
export { deepMerge } from '../src/shared/utils/deep-merge.js';
|
|
2
3
|
export { localizePathname } from '../src/shared/utils/pathname/localize-pathname.js';
|
|
3
4
|
export { IntorError, IntorErrorCode } from '../src/shared/error/intor-error.js';
|
|
4
5
|
import 'intor-translator';
|
|
@@ -73,13 +73,10 @@ async function parseFileEntries({ fileEntries, limit, extraOptions: { messagesRe
|
|
|
73
73
|
for (const { namespace, messages } of parsedFileEntries) {
|
|
74
74
|
// Handle root-level namespace (i.e., [rootDir]/index.json)
|
|
75
75
|
if (namespace === "index") {
|
|
76
|
-
|
|
77
|
-
if (merged)
|
|
78
|
-
Object.assign(result, merged);
|
|
76
|
+
Object.assign(result, deepMerge(result, messages));
|
|
79
77
|
}
|
|
80
78
|
else {
|
|
81
|
-
result[namespace] =
|
|
82
|
-
deepMerge(result[namespace] ?? {}, messages) || {};
|
|
79
|
+
result[namespace] = deepMerge(result[namespace], messages);
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
82
|
return result;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deeply merges two objects.
|
|
3
|
+
*
|
|
3
4
|
* - Nested objects → merged recursively
|
|
4
5
|
* - Array / primitive → b overwrites a
|
|
6
|
+
*
|
|
7
|
+
* This function always returns a plain object.
|
|
5
8
|
*/
|
|
6
|
-
const deepMerge = (a, b) => {
|
|
7
|
-
if (!a && !b)
|
|
8
|
-
return undefined;
|
|
9
|
-
if (!a)
|
|
10
|
-
return b;
|
|
11
|
-
if (!b)
|
|
12
|
-
return a;
|
|
9
|
+
const deepMerge = (a = {}, b = {}) => {
|
|
13
10
|
const result = { ...a };
|
|
14
11
|
for (const key in b) {
|
|
15
12
|
if (Object.prototype.hasOwnProperty.call(b, key)) {
|
|
@@ -21,11 +18,9 @@ const deepMerge = (a, b) => {
|
|
|
21
18
|
typeof bv === "object" &&
|
|
22
19
|
!Array.isArray(av) &&
|
|
23
20
|
!Array.isArray(bv)) {
|
|
24
|
-
// recursive merge
|
|
25
21
|
result[key] = deepMerge(av, bv);
|
|
26
22
|
}
|
|
27
23
|
else {
|
|
28
|
-
// overwrite with primitive or array
|
|
29
24
|
result[key] = bv;
|
|
30
25
|
}
|
|
31
26
|
}
|
|
@@ -73,13 +73,10 @@ async function parseFileEntries({ fileEntries, limit, extraOptions: { messagesRe
|
|
|
73
73
|
for (const { namespace, messages } of parsedFileEntries) {
|
|
74
74
|
// Handle root-level namespace (i.e., [rootDir]/index.json)
|
|
75
75
|
if (namespace === "index") {
|
|
76
|
-
|
|
77
|
-
if (merged)
|
|
78
|
-
Object.assign(result, merged);
|
|
76
|
+
Object.assign(result, deepMerge(result, messages));
|
|
79
77
|
}
|
|
80
78
|
else {
|
|
81
|
-
result[namespace] =
|
|
82
|
-
deepMerge(result[namespace] ?? {}, messages) || {};
|
|
79
|
+
result[namespace] = deepMerge(result[namespace], messages);
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
82
|
return result;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deeply merges two objects.
|
|
3
|
+
*
|
|
3
4
|
* - Nested objects → merged recursively
|
|
4
5
|
* - Array / primitive → b overwrites a
|
|
6
|
+
*
|
|
7
|
+
* This function always returns a plain object.
|
|
5
8
|
*/
|
|
6
|
-
const deepMerge = (a, b) => {
|
|
7
|
-
if (!a && !b)
|
|
8
|
-
return undefined;
|
|
9
|
-
if (!a)
|
|
10
|
-
return b;
|
|
11
|
-
if (!b)
|
|
12
|
-
return a;
|
|
9
|
+
const deepMerge = (a = {}, b = {}) => {
|
|
13
10
|
const result = { ...a };
|
|
14
11
|
for (const key in b) {
|
|
15
12
|
if (Object.prototype.hasOwnProperty.call(b, key)) {
|
|
@@ -21,11 +18,9 @@ const deepMerge = (a, b) => {
|
|
|
21
18
|
typeof bv === "object" &&
|
|
22
19
|
!Array.isArray(av) &&
|
|
23
20
|
!Array.isArray(bv)) {
|
|
24
|
-
// recursive merge
|
|
25
21
|
result[key] = deepMerge(av, bv);
|
|
26
22
|
}
|
|
27
23
|
else {
|
|
28
|
-
// overwrite with primitive or array
|
|
29
24
|
result[key] = bv;
|
|
30
25
|
}
|
|
31
26
|
}
|
|
@@ -39,7 +39,7 @@ const useRefetchMessages = ({ config, setRuntimeMessages, setIsLoadingMessages,
|
|
|
39
39
|
});
|
|
40
40
|
// Update state only if this request was not aborted
|
|
41
41
|
if (!controller.signal.aborted) {
|
|
42
|
-
setRuntimeMessages(deepMerge(config.messages, loadedMessages)
|
|
42
|
+
setRuntimeMessages(deepMerge(config.messages, loadedMessages));
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
finally {
|
|
@@ -20,7 +20,15 @@ function TranslatorProvider({ value: { isLoading: externalIsLoading } = {}, chil
|
|
|
20
20
|
const { messages, isLoading: internalIsLoading } = useMessages();
|
|
21
21
|
const { locale } = useLocale();
|
|
22
22
|
const runtime = useTranslatorRuntime();
|
|
23
|
-
|
|
23
|
+
// Treat locale changes as a loading boundary to avoid transient missing states.
|
|
24
|
+
// isLoading defaults to false, but is eagerly set to true on locale switches.
|
|
25
|
+
const prevLocaleRef = React.useRef(locale);
|
|
26
|
+
// eslint-disable-next-line react-hooks/refs -- intentional render-time read to detect locale switches
|
|
27
|
+
const localeChanged = prevLocaleRef.current !== locale;
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
prevLocaleRef.current = locale;
|
|
30
|
+
}, [locale]);
|
|
31
|
+
const isLoading = !!externalIsLoading || internalIsLoading || localeChanged;
|
|
24
32
|
// context value
|
|
25
33
|
const value = React.useMemo(() => {
|
|
26
34
|
const translator = new Translator({
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deeply merges two objects.
|
|
3
|
+
*
|
|
3
4
|
* - Nested objects → merged recursively
|
|
4
5
|
* - Array / primitive → b overwrites a
|
|
6
|
+
*
|
|
7
|
+
* This function always returns a plain object.
|
|
5
8
|
*/
|
|
6
|
-
const deepMerge = (a, b) => {
|
|
7
|
-
if (!a && !b)
|
|
8
|
-
return undefined;
|
|
9
|
-
if (!a)
|
|
10
|
-
return b;
|
|
11
|
-
if (!b)
|
|
12
|
-
return a;
|
|
9
|
+
const deepMerge = (a = {}, b = {}) => {
|
|
13
10
|
const result = { ...a };
|
|
14
11
|
for (const key in b) {
|
|
15
12
|
if (Object.prototype.hasOwnProperty.call(b, key)) {
|
|
@@ -21,11 +18,9 @@ const deepMerge = (a, b) => {
|
|
|
21
18
|
typeof bv === "object" &&
|
|
22
19
|
!Array.isArray(av) &&
|
|
23
20
|
!Array.isArray(bv)) {
|
|
24
|
-
// recursive merge
|
|
25
21
|
result[key] = deepMerge(av, bv);
|
|
26
22
|
}
|
|
27
23
|
else {
|
|
28
|
-
// overwrite with primitive or array
|
|
29
24
|
result[key] = bv;
|
|
30
25
|
}
|
|
31
26
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { PREFIX_PLACEHOLDER } from "../src/shared/constants";
|
|
2
|
-
export { localizePathname, } from "../src/shared/utils";
|
|
2
|
+
export { deepMerge, localizePathname, } from "../src/shared/utils";
|
|
3
3
|
export { IntorError, IntorErrorCode } from "../src/shared/error";
|
|
4
4
|
export { type TranslatorPlugin, type TranslateHandlers, type FormatHandler, type LoadingHandler, type MissingHandler, type HandlerContext, type TranslateContext, type TranslateHook, type LocaleMessages, } from "intor-translator";
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
type PlainObject = Record<string, unknown>;
|
|
2
2
|
/**
|
|
3
3
|
* Deeply merges two objects.
|
|
4
|
+
*
|
|
4
5
|
* - Nested objects → merged recursively
|
|
5
6
|
* - Array / primitive → b overwrites a
|
|
7
|
+
*
|
|
8
|
+
* This function always returns a plain object.
|
|
6
9
|
*/
|
|
7
|
-
export declare const deepMerge: <T extends PlainObject, U extends PlainObject>(a?: T, b?: U) =>
|
|
10
|
+
export declare const deepMerge: <T extends PlainObject, U extends PlainObject>(a?: T, b?: U) => T & U;
|
|
8
11
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intor",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"description": "A modular and extensible i18n core designed for TypeScript and JavaScript projects. Intor enables custom translation logic with support for both frontend and backend environments, featuring runtime configuration, caching, adapters, and message loaders.",
|
|
5
5
|
"author": "Yiming Liao",
|
|
6
6
|
"homepage": "https://github.com/yiming-liao/intor#readme",
|