intor 2.3.29 → 2.3.31
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/src/core/messages/load-remote-messages/fetch-remote-resource.js +1 -1
- package/dist/core/src/core/messages/load-remote-messages/load-remote-messages.js +2 -2
- package/dist/core/src/routing/pathname/canonicalize-pathname.js +11 -7
- package/dist/core/src/server/helpers/get-translator.js +2 -2
- package/dist/core/src/server/intor/intor.js +3 -8
- package/dist/core/src/server/messages/load-messages.js +2 -1
- package/dist/core/src/server/translator/init-translator.js +9 -3
- package/dist/express/src/adapters/express/middleware/create-intor-middleware.js +4 -11
- package/dist/express/src/core/messages/load-remote-messages/fetch-remote-resource.js +1 -1
- package/dist/express/src/core/messages/load-remote-messages/load-remote-messages.js +2 -2
- package/dist/express/src/routing/pathname/canonicalize-pathname.js +11 -7
- package/dist/express/src/server/helpers/get-translator.js +2 -2
- package/dist/express/src/server/messages/load-messages.js +2 -1
- package/dist/express/src/server/translator/init-translator.js +9 -3
- package/dist/next/export/next/index.js +0 -1
- package/dist/next/export/next/server/index.js +0 -1
- package/dist/next/src/adapters/next/navigation/link.js +11 -10
- package/dist/next/src/adapters/next/navigation/use-router.js +14 -20
- package/dist/next/src/adapters/next/proxy/intor-proxy.js +1 -1
- package/dist/next/src/adapters/next/server/intor.js +1 -1
- package/dist/next/src/client/shared/navigation/execute-navigation.js +50 -0
- package/dist/next/src/client/shared/utils/build-cookie-string.js +30 -0
- package/dist/next/src/client/shared/utils/locale/set-locale-cookie.js +15 -0
- package/dist/next/src/core/messages/load-remote-messages/fetch-remote-resource.js +1 -1
- package/dist/next/src/core/messages/load-remote-messages/load-remote-messages.js +2 -2
- package/dist/next/src/routing/pathname/canonicalize-pathname.js +11 -7
- package/dist/next/src/server/helpers/get-translator.js +2 -2
- package/dist/next/src/server/intor/intor.js +3 -8
- package/dist/next/src/server/messages/load-messages.js +2 -1
- package/dist/next/src/server/translator/init-translator.js +9 -3
- package/dist/react/export/react/index.js +0 -2
- package/dist/react/src/client/shared/messages/create-refetch-messages.js +1 -0
- package/dist/react/src/core/messages/load-remote-messages/fetch-remote-resource.js +1 -1
- package/dist/react/src/core/messages/load-remote-messages/load-remote-messages.js +2 -2
- package/dist/svelte/export/svelte/index.js +4 -2
- package/dist/svelte/src/client/shared/messages/create-refetch-messages.js +1 -0
- package/dist/svelte/src/client/svelte/{store → provider}/create-intor-store.js +7 -14
- package/dist/svelte/src/client/svelte/provider/intor-provider.svelte +7 -0
- package/dist/svelte/src/client/svelte/provider/use-intor-context.js +11 -0
- package/dist/svelte/src/client/svelte/render/create-svelte-renderer.js +5 -6
- package/dist/svelte/src/client/svelte/translator/create-t-rich.js +23 -0
- package/dist/svelte/src/client/svelte/translator/use-translator.js +32 -0
- package/dist/svelte/src/core/messages/load-remote-messages/fetch-remote-resource.js +1 -1
- package/dist/svelte/src/core/messages/load-remote-messages/load-remote-messages.js +2 -2
- package/dist/svelte-kit/export/svelte-kit/index.js +1 -0
- package/dist/svelte-kit/export/svelte-kit/server/index.js +2 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/navigation/use-navigation.js +36 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/server/create-intor-handle.js +66 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/server/intor.js +24 -0
- package/dist/svelte-kit/src/adapters/svelte-kit/server/utils/is-svelte-kit-ssg.js +15 -0
- package/dist/svelte-kit/src/client/shared/navigation/execute-navigation.js +49 -0
- package/dist/svelte-kit/src/client/shared/utils/build-cookie-string.js +30 -0
- package/dist/svelte-kit/src/client/shared/utils/locale/set-locale-cookie.js +15 -0
- package/dist/svelte-kit/src/core/error/intor-error.js +9 -0
- package/dist/svelte-kit/src/core/logger/get-logger.js +39 -0
- package/dist/svelte-kit/src/core/logger/global-logger-pool.js +8 -0
- package/dist/svelte-kit/src/core/messages/load-remote-messages/collect-remote-resources.js +25 -0
- package/dist/svelte-kit/src/core/messages/load-remote-messages/fetch-remote-resource.js +47 -0
- package/dist/svelte-kit/src/core/messages/load-remote-messages/load-remote-messages.js +93 -0
- package/dist/svelte-kit/src/core/messages/load-remote-messages/resolve-remote-resources.js +24 -0
- package/dist/svelte-kit/src/core/messages/merge-messages.js +33 -0
- package/dist/svelte-kit/src/core/messages/utils/is-valid-messages.js +44 -0
- package/dist/svelte-kit/src/core/messages/utils/nest-object-from-path.js +21 -0
- package/dist/svelte-kit/src/core/utils/deep-merge.js +47 -0
- package/dist/svelte-kit/src/core/utils/normalizers/normalize-cache-key.js +45 -0
- package/dist/svelte-kit/src/core/utils/normalizers/normalize-locale.js +59 -0
- package/dist/svelte-kit/src/core/utils/normalizers/normalize-query.js +25 -0
- package/dist/svelte-kit/src/core/utils/resolve-loader-options.js +34 -0
- package/dist/{react → svelte-kit}/src/policies/shoud-full-reload.js +1 -1
- package/dist/svelte-kit/src/policies/should-sync-locale.js +8 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-inbound.js +46 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-locale/resolve-locale.js +33 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-pathname/resolve-pathname.js +42 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-pathname/strategies/all.js +28 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-pathname/strategies/except-default.js +29 -0
- package/dist/svelte-kit/src/routing/inbound/resolve-pathname/strategies/none.js +8 -0
- package/dist/svelte-kit/src/routing/locale/get-locale-from-accept-language.js +38 -0
- package/dist/svelte-kit/src/routing/locale/get-locale-from-host.js +32 -0
- package/dist/svelte-kit/src/routing/locale/get-locale-from-pathname.js +46 -0
- package/dist/svelte-kit/src/routing/locale/get-locale-from-query.js +29 -0
- package/dist/{react → svelte-kit}/src/routing/pathname/canonicalize-pathname.js +11 -7
- package/dist/svelte-kit/src/server/intor/intor.js +31 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/cache/messages-pool.js +11 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/load-local-messages.js +107 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +90 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +102 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/utils/json-reader.js +12 -0
- package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/read-locale-messages.js +42 -0
- package/dist/svelte-kit/src/server/messages/load-messages.js +77 -0
- package/dist/svelte-kit/src/server/translator/create-translator.js +40 -0
- package/dist/svelte-kit/src/server/translator/init-translator.js +42 -0
- package/dist/types/export/next/index.d.ts +1 -1
- package/dist/types/export/next/server/index.d.ts +1 -1
- package/dist/types/export/react/index.d.ts +2 -2
- package/dist/types/export/svelte/index.d.ts +3 -1
- package/dist/types/export/svelte-kit/index.d.ts +1 -0
- package/dist/types/export/svelte-kit/server/index.d.ts +1 -0
- package/dist/types/src/adapters/express/global.d.ts +5 -8
- package/dist/types/src/adapters/next/navigation/index.d.ts +0 -1
- package/dist/types/src/adapters/next/server/index.d.ts +0 -1
- package/dist/types/src/adapters/svelte-kit/navigation/index.d.ts +1 -0
- package/dist/types/src/adapters/svelte-kit/navigation/use-navigation.d.ts +15 -0
- package/dist/types/src/adapters/svelte-kit/server/create-intor-handle.d.ts +12 -0
- package/dist/types/src/adapters/svelte-kit/server/index.d.ts +2 -0
- package/dist/types/src/adapters/svelte-kit/server/intor.d.ts +16 -0
- package/dist/types/src/adapters/svelte-kit/server/utils/is-svelte-kit-ssg.d.ts +8 -0
- package/dist/types/src/client/index.d.ts +1 -0
- package/dist/types/src/client/react/index.d.ts +0 -1
- package/dist/types/src/client/shared/navigation/execute-navigation.d.ts +19 -0
- package/dist/types/src/client/shared/navigation/index.d.ts +1 -0
- package/dist/types/src/client/svelte/index.d.ts +2 -2
- package/dist/types/src/client/svelte/provider/create-intor-store.d.ts +3 -0
- package/dist/types/src/client/svelte/provider/index.d.ts +3 -0
- package/dist/types/src/client/svelte/provider/types.d.ts +18 -0
- package/dist/types/src/client/svelte/provider/use-intor-context.d.ts +2 -0
- package/dist/types/src/client/svelte/render/types.d.ts +7 -13
- package/dist/types/src/client/svelte/translator/create-t-rich.d.ts +15 -0
- package/dist/types/src/client/svelte/translator/index.d.ts +1 -0
- package/dist/types/src/client/svelte/translator/translator-instance.d.ts +20 -0
- package/dist/types/src/client/svelte/translator/use-translator.d.ts +8 -0
- package/dist/types/src/core/index.d.ts +1 -1
- package/dist/types/src/core/messages/load-remote-messages/fetch-remote-resource.d.ts +3 -1
- package/dist/types/src/core/messages/load-remote-messages/load-remote-messages.d.ts +1 -1
- package/dist/types/src/core/messages/load-remote-messages/types.d.ts +2 -0
- package/dist/types/src/core/types/index.d.ts +1 -0
- package/dist/types/src/core/types/runtime-fetch.d.ts +1 -0
- package/dist/types/src/routing/inbound/index.d.ts +1 -0
- package/dist/types/src/routing/inbound/resolve-inbound.d.ts +1 -12
- package/dist/types/src/routing/inbound/types.d.ts +12 -0
- package/dist/types/src/routing/index.d.ts +1 -1
- package/dist/types/src/routing/pathname/canonicalize-pathname.d.ts +2 -0
- package/dist/types/src/server/helpers/get-translator.d.ts +2 -1
- package/dist/types/src/server/intor/intor.d.ts +4 -3
- package/dist/types/src/server/intor/types.d.ts +0 -2
- package/dist/types/src/server/messages/load-messages.d.ts +1 -1
- package/dist/types/src/server/messages/types.d.ts +2 -1
- package/dist/types/src/server/translator/init-translator.d.ts +2 -2
- package/dist/vue/src/client/shared/messages/create-refetch-messages.js +1 -0
- package/dist/vue/src/core/messages/load-remote-messages/fetch-remote-resource.js +1 -1
- package/dist/vue/src/core/messages/load-remote-messages/load-remote-messages.js +2 -2
- package/package.json +11 -1
- package/dist/express/src/core/constants/headers.js +0 -6
- package/dist/next/src/adapters/next/navigation/use-pathname.js +0 -26
- package/dist/next/src/adapters/next/server/get-pathname.js +0 -28
- package/dist/react/src/client/react/navigation/use-execute-navigation.js +0 -41
- package/dist/react/src/client/react/navigation/use-resolve-navigation.js +0 -16
- package/dist/svelte/src/client/svelte/helpers/create-intor.js +0 -45
- package/dist/svelte/src/client/svelte/store/create-translator-bindings.js +0 -25
- package/dist/types/src/adapters/next/navigation/use-pathname.d.ts +0 -14
- package/dist/types/src/adapters/next/server/get-pathname.d.ts +0 -16
- package/dist/types/src/client/react/navigation/index.d.ts +0 -2
- package/dist/types/src/client/react/navigation/use-execute-navigation.d.ts +0 -5
- package/dist/types/src/client/react/navigation/use-resolve-navigation.d.ts +0 -5
- package/dist/types/src/client/svelte/helpers/create-intor.d.ts +0 -4
- package/dist/types/src/client/svelte/helpers/index.d.ts +0 -1
- package/dist/types/src/client/svelte/store/create-intor-store.d.ts +0 -2
- package/dist/types/src/client/svelte/store/create-translator-bindings.d.ts +0 -13
- package/dist/types/src/client/svelte/store/index.d.ts +0 -2
- package/dist/types/src/client/svelte/store/types.d.ts +0 -31
- /package/dist/{react → next}/src/policies/should-sync-locale.js +0 -0
- /package/dist/svelte/src/client/svelte/{store → provider}/effects/locale-effects.js +0 -0
- /package/dist/svelte/src/client/svelte/{store → provider}/effects/messages-effects.js +0 -0
- /package/dist/{react → svelte-kit}/src/core/constants/prefix-placeholder.js +0 -0
- /package/dist/{react → svelte-kit}/src/core/utils/normalizers/normalize-pathname.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/navigation/decide-strategy.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/navigation/derive-target.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/navigation/resolve-navigation.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/navigation/utils/derive-host-destination.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/navigation/utils/derive-query-destination.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/navigation/utils/is-external-destination.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/pathname/localize-pathname.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/pathname/materialize-pathname.js +0 -0
- /package/dist/{react → svelte-kit}/src/routing/pathname/standardize-pathname.js +0 -0
- /package/dist/types/src/client/svelte/{store → provider}/effects/locale-effects.d.ts +0 -0
- /package/dist/types/src/client/svelte/{store → provider}/effects/messages-effects.d.ts +0 -0
|
@@ -2,12 +2,12 @@ import { initTranslator } from '../translator/init-translator.js';
|
|
|
2
2
|
|
|
3
3
|
// Implementation
|
|
4
4
|
async function getTranslator(config, params) {
|
|
5
|
-
const { readers, allowCacheWrite, preKey, handlers, plugins } = params;
|
|
6
|
-
const locale = params.locale;
|
|
5
|
+
const { locale, readers, allowCacheWrite, fetch, preKey, handlers, plugins } = params;
|
|
7
6
|
// Initialize a locale-bound translator snapshot with messages loaded
|
|
8
7
|
const translator = await initTranslator(config, locale, {
|
|
9
8
|
readers,
|
|
10
9
|
allowCacheWrite,
|
|
10
|
+
fetch: fetch || globalThis.fetch,
|
|
11
11
|
preKey,
|
|
12
12
|
plugins,
|
|
13
13
|
handlers,
|
|
@@ -9,21 +9,16 @@ import { initTranslator } from '../translator/init-translator.js';
|
|
|
9
9
|
* Produces a server-side snapshot for SSR and
|
|
10
10
|
* full-stack rendering environments.
|
|
11
11
|
*/
|
|
12
|
-
async function intor(config,
|
|
12
|
+
async function intor(config, locale, options) {
|
|
13
13
|
const baseLogger = getLogger(config.logger);
|
|
14
14
|
const logger = baseLogger.child({ scope: "intor" });
|
|
15
15
|
logger.info("Start Intor initialization.");
|
|
16
|
-
|
|
17
|
-
const isLocaleFunction = typeof localeOrResolver === "function";
|
|
18
|
-
const locale = isLocaleFunction
|
|
19
|
-
? await localeOrResolver(config)
|
|
20
|
-
: localeOrResolver || config.defaultLocale;
|
|
21
|
-
const source = typeof localeOrResolver === "function" ? "resolver" : "static";
|
|
22
|
-
logger.debug(`Initial locale resolved as "${locale}" via "${source}".`);
|
|
16
|
+
logger.debug(`Initializing Intor with locale "${locale}".`);
|
|
23
17
|
// Initialize a locale-bound translator snapshot with messages loaded
|
|
24
18
|
const translator = await initTranslator(config, locale, {
|
|
25
19
|
readers: options?.readers,
|
|
26
20
|
allowCacheWrite: options?.allowCacheWrite,
|
|
21
|
+
fetch: options?.fetch || globalThis.fetch,
|
|
27
22
|
});
|
|
28
23
|
logger.info("Intor initialized.");
|
|
29
24
|
return {
|
|
@@ -17,7 +17,7 @@ import { loadLocalMessages } from './load-local-messages/load-local-messages.js'
|
|
|
17
17
|
* Message traversal, parsing, fallback resolution, and caching logic
|
|
18
18
|
* are delegated to the selected loader.
|
|
19
19
|
*/
|
|
20
|
-
const loadMessages = async ({ config, locale, readers, allowCacheWrite = false, }) => {
|
|
20
|
+
const loadMessages = async ({ config, locale, readers, allowCacheWrite = false, fetch, }) => {
|
|
21
21
|
const baseLogger = getLogger(config.logger);
|
|
22
22
|
const logger = baseLogger.child({ scope: "load-messages" });
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
@@ -61,6 +61,7 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
61
61
|
fallbackLocales,
|
|
62
62
|
namespaces,
|
|
63
63
|
concurrency,
|
|
64
|
+
fetch,
|
|
64
65
|
url: loader.url,
|
|
65
66
|
headers: loader.headers,
|
|
66
67
|
loggerOptions: config.logger,
|
|
@@ -14,13 +14,19 @@ import { createTranslator } from './create-translator.js';
|
|
|
14
14
|
* - Returns an immutable translator snapshot.
|
|
15
15
|
*/
|
|
16
16
|
async function initTranslator(config, locale, options) {
|
|
17
|
-
const { readers, allowCacheWrite = false, preKey, handlers, plugins, } = options
|
|
17
|
+
const { readers, allowCacheWrite = false, fetch, preKey, handlers, plugins, } = options;
|
|
18
18
|
const loader = resolveLoaderOptions(config, "server");
|
|
19
19
|
// Load messages
|
|
20
20
|
let messages = {};
|
|
21
21
|
if (loader) {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const loaded = await loadMessages({
|
|
23
|
+
config,
|
|
24
|
+
locale,
|
|
25
|
+
readers,
|
|
26
|
+
allowCacheWrite,
|
|
27
|
+
fetch,
|
|
28
|
+
});
|
|
29
|
+
messages = loaded || {};
|
|
24
30
|
}
|
|
25
31
|
// Create immutable translator snapshot
|
|
26
32
|
return createTranslator({
|
|
@@ -2,7 +2,5 @@ export { IntorProvider } from '../../src/client/react/provider/intor-provider.js
|
|
|
2
2
|
export { useIntorContext } from '../../src/client/react/provider/use-intor-context.js';
|
|
3
3
|
export { useTranslator } from '../../src/client/react/translator/use-translator.js';
|
|
4
4
|
export { Trans } from '../../src/client/react/translator/trans.js';
|
|
5
|
-
export { useResolveNavigation } from '../../src/client/react/navigation/use-resolve-navigation.js';
|
|
6
|
-
export { useExecuteNavigation } from '../../src/client/react/navigation/use-execute-navigation.js';
|
|
7
5
|
export { useIntor } from '../../src/client/react/helpers/use-intor.js';
|
|
8
6
|
export { getClientLocale } from '../../src/client/shared/helpers/get-client-locale.js';
|
|
@@ -30,6 +30,7 @@ const createRefetchMessages = ({ config, onLoadingStart, onLoadingEnd, onMessage
|
|
|
30
30
|
fallbackLocales: config.fallbackLocales[newLocale] || [],
|
|
31
31
|
namespaces: loader.namespaces,
|
|
32
32
|
concurrency: loader.concurrency,
|
|
33
|
+
fetch: globalThis.fetch,
|
|
33
34
|
url: loader.url,
|
|
34
35
|
headers: loader.headers,
|
|
35
36
|
signal: currentController.signal,
|
|
@@ -12,7 +12,7 @@ import { isValidMessages } from '../utils/is-valid-messages.js';
|
|
|
12
12
|
* - Validating the returned message structure
|
|
13
13
|
* - Handling abort and network errors
|
|
14
14
|
*/
|
|
15
|
-
async function fetchRemoteResource({ url, headers, signal, loggerOptions, }) {
|
|
15
|
+
async function fetchRemoteResource({ fetch, url, headers, signal, loggerOptions, }) {
|
|
16
16
|
const baseLogger = getLogger(loggerOptions);
|
|
17
17
|
const logger = baseLogger.child({ scope: "fetch-locale-messages" });
|
|
18
18
|
try {
|
|
@@ -18,7 +18,7 @@ import { resolveRemoteResources } from './resolve-remote-resources.js';
|
|
|
18
18
|
*
|
|
19
19
|
* Network requests and response validation are delegated to lower-level utilities.
|
|
20
20
|
*/
|
|
21
|
-
const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurrency, url: baseUrl, headers, signal, loggerOptions, }) => {
|
|
21
|
+
const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurrency, fetch, url: baseUrl, headers, signal, loggerOptions, }) => {
|
|
22
22
|
const baseLogger = getLogger(loggerOptions);
|
|
23
23
|
const logger = baseLogger.child({ scope: "load-remote-messages" });
|
|
24
24
|
// Abort early if the request has already been cancelled
|
|
@@ -49,7 +49,7 @@ const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurr
|
|
|
49
49
|
// -----------------------------------------------------------------
|
|
50
50
|
// Fetch all message chunks in parallel
|
|
51
51
|
// -----------------------------------------------------------------
|
|
52
|
-
const fetchUrl = (url) => fetchRemoteResource({ url, headers, signal, loggerOptions });
|
|
52
|
+
const fetchUrl = (url) => fetchRemoteResource({ url, headers, signal, loggerOptions, fetch });
|
|
53
53
|
const results = await Promise.all(resources.map(({ url }) => limit ? limit(() => fetchUrl(url)) : fetchUrl(url)));
|
|
54
54
|
// Guard: no valid remote resources
|
|
55
55
|
if (!results.some(Boolean))
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { createIntorStore } from '../../src/client/svelte/
|
|
2
|
-
export {
|
|
1
|
+
export { createIntorStore } from '../../src/client/svelte/provider/create-intor-store.js';
|
|
2
|
+
export { default as IntorProvider } from '../../src/client/svelte/provider/intor-provider.svelte';
|
|
3
|
+
export { useIntorContext } from '../../src/client/svelte/provider/use-intor-context.js';
|
|
4
|
+
export { useTranslator } from '../../src/client/svelte/translator/use-translator.js';
|
|
3
5
|
export { getClientLocale } from '../../src/client/shared/helpers/get-client-locale.js';
|
|
@@ -30,6 +30,7 @@ const createRefetchMessages = ({ config, onLoadingStart, onLoadingEnd, onMessage
|
|
|
30
30
|
fallbackLocales: config.fallbackLocales[newLocale] || [],
|
|
31
31
|
namespaces: loader.namespaces,
|
|
32
32
|
concurrency: loader.concurrency,
|
|
33
|
+
fetch: globalThis.fetch,
|
|
33
34
|
url: loader.url,
|
|
34
35
|
headers: loader.headers,
|
|
35
36
|
signal: currentController.signal,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Translator } from 'intor-translator';
|
|
2
|
+
import { setContext } from 'svelte';
|
|
2
3
|
import { writable, readable, derived, get } from 'svelte/store';
|
|
3
|
-
import { createTranslatorBindings } from './create-translator-bindings.js';
|
|
4
4
|
import { attachLocaleEffects } from './effects/locale-effects.js';
|
|
5
5
|
import { attachMessagesEffects } from './effects/messages-effects.js';
|
|
6
6
|
|
|
7
|
+
const INTOR_CONTEXT_KEY = Symbol("intor:svelte");
|
|
7
8
|
function createIntorStore({ config, locale: initialLocale, messages, handlers, plugins, onLocaleChange, isLoading: externalIsLoading, }) {
|
|
8
9
|
// ---------------------------------------------------------------------------
|
|
9
10
|
// Internal state
|
|
@@ -25,11 +26,12 @@ function createIntorStore({ config, locale: initialLocale, messages, handlers, p
|
|
|
25
26
|
// ---------------------------------------------------------------------------
|
|
26
27
|
// Effective state
|
|
27
28
|
// ---------------------------------------------------------------------------
|
|
28
|
-
const externalIsLoadingStore =
|
|
29
|
+
const externalIsLoadingStore = readable(!!externalIsLoading);
|
|
29
30
|
// external > internal
|
|
30
31
|
const effectiveIsLoading = derived([externalIsLoadingStore, internalIsLoading], ([$external, $internal]) => $external || $internal);
|
|
31
32
|
// runtime (client refetch) > initial > config (static)
|
|
32
|
-
const
|
|
33
|
+
const initialMessagesStore = readable(messages || config.messages || {});
|
|
34
|
+
const effectiveMessages = derived([runtimeMessages, initialMessagesStore], ([$runtime, $initial]) => $runtime || $initial);
|
|
33
35
|
// ---------------------------------------------------------------------------
|
|
34
36
|
// Translator
|
|
35
37
|
// ---------------------------------------------------------------------------
|
|
@@ -48,16 +50,7 @@ function createIntorStore({ config, locale: initialLocale, messages, handlers, p
|
|
|
48
50
|
// ---------------------------------------------------------------------------
|
|
49
51
|
attachLocaleEffects(locale, config);
|
|
50
52
|
attachMessagesEffects({ config, locale, runtimeMessages, internalIsLoading });
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
messages: effectiveMessages,
|
|
54
|
-
locale,
|
|
55
|
-
isLoading: effectiveIsLoading,
|
|
56
|
-
setLocale,
|
|
57
|
-
scoped,
|
|
58
|
-
t,
|
|
59
|
-
tRich,
|
|
60
|
-
};
|
|
53
|
+
setContext(INTOR_CONTEXT_KEY, { config, locale, setLocale, translator });
|
|
61
54
|
}
|
|
62
55
|
|
|
63
|
-
export { createIntorStore };
|
|
56
|
+
export { INTOR_CONTEXT_KEY, createIntorStore };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getContext } from 'svelte';
|
|
2
|
+
import { INTOR_CONTEXT_KEY } from './create-intor-store.js';
|
|
3
|
+
|
|
4
|
+
function useIntorContext() {
|
|
5
|
+
const context = getContext(INTOR_CONTEXT_KEY);
|
|
6
|
+
if (!context)
|
|
7
|
+
throw new Error("useIntorContext must be used within IntorProvider");
|
|
8
|
+
return context;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { useIntorContext };
|
|
@@ -18,12 +18,11 @@ const createSvelteRenderer = (options) => {
|
|
|
18
18
|
},
|
|
19
19
|
/** Render semantic tag nodes */
|
|
20
20
|
tag(name, attributes, children) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
: renderer;
|
|
21
|
+
const tagRenderer = tagRenderers?.[name];
|
|
22
|
+
if (tagRenderer) {
|
|
23
|
+
return typeof tagRenderer === "function"
|
|
24
|
+
? tagRenderer(children)
|
|
25
|
+
: tagRenderer;
|
|
27
26
|
}
|
|
28
27
|
// Default behavior: render as native HTML tag
|
|
29
28
|
return `<${name}${renderAttributes(attributes)}>${children.join("")}</${name}>`;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { renderRichMessageSvelte } from '../render/render-rich-message-svelte.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a Svelte-specific rich translation function.
|
|
5
|
+
*
|
|
6
|
+
* This adapter bridges the core Translator with the Svelte rich
|
|
7
|
+
* message rendering flow.
|
|
8
|
+
*
|
|
9
|
+
* - Resolves translated messages via `translator.t`
|
|
10
|
+
* - Renders semantic tags using Svelte renderers
|
|
11
|
+
* - Supports optional scoped keys via `preKey`
|
|
12
|
+
*
|
|
13
|
+
* Intended for Svelte client usage only.
|
|
14
|
+
*/
|
|
15
|
+
const createTRich = (translator, preKey) => {
|
|
16
|
+
const t = preKey ? translator.scoped(preKey).t : translator.t;
|
|
17
|
+
return (key, tagRenderers, replacements) => {
|
|
18
|
+
const message = t(key, replacements);
|
|
19
|
+
return renderRichMessageSvelte(message, tagRenderers);
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { createTRich };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { derived } from 'svelte/store';
|
|
2
|
+
import 'intor-translator';
|
|
3
|
+
import 'svelte';
|
|
4
|
+
import '../../../core/error/intor-error.js';
|
|
5
|
+
import 'logry';
|
|
6
|
+
import 'p-limit';
|
|
7
|
+
import '../provider/intor-provider.svelte';
|
|
8
|
+
import { useIntorContext } from '../provider/use-intor-context.js';
|
|
9
|
+
import { createTRich } from './create-t-rich.js';
|
|
10
|
+
|
|
11
|
+
// Implementation
|
|
12
|
+
function useTranslator(preKey) {
|
|
13
|
+
const { translator, locale, setLocale } = useIntorContext();
|
|
14
|
+
const scoped = preKey
|
|
15
|
+
? derived(translator, ($t) => $t.scoped(preKey))
|
|
16
|
+
: translator;
|
|
17
|
+
return {
|
|
18
|
+
messages: derived(translator, ($t) => $t.messages),
|
|
19
|
+
locale,
|
|
20
|
+
isLoading: derived(translator, ($t) => $t.isLoading),
|
|
21
|
+
setLocale,
|
|
22
|
+
hasKey: derived(scoped, ($t) => $t.hasKey),
|
|
23
|
+
t: derived(scoped, ($t) => $t.t),
|
|
24
|
+
tRich: derived(translator, ($t) => createTRich($t, preKey)),
|
|
25
|
+
// NOTE:
|
|
26
|
+
// The runtime implementation is intentionally erased.
|
|
27
|
+
// Type safety is guaranteed by public type contracts.
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { useTranslator };
|
|
@@ -12,7 +12,7 @@ import { isValidMessages } from '../utils/is-valid-messages.js';
|
|
|
12
12
|
* - Validating the returned message structure
|
|
13
13
|
* - Handling abort and network errors
|
|
14
14
|
*/
|
|
15
|
-
async function fetchRemoteResource({ url, headers, signal, loggerOptions, }) {
|
|
15
|
+
async function fetchRemoteResource({ fetch, url, headers, signal, loggerOptions, }) {
|
|
16
16
|
const baseLogger = getLogger(loggerOptions);
|
|
17
17
|
const logger = baseLogger.child({ scope: "fetch-locale-messages" });
|
|
18
18
|
try {
|
|
@@ -18,7 +18,7 @@ import { resolveRemoteResources } from './resolve-remote-resources.js';
|
|
|
18
18
|
*
|
|
19
19
|
* Network requests and response validation are delegated to lower-level utilities.
|
|
20
20
|
*/
|
|
21
|
-
const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurrency, url: baseUrl, headers, signal, loggerOptions, }) => {
|
|
21
|
+
const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurrency, fetch, url: baseUrl, headers, signal, loggerOptions, }) => {
|
|
22
22
|
const baseLogger = getLogger(loggerOptions);
|
|
23
23
|
const logger = baseLogger.child({ scope: "load-remote-messages" });
|
|
24
24
|
// Abort early if the request has already been cancelled
|
|
@@ -49,7 +49,7 @@ const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurr
|
|
|
49
49
|
// -----------------------------------------------------------------
|
|
50
50
|
// Fetch all message chunks in parallel
|
|
51
51
|
// -----------------------------------------------------------------
|
|
52
|
-
const fetchUrl = (url) => fetchRemoteResource({ url, headers, signal, loggerOptions });
|
|
52
|
+
const fetchUrl = (url) => fetchRemoteResource({ url, headers, signal, loggerOptions, fetch });
|
|
53
53
|
const results = await Promise.all(resources.map(({ url }) => limit ? limit(() => fetchUrl(url)) : fetchUrl(url)));
|
|
54
54
|
// Guard: no valid remote resources
|
|
55
55
|
if (!results.some(Boolean))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useNavigation } from '../../src/adapters/svelte-kit/navigation/use-navigation.js';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { get } from 'svelte/store';
|
|
2
|
+
import { executeNavigation } from '../../../client/shared/navigation/execute-navigation.js';
|
|
3
|
+
import { useIntorContext } from 'intor/svelte';
|
|
4
|
+
import '../../../core/error/intor-error.js';
|
|
5
|
+
import 'logry';
|
|
6
|
+
import 'p-limit';
|
|
7
|
+
import { resolveNavigation } from '../../../routing/navigation/resolve-navigation.js';
|
|
8
|
+
import { goto } from '$app/navigation';
|
|
9
|
+
import { page } from '$app/state';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Locale-aware navigation utilities for SvelteKit.
|
|
13
|
+
*
|
|
14
|
+
* Provides imperative navigation helpers that integrate
|
|
15
|
+
* Intor's locale-aware routing and side effects.
|
|
16
|
+
*
|
|
17
|
+
* @platform SvelteKit
|
|
18
|
+
*/
|
|
19
|
+
function useNavigation() {
|
|
20
|
+
const { config, locale: currentLocale, setLocale } = useIntorContext();
|
|
21
|
+
async function goto$1(url, opts) {
|
|
22
|
+
const { locale, ...rest } = opts || {};
|
|
23
|
+
const navigationResult = resolveNavigation(config, get(currentLocale), page.url.pathname, { destination: url, locale });
|
|
24
|
+
executeNavigation(navigationResult, {
|
|
25
|
+
config,
|
|
26
|
+
currentLocale: get(currentLocale),
|
|
27
|
+
setLocale,
|
|
28
|
+
});
|
|
29
|
+
return goto(navigationResult.destination, rest);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
goto: goto$1,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { useNavigation };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { redirect } from '@sveltejs/kit';
|
|
2
|
+
import { isSvelteKitSSG } from './utils/is-svelte-kit-ssg.js';
|
|
3
|
+
import '../../../core/error/intor-error.js';
|
|
4
|
+
import { normalizeQuery } from '../../../core/utils/normalizers/normalize-query.js';
|
|
5
|
+
import 'logry';
|
|
6
|
+
import 'p-limit';
|
|
7
|
+
import { resolveInbound } from '../../../routing/inbound/resolve-inbound.js';
|
|
8
|
+
import { getLocaleFromAcceptLanguage } from '../../../routing/locale/get-locale-from-accept-language.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolves locale-aware routing for the current execution context.
|
|
12
|
+
*
|
|
13
|
+
* The resolved routing state is exposed via response headers.
|
|
14
|
+
*
|
|
15
|
+
* - Acts as the canonical routing authority within the SvelteKit request lifecycle.
|
|
16
|
+
*
|
|
17
|
+
* @platform SvelteKit
|
|
18
|
+
*/
|
|
19
|
+
function createIntorHandle(config) {
|
|
20
|
+
return async ({ event, resolve }) => {
|
|
21
|
+
// Locale from Accept-Language header
|
|
22
|
+
const acceptLanguage = event.request.headers.get("accept-language");
|
|
23
|
+
const localeFromAcceptLanguage = getLocaleFromAcceptLanguage(acceptLanguage, config.supportedLocales);
|
|
24
|
+
// ----------------------------------------------------------
|
|
25
|
+
// Resolve inbound routing decision (pure computation)
|
|
26
|
+
// ----------------------------------------------------------
|
|
27
|
+
let inbound;
|
|
28
|
+
if (isSvelteKitSSG(event)) {
|
|
29
|
+
inbound = {
|
|
30
|
+
locale: event.params?.locale,
|
|
31
|
+
localeSource: "path",
|
|
32
|
+
pathname: event.url.pathname,
|
|
33
|
+
shouldRedirect: false,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
inbound = await resolveInbound(config, event.url.pathname, false, {
|
|
38
|
+
host: event.url.host,
|
|
39
|
+
query: normalizeQuery(Object.fromEntries(event.url.searchParams.entries())),
|
|
40
|
+
cookie: event.cookies.get(config.cookie.name),
|
|
41
|
+
detected: localeFromAcceptLanguage || config.defaultLocale,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const { locale, localeSource, pathname, shouldRedirect } = inbound;
|
|
45
|
+
// ----------------------------------------------------------
|
|
46
|
+
// Redirect if needed
|
|
47
|
+
// ----------------------------------------------------------
|
|
48
|
+
if (shouldRedirect)
|
|
49
|
+
redirect(307, pathname);
|
|
50
|
+
// ----------------------------------------------------------
|
|
51
|
+
// Bind inbound routing context
|
|
52
|
+
// ----------------------------------------------------------
|
|
53
|
+
// @ts-expect-error - App.Locals must be extended by user
|
|
54
|
+
event.locals.intor = {
|
|
55
|
+
locale,
|
|
56
|
+
localeSource,
|
|
57
|
+
pathname,
|
|
58
|
+
};
|
|
59
|
+
const response = await resolve(event, {
|
|
60
|
+
transformPageChunk: ({ html }) => html.replace("%lang%", locale),
|
|
61
|
+
});
|
|
62
|
+
return response;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { createIntorHandle };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import '../../../core/error/intor-error.js';
|
|
2
|
+
import 'logry';
|
|
3
|
+
import 'p-limit';
|
|
4
|
+
import { intor as intor$1 } from '../../../server/intor/intor.js';
|
|
5
|
+
import 'node:path';
|
|
6
|
+
import 'node:fs/promises';
|
|
7
|
+
import 'intor-translator';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Initializes Intor for the current execution context.
|
|
11
|
+
*
|
|
12
|
+
* - Uses the locale resolved by the SvelteKit request lifecycle.
|
|
13
|
+
* - Permits cache writes during server execution.
|
|
14
|
+
* @platform SvelteKit
|
|
15
|
+
*/
|
|
16
|
+
async function intor(config, locale, fetch, options) {
|
|
17
|
+
return await intor$1(config, locale, {
|
|
18
|
+
readers: options?.readers,
|
|
19
|
+
allowCacheWrite: options?.allowCacheWrite ?? true,
|
|
20
|
+
fetch,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { intor };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic to detect static (prerender) execution in SvelteKit.
|
|
3
|
+
*
|
|
4
|
+
* This is NOT a guaranteed signal.
|
|
5
|
+
* It intentionally prefers false positives over false negatives.
|
|
6
|
+
*/
|
|
7
|
+
function isSvelteKitSSG(event) {
|
|
8
|
+
// No user-agent is a strong signal of static rendering
|
|
9
|
+
if (event.request.headers.get("user-agent") === null) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { isSvelteKitSSG };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import '../../../core/error/intor-error.js';
|
|
2
|
+
import 'logry';
|
|
3
|
+
import 'p-limit';
|
|
4
|
+
import { shouldSyncLocale } from '../../../policies/should-sync-locale.js';
|
|
5
|
+
import { setLocaleCookie } from '../utils/locale/set-locale-cookie.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Executes a resolved navigation result.
|
|
9
|
+
*
|
|
10
|
+
* Applies all imperative side effects required to complete navigation,
|
|
11
|
+
* including locale synchronization, cookie persistence, and full reloads.
|
|
12
|
+
*
|
|
13
|
+
* This function must be called after `resolveNavigation`.
|
|
14
|
+
*/
|
|
15
|
+
function executeNavigation(navigationResult, context, e) {
|
|
16
|
+
const { config, currentLocale, setLocale } = context;
|
|
17
|
+
const { cookie } = config;
|
|
18
|
+
const { destination, kind, locale } = navigationResult;
|
|
19
|
+
// ------------------------------------------------------
|
|
20
|
+
// External navigation: let browser handle it
|
|
21
|
+
// ------------------------------------------------------
|
|
22
|
+
if (kind === "external") {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// ------------------------------------------------------
|
|
26
|
+
// Full reload: commit locale side effects, then perform document reload
|
|
27
|
+
// ------------------------------------------------------
|
|
28
|
+
if (kind === "reload") {
|
|
29
|
+
if (shouldSyncLocale(locale, currentLocale)) {
|
|
30
|
+
if (cookie.persist) {
|
|
31
|
+
setLocaleCookie(cookie, locale);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
globalThis.location.href = destination;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// ------------------------------------------------------
|
|
38
|
+
// Client-side navigation only
|
|
39
|
+
// ------------------------------------------------------
|
|
40
|
+
if (shouldSyncLocale(locale, currentLocale)) {
|
|
41
|
+
// Eagerly persist locale to avoid stale cookie during client-side navigation.
|
|
42
|
+
if (cookie.persist) {
|
|
43
|
+
setLocaleCookie(cookie, locale);
|
|
44
|
+
}
|
|
45
|
+
setLocale(locale);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { executeNavigation };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a serialized cookie string.
|
|
3
|
+
*/
|
|
4
|
+
const buildCookieString = (cookieOptions, value) => {
|
|
5
|
+
const { name, maxAge, path, domain, sameSite, secure } = cookieOptions;
|
|
6
|
+
// Cookie name and encoded value
|
|
7
|
+
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
8
|
+
// Add expiration and max-age if provided
|
|
9
|
+
if (maxAge) {
|
|
10
|
+
const expires = new Date(Date.now() + maxAge * 1000).toUTCString();
|
|
11
|
+
parts.push(`expires=${expires}`, `max-age=${maxAge}`);
|
|
12
|
+
}
|
|
13
|
+
// Set path (default to "/")
|
|
14
|
+
parts.push(`path=${path ?? "/"}`);
|
|
15
|
+
// Add domain if specified
|
|
16
|
+
if (domain) {
|
|
17
|
+
parts.push(`domain=${domain}`);
|
|
18
|
+
}
|
|
19
|
+
// Add SameSite policy (e.g., Lax, Strict)
|
|
20
|
+
if (sameSite) {
|
|
21
|
+
parts.push(`SameSite=${sameSite[0].toUpperCase()}${sameSite.slice(1).toLowerCase()}`);
|
|
22
|
+
}
|
|
23
|
+
// Add Secure flag if not explicitly disabled
|
|
24
|
+
if (secure !== false) {
|
|
25
|
+
parts.push(`Secure`);
|
|
26
|
+
}
|
|
27
|
+
return parts.join("; ");
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { buildCookieString };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { buildCookieString } from '../build-cookie-string.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Persist locale to a cookie.
|
|
5
|
+
*
|
|
6
|
+
* This function relies on `document.cookie`.
|
|
7
|
+
*/
|
|
8
|
+
const setLocaleCookie = (cookieOptions, locale) => {
|
|
9
|
+
if (typeof document === "undefined")
|
|
10
|
+
return;
|
|
11
|
+
// Build and apply the cookie string
|
|
12
|
+
document.cookie = buildCookieString(cookieOptions, locale);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { setLocaleCookie };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var IntorErrorCode;
|
|
2
|
+
(function (IntorErrorCode) {
|
|
3
|
+
// config
|
|
4
|
+
IntorErrorCode["INVALID_CONFIG_ID"] = "INTOR_INVALID_CONFIG_ID";
|
|
5
|
+
IntorErrorCode["MISSING_SUPPORTED_LOCALES"] = "INTOR_MISSING_SUPPORTED_LOCALES";
|
|
6
|
+
IntorErrorCode["UNSUPPORTED_DEFAULT_LOCALE"] = "INTOR_UNSUPPORTED_DEFAULT_LOCALE";
|
|
7
|
+
})(IntorErrorCode || (IntorErrorCode = {}));
|
|
8
|
+
|
|
9
|
+
export { IntorErrorCode };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { logry } from 'logry';
|
|
2
|
+
import { getGlobalLoggerPool } from './global-logger-pool.js';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_FORMAT_CONFIG = {
|
|
5
|
+
timestamp: { withDate: false },
|
|
6
|
+
};
|
|
7
|
+
const DEFAULT_RENDER_CONFIG = {
|
|
8
|
+
timestamp: {},
|
|
9
|
+
id: { visible: true, prefix: "<", suffix: ">" },
|
|
10
|
+
meta: { lineBreaksAfter: 1 },
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Get a shared logger instance by id.
|
|
14
|
+
* - Safe across hot reloads
|
|
15
|
+
* - Prevents unbounded memory usage via soft LRU
|
|
16
|
+
*/
|
|
17
|
+
function getLogger({ id = "default", formatConfig, renderConfig, preset, ...options }) {
|
|
18
|
+
const pool = getGlobalLoggerPool();
|
|
19
|
+
let logger = pool.get(id);
|
|
20
|
+
if (!logger) {
|
|
21
|
+
logger = logry({
|
|
22
|
+
id,
|
|
23
|
+
formatConfig: !formatConfig && !preset ? DEFAULT_FORMAT_CONFIG : formatConfig,
|
|
24
|
+
renderConfig: !renderConfig && !preset ? DEFAULT_RENDER_CONFIG : renderConfig,
|
|
25
|
+
preset,
|
|
26
|
+
...options,
|
|
27
|
+
});
|
|
28
|
+
pool.set(id, logger);
|
|
29
|
+
// Soft LRU: keep pool size under control
|
|
30
|
+
if (pool.size > 1000) {
|
|
31
|
+
const keys = [...pool.keys()];
|
|
32
|
+
for (const key of keys.slice(0, 200))
|
|
33
|
+
pool.delete(key);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return logger;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { getLogger };
|