intor 2.3.13 → 2.3.14
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 -2
- package/dist/core/src/config/define-intor-config.js +0 -3
- package/dist/core/src/config/resolvers/resolve-cookie-options.js +0 -1
- package/dist/core/src/config/resolvers/resolve-fallback-locales.js +0 -1
- package/dist/core/src/config/resolvers/resolve-routing-options.js +0 -2
- package/dist/core/src/config/validators/validate-default-locale.js +0 -1
- package/dist/core/src/config/validators/validate-id.js +0 -1
- package/dist/core/src/config/validators/validate-supported-locales.js +0 -1
- package/dist/core/src/core/messages/global-messages-pool.js +11 -17
- package/dist/core/src/core/messages/load-remote-messages/load-remote-messages.js +1 -40
- package/dist/core/src/routing/pathname/get-unprefixed-pathname.js +0 -1
- package/dist/core/src/routing/pathname/locale-prefix-pathname.js +0 -1
- package/dist/core/src/routing/pathname/standardize-pathname.js +0 -1
- package/dist/core/src/server/intor/intor.js +0 -1
- package/dist/core/src/server/messages/load-local-messages/load-local-messages.js +9 -10
- package/dist/core/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +0 -1
- package/dist/core/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +0 -1
- package/dist/core/src/server/messages/load-messages.js +4 -8
- package/dist/core/src/server/runtime/create-intor-runtime.js +0 -1
- package/dist/express/src/adapters/express/helpers/get-translator.js +0 -1
- package/dist/express/src/adapters/express/middleware/create-intor.js +0 -1
- package/dist/express/src/core/messages/global-messages-pool.js +9 -3
- package/dist/express/src/core/messages/load-remote-messages/load-remote-messages.js +1 -40
- package/dist/express/src/routing/inbound/resolve-inbound.js +0 -1
- package/dist/express/src/routing/locale/get-locale-from-accept-language.js +0 -1
- package/dist/express/src/routing/locale/get-locale-from-host.js +0 -1
- package/dist/express/src/routing/locale/get-locale-from-pathname.js +0 -1
- package/dist/express/src/routing/locale/get-locale-from-query.js +0 -1
- package/dist/express/src/routing/pathname/get-unprefixed-pathname.js +0 -1
- package/dist/express/src/routing/pathname/locale-prefix-pathname.js +0 -1
- package/dist/express/src/routing/pathname/standardize-pathname.js +0 -1
- package/dist/express/src/server/messages/load-local-messages/load-local-messages.js +9 -10
- package/dist/express/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +0 -1
- package/dist/express/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +0 -1
- package/dist/express/src/server/messages/load-messages.js +4 -8
- package/dist/express/src/server/runtime/create-intor-runtime.js +0 -1
- package/dist/next/src/adapters/next/navigation/redirect.js +0 -1
- package/dist/next/src/adapters/next/navigation/use-pathname.js +0 -1
- package/dist/next/src/adapters/next/proxy/intor-proxy.js +0 -1
- package/dist/next/src/adapters/next/server/get-locale.js +0 -1
- package/dist/next/src/adapters/next/server/get-pathname.js +0 -1
- package/dist/next/src/adapters/next/server/get-translator.js +0 -1
- package/dist/next/src/adapters/next/server/intor.js +0 -1
- package/dist/next/src/core/messages/global-messages-pool.js +9 -3
- package/dist/next/src/core/messages/load-remote-messages/load-remote-messages.js +1 -40
- package/dist/next/src/policies/shoud-full-reload.js +0 -1
- package/dist/next/src/routing/inbound/resolve-inbound.js +0 -1
- package/dist/next/src/routing/locale/get-locale-from-accept-language.js +0 -1
- package/dist/next/src/routing/locale/get-locale-from-host.js +0 -1
- package/dist/next/src/routing/locale/get-locale-from-pathname.js +0 -1
- package/dist/next/src/routing/locale/get-locale-from-query.js +0 -1
- package/dist/next/src/routing/pathname/get-unprefixed-pathname.js +0 -1
- package/dist/next/src/routing/pathname/locale-prefix-pathname.js +0 -1
- package/dist/next/src/routing/pathname/standardize-pathname.js +0 -1
- package/dist/next/src/server/intor/intor.js +0 -1
- package/dist/next/src/server/messages/load-local-messages/load-local-messages.js +9 -10
- package/dist/next/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +0 -1
- package/dist/next/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +0 -1
- package/dist/next/src/server/messages/load-messages.js +4 -8
- package/dist/next/src/server/runtime/create-intor-runtime.js +0 -1
- package/dist/react/src/client/react/helpers/use-runtime-state.js +0 -1
- package/dist/react/src/client/react/navigation/use-execute-navigation.js +0 -1
- package/dist/react/src/client/react/navigation/use-resolve-navigation.js +0 -1
- package/dist/react/src/client/react/provider/effects/use-locale-effects.js +0 -1
- package/dist/react/src/client/shared/helpers/get-client-locale.js +0 -1
- package/dist/react/src/client/shared/messages/create-refetch-messages.js +0 -3
- package/dist/react/src/core/messages/load-remote-messages/load-remote-messages.js +1 -40
- package/dist/react/src/policies/shoud-full-reload.js +0 -1
- package/dist/react/src/routing/pathname/get-unprefixed-pathname.js +0 -1
- package/dist/react/src/routing/pathname/locale-prefix-pathname.js +0 -1
- package/dist/react/src/routing/pathname/standardize-pathname.js +0 -1
- package/dist/svelte/src/client/shared/helpers/get-client-locale.js +0 -1
- package/dist/svelte/src/client/shared/messages/create-refetch-messages.js +0 -3
- package/dist/svelte/src/client/svelte/helpers/create-runtime-state.js +0 -1
- package/dist/svelte/src/client/svelte/runtime/effects/locale-effects.js +0 -1
- package/dist/svelte/src/core/messages/load-remote-messages/load-remote-messages.js +1 -40
- package/dist/types/export/index.d.ts +1 -1
- package/dist/types/src/config/constants/index.d.ts +0 -1
- package/dist/types/src/config/index.d.ts +2 -2
- package/dist/types/src/config/types/index.d.ts +0 -1
- package/dist/types/src/config/types/intor-config.d.ts +0 -4
- package/dist/types/src/core/index.d.ts +1 -1
- package/dist/types/src/core/messages/global-messages-pool.d.ts +15 -12
- package/dist/types/src/core/messages/index.d.ts +1 -1
- package/dist/types/src/core/messages/load-remote-messages/load-remote-messages.d.ts +1 -2
- package/dist/types/src/core/messages/load-remote-messages/types.d.ts +1 -6
- package/dist/types/src/server/messages/load-local-messages/load-local-messages.d.ts +1 -1
- package/dist/vue/src/client/shared/helpers/get-client-locale.js +0 -1
- package/dist/vue/src/client/shared/messages/create-refetch-messages.js +0 -3
- package/dist/vue/src/client/vue/helpers/use-runtime-state.js +0 -1
- package/dist/vue/src/client/vue/provider/effects/use-locale-effects.js +0 -1
- package/dist/vue/src/core/messages/load-remote-messages/load-remote-messages.js +1 -40
- package/package.json +2 -3
- package/dist/core/src/config/constants/cache.js +0 -7
- package/dist/core/src/config/resolvers/resolve-cache-options.js +0 -11
- package/dist/react/src/core/utils/normalizers/normalize-cache-key.js +0 -45
- package/dist/svelte/src/core/utils/normalizers/normalize-cache-key.js +0 -45
- package/dist/types/src/config/constants/cache.d.ts +0 -2
- package/dist/types/src/config/resolvers/resolve-cache-options.d.ts +0 -2
- package/dist/types/src/config/types/cache.d.ts +0 -7
- package/dist/vue/src/core/utils/normalizers/normalize-cache-key.js +0 -45
|
@@ -5,10 +5,9 @@ export { resolveLoaderOptions } from '../src/core/utils/resolve-loader-options.j
|
|
|
5
5
|
import 'logry';
|
|
6
6
|
export { clearLoggerPool } from '../src/core/logger/global-logger-pool.js';
|
|
7
7
|
export { isValidMessages } from '../src/core/messages/utils/is-valid-messages.js';
|
|
8
|
-
export { clearMessagesPool
|
|
8
|
+
export { clearMessagesPool } from '../src/core/messages/global-messages-pool.js';
|
|
9
9
|
export { mergeMessages } from '../src/core/messages/merge-messages.js';
|
|
10
10
|
export { defineIntorConfig } from '../src/config/define-intor-config.js';
|
|
11
11
|
import '../src/config/constants/cookie.js';
|
|
12
|
-
import '../src/config/constants/cache.js';
|
|
13
12
|
export { localizePathname } from '../src/routing/pathname/localize-pathname.js';
|
|
14
13
|
export { Translator } from 'intor-translator';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { resolveCacheOptions } from './resolvers/resolve-cache-options.js';
|
|
2
1
|
import { resolveCookieOptions } from './resolvers/resolve-cookie-options.js';
|
|
3
2
|
import { resolveFallbackLocales } from './resolvers/resolve-fallback-locales.js';
|
|
4
3
|
import { resolveRoutingOptions } from './resolvers/resolve-routing-options.js';
|
|
@@ -30,7 +29,6 @@ const defineIntorConfig = (config) => {
|
|
|
30
29
|
const fallbackLocales = resolveFallbackLocales(config, id, supportedSet);
|
|
31
30
|
const cookie = resolveCookieOptions(config.cookie);
|
|
32
31
|
const routing = resolveRoutingOptions(config.routing);
|
|
33
|
-
const cache = resolveCacheOptions(config.cache);
|
|
34
32
|
return {
|
|
35
33
|
id,
|
|
36
34
|
messages: config.messages,
|
|
@@ -42,7 +40,6 @@ const defineIntorConfig = (config) => {
|
|
|
42
40
|
cookie,
|
|
43
41
|
routing,
|
|
44
42
|
logger: { id, ...config.logger },
|
|
45
|
-
cache,
|
|
46
43
|
client: config.client,
|
|
47
44
|
server: config.server,
|
|
48
45
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import '../../core/error/intor-error.js';
|
|
2
2
|
import { deepMerge } from '../../core/utils/deep-merge.js';
|
|
3
3
|
import 'logry';
|
|
4
|
-
import 'keyv';
|
|
5
4
|
import { DEFAULT_ROUTING_OPTIONS } from '../constants/routing.js';
|
|
6
5
|
import '../constants/cookie.js';
|
|
7
|
-
import '../constants/cache.js';
|
|
8
6
|
|
|
9
7
|
/**
|
|
10
8
|
* Resolves routing configuration into a fully normalized form.
|
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Get the global messages pool.
|
|
3
|
+
*
|
|
4
|
+
* Lazily initialized to ensure:
|
|
5
|
+
* - Cross-module sharing
|
|
6
|
+
* - Dev / HMR safety
|
|
7
|
+
*/
|
|
3
8
|
function getGlobalMessagesPool() {
|
|
4
9
|
if (!globalThis.__INTOR_MESSAGES_POOL__) {
|
|
5
|
-
|
|
10
|
+
const pool = new Map();
|
|
11
|
+
globalThis.__INTOR_MESSAGES_POOL__ = pool;
|
|
6
12
|
}
|
|
7
13
|
return globalThis.__INTOR_MESSAGES_POOL__;
|
|
8
14
|
}
|
|
9
|
-
/**
|
|
10
|
-
* Replace the global messages pool.
|
|
11
|
-
*
|
|
12
|
-
* - Intended for advanced usage (e.g. Redis, custom cache backends).
|
|
13
|
-
* - Must be called during application bootstrap.
|
|
14
|
-
*/
|
|
15
|
-
function setGlobalMessagesPool(pool) {
|
|
16
|
-
globalThis.__INTOR_MESSAGES_POOL__ = pool;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Optional: clear all cache
|
|
20
|
-
* - Useful in tests or dynamic reloads.
|
|
21
|
-
*/
|
|
15
|
+
/** Clear all cached messages. */
|
|
22
16
|
function clearMessagesPool() {
|
|
23
17
|
const pool = getGlobalMessagesPool();
|
|
24
18
|
pool.clear();
|
|
25
19
|
}
|
|
26
20
|
|
|
27
|
-
export { clearMessagesPool, getGlobalMessagesPool
|
|
21
|
+
export { clearMessagesPool, getGlobalMessagesPool };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getLogger } from '../../logger/get-logger.js';
|
|
2
|
-
import { normalizeCacheKey } from '../../utils/normalizers/normalize-cache-key.js';
|
|
3
2
|
import { fetchLocaleMessages } from './fetch-locale-messages/fetch-locale-messages.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -9,12 +8,11 @@ import { fetchLocaleMessages } from './fetch-locale-messages/fetch-locale-messag
|
|
|
9
8
|
* It coordinates:
|
|
10
9
|
*
|
|
11
10
|
* - Locale resolution with fallbacks
|
|
12
|
-
* - Cache read / write behavior
|
|
13
11
|
* - Respecting abort signals across the entire async flow
|
|
14
12
|
*
|
|
15
13
|
* Network fetching and data validation are delegated to lower-level utilities.
|
|
16
14
|
*/
|
|
17
|
-
const loadRemoteMessages = async ({
|
|
15
|
+
const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, rootDir, url, headers, signal, loggerOptions, }) => {
|
|
18
16
|
const baseLogger = getLogger(loggerOptions);
|
|
19
17
|
const logger = baseLogger.child({ scope: "load-remote-messages" });
|
|
20
18
|
// Abort early if the request has already been cancelled
|
|
@@ -25,31 +23,6 @@ const loadRemoteMessages = async ({ id, locale, fallbackLocales, namespaces, roo
|
|
|
25
23
|
const start = performance.now();
|
|
26
24
|
logger.debug("Loading remote messages.", { url });
|
|
27
25
|
// ---------------------------------------------------------------------------
|
|
28
|
-
// Cache key resolution
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
const cacheKey = normalizeCacheKey([
|
|
31
|
-
id,
|
|
32
|
-
"loaderType:remote",
|
|
33
|
-
rootDir,
|
|
34
|
-
locale,
|
|
35
|
-
(fallbackLocales || []).toSorted().join(","),
|
|
36
|
-
(namespaces || []).toSorted().join(","),
|
|
37
|
-
]);
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
// Cache read
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
if (cacheOptions.enabled && cacheKey) {
|
|
42
|
-
const cached = await pool?.get(cacheKey);
|
|
43
|
-
if (signal?.aborted) {
|
|
44
|
-
logger.debug("Remote message loading aborted after cache read.");
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
if (cached) {
|
|
48
|
-
logger.debug("Messages cache hit.", { key: cacheKey });
|
|
49
|
-
return cached;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
26
|
// Resolve locale messages with ordered fallback strategy
|
|
54
27
|
// ---------------------------------------------------------------------------
|
|
55
28
|
const candidateLocales = [locale, ...(fallbackLocales || [])];
|
|
@@ -93,18 +66,6 @@ const loadRemoteMessages = async ({ id, locale, fallbackLocales, namespaces, roo
|
|
|
93
66
|
});
|
|
94
67
|
}
|
|
95
68
|
}
|
|
96
|
-
// ---------------------------------------------------------------------------
|
|
97
|
-
// Cache write (explicitly permitted)
|
|
98
|
-
// ---------------------------------------------------------------------------
|
|
99
|
-
if (cacheOptions.enabled && allowCacheWrite) {
|
|
100
|
-
if (signal?.aborted) {
|
|
101
|
-
logger.debug("Remote message loading aborted before cache write.");
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (cacheKey && messages) {
|
|
105
|
-
await pool?.set(cacheKey, messages, cacheOptions.ttl);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
69
|
// Final success log with resolved locale and timing
|
|
109
70
|
if (messages) {
|
|
110
71
|
logger.trace("Finished loading remote messages.", {
|
|
@@ -2,7 +2,6 @@ import { PREFIX_PLACEHOLDER } from '../../core/constants/prefix-placeholder.js';
|
|
|
2
2
|
import '../../core/error/intor-error.js';
|
|
3
3
|
import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
|
|
4
4
|
import 'logry';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Applies the configured locale prefix behavior to a standardized pathname.
|
|
@@ -2,7 +2,6 @@ import { PREFIX_PLACEHOLDER } from '../../core/constants/prefix-placeholder.js';
|
|
|
2
2
|
import '../../core/error/intor-error.js';
|
|
3
3
|
import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
|
|
4
4
|
import 'logry';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Standardizes a canonical pathname by applying the base path
|
|
@@ -13,8 +13,8 @@ import { readLocaleMessages } from './read-locale-messages/read-locale-messages.
|
|
|
13
13
|
* It coordinates:
|
|
14
14
|
*
|
|
15
15
|
* - Locale resolution with fallbacks
|
|
16
|
-
* - Process-level memoization (read by default, write by ownership)
|
|
17
16
|
* - Concurrency control for file system access
|
|
17
|
+
* - Process-level memoization (read by default, write by ownership)
|
|
18
18
|
*
|
|
19
19
|
* Local messages are cached for the lifetime of the process.
|
|
20
20
|
* Cache writes are restricted to the primary initialization flow.
|
|
@@ -22,7 +22,6 @@ import { readLocaleMessages } from './read-locale-messages/read-locale-messages.
|
|
|
22
22
|
* File traversal, parsing, and validation are delegated to lower-level utilities.
|
|
23
23
|
*/
|
|
24
24
|
const loadLocalMessages = async ({ id, locale, fallbackLocales, namespaces, rootDir = "messages", concurrency = 10, readOptions, pool = getGlobalMessagesPool(), allowCacheWrite = false, loggerOptions, }) => {
|
|
25
|
-
const isProd = process.env.NODE_ENV === "production";
|
|
26
25
|
const baseLogger = getLogger(loggerOptions);
|
|
27
26
|
const logger = baseLogger.child({ scope: "load-local-messages" });
|
|
28
27
|
const start = performance.now();
|
|
@@ -38,14 +37,14 @@ const loadLocalMessages = async ({ id, locale, fallbackLocales, namespaces, root
|
|
|
38
37
|
"loaderType:local",
|
|
39
38
|
rootDir,
|
|
40
39
|
locale,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
]);
|
|
40
|
+
fallbackLocales?.toSorted().join(","),
|
|
41
|
+
namespaces?.toSorted().join(","),
|
|
42
|
+
].filter(Boolean));
|
|
44
43
|
// ---------------------------------------------------------------------------
|
|
45
44
|
// Cache read
|
|
46
45
|
// ---------------------------------------------------------------------------
|
|
47
46
|
if (cacheKey) {
|
|
48
|
-
const cached =
|
|
47
|
+
const cached = pool.get(cacheKey);
|
|
49
48
|
if (cached) {
|
|
50
49
|
logger.debug("Messages cache hit.", { key: cacheKey });
|
|
51
50
|
return cached;
|
|
@@ -90,10 +89,10 @@ const loadLocalMessages = async ({ id, locale, fallbackLocales, namespaces, root
|
|
|
90
89
|
// ---------------------------------------------------------------------------
|
|
91
90
|
// Cache write (explicitly permitted)
|
|
92
91
|
// ---------------------------------------------------------------------------
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
93
|
+
const canWriteCache = isProd && allowCacheWrite;
|
|
94
|
+
if (canWriteCache && cacheKey && messages) {
|
|
95
|
+
pool.set(cacheKey, messages);
|
|
97
96
|
}
|
|
98
97
|
// Final success log with resolved locale and timing
|
|
99
98
|
if (messages) {
|
|
@@ -2,7 +2,6 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import '../../../../../core/error/intor-error.js';
|
|
4
4
|
import { getLogger } from '../../../../../core/logger/get-logger.js';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Recursively collects message file metadata under a given locale root.
|
|
@@ -3,7 +3,6 @@ import '../../../../../core/error/intor-error.js';
|
|
|
3
3
|
import { deepMerge } from '../../../../../core/utils/deep-merge.js';
|
|
4
4
|
import { getLogger } from '../../../../../core/logger/get-logger.js';
|
|
5
5
|
import { isValidMessages } from '../../../../../core/messages/utils/is-valid-messages.js';
|
|
6
|
-
import 'keyv';
|
|
7
6
|
import { jsonReader } from './utils/json-reader.js';
|
|
8
7
|
import { nestObjectFromPath } from './utils/nest-object-from-path.js';
|
|
9
8
|
|
|
@@ -2,7 +2,6 @@ import '../../core/error/intor-error.js';
|
|
|
2
2
|
import { resolveLoaderOptions } from '../../core/utils/resolve-loader-options.js';
|
|
3
3
|
import { getLogger } from '../../core/logger/get-logger.js';
|
|
4
4
|
import { loadRemoteMessages } from '../../core/messages/load-remote-messages/load-remote-messages.js';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
import { loadLocalMessages } from './load-local-messages/load-local-messages.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -29,15 +28,15 @@ const loadMessages = async ({ config, locale, readOptions, allowCacheWrite = fal
|
|
|
29
28
|
logger.warn("No loader options have been configured in the current config.");
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
32
|
-
const { type, namespaces } = loader;
|
|
31
|
+
const { type, namespaces, rootDir } = loader;
|
|
33
32
|
const fallbackLocales = config.fallbackLocales[locale] || [];
|
|
34
33
|
logger.info(`Loading messages for locale "${locale}".`);
|
|
35
34
|
logger.trace("Starting to load messages with runtime context.", {
|
|
36
35
|
loaderType: type,
|
|
36
|
+
rootDir,
|
|
37
37
|
locale,
|
|
38
38
|
fallbackLocales,
|
|
39
39
|
namespaces: namespaces && namespaces.length > 0 ? [...namespaces] : ["*"],
|
|
40
|
-
cache: config.cache,
|
|
41
40
|
});
|
|
42
41
|
// ---------------------------------------------------------------------------
|
|
43
42
|
// Dispatch to loader implementation
|
|
@@ -49,7 +48,7 @@ const loadMessages = async ({ config, locale, readOptions, allowCacheWrite = fal
|
|
|
49
48
|
locale,
|
|
50
49
|
fallbackLocales,
|
|
51
50
|
namespaces,
|
|
52
|
-
rootDir
|
|
51
|
+
rootDir,
|
|
53
52
|
concurrency: loader.concurrency,
|
|
54
53
|
readOptions,
|
|
55
54
|
allowCacheWrite,
|
|
@@ -58,15 +57,12 @@ const loadMessages = async ({ config, locale, readOptions, allowCacheWrite = fal
|
|
|
58
57
|
}
|
|
59
58
|
else if (type === "remote") {
|
|
60
59
|
loadedMessages = await loadRemoteMessages({
|
|
61
|
-
id: config.id,
|
|
62
60
|
locale,
|
|
63
61
|
fallbackLocales,
|
|
64
62
|
namespaces,
|
|
65
|
-
rootDir
|
|
63
|
+
rootDir,
|
|
66
64
|
url: loader.url,
|
|
67
65
|
headers: loader.headers,
|
|
68
|
-
allowCacheWrite,
|
|
69
|
-
cacheOptions: config.cache,
|
|
70
66
|
loggerOptions: config.logger,
|
|
71
67
|
});
|
|
72
68
|
}
|
|
@@ -2,7 +2,6 @@ import { INTOR_HEADERS } from '../../../core/constants/headers.js';
|
|
|
2
2
|
import '../../../core/error/intor-error.js';
|
|
3
3
|
import { normalizeQuery } from '../../../core/utils/normalizers/normalize-query.js';
|
|
4
4
|
import 'logry';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
import { resolveInbound } from '../../../routing/inbound/resolve-inbound.js';
|
|
7
6
|
import { getLocaleFromAcceptLanguage } from '../../../routing/locale/get-locale-from-accept-language.js';
|
|
8
7
|
import 'node:path';
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Get the global messages pool.
|
|
3
|
+
*
|
|
4
|
+
* Lazily initialized to ensure:
|
|
5
|
+
* - Cross-module sharing
|
|
6
|
+
* - Dev / HMR safety
|
|
7
|
+
*/
|
|
3
8
|
function getGlobalMessagesPool() {
|
|
4
9
|
if (!globalThis.__INTOR_MESSAGES_POOL__) {
|
|
5
|
-
|
|
10
|
+
const pool = new Map();
|
|
11
|
+
globalThis.__INTOR_MESSAGES_POOL__ = pool;
|
|
6
12
|
}
|
|
7
13
|
return globalThis.__INTOR_MESSAGES_POOL__;
|
|
8
14
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getLogger } from '../../logger/get-logger.js';
|
|
2
|
-
import { normalizeCacheKey } from '../../utils/normalizers/normalize-cache-key.js';
|
|
3
2
|
import { fetchLocaleMessages } from './fetch-locale-messages/fetch-locale-messages.js';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -9,12 +8,11 @@ import { fetchLocaleMessages } from './fetch-locale-messages/fetch-locale-messag
|
|
|
9
8
|
* It coordinates:
|
|
10
9
|
*
|
|
11
10
|
* - Locale resolution with fallbacks
|
|
12
|
-
* - Cache read / write behavior
|
|
13
11
|
* - Respecting abort signals across the entire async flow
|
|
14
12
|
*
|
|
15
13
|
* Network fetching and data validation are delegated to lower-level utilities.
|
|
16
14
|
*/
|
|
17
|
-
const loadRemoteMessages = async ({
|
|
15
|
+
const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, rootDir, url, headers, signal, loggerOptions, }) => {
|
|
18
16
|
const baseLogger = getLogger(loggerOptions);
|
|
19
17
|
const logger = baseLogger.child({ scope: "load-remote-messages" });
|
|
20
18
|
// Abort early if the request has already been cancelled
|
|
@@ -25,31 +23,6 @@ const loadRemoteMessages = async ({ id, locale, fallbackLocales, namespaces, roo
|
|
|
25
23
|
const start = performance.now();
|
|
26
24
|
logger.debug("Loading remote messages.", { url });
|
|
27
25
|
// ---------------------------------------------------------------------------
|
|
28
|
-
// Cache key resolution
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
const cacheKey = normalizeCacheKey([
|
|
31
|
-
id,
|
|
32
|
-
"loaderType:remote",
|
|
33
|
-
rootDir,
|
|
34
|
-
locale,
|
|
35
|
-
(fallbackLocales || []).toSorted().join(","),
|
|
36
|
-
(namespaces || []).toSorted().join(","),
|
|
37
|
-
]);
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
// Cache read
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
if (cacheOptions.enabled && cacheKey) {
|
|
42
|
-
const cached = await pool?.get(cacheKey);
|
|
43
|
-
if (signal?.aborted) {
|
|
44
|
-
logger.debug("Remote message loading aborted after cache read.");
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
if (cached) {
|
|
48
|
-
logger.debug("Messages cache hit.", { key: cacheKey });
|
|
49
|
-
return cached;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
26
|
// Resolve locale messages with ordered fallback strategy
|
|
54
27
|
// ---------------------------------------------------------------------------
|
|
55
28
|
const candidateLocales = [locale, ...(fallbackLocales || [])];
|
|
@@ -93,18 +66,6 @@ const loadRemoteMessages = async ({ id, locale, fallbackLocales, namespaces, roo
|
|
|
93
66
|
});
|
|
94
67
|
}
|
|
95
68
|
}
|
|
96
|
-
// ---------------------------------------------------------------------------
|
|
97
|
-
// Cache write (explicitly permitted)
|
|
98
|
-
// ---------------------------------------------------------------------------
|
|
99
|
-
if (cacheOptions.enabled && allowCacheWrite) {
|
|
100
|
-
if (signal?.aborted) {
|
|
101
|
-
logger.debug("Remote message loading aborted before cache write.");
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (cacheKey && messages) {
|
|
105
|
-
await pool?.set(cacheKey, messages, cacheOptions.ttl);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
69
|
// Final success log with resolved locale and timing
|
|
109
70
|
if (messages) {
|
|
110
71
|
logger.trace("Finished loading remote messages.", {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import '../../core/error/intor-error.js';
|
|
2
2
|
import 'logry';
|
|
3
|
-
import 'keyv';
|
|
4
3
|
import { getLocaleFromPathname } from '../locale/get-locale-from-pathname.js';
|
|
5
4
|
import { getLocaleFromHost } from '../locale/get-locale-from-host.js';
|
|
6
5
|
import { getLocaleFromQuery } from '../locale/get-locale-from-query.js';
|
|
@@ -2,7 +2,6 @@ import { PREFIX_PLACEHOLDER } from '../../core/constants/prefix-placeholder.js';
|
|
|
2
2
|
import '../../core/error/intor-error.js';
|
|
3
3
|
import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
|
|
4
4
|
import 'logry';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Applies the configured locale prefix behavior to a standardized pathname.
|
|
@@ -2,7 +2,6 @@ import { PREFIX_PLACEHOLDER } from '../../core/constants/prefix-placeholder.js';
|
|
|
2
2
|
import '../../core/error/intor-error.js';
|
|
3
3
|
import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
|
|
4
4
|
import 'logry';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Standardizes a canonical pathname by applying the base path
|
|
@@ -13,8 +13,8 @@ import { readLocaleMessages } from './read-locale-messages/read-locale-messages.
|
|
|
13
13
|
* It coordinates:
|
|
14
14
|
*
|
|
15
15
|
* - Locale resolution with fallbacks
|
|
16
|
-
* - Process-level memoization (read by default, write by ownership)
|
|
17
16
|
* - Concurrency control for file system access
|
|
17
|
+
* - Process-level memoization (read by default, write by ownership)
|
|
18
18
|
*
|
|
19
19
|
* Local messages are cached for the lifetime of the process.
|
|
20
20
|
* Cache writes are restricted to the primary initialization flow.
|
|
@@ -22,7 +22,6 @@ import { readLocaleMessages } from './read-locale-messages/read-locale-messages.
|
|
|
22
22
|
* File traversal, parsing, and validation are delegated to lower-level utilities.
|
|
23
23
|
*/
|
|
24
24
|
const loadLocalMessages = async ({ id, locale, fallbackLocales, namespaces, rootDir = "messages", concurrency = 10, readOptions, pool = getGlobalMessagesPool(), allowCacheWrite = false, loggerOptions, }) => {
|
|
25
|
-
const isProd = process.env.NODE_ENV === "production";
|
|
26
25
|
const baseLogger = getLogger(loggerOptions);
|
|
27
26
|
const logger = baseLogger.child({ scope: "load-local-messages" });
|
|
28
27
|
const start = performance.now();
|
|
@@ -38,14 +37,14 @@ const loadLocalMessages = async ({ id, locale, fallbackLocales, namespaces, root
|
|
|
38
37
|
"loaderType:local",
|
|
39
38
|
rootDir,
|
|
40
39
|
locale,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
]);
|
|
40
|
+
fallbackLocales?.toSorted().join(","),
|
|
41
|
+
namespaces?.toSorted().join(","),
|
|
42
|
+
].filter(Boolean));
|
|
44
43
|
// ---------------------------------------------------------------------------
|
|
45
44
|
// Cache read
|
|
46
45
|
// ---------------------------------------------------------------------------
|
|
47
46
|
if (cacheKey) {
|
|
48
|
-
const cached =
|
|
47
|
+
const cached = pool.get(cacheKey);
|
|
49
48
|
if (cached) {
|
|
50
49
|
logger.debug("Messages cache hit.", { key: cacheKey });
|
|
51
50
|
return cached;
|
|
@@ -90,10 +89,10 @@ const loadLocalMessages = async ({ id, locale, fallbackLocales, namespaces, root
|
|
|
90
89
|
// ---------------------------------------------------------------------------
|
|
91
90
|
// Cache write (explicitly permitted)
|
|
92
91
|
// ---------------------------------------------------------------------------
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
93
|
+
const canWriteCache = isProd && allowCacheWrite;
|
|
94
|
+
if (canWriteCache && cacheKey && messages) {
|
|
95
|
+
pool.set(cacheKey, messages);
|
|
97
96
|
}
|
|
98
97
|
// Final success log with resolved locale and timing
|
|
99
98
|
if (messages) {
|
|
@@ -2,7 +2,6 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import '../../../../../core/error/intor-error.js';
|
|
4
4
|
import { getLogger } from '../../../../../core/logger/get-logger.js';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* Recursively collects message file metadata under a given locale root.
|
|
@@ -3,7 +3,6 @@ import '../../../../../core/error/intor-error.js';
|
|
|
3
3
|
import { deepMerge } from '../../../../../core/utils/deep-merge.js';
|
|
4
4
|
import { getLogger } from '../../../../../core/logger/get-logger.js';
|
|
5
5
|
import { isValidMessages } from '../../../../../core/messages/utils/is-valid-messages.js';
|
|
6
|
-
import 'keyv';
|
|
7
6
|
import { jsonReader } from './utils/json-reader.js';
|
|
8
7
|
import { nestObjectFromPath } from './utils/nest-object-from-path.js';
|
|
9
8
|
|