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
|
@@ -2,7 +2,6 @@ import '../../../core/error/intor-error.js';
|
|
|
2
2
|
import { resolveLoaderOptions } from '../../../core/utils/resolve-loader-options.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import { loadRemoteMessages } from '../../../core/messages/load-remote-messages/load-remote-messages.js';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -27,7 +26,6 @@ const createRefetchMessages = ({ config, onLoadingStart, onLoadingEnd, onMessage
|
|
|
27
26
|
onLoadingStart?.();
|
|
28
27
|
try {
|
|
29
28
|
const loadedMessages = await loadRemoteMessages({
|
|
30
|
-
id: config.id,
|
|
31
29
|
locale: newLocale,
|
|
32
30
|
fallbackLocales: config.fallbackLocales[newLocale] || [],
|
|
33
31
|
namespaces: loader.namespaces,
|
|
@@ -35,7 +33,6 @@ const createRefetchMessages = ({ config, onLoadingStart, onLoadingEnd, onMessage
|
|
|
35
33
|
url: loader.url,
|
|
36
34
|
headers: loader.headers,
|
|
37
35
|
signal: currentController.signal,
|
|
38
|
-
cacheOptions: config.cache,
|
|
39
36
|
loggerOptions: config.logger,
|
|
40
37
|
});
|
|
41
38
|
// Apply state updates only when this request is still the active one
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { writable } from 'svelte/store';
|
|
2
2
|
import '../../../core/error/intor-error.js';
|
|
3
3
|
import 'logry';
|
|
4
|
-
import 'keyv';
|
|
5
4
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
6
5
|
import { getClientLocale } from '../../shared/helpers/get-client-locale.js';
|
|
7
6
|
|
|
@@ -2,7 +2,6 @@ import { shouldPersist } from '../../../../policies/should-persist.js';
|
|
|
2
2
|
import { shouldPersistOnFirstVisit } from '../../../../policies/should-persist-on-first-visit.js';
|
|
3
3
|
import '../../../../core/error/intor-error.js';
|
|
4
4
|
import 'logry';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
import { getLocaleCookieBrowser } from '../../../shared/utils/locale/get-locale-cookie-browser.js';
|
|
7
6
|
import { setLocaleCookieBrowser } from '../../../shared/utils/locale/set-locale-cookie-browser.js';
|
|
8
7
|
import { setDocumentLocale } from '../../../shared/utils/locale/set-document-locale.js';
|
|
@@ -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,4 +1,4 @@
|
|
|
1
|
-
export { PREFIX_PLACEHOLDER, IntorError, IntorErrorCode, deepMerge, resolveLoaderOptions, clearLoggerPool, clearMessagesPool,
|
|
1
|
+
export { PREFIX_PLACEHOLDER, IntorError, IntorErrorCode, deepMerge, resolveLoaderOptions, clearLoggerPool, clearMessagesPool, mergeMessages, isValidMessages, type Messages, type MessagesReader, } from "../src/core";
|
|
2
2
|
export { defineIntorConfig, type IntorRawConfig, type IntorResolvedConfig, } from "../src/config";
|
|
3
3
|
export { localizePathname } from "../src/routing";
|
|
4
4
|
export { Translator, type TranslatorPlugin, type TranslateHandlers, type FormatHandler, type LoadingHandler, type MissingHandler, type HandlerContext, type TranslateContext, type TranslateHook, type LocaleMessages, } from "intor-translator";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { defineIntorConfig } from "./define-intor-config";
|
|
2
|
-
export { DEFAULT_ROUTING_OPTIONS, DEFAULT_COOKIE_OPTIONS
|
|
3
|
-
export type { IntorRawConfig, IntorResolvedConfig, LoaderOptions, RemoteHeaders, TranslatorOptions, RoutingResolvedOptions, CookieResolvedOptions, LoggerOptions,
|
|
2
|
+
export { DEFAULT_ROUTING_OPTIONS, DEFAULT_COOKIE_OPTIONS } from "./constants";
|
|
3
|
+
export type { IntorRawConfig, IntorResolvedConfig, LoaderOptions, RemoteHeaders, TranslatorOptions, RoutingResolvedOptions, CookieResolvedOptions, LoggerOptions, } from "./types";
|
|
@@ -4,4 +4,3 @@ export type { TranslatorOptions } from "./translator";
|
|
|
4
4
|
export type { RoutingResolvedOptions } from "./routing";
|
|
5
5
|
export type { CookieRawOptions, CookieResolvedOptions } from "./cookie";
|
|
6
6
|
export type { LoggerOptions } from "./logger";
|
|
7
|
-
export type { CacheRawOptions, CacheResolvedOptions } from "./cache";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CacheRawOptions, CacheResolvedOptions } from "./cache";
|
|
2
1
|
import type { CookieRawOptions, CookieResolvedOptions } from "./cookie";
|
|
3
2
|
import type { ClientLoaderOptions, LoaderOptions, ServerLoaderOptions } from "./loader";
|
|
4
3
|
import type { LoggerOptions } from "./logger";
|
|
@@ -35,8 +34,6 @@ export type IntorRawConfig = {
|
|
|
35
34
|
};
|
|
36
35
|
/** Logging and diagnostic configuration. */
|
|
37
36
|
readonly logger?: Omit<LoggerOptions, "id">;
|
|
38
|
-
/** Cache policy used by remote messages loading. */
|
|
39
|
-
readonly cache?: CacheRawOptions;
|
|
40
37
|
};
|
|
41
38
|
/** Fully resolved configuration after validation and normalization. */
|
|
42
39
|
export type IntorResolvedConfig = {
|
|
@@ -56,5 +53,4 @@ export type IntorResolvedConfig = {
|
|
|
56
53
|
loader?: ClientLoaderOptions;
|
|
57
54
|
};
|
|
58
55
|
readonly logger: LoggerOptions;
|
|
59
|
-
readonly cache: CacheResolvedOptions;
|
|
60
56
|
};
|
|
@@ -2,5 +2,5 @@ export { PREFIX_PLACEHOLDER, INTOR_HEADERS } from "./constants";
|
|
|
2
2
|
export { IntorError, IntorErrorCode } from "./error";
|
|
3
3
|
export { deepMerge, type PlainObject, type DeepMergeOverrideEvent, resolveLoaderOptions, normalizePathname, normalizeCacheKey, normalizeLocale, normalizeQuery, } from "./utils";
|
|
4
4
|
export { getLogger, clearLoggerPool } from "./logger";
|
|
5
|
-
export { loadRemoteMessages, type MessagesPool, getGlobalMessagesPool, clearMessagesPool,
|
|
5
|
+
export { loadRemoteMessages, type MessagesPool, getGlobalMessagesPool, clearMessagesPool, mergeMessages, isValidMessages, type Messages, type MessagesReader, type MessagesReadOptions, } from "./messages";
|
|
6
6
|
export type { INTOR_GENERATED_KEY, IfGen, GenConfigKeys, GenConfig, GenMessages, GenLocale, BootstrapCore, MessageKey, TranslatorInstance, KeyMode, RoutingLocaleSource, RoutingLocaleCarrier, LocalePathPrefix, } from "./types";
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import type { LocaleMessages } from "intor-translator";
|
|
2
|
-
import Keyv from "keyv";
|
|
3
2
|
/**
|
|
4
|
-
* Global messages pool (
|
|
3
|
+
* Global messages pool (process-level, hot-reload safe).
|
|
4
|
+
*
|
|
5
|
+
* This pool is intentionally minimal:
|
|
6
|
+
* - No TTL
|
|
7
|
+
* - No eviction
|
|
8
|
+
* - No external backends
|
|
9
|
+
*
|
|
10
|
+
* Messages are treated as immutable within a process lifecycle.
|
|
5
11
|
*/
|
|
6
|
-
export type MessagesPool =
|
|
12
|
+
export type MessagesPool = Map<string, LocaleMessages>;
|
|
7
13
|
declare global {
|
|
8
14
|
var __INTOR_MESSAGES_POOL__: MessagesPool | undefined;
|
|
9
15
|
}
|
|
10
|
-
export declare function getGlobalMessagesPool(): MessagesPool;
|
|
11
16
|
/**
|
|
12
|
-
*
|
|
17
|
+
* Get the global messages pool.
|
|
13
18
|
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
|
|
17
|
-
export declare function setGlobalMessagesPool(pool: MessagesPool): void;
|
|
18
|
-
/**
|
|
19
|
-
* Optional: clear all cache
|
|
20
|
-
* - Useful in tests or dynamic reloads.
|
|
19
|
+
* Lazily initialized to ensure:
|
|
20
|
+
* - Cross-module sharing
|
|
21
|
+
* - Dev / HMR safety
|
|
21
22
|
*/
|
|
23
|
+
export declare function getGlobalMessagesPool(): MessagesPool;
|
|
24
|
+
/** Clear all cached messages. */
|
|
22
25
|
export declare function clearMessagesPool(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { loadRemoteMessages } from "./load-remote-messages";
|
|
2
|
-
export { type MessagesPool, getGlobalMessagesPool, clearMessagesPool,
|
|
2
|
+
export { type MessagesPool, getGlobalMessagesPool, clearMessagesPool, } from "./global-messages-pool";
|
|
3
3
|
export { mergeMessages } from "./merge-messages";
|
|
4
4
|
export { isValidMessages } from "./utils/is-valid-messages";
|
|
5
5
|
export type { Messages, MessagesReader, MessagesReadOptions } from "./types";
|
|
@@ -7,9 +7,8 @@ import type { LocaleMessages } from "intor-translator";
|
|
|
7
7
|
* It coordinates:
|
|
8
8
|
*
|
|
9
9
|
* - Locale resolution with fallbacks
|
|
10
|
-
* - Cache read / write behavior
|
|
11
10
|
* - Respecting abort signals across the entire async flow
|
|
12
11
|
*
|
|
13
12
|
* Network fetching and data validation are delegated to lower-level utilities.
|
|
14
13
|
*/
|
|
15
|
-
export declare const loadRemoteMessages: ({
|
|
14
|
+
export declare const loadRemoteMessages: ({ locale, fallbackLocales, namespaces, rootDir, url, headers, signal, loggerOptions, }: LoadRemoteMessagesParams) => Promise<LocaleMessages | undefined>;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type { RemoteHeaders, LoggerOptions
|
|
2
|
-
import type { MessagesPool } from "../../../core";
|
|
1
|
+
import type { RemoteHeaders, LoggerOptions } from "../../../config";
|
|
3
2
|
export interface LoadRemoteMessagesParams {
|
|
4
|
-
id: string;
|
|
5
3
|
locale: string;
|
|
6
4
|
fallbackLocales?: string[];
|
|
7
5
|
namespaces?: string[];
|
|
@@ -9,8 +7,5 @@ export interface LoadRemoteMessagesParams {
|
|
|
9
7
|
url: string;
|
|
10
8
|
headers?: RemoteHeaders;
|
|
11
9
|
signal?: AbortSignal;
|
|
12
|
-
pool?: MessagesPool;
|
|
13
|
-
cacheOptions: CacheResolvedOptions;
|
|
14
|
-
allowCacheWrite?: boolean;
|
|
15
10
|
loggerOptions: LoggerOptions;
|
|
16
11
|
}
|
|
@@ -7,8 +7,8 @@ import type { LocaleMessages } from "intor-translator";
|
|
|
7
7
|
* It coordinates:
|
|
8
8
|
*
|
|
9
9
|
* - Locale resolution with fallbacks
|
|
10
|
-
* - Process-level memoization (read by default, write by ownership)
|
|
11
10
|
* - Concurrency control for file system access
|
|
11
|
+
* - Process-level memoization (read by default, write by ownership)
|
|
12
12
|
*
|
|
13
13
|
* Local messages are cached for the lifetime of the process.
|
|
14
14
|
* Cache writes are restricted to the primary initialization flow.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import '../../../core/error/intor-error.js';
|
|
2
2
|
import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
|
|
3
3
|
import 'logry';
|
|
4
|
-
import 'keyv';
|
|
5
4
|
import { detectBrowserLocale } from '../utils/locale/detect-browser-locale.js';
|
|
6
5
|
import { getLocaleCookieBrowser } from '../utils/locale/get-locale-cookie-browser.js';
|
|
7
6
|
|
|
@@ -2,7 +2,6 @@ import '../../../core/error/intor-error.js';
|
|
|
2
2
|
import { resolveLoaderOptions } from '../../../core/utils/resolve-loader-options.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import { loadRemoteMessages } from '../../../core/messages/load-remote-messages/load-remote-messages.js';
|
|
5
|
-
import 'keyv';
|
|
6
5
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -27,7 +26,6 @@ const createRefetchMessages = ({ config, onLoadingStart, onLoadingEnd, onMessage
|
|
|
27
26
|
onLoadingStart?.();
|
|
28
27
|
try {
|
|
29
28
|
const loadedMessages = await loadRemoteMessages({
|
|
30
|
-
id: config.id,
|
|
31
29
|
locale: newLocale,
|
|
32
30
|
fallbackLocales: config.fallbackLocales[newLocale] || [],
|
|
33
31
|
namespaces: loader.namespaces,
|
|
@@ -35,7 +33,6 @@ const createRefetchMessages = ({ config, onLoadingStart, onLoadingEnd, onMessage
|
|
|
35
33
|
url: loader.url,
|
|
36
34
|
headers: loader.headers,
|
|
37
35
|
signal: currentController.signal,
|
|
38
|
-
cacheOptions: config.cache,
|
|
39
36
|
loggerOptions: config.logger,
|
|
40
37
|
});
|
|
41
38
|
// Apply state updates only when this request is still the active one
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ref, onMounted } from 'vue';
|
|
2
2
|
import '../../../core/error/intor-error.js';
|
|
3
3
|
import 'logry';
|
|
4
|
-
import 'keyv';
|
|
5
4
|
import { mergeMessages } from '../../../core/messages/merge-messages.js';
|
|
6
5
|
import { getClientLocale } from '../../shared/helpers/get-client-locale.js';
|
|
7
6
|
|
|
@@ -3,7 +3,6 @@ import { shouldPersist } from '../../../../policies/should-persist.js';
|
|
|
3
3
|
import { shouldPersistOnFirstVisit } from '../../../../policies/should-persist-on-first-visit.js';
|
|
4
4
|
import '../../../../core/error/intor-error.js';
|
|
5
5
|
import 'logry';
|
|
6
|
-
import 'keyv';
|
|
7
6
|
import { getLocaleCookieBrowser } from '../../../shared/utils/locale/get-locale-cookie-browser.js';
|
|
8
7
|
import { setLocaleCookieBrowser } from '../../../shared/utils/locale/set-locale-cookie-browser.js';
|
|
9
8
|
import { setDocumentLocale } from '../../../shared/utils/locale/set-document-locale.js';
|
|
@@ -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.", {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "intor",
|
|
3
|
-
"version": "2.3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.3.14",
|
|
4
|
+
"description": "The i18n library for modern JavaScript",
|
|
5
5
|
"author": "Yiming Liao",
|
|
6
6
|
"homepage": "https://github.com/yiming-liao/intor#readme",
|
|
7
7
|
"repository": {
|
|
@@ -101,7 +101,6 @@
|
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
103
|
"intor-translator": "1.3.2",
|
|
104
|
-
"keyv": "5.5.5",
|
|
105
104
|
"logry": "2.1.6",
|
|
106
105
|
"p-limit": "7.2.0"
|
|
107
106
|
},
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const CACHE_KEY_DELIMITER = "|";
|
|
2
|
-
const sanitize = (k) => k
|
|
3
|
-
.replaceAll(/[\u200B-\u200D\uFEFF]/g, "")
|
|
4
|
-
.replaceAll(/[\r\n]/g, "")
|
|
5
|
-
.trim();
|
|
6
|
-
/**
|
|
7
|
-
* Normalizes a value into a stable cache key string.
|
|
8
|
-
*
|
|
9
|
-
* - Supports primitive values and structured array keys.
|
|
10
|
-
* - Produces deterministic output suitable for cache identifiers.
|
|
11
|
-
*
|
|
12
|
-
* Notes:
|
|
13
|
-
* - `null`, `undefined`, or empty arrays return `null`.
|
|
14
|
-
* - Special tokens are used for boolean, null, and undefined values
|
|
15
|
-
* to preserve semantic differences.
|
|
16
|
-
*/
|
|
17
|
-
const normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
|
|
18
|
-
// Treat nullish values as "no cache key"
|
|
19
|
-
if (key === null || key === undefined)
|
|
20
|
-
return null;
|
|
21
|
-
if (Array.isArray(key)) {
|
|
22
|
-
// Empty array produces no meaningful cache key
|
|
23
|
-
if (key.length === 0)
|
|
24
|
-
return null;
|
|
25
|
-
const normalized = key.map((k) => {
|
|
26
|
-
// Preserve semantic differences for special values
|
|
27
|
-
if (k === null)
|
|
28
|
-
return "__null";
|
|
29
|
-
if (k === undefined)
|
|
30
|
-
return "__undefined";
|
|
31
|
-
if (typeof k === "boolean")
|
|
32
|
-
return k ? "__true" : "__false";
|
|
33
|
-
return sanitize(String(k));
|
|
34
|
-
});
|
|
35
|
-
// Join segments into a single deterministic cache key
|
|
36
|
-
return normalized.join(delimiter);
|
|
37
|
-
}
|
|
38
|
-
// Normalize boolean primitives explicitly
|
|
39
|
-
if (typeof key === "boolean")
|
|
40
|
-
return key ? "__true" : "__false";
|
|
41
|
-
// Fallback: stringify primitive values
|
|
42
|
-
return String(key);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export { normalizeCacheKey };
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const CACHE_KEY_DELIMITER = "|";
|
|
2
|
-
const sanitize = (k) => k
|
|
3
|
-
.replaceAll(/[\u200B-\u200D\uFEFF]/g, "")
|
|
4
|
-
.replaceAll(/[\r\n]/g, "")
|
|
5
|
-
.trim();
|
|
6
|
-
/**
|
|
7
|
-
* Normalizes a value into a stable cache key string.
|
|
8
|
-
*
|
|
9
|
-
* - Supports primitive values and structured array keys.
|
|
10
|
-
* - Produces deterministic output suitable for cache identifiers.
|
|
11
|
-
*
|
|
12
|
-
* Notes:
|
|
13
|
-
* - `null`, `undefined`, or empty arrays return `null`.
|
|
14
|
-
* - Special tokens are used for boolean, null, and undefined values
|
|
15
|
-
* to preserve semantic differences.
|
|
16
|
-
*/
|
|
17
|
-
const normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
|
|
18
|
-
// Treat nullish values as "no cache key"
|
|
19
|
-
if (key === null || key === undefined)
|
|
20
|
-
return null;
|
|
21
|
-
if (Array.isArray(key)) {
|
|
22
|
-
// Empty array produces no meaningful cache key
|
|
23
|
-
if (key.length === 0)
|
|
24
|
-
return null;
|
|
25
|
-
const normalized = key.map((k) => {
|
|
26
|
-
// Preserve semantic differences for special values
|
|
27
|
-
if (k === null)
|
|
28
|
-
return "__null";
|
|
29
|
-
if (k === undefined)
|
|
30
|
-
return "__undefined";
|
|
31
|
-
if (typeof k === "boolean")
|
|
32
|
-
return k ? "__true" : "__false";
|
|
33
|
-
return sanitize(String(k));
|
|
34
|
-
});
|
|
35
|
-
// Join segments into a single deterministic cache key
|
|
36
|
-
return normalized.join(delimiter);
|
|
37
|
-
}
|
|
38
|
-
// Normalize boolean primitives explicitly
|
|
39
|
-
if (typeof key === "boolean")
|
|
40
|
-
return key ? "__true" : "__false";
|
|
41
|
-
// Fallback: stringify primitive values
|
|
42
|
-
return String(key);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export { normalizeCacheKey };
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const CACHE_KEY_DELIMITER = "|";
|
|
2
|
-
const sanitize = (k) => k
|
|
3
|
-
.replaceAll(/[\u200B-\u200D\uFEFF]/g, "")
|
|
4
|
-
.replaceAll(/[\r\n]/g, "")
|
|
5
|
-
.trim();
|
|
6
|
-
/**
|
|
7
|
-
* Normalizes a value into a stable cache key string.
|
|
8
|
-
*
|
|
9
|
-
* - Supports primitive values and structured array keys.
|
|
10
|
-
* - Produces deterministic output suitable for cache identifiers.
|
|
11
|
-
*
|
|
12
|
-
* Notes:
|
|
13
|
-
* - `null`, `undefined`, or empty arrays return `null`.
|
|
14
|
-
* - Special tokens are used for boolean, null, and undefined values
|
|
15
|
-
* to preserve semantic differences.
|
|
16
|
-
*/
|
|
17
|
-
const normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
|
|
18
|
-
// Treat nullish values as "no cache key"
|
|
19
|
-
if (key === null || key === undefined)
|
|
20
|
-
return null;
|
|
21
|
-
if (Array.isArray(key)) {
|
|
22
|
-
// Empty array produces no meaningful cache key
|
|
23
|
-
if (key.length === 0)
|
|
24
|
-
return null;
|
|
25
|
-
const normalized = key.map((k) => {
|
|
26
|
-
// Preserve semantic differences for special values
|
|
27
|
-
if (k === null)
|
|
28
|
-
return "__null";
|
|
29
|
-
if (k === undefined)
|
|
30
|
-
return "__undefined";
|
|
31
|
-
if (typeof k === "boolean")
|
|
32
|
-
return k ? "__true" : "__false";
|
|
33
|
-
return sanitize(String(k));
|
|
34
|
-
});
|
|
35
|
-
// Join segments into a single deterministic cache key
|
|
36
|
-
return normalized.join(delimiter);
|
|
37
|
-
}
|
|
38
|
-
// Normalize boolean primitives explicitly
|
|
39
|
-
if (typeof key === "boolean")
|
|
40
|
-
return key ? "__true" : "__false";
|
|
41
|
-
// Fallback: stringify primitive values
|
|
42
|
-
return String(key);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export { normalizeCacheKey };
|