intor 2.3.31 → 2.3.32

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.
Files changed (144) hide show
  1. package/dist/core/export/index.js +1 -1
  2. package/dist/core/export/server/index.js +1 -1
  3. package/dist/core/src/config/resolvers/resolve-fallback-locales.js +1 -0
  4. package/dist/core/src/config/resolvers/resolve-routing-options.js +1 -0
  5. package/dist/core/src/config/validators/validate-default-locale.js +1 -0
  6. package/dist/core/src/config/validators/validate-id.js +1 -0
  7. package/dist/core/src/config/validators/validate-supported-locales.js +1 -0
  8. package/dist/{svelte/src/client/svelte/render/create-svelte-renderer.js → core/src/core/render/create-html-renderer.js} +6 -7
  9. package/dist/{svelte/src/client/svelte → core/src/core}/render/utils/render-attributes.js +7 -5
  10. package/dist/core/src/core/translator/create-t-rich.js +22 -0
  11. package/dist/core/src/routing/pathname/canonicalize-pathname.js +1 -0
  12. package/dist/core/src/routing/pathname/materialize-pathname.js +1 -0
  13. package/dist/core/src/routing/pathname/standardize-pathname.js +1 -0
  14. package/dist/core/src/server/helpers/get-translator.js +12 -3
  15. package/dist/core/src/server/intor/intor.js +1 -0
  16. package/dist/core/src/server/messages/load-local-messages/load-local-messages.js +1 -0
  17. package/dist/core/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
  18. package/dist/core/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
  19. package/dist/core/src/server/messages/load-messages.js +1 -0
  20. package/dist/core/src/server/translator/create-translator.js +5 -15
  21. package/dist/core/src/server/translator/init-translator.js +6 -12
  22. package/dist/express/src/adapters/express/helpers/get-translator.js +1 -1
  23. package/dist/express/src/adapters/express/middleware/create-intor-middleware.js +3 -3
  24. package/dist/express/src/core/render/create-html-renderer.js +44 -0
  25. package/dist/express/src/core/render/utils/escape-html.js +10 -0
  26. package/dist/express/src/core/render/utils/render-attributes.js +17 -0
  27. package/dist/express/src/core/translator/create-t-rich.js +22 -0
  28. package/dist/express/src/routing/inbound/resolve-locale/resolve-locale.js +1 -0
  29. package/dist/express/src/routing/locale/get-locale-from-pathname.js +1 -0
  30. package/dist/express/src/routing/pathname/canonicalize-pathname.js +1 -0
  31. package/dist/express/src/routing/pathname/materialize-pathname.js +1 -0
  32. package/dist/express/src/routing/pathname/standardize-pathname.js +1 -0
  33. package/dist/express/src/server/helpers/get-translator.js +12 -3
  34. package/dist/express/src/server/messages/load-local-messages/load-local-messages.js +1 -0
  35. package/dist/express/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
  36. package/dist/express/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
  37. package/dist/express/src/server/messages/load-messages.js +1 -0
  38. package/dist/express/src/server/translator/create-translator.js +5 -15
  39. package/dist/express/src/server/translator/init-translator.js +6 -12
  40. package/dist/next/src/adapters/next/navigation/link.js +1 -0
  41. package/dist/next/src/adapters/next/navigation/redirect.js +1 -0
  42. package/dist/next/src/adapters/next/navigation/use-router.js +1 -0
  43. package/dist/next/src/adapters/next/proxy/intor-proxy.js +1 -0
  44. package/dist/next/src/adapters/next/server/get-locale.js +1 -0
  45. package/dist/next/src/adapters/next/server/get-translator.js +1 -1
  46. package/dist/next/src/adapters/next/server/intor.js +1 -1
  47. package/dist/next/src/client/shared/navigation/execute-navigation.js +1 -0
  48. package/dist/next/src/core/render/create-html-renderer.js +44 -0
  49. package/dist/next/src/core/render/utils/escape-html.js +10 -0
  50. package/dist/next/src/core/render/utils/render-attributes.js +17 -0
  51. package/dist/next/src/core/translator/create-t-rich.js +22 -0
  52. package/dist/next/src/policies/shoud-full-reload.js +1 -0
  53. package/dist/next/src/routing/inbound/resolve-locale/resolve-locale.js +1 -0
  54. package/dist/next/src/routing/locale/get-locale-from-pathname.js +1 -0
  55. package/dist/next/src/routing/pathname/canonicalize-pathname.js +1 -0
  56. package/dist/next/src/routing/pathname/materialize-pathname.js +1 -0
  57. package/dist/next/src/routing/pathname/standardize-pathname.js +1 -0
  58. package/dist/next/src/server/helpers/get-translator.js +12 -3
  59. package/dist/next/src/server/intor/intor.js +1 -0
  60. package/dist/next/src/server/messages/load-local-messages/load-local-messages.js +1 -0
  61. package/dist/next/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
  62. package/dist/next/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
  63. package/dist/next/src/server/messages/load-messages.js +1 -0
  64. package/dist/next/src/server/translator/create-translator.js +5 -15
  65. package/dist/next/src/server/translator/init-translator.js +6 -12
  66. package/dist/react/src/client/react/helpers/use-intor.js +1 -0
  67. package/dist/react/src/client/react/provider/effects/use-locale-effects.js +1 -0
  68. package/dist/react/src/client/react/render/create-react-renderer.js +0 -1
  69. package/dist/react/src/client/react/translator/create-t-rich.js +7 -4
  70. package/dist/react/src/client/react/translator/use-translator.js +3 -3
  71. package/dist/react/src/client/shared/helpers/get-client-locale.js +1 -0
  72. package/dist/react/src/client/shared/messages/create-refetch-messages.js +1 -0
  73. package/dist/svelte/src/client/shared/helpers/get-client-locale.js +1 -0
  74. package/dist/svelte/src/client/shared/messages/create-refetch-messages.js +1 -0
  75. package/dist/svelte/src/client/svelte/provider/effects/locale-effects.js +1 -0
  76. package/dist/svelte/src/client/svelte/provider/intor-provider.svelte +7 -2
  77. package/dist/svelte/src/client/svelte/translator/use-translator.js +5 -7
  78. package/dist/svelte/src/core/render/create-html-renderer.js +44 -0
  79. package/dist/svelte/src/core/render/utils/escape-html.js +10 -0
  80. package/dist/svelte/src/core/render/utils/render-attributes.js +17 -0
  81. package/dist/svelte/src/core/translator/create-t-rich.js +22 -0
  82. package/dist/svelte-kit/src/adapters/svelte-kit/navigation/use-navigation.js +1 -0
  83. package/dist/svelte-kit/src/adapters/svelte-kit/server/create-intor-handle.js +1 -0
  84. package/dist/svelte-kit/src/adapters/svelte-kit/server/intor.js +1 -1
  85. package/dist/svelte-kit/src/client/shared/navigation/execute-navigation.js +1 -0
  86. package/dist/svelte-kit/src/policies/shoud-full-reload.js +1 -0
  87. package/dist/svelte-kit/src/routing/inbound/resolve-locale/resolve-locale.js +1 -0
  88. package/dist/svelte-kit/src/routing/locale/get-locale-from-pathname.js +1 -0
  89. package/dist/svelte-kit/src/routing/pathname/canonicalize-pathname.js +1 -0
  90. package/dist/svelte-kit/src/routing/pathname/materialize-pathname.js +1 -0
  91. package/dist/svelte-kit/src/routing/pathname/standardize-pathname.js +1 -0
  92. package/dist/svelte-kit/src/server/intor/intor.js +1 -0
  93. package/dist/svelte-kit/src/server/messages/load-local-messages/load-local-messages.js +1 -0
  94. package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +1 -0
  95. package/dist/svelte-kit/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +1 -0
  96. package/dist/svelte-kit/src/server/messages/load-messages.js +1 -0
  97. package/dist/svelte-kit/src/server/translator/create-translator.js +5 -15
  98. package/dist/svelte-kit/src/server/translator/init-translator.js +6 -12
  99. package/dist/types/export/internal/index.d.ts +1 -1
  100. package/dist/types/export/svelte/index.d.ts +1 -1
  101. package/dist/types/src/client/react/render/index.d.ts +1 -1
  102. package/dist/types/src/client/react/render/types.d.ts +2 -6
  103. package/dist/types/src/client/react/translator/create-t-rich.d.ts +2 -2
  104. package/dist/types/src/client/react/translator/translator-instance.d.ts +1 -1
  105. package/dist/types/src/client/svelte/index.d.ts +1 -1
  106. package/dist/types/src/client/svelte/provider/index.d.ts +1 -0
  107. package/dist/types/src/client/svelte/provider/types.d.ts +4 -0
  108. package/dist/types/src/client/svelte/translator/translator-instance.d.ts +3 -4
  109. package/dist/types/src/client/vue/render/index.d.ts +1 -1
  110. package/dist/types/src/client/vue/render/types.d.ts +2 -6
  111. package/dist/types/src/client/vue/translator/create-t-rich.d.ts +2 -3
  112. package/dist/types/src/client/vue/translator/translator-instance.d.ts +1 -1
  113. package/dist/types/src/core/index.d.ts +2 -0
  114. package/dist/types/src/core/render/create-html-renderer.d.ts +11 -0
  115. package/dist/types/src/core/render/index.d.ts +2 -0
  116. package/dist/types/src/core/render/types.d.ts +10 -0
  117. package/dist/types/src/core/translator/create-t-rich.d.ts +12 -0
  118. package/dist/types/src/core/translator/index.d.ts +1 -0
  119. package/dist/types/src/server/helpers/get-translator.d.ts +4 -4
  120. package/dist/types/src/server/translator/create-translator.d.ts +5 -13
  121. package/dist/types/src/server/translator/init-translator.d.ts +6 -7
  122. package/dist/types/src/server/translator/translator-instance.d.ts +5 -3
  123. package/dist/vue/src/client/shared/helpers/get-client-locale.js +1 -0
  124. package/dist/vue/src/client/shared/messages/create-refetch-messages.js +1 -0
  125. package/dist/vue/src/client/vue/helpers/use-intor.js +1 -0
  126. package/dist/vue/src/client/vue/provider/effects/use-locale-effects.js +1 -0
  127. package/dist/vue/src/client/vue/render/create-vue-renderer.js +0 -1
  128. package/dist/vue/src/client/vue/translator/create-t-rich.js +6 -8
  129. package/dist/vue/src/client/vue/translator/use-translator.js +4 -6
  130. package/package.json +15 -15
  131. package/dist/react/src/client/react/render/render-rich-message-react.js +0 -22
  132. package/dist/svelte/src/client/svelte/render/render-rich-message-svelte.js +0 -20
  133. package/dist/svelte/src/client/svelte/translator/create-t-rich.js +0 -23
  134. package/dist/types/src/client/react/render/render-rich-message-react.d.ts +0 -14
  135. package/dist/types/src/client/svelte/render/create-svelte-renderer.d.ts +0 -14
  136. package/dist/types/src/client/svelte/render/index.d.ts +0 -2
  137. package/dist/types/src/client/svelte/render/render-rich-message-svelte.d.ts +0 -12
  138. package/dist/types/src/client/svelte/render/types.d.ts +0 -8
  139. package/dist/types/src/client/svelte/translator/create-t-rich.d.ts +0 -15
  140. package/dist/types/src/client/vue/render/render-rich-message-vue.d.ts +0 -14
  141. package/dist/vue/src/client/vue/render/render-rich-message-vue.js +0 -19
  142. /package/dist/{svelte/src/client/svelte → core/src/core}/render/utils/escape-html.js +0 -0
  143. /package/dist/types/src/{client/svelte → core}/render/utils/escape-html.d.ts +0 -0
  144. /package/dist/types/src/{client/svelte → core}/render/utils/render-attributes.d.ts +0 -0
@@ -2,19 +2,20 @@ import '../../core/error/intor-error.js';
2
2
  import { resolveLoaderOptions } from '../../core/utils/resolve-loader-options.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
  import { loadMessages } from '../messages/load-messages.js';
6
7
  import 'node:path';
7
8
  import 'node:fs/promises';
8
9
  import { createTranslator } from './create-translator.js';
9
10
 
10
11
  /**
11
- * Initializes a server-side translator for a specific locale.
12
+ * Initialize a locale-bound Translator snapshot.
12
13
  *
13
- * - Performs message loading during initialization.
14
- * - Returns an immutable translator snapshot.
14
+ * - Resolves loader options and loads messages if configured
15
+ * - Creates an immutable Translator instance for server usage
15
16
  */
16
17
  async function initTranslator(config, locale, options) {
17
- const { readers, allowCacheWrite = false, fetch, preKey, handlers, plugins, } = options;
18
+ const { readers, allowCacheWrite = false, fetch, handlers, plugins, } = options;
18
19
  const loader = resolveLoaderOptions(config);
19
20
  // Load messages
20
21
  let messages = {};
@@ -29,14 +30,7 @@ async function initTranslator(config, locale, options) {
29
30
  messages = loaded || {};
30
31
  }
31
32
  // Create immutable translator snapshot
32
- return createTranslator({
33
- config,
34
- locale,
35
- messages,
36
- preKey,
37
- handlers,
38
- plugins,
39
- });
33
+ return createTranslator({ config, locale, messages, handlers, plugins });
40
34
  }
41
35
 
42
36
  export { initTranslator };
@@ -9,6 +9,7 @@ import { useIntorContext } from 'intor/react';
9
9
  import '../../../core/error/intor-error.js';
10
10
  import 'logry';
11
11
  import 'p-limit';
12
+ import 'intor-translator';
12
13
  import { resolveNavigation } from '../../../routing/navigation/resolve-navigation.js';
13
14
 
14
15
  /**
@@ -2,6 +2,7 @@ import { redirect as redirect$1 } from 'next/navigation';
2
2
  import '../../../core/error/intor-error.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
  import { resolveNavigation } from '../../../routing/navigation/resolve-navigation.js';
6
7
  import { getLocale } from '../server/get-locale.js';
7
8
 
@@ -4,6 +4,7 @@ import { useIntorContext } from 'intor/react';
4
4
  import '../../../core/error/intor-error.js';
5
5
  import 'logry';
6
6
  import 'p-limit';
7
+ import 'intor-translator';
7
8
  import { resolveNavigation } from '../../../routing/navigation/resolve-navigation.js';
8
9
 
9
10
  /**
@@ -4,6 +4,7 @@ import '../../../core/error/intor-error.js';
4
4
  import { normalizeQuery } from '../../../core/utils/normalizers/normalize-query.js';
5
5
  import 'logry';
6
6
  import 'p-limit';
7
+ import 'intor-translator';
7
8
  import { resolveInbound } from '../../../routing/inbound/resolve-inbound.js';
8
9
  import { getLocaleFromAcceptLanguage } from '../../../routing/locale/get-locale-from-accept-language.js';
9
10
 
@@ -4,6 +4,7 @@ import '../../../core/error/intor-error.js';
4
4
  import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
5
5
  import 'logry';
6
6
  import 'p-limit';
7
+ import 'intor-translator';
7
8
 
8
9
  /**
9
10
  * Get the locale for the current execution context.
@@ -1,9 +1,9 @@
1
1
  import '../../../core/error/intor-error.js';
2
2
  import 'logry';
3
3
  import 'p-limit';
4
+ import 'intor-translator';
4
5
  import 'node:path';
5
6
  import 'node:fs/promises';
6
- import 'intor-translator';
7
7
  import { getTranslator as getTranslator$1 } from '../../../server/helpers/get-translator.js';
8
8
  import { getLocale } from './get-locale.js';
9
9
 
@@ -1,10 +1,10 @@
1
1
  import '../../../core/error/intor-error.js';
2
2
  import 'logry';
3
3
  import 'p-limit';
4
+ import 'intor-translator';
4
5
  import { intor as intor$1 } from '../../../server/intor/intor.js';
5
6
  import 'node:path';
6
7
  import 'node:fs/promises';
7
- import 'intor-translator';
8
8
  import { getLocale } from './get-locale.js';
9
9
 
10
10
  /**
@@ -1,6 +1,7 @@
1
1
  import '../../../core/error/intor-error.js';
2
2
  import 'logry';
3
3
  import 'p-limit';
4
+ import 'intor-translator';
4
5
  import { shouldSyncLocale } from '../../../policies/should-sync-locale.js';
5
6
  import { setLocaleCookie } from '../utils/locale/set-locale-cookie.js';
6
7
 
@@ -0,0 +1,44 @@
1
+ import { escapeHtml } from './utils/escape-html.js';
2
+ import { renderAttributes } from './utils/render-attributes.js';
3
+
4
+ /**
5
+ * Create an HTML string renderer for semantic rich messages.
6
+ *
7
+ * - Transforms semantic rich AST nodes into escaped HTML strings.
8
+ * - Can be used in any HTML-based environment.
9
+ *
10
+ * This renderer is intentionally minimal and stateless.
11
+ */
12
+ const createHtmlRenderer = (tagRenderers) => {
13
+ return {
14
+ /** Render plain text nodes */
15
+ text(value) {
16
+ return escapeHtml(value);
17
+ },
18
+ /** Render semantic tag nodes */
19
+ tag(name, attributes, children) {
20
+ const tagRenderer = tagRenderers?.[name];
21
+ if (tagRenderer) {
22
+ return typeof tagRenderer === "function"
23
+ ? tagRenderer(children)
24
+ : tagRenderer;
25
+ }
26
+ // Default behavior: render as native HTML tag
27
+ return `<${name}${renderAttributes(attributes)}>${children.join("")}</${name}>`;
28
+ },
29
+ /** Render raw (non-tokenized) message values as escaped HTML strings */
30
+ raw(value) {
31
+ if (value == null)
32
+ return "";
33
+ if (typeof value === "string" || typeof value === "number") {
34
+ return escapeHtml(String(value));
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value.map((v) => escapeHtml(String(v))).join("");
38
+ }
39
+ throw new Error("[intor] HTML renderer cannot render raw non-primitive values.");
40
+ },
41
+ };
42
+ };
43
+
44
+ export { createHtmlRenderer };
@@ -0,0 +1,10 @@
1
+ function escapeHtml(value) {
2
+ return value
3
+ .replaceAll("&", "&amp;")
4
+ .replaceAll("<", "&lt;")
5
+ .replaceAll(">", "&gt;")
6
+ .replaceAll('"', "&quot;")
7
+ .replaceAll("'", "&#39;");
8
+ }
9
+
10
+ export { escapeHtml };
@@ -0,0 +1,17 @@
1
+ import { escapeHtml } from './escape-html.js';
2
+
3
+ function renderAttributes(attributes) {
4
+ if (!attributes)
5
+ return "";
6
+ return Object.entries(attributes)
7
+ .map(([key, value]) => {
8
+ if (value === true)
9
+ return ` ${key}`;
10
+ if (value == null)
11
+ return "";
12
+ return ` ${key}="${escapeHtml(String(value))}"`;
13
+ })
14
+ .join("");
15
+ }
16
+
17
+ export { renderAttributes };
@@ -0,0 +1,22 @@
1
+ import { renderRichMessage } from 'intor-translator';
2
+ import { createHtmlRenderer } from '../render/create-html-renderer.js';
3
+
4
+ /**
5
+ * Create an HTML-string rich translation function.
6
+ *
7
+ * - Resolves translated messages via `translator.t`
8
+ * - Renders semantic rich tags into escaped HTML strings
9
+ * - Supports optional scoped keys via `preKey`
10
+ *
11
+ * Can be used in any HTML-based environment (Astro, Svelte, SSR, etc.).
12
+ */
13
+ const createTRich = (t) => {
14
+ return (key, tagRenderers, replacements) => {
15
+ const message = t(key, replacements);
16
+ const renderer = createHtmlRenderer(tagRenderers);
17
+ const nodes = renderRichMessage(message, renderer);
18
+ return nodes.join("");
19
+ };
20
+ };
21
+
22
+ export { createTRich };
@@ -2,6 +2,7 @@ import '../core/error/intor-error.js';
2
2
  import { resolveLoaderOptions } from '../core/utils/resolve-loader-options.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
 
6
7
  /**
7
8
  * Determine whether client-side navigation must be forced to reload.
@@ -2,6 +2,7 @@ import '../../../core/error/intor-error.js';
2
2
  import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
 
6
7
  /**
7
8
  * Resolve the active locale from inbound routing configuration.
@@ -2,6 +2,7 @@ import '../../core/error/intor-error.js';
2
2
  import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
 
6
7
  /**
7
8
  * Get locale from pathname.
@@ -3,6 +3,7 @@ import '../../core/error/intor-error.js';
3
3
  import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
4
4
  import 'logry';
5
5
  import 'p-limit';
6
+ import 'intor-translator';
6
7
 
7
8
  /**
8
9
  * Returns a canonical, locale-agnostic pathname.
@@ -3,6 +3,7 @@ import '../../core/error/intor-error.js';
3
3
  import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
4
4
  import 'logry';
5
5
  import 'p-limit';
6
+ import 'intor-translator';
6
7
 
7
8
  /**
8
9
  * Materializes a standardized pathname by applying
@@ -3,6 +3,7 @@ import '../../core/error/intor-error.js';
3
3
  import { normalizePathname } from '../../core/utils/normalizers/normalize-pathname.js';
4
4
  import 'logry';
5
5
  import 'p-limit';
6
+ import 'intor-translator';
6
7
 
7
8
  /**
8
9
  * Standardizes a canonical pathname into an internal routing template
@@ -1,3 +1,7 @@
1
+ import '../../core/error/intor-error.js';
2
+ import 'logry';
3
+ import 'p-limit';
4
+ import { createTRich } from '../../core/translator/create-t-rich.js';
1
5
  import { initTranslator } from '../translator/init-translator.js';
2
6
 
3
7
  // Implementation
@@ -8,15 +12,20 @@ async function getTranslator(config, params) {
8
12
  readers,
9
13
  allowCacheWrite,
10
14
  fetch: fetch || globalThis.fetch,
11
- preKey,
12
15
  plugins,
13
16
  handlers,
14
17
  });
18
+ const scoped = translator.scoped(preKey);
15
19
  return {
16
20
  messages: translator.messages,
17
21
  locale: translator.locale,
18
- hasKey: translator.hasKey,
19
- t: translator.t,
22
+ hasKey: scoped.hasKey,
23
+ t: scoped.t,
24
+ tRich: createTRich(scoped.t),
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
20
29
  };
21
30
  }
22
31
 
@@ -1,6 +1,7 @@
1
1
  import '../../core/error/intor-error.js';
2
2
  import { getLogger } from '../../core/logger/get-logger.js';
3
3
  import 'p-limit';
4
+ import 'intor-translator';
4
5
  import { initTranslator } from '../translator/init-translator.js';
5
6
 
6
7
  /**
@@ -3,6 +3,7 @@ import pLimit from 'p-limit';
3
3
  import '../../../core/error/intor-error.js';
4
4
  import { normalizeCacheKey } from '../../../core/utils/normalizers/normalize-cache-key.js';
5
5
  import { getLogger } from '../../../core/logger/get-logger.js';
6
+ import 'intor-translator';
6
7
  import { getMessagesPool } from './cache/messages-pool.js';
7
8
  import { readLocaleMessages } from './read-locale-messages/read-locale-messages.js';
8
9
 
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import '../../../../../core/error/intor-error.js';
4
4
  import { getLogger } from '../../../../../core/logger/get-logger.js';
5
5
  import 'p-limit';
6
+ import 'intor-translator';
6
7
 
7
8
  /**
8
9
  * Recursively collects message file metadata under a given locale root.
@@ -5,6 +5,7 @@ import { getLogger } from '../../../../../core/logger/get-logger.js';
5
5
  import 'p-limit';
6
6
  import { isValidMessages } from '../../../../../core/messages/utils/is-valid-messages.js';
7
7
  import { nestObjectFromPath } from '../../../../../core/messages/utils/nest-object-from-path.js';
8
+ import 'intor-translator';
8
9
  import { jsonReader } from './utils/json-reader.js';
9
10
 
10
11
  /**
@@ -2,6 +2,7 @@ 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 'intor-translator';
5
6
  import { loadLocalMessages } from './load-local-messages/load-local-messages.js';
6
7
 
7
8
  /**
@@ -2,17 +2,14 @@ import { Translator } from 'intor-translator';
2
2
  import { mergeMessages } from '../../core/messages/merge-messages.js';
3
3
 
4
4
  /**
5
- * Create a server-side translator snapshot.
5
+ * Create a server-side Translator instance for a fixed locale.
6
6
  *
7
7
  * - Merges static config messages with runtime-loaded messages
8
- * - Creates a Translator instance for a fixed locale
9
- * - Optionally scopes the translator with a preKey
10
- *
11
- * The returned object is a read-only translation view
12
- * and does not expose the underlying Translator instance.
8
+ * - Initializes a Translator bound to a specific locale
9
+ * - Injects fallback rules, handlers, and plugins from config
13
10
  */
14
11
  function createTranslator(params) {
15
- const { config, locale, messages, preKey, handlers, plugins } = params;
12
+ const { config, locale, messages, handlers, plugins } = params;
16
13
  // Merge static config messages with runtime-loaded messages
17
14
  const finalMessages = mergeMessages(config.messages, messages, {
18
15
  config,
@@ -27,14 +24,7 @@ function createTranslator(params) {
27
24
  handlers,
28
25
  plugins,
29
26
  });
30
- // Apply scoped view when preKey is provided
31
- const scoped = preKey ? translator.scoped(preKey) : null;
32
- return {
33
- messages: finalMessages,
34
- locale,
35
- hasKey: scoped ? scoped.hasKey : translator.hasKey,
36
- t: scoped ? scoped.t : translator.t,
37
- };
27
+ return translator;
38
28
  }
39
29
 
40
30
  export { createTranslator };
@@ -2,19 +2,20 @@ import '../../core/error/intor-error.js';
2
2
  import { resolveLoaderOptions } from '../../core/utils/resolve-loader-options.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
  import { loadMessages } from '../messages/load-messages.js';
6
7
  import 'node:path';
7
8
  import 'node:fs/promises';
8
9
  import { createTranslator } from './create-translator.js';
9
10
 
10
11
  /**
11
- * Initializes a server-side translator for a specific locale.
12
+ * Initialize a locale-bound Translator snapshot.
12
13
  *
13
- * - Performs message loading during initialization.
14
- * - Returns an immutable translator snapshot.
14
+ * - Resolves loader options and loads messages if configured
15
+ * - Creates an immutable Translator instance for server usage
15
16
  */
16
17
  async function initTranslator(config, locale, options) {
17
- const { readers, allowCacheWrite = false, fetch, preKey, handlers, plugins, } = options;
18
+ const { readers, allowCacheWrite = false, fetch, handlers, plugins, } = options;
18
19
  const loader = resolveLoaderOptions(config, "server");
19
20
  // Load messages
20
21
  let messages = {};
@@ -29,14 +30,7 @@ async function initTranslator(config, locale, options) {
29
30
  messages = loaded || {};
30
31
  }
31
32
  // Create immutable translator snapshot
32
- return createTranslator({
33
- config,
34
- locale,
35
- messages,
36
- preKey,
37
- handlers,
38
- plugins,
39
- });
33
+ return createTranslator({ config, locale, messages, handlers, plugins });
40
34
  }
41
35
 
42
36
  export { initTranslator };
@@ -3,6 +3,7 @@ import '../../../core/error/intor-error.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
5
  import { mergeMessages } from '../../../core/messages/merge-messages.js';
6
+ import 'intor-translator';
6
7
  import { getClientLocale } from '../../shared/helpers/get-client-locale.js';
7
8
 
8
9
  function useIntor(config, loader) {
@@ -4,6 +4,7 @@ import { shouldPersistOnFirstVisit } from '../../../../policies/should-persist-o
4
4
  import '../../../../core/error/intor-error.js';
5
5
  import 'logry';
6
6
  import 'p-limit';
7
+ import 'intor-translator';
7
8
  import { getLocaleFromCookie } from '../../../shared/utils/locale/get-locale-from-cookie.js';
8
9
  import { setLocaleCookie } from '../../../shared/utils/locale/set-locale-cookie.js';
9
10
  import { setDocumentLocale } from '../../../shared/utils/locale/set-document-locale.js';
@@ -11,7 +11,6 @@ const createReactRenderer = (tagRenderers) => {
11
11
  },
12
12
  /** Render semantic tag nodes */
13
13
  tag(name, _attributes, children) {
14
- // Custom tag renderers override
15
14
  const tagRenderer = tagRenderers?.[name];
16
15
  if (tagRenderer) {
17
16
  return typeof tagRenderer === "function"
@@ -1,4 +1,6 @@
1
- import { renderRichMessageReact } from '../render/render-rich-message-react.js';
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { renderRichMessage } from 'intor-translator';
3
+ import { createReactRenderer } from '../render/create-react-renderer.js';
2
4
 
3
5
  /**
4
6
  * Create a React-specific rich translation function.
@@ -12,11 +14,12 @@ import { renderRichMessageReact } from '../render/render-rich-message-react.js';
12
14
  *
13
15
  * Intended for React client usage only.
14
16
  */
15
- const createTRich = (translator, preKey) => {
16
- const t = preKey ? translator.scoped(preKey).t : translator.t;
17
+ const createTRich = (t) => {
17
18
  return (key, tagRenderers, replacements) => {
18
19
  const message = t(key, replacements);
19
- return renderRichMessageReact(message, tagRenderers);
20
+ const reactRenderer = createReactRenderer(tagRenderers);
21
+ const nodes = renderRichMessage(message, reactRenderer);
22
+ return nodes.map((node, index) => jsx(Fragment, { children: node }, index));
20
23
  };
21
24
  };
22
25
 
@@ -11,9 +11,9 @@ function useTranslator(preKey) {
11
11
  locale: translator.locale,
12
12
  isLoading: translator.isLoading,
13
13
  setLocale,
14
- hasKey: preKey ? scoped.hasKey : translator.hasKey,
15
- t: preKey ? scoped.t : translator.t,
16
- tRich: createTRich(translator, preKey),
14
+ hasKey: scoped.hasKey,
15
+ t: scoped.t,
16
+ tRich: createTRich(scoped.t),
17
17
  // NOTE:
18
18
  // The runtime implementation is intentionally erased.
19
19
  // Type safety is guaranteed by public type contracts.
@@ -2,6 +2,7 @@ import '../../../core/error/intor-error.js';
2
2
  import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
  import { detectBrowserLocale } from '../utils/locale/detect-browser-locale.js';
6
7
  import { getLocaleFromCookie } from '../utils/locale/get-locale-from-cookie.js';
7
8
 
@@ -3,6 +3,7 @@ import { resolveLoaderOptions } from '../../../core/utils/resolve-loader-options
3
3
  import 'logry';
4
4
  import { loadRemoteMessages } from '../../../core/messages/load-remote-messages/load-remote-messages.js';
5
5
  import { mergeMessages } from '../../../core/messages/merge-messages.js';
6
+ import 'intor-translator';
6
7
 
7
8
  /**
8
9
  * Creates a framework-agnostic message refetcher.
@@ -2,6 +2,7 @@ import '../../../core/error/intor-error.js';
2
2
  import { normalizeLocale } from '../../../core/utils/normalizers/normalize-locale.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
  import { detectBrowserLocale } from '../utils/locale/detect-browser-locale.js';
6
7
  import { getLocaleFromCookie } from '../utils/locale/get-locale-from-cookie.js';
7
8
 
@@ -3,6 +3,7 @@ import { resolveLoaderOptions } from '../../../core/utils/resolve-loader-options
3
3
  import 'logry';
4
4
  import { loadRemoteMessages } from '../../../core/messages/load-remote-messages/load-remote-messages.js';
5
5
  import { mergeMessages } from '../../../core/messages/merge-messages.js';
6
+ import 'intor-translator';
6
7
 
7
8
  /**
8
9
  * Creates a framework-agnostic message refetcher.
@@ -2,6 +2,7 @@ import { shouldPersistOnFirstVisit } from '../../../../policies/should-persist-o
2
2
  import '../../../../core/error/intor-error.js';
3
3
  import 'logry';
4
4
  import 'p-limit';
5
+ import 'intor-translator';
5
6
  import { getLocaleFromCookie } from '../../../shared/utils/locale/get-locale-from-cookie.js';
6
7
  import { setLocaleCookie } from '../../../shared/utils/locale/set-locale-cookie.js';
7
8
  import { setDocumentLocale } from '../../../shared/utils/locale/set-document-locale.js';
@@ -1,7 +1,12 @@
1
1
  <script lang="ts">
2
+ import type { IntorProviderProps } from "./types";
2
3
  import { createIntorStore } from "./create-intor-store";
3
- export let value;
4
+ const { value, children } = $props<{
5
+ value: IntorProviderProps["value"];
6
+ children: IntorProviderProps["children"];
7
+ }>();
8
+ // svelte-ignore state_referenced_locally
4
9
  createIntorStore(value);
5
10
  </script>
6
11
 
7
- <slot />
12
+ {@render children()}
@@ -1,19 +1,17 @@
1
1
  import { derived } from 'svelte/store';
2
- import 'intor-translator';
3
- import 'svelte';
4
2
  import '../../../core/error/intor-error.js';
5
3
  import 'logry';
6
4
  import 'p-limit';
5
+ import { createTRich } from '../../../core/translator/create-t-rich.js';
6
+ import 'intor-translator';
7
+ import 'svelte';
7
8
  import '../provider/intor-provider.svelte';
8
9
  import { useIntorContext } from '../provider/use-intor-context.js';
9
- import { createTRich } from './create-t-rich.js';
10
10
 
11
11
  // Implementation
12
12
  function useTranslator(preKey) {
13
13
  const { translator, locale, setLocale } = useIntorContext();
14
- const scoped = preKey
15
- ? derived(translator, ($t) => $t.scoped(preKey))
16
- : translator;
14
+ const scoped = derived(translator, ($t) => $t.scoped(preKey));
17
15
  return {
18
16
  messages: derived(translator, ($t) => $t.messages),
19
17
  locale,
@@ -21,7 +19,7 @@ function useTranslator(preKey) {
21
19
  setLocale,
22
20
  hasKey: derived(scoped, ($t) => $t.hasKey),
23
21
  t: derived(scoped, ($t) => $t.t),
24
- tRich: derived(translator, ($t) => createTRich($t, preKey)),
22
+ tRich: derived(scoped, ($t) => createTRich($t.t)),
25
23
  // NOTE:
26
24
  // The runtime implementation is intentionally erased.
27
25
  // Type safety is guaranteed by public type contracts.
@@ -0,0 +1,44 @@
1
+ import { escapeHtml } from './utils/escape-html.js';
2
+ import { renderAttributes } from './utils/render-attributes.js';
3
+
4
+ /**
5
+ * Create an HTML string renderer for semantic rich messages.
6
+ *
7
+ * - Transforms semantic rich AST nodes into escaped HTML strings.
8
+ * - Can be used in any HTML-based environment.
9
+ *
10
+ * This renderer is intentionally minimal and stateless.
11
+ */
12
+ const createHtmlRenderer = (tagRenderers) => {
13
+ return {
14
+ /** Render plain text nodes */
15
+ text(value) {
16
+ return escapeHtml(value);
17
+ },
18
+ /** Render semantic tag nodes */
19
+ tag(name, attributes, children) {
20
+ const tagRenderer = tagRenderers?.[name];
21
+ if (tagRenderer) {
22
+ return typeof tagRenderer === "function"
23
+ ? tagRenderer(children)
24
+ : tagRenderer;
25
+ }
26
+ // Default behavior: render as native HTML tag
27
+ return `<${name}${renderAttributes(attributes)}>${children.join("")}</${name}>`;
28
+ },
29
+ /** Render raw (non-tokenized) message values as escaped HTML strings */
30
+ raw(value) {
31
+ if (value == null)
32
+ return "";
33
+ if (typeof value === "string" || typeof value === "number") {
34
+ return escapeHtml(String(value));
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value.map((v) => escapeHtml(String(v))).join("");
38
+ }
39
+ throw new Error("[intor] HTML renderer cannot render raw non-primitive values.");
40
+ },
41
+ };
42
+ };
43
+
44
+ export { createHtmlRenderer };