intor 2.5.0 → 2.6.0

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 (322) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/dist/core/export/index.js +1 -0
  4. package/dist/core/src/client/shared/helpers/get-client-locale.js +5 -20
  5. package/dist/core/src/client/shared/utils/locale/detect-browser-locale.js +2 -8
  6. package/dist/core/src/client/shared/utils/locale/get-locale-from-cookie.js +5 -12
  7. package/dist/core/src/config/constants/cookie.js +9 -9
  8. package/dist/core/src/config/constants/routing.js +13 -14
  9. package/dist/core/src/config/define-intor-config.js +28 -44
  10. package/dist/core/src/config/resolvers/resolve-cookie-options.js +4 -4
  11. package/dist/core/src/config/resolvers/resolve-fallback-locales.js +33 -50
  12. package/dist/core/src/config/resolvers/resolve-routing-options.js +32 -61
  13. package/dist/core/src/config/validators/validate-default-locale.js +8 -13
  14. package/dist/core/src/config/validators/validate-id.js +8 -13
  15. package/dist/core/src/config/validators/validate-supported-locales.js +8 -13
  16. package/dist/core/src/core/constants/locale-placeholder.js +0 -1
  17. package/dist/core/src/core/error/intor-error.js +14 -29
  18. package/dist/core/src/core/locale/canonicalize-locale.js +7 -18
  19. package/dist/core/src/core/locale/match-locale.js +24 -50
  20. package/dist/core/src/core/locale/parse-locale.js +12 -22
  21. package/dist/core/src/core/logger/get-logger.js +26 -31
  22. package/dist/core/src/core/logger/global-logger-pool.js +4 -4
  23. package/dist/core/src/core/messages/internal-metadata.js +1 -1
  24. package/dist/core/src/core/messages/load-remote-messages/collect-remote-resources.js +13 -22
  25. package/dist/core/src/core/messages/load-remote-messages/fetch-remote-resource.js +30 -39
  26. package/dist/core/src/core/messages/load-remote-messages/load-remote-messages.js +72 -89
  27. package/dist/core/src/core/messages/load-remote-messages/resolve-remote-resources.js +7 -17
  28. package/dist/core/src/core/messages/merge-messages.js +17 -28
  29. package/dist/core/src/core/messages/utils/is-valid-messages.js +22 -37
  30. package/dist/core/src/core/messages/utils/nest-object-from-path.js +5 -17
  31. package/dist/core/src/core/render/create-html-renderer.js +29 -37
  32. package/dist/core/src/core/render/utils/escape-html.js +1 -6
  33. package/dist/core/src/core/render/utils/render-attributes.js +6 -11
  34. package/dist/core/src/core/translator/create-t-rich.js +6 -15
  35. package/dist/core/src/core/translator/create-translator.js +16 -24
  36. package/dist/core/src/core/utils/deep-merge.js +24 -42
  37. package/dist/core/src/core/utils/normalizers/normalize-cache-key.js +14 -40
  38. package/dist/core/src/core/utils/normalizers/normalize-pathname.js +19 -37
  39. package/dist/core/src/core/utils/normalizers/normalize-query.js +6 -20
  40. package/dist/core/src/core/utils/parse-cookie-header.js +11 -18
  41. package/dist/core/src/core/utils/resolve-loader-options.js +6 -32
  42. package/dist/core/src/edge/helpers/get-translator.js +14 -20
  43. package/dist/core/src/edge/translator/init-translator.js +23 -31
  44. package/dist/core/src/routing/inbound/helpers/resolve-inbound-from-request.js +21 -28
  45. package/dist/core/src/routing/inbound/resolve-inbound.js +22 -37
  46. package/dist/core/src/routing/inbound/resolve-locale/resolve-locale.js +22 -39
  47. package/dist/core/src/routing/inbound/resolve-pathname/resolve-pathname.js +24 -30
  48. package/dist/core/src/routing/inbound/resolve-pathname/strategies/all.js +10 -23
  49. package/dist/core/src/routing/inbound/resolve-pathname/strategies/except-default.js +11 -24
  50. package/dist/core/src/routing/inbound/resolve-pathname/strategies/none.js +1 -4
  51. package/dist/core/src/routing/locale/get-locale-from-accept-language.js +21 -36
  52. package/dist/core/src/routing/locale/get-locale-from-host.js +5 -28
  53. package/dist/core/src/routing/locale/get-locale-from-pathname.js +11 -37
  54. package/dist/core/src/routing/locale/get-locale-from-query.js +2 -17
  55. package/dist/core/src/routing/pathname/canonicalize-pathname.js +25 -67
  56. package/dist/core/src/routing/pathname/localize-pathname.js +12 -30
  57. package/dist/core/src/routing/pathname/materialize-pathname.js +9 -44
  58. package/dist/core/src/routing/pathname/standardize-pathname.js +6 -30
  59. package/dist/core/src/server/helpers/get-translator.js +26 -23
  60. package/dist/core/src/server/intor/intor.js +20 -25
  61. package/dist/core/src/server/messages/load-local-messages/cache/messages-pool.js +4 -7
  62. package/dist/core/src/server/messages/load-local-messages/load-local-messages.js +76 -92
  63. package/dist/core/src/server/messages/load-local-messages/read-locale-messages/collect-file-entries/collect-file-entries.js +59 -80
  64. package/dist/core/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/parse-file-entries.js +53 -87
  65. package/dist/core/src/server/messages/load-local-messages/read-locale-messages/parse-file-entries/utils/json-reader.js +3 -6
  66. package/dist/core/src/server/messages/load-local-messages/read-locale-messages/read-locale-messages.js +23 -35
  67. package/dist/core/src/server/messages/load-messages.js +56 -69
  68. package/dist/core/src/server/translator/init-translator.js +28 -30
  69. package/dist/express/src/adapters/express/create-intor-handler.js +35 -46
  70. package/dist/express/src/adapters/express/get-translator.js +2 -9
  71. package/dist/express/src/core/constants/locale-placeholder.js +0 -1
  72. package/dist/express/src/core/locale/canonicalize-locale.js +7 -18
  73. package/dist/express/src/core/locale/match-locale.js +24 -50
  74. package/dist/express/src/core/locale/parse-locale.js +12 -22
  75. package/dist/express/src/core/utils/normalizers/normalize-pathname.js +19 -37
  76. package/dist/express/src/core/utils/normalizers/normalize-query.js +6 -20
  77. package/dist/express/src/core/utils/parse-cookie-header.js +11 -18
  78. package/dist/express/src/routing/inbound/resolve-inbound.js +22 -37
  79. package/dist/express/src/routing/inbound/resolve-locale/resolve-locale.js +22 -39
  80. package/dist/express/src/routing/inbound/resolve-pathname/resolve-pathname.js +24 -30
  81. package/dist/express/src/routing/inbound/resolve-pathname/strategies/all.js +10 -23
  82. package/dist/express/src/routing/inbound/resolve-pathname/strategies/except-default.js +11 -24
  83. package/dist/express/src/routing/inbound/resolve-pathname/strategies/none.js +1 -4
  84. package/dist/express/src/routing/locale/get-locale-from-accept-language.js +21 -36
  85. package/dist/express/src/routing/locale/get-locale-from-host.js +5 -28
  86. package/dist/express/src/routing/locale/get-locale-from-pathname.js +11 -37
  87. package/dist/express/src/routing/locale/get-locale-from-query.js +2 -17
  88. package/dist/express/src/routing/pathname/canonicalize-pathname.js +25 -67
  89. package/dist/express/src/routing/pathname/localize-pathname.js +12 -30
  90. package/dist/express/src/routing/pathname/materialize-pathname.js +9 -44
  91. package/dist/express/src/routing/pathname/standardize-pathname.js +6 -30
  92. package/dist/fastify/src/adapters/fastify/create-intor-handler.js +35 -47
  93. package/dist/fastify/src/adapters/fastify/get-translator.js +2 -9
  94. package/dist/fastify/src/adapters/fastify/intor-fastify-plugin.js +29 -38
  95. package/dist/fastify/src/core/constants/locale-placeholder.js +0 -1
  96. package/dist/fastify/src/core/locale/canonicalize-locale.js +7 -18
  97. package/dist/fastify/src/core/locale/match-locale.js +24 -50
  98. package/dist/fastify/src/core/locale/parse-locale.js +12 -22
  99. package/dist/fastify/src/core/utils/normalizers/normalize-pathname.js +19 -37
  100. package/dist/fastify/src/core/utils/normalizers/normalize-query.js +6 -20
  101. package/dist/fastify/src/core/utils/parse-cookie-header.js +11 -18
  102. package/dist/fastify/src/routing/inbound/resolve-inbound.js +22 -37
  103. package/dist/fastify/src/routing/inbound/resolve-locale/resolve-locale.js +22 -39
  104. package/dist/fastify/src/routing/inbound/resolve-pathname/resolve-pathname.js +24 -30
  105. package/dist/fastify/src/routing/inbound/resolve-pathname/strategies/all.js +10 -23
  106. package/dist/fastify/src/routing/inbound/resolve-pathname/strategies/except-default.js +11 -24
  107. package/dist/fastify/src/routing/inbound/resolve-pathname/strategies/none.js +1 -4
  108. package/dist/fastify/src/routing/locale/get-locale-from-accept-language.js +21 -36
  109. package/dist/fastify/src/routing/locale/get-locale-from-host.js +5 -28
  110. package/dist/fastify/src/routing/locale/get-locale-from-pathname.js +11 -37
  111. package/dist/fastify/src/routing/locale/get-locale-from-query.js +2 -17
  112. package/dist/fastify/src/routing/pathname/canonicalize-pathname.js +25 -67
  113. package/dist/fastify/src/routing/pathname/localize-pathname.js +12 -30
  114. package/dist/fastify/src/routing/pathname/materialize-pathname.js +9 -44
  115. package/dist/fastify/src/routing/pathname/standardize-pathname.js +6 -30
  116. package/dist/hono/src/adapters/hono/create-intor-handler.js +33 -44
  117. package/dist/hono/src/adapters/hono/get-translator.js +2 -9
  118. package/dist/hono/src/core/constants/locale-placeholder.js +0 -1
  119. package/dist/hono/src/core/locale/canonicalize-locale.js +7 -18
  120. package/dist/hono/src/core/locale/match-locale.js +24 -50
  121. package/dist/hono/src/core/locale/parse-locale.js +12 -22
  122. package/dist/hono/src/core/utils/normalizers/normalize-pathname.js +19 -37
  123. package/dist/hono/src/core/utils/normalizers/normalize-query.js +6 -20
  124. package/dist/hono/src/core/utils/parse-cookie-header.js +11 -18
  125. package/dist/hono/src/routing/inbound/resolve-inbound.js +22 -37
  126. package/dist/hono/src/routing/inbound/resolve-locale/resolve-locale.js +22 -39
  127. package/dist/hono/src/routing/inbound/resolve-pathname/resolve-pathname.js +24 -30
  128. package/dist/hono/src/routing/inbound/resolve-pathname/strategies/all.js +10 -23
  129. package/dist/hono/src/routing/inbound/resolve-pathname/strategies/except-default.js +11 -24
  130. package/dist/hono/src/routing/inbound/resolve-pathname/strategies/none.js +1 -4
  131. package/dist/hono/src/routing/locale/get-locale-from-accept-language.js +21 -36
  132. package/dist/hono/src/routing/locale/get-locale-from-host.js +5 -28
  133. package/dist/hono/src/routing/locale/get-locale-from-pathname.js +11 -37
  134. package/dist/hono/src/routing/locale/get-locale-from-query.js +2 -17
  135. package/dist/hono/src/routing/pathname/canonicalize-pathname.js +25 -67
  136. package/dist/hono/src/routing/pathname/localize-pathname.js +12 -30
  137. package/dist/hono/src/routing/pathname/materialize-pathname.js +9 -44
  138. package/dist/hono/src/routing/pathname/standardize-pathname.js +6 -30
  139. package/dist/next/export/next/server/index.js +1 -0
  140. package/dist/next/src/adapters/next/create-intor-handler.js +39 -48
  141. package/dist/next/src/adapters/next/header-keys.js +9 -0
  142. package/dist/next/src/adapters/next/link.js +33 -28
  143. package/dist/next/src/adapters/next/redirect.js +12 -15
  144. package/dist/next/src/adapters/next/server/get-locale.js +13 -24
  145. package/dist/next/src/adapters/next/server/get-translator.js +2 -9
  146. package/dist/next/src/adapters/next/server/intor.js +5 -13
  147. package/dist/next/src/adapters/next/server/read-intor-url-state.js +13 -0
  148. package/dist/next/src/adapters/next/use-router.js +47 -66
  149. package/dist/next/src/client/shared/navigation/execute-navigation.js +20 -38
  150. package/dist/next/src/client/shared/utils/build-cookie-string.js +18 -27
  151. package/dist/next/src/client/shared/utils/locale/set-locale-cookie.js +2 -9
  152. package/dist/next/src/core/constants/locale-placeholder.js +0 -1
  153. package/dist/next/src/core/locale/canonicalize-locale.js +7 -18
  154. package/dist/next/src/core/locale/match-locale.js +24 -50
  155. package/dist/next/src/core/locale/parse-locale.js +12 -22
  156. package/dist/next/src/core/utils/normalizers/normalize-pathname.js +19 -37
  157. package/dist/next/src/core/utils/normalizers/normalize-query.js +6 -20
  158. package/dist/next/src/core/utils/resolve-loader-options.js +6 -29
  159. package/dist/next/src/policies/shoud-full-reload.js +2 -5
  160. package/dist/next/src/policies/should-sync-locale.js +1 -4
  161. package/dist/next/src/routing/inbound/resolve-inbound.js +24 -39
  162. package/dist/next/src/routing/inbound/resolve-locale/resolve-locale.js +22 -39
  163. package/dist/next/src/routing/inbound/resolve-pathname/resolve-pathname.js +24 -30
  164. package/dist/next/src/routing/inbound/resolve-pathname/strategies/all.js +13 -29
  165. package/dist/next/src/routing/inbound/resolve-pathname/strategies/except-default.js +14 -30
  166. package/dist/next/src/routing/inbound/resolve-pathname/strategies/none.js +1 -4
  167. package/dist/next/src/routing/locale/get-locale-from-accept-language.js +21 -36
  168. package/dist/next/src/routing/locale/get-locale-from-host.js +5 -28
  169. package/dist/next/src/routing/locale/get-locale-from-pathname.js +11 -37
  170. package/dist/next/src/routing/locale/get-locale-from-query.js +2 -17
  171. package/dist/next/src/routing/outbound/decide-strategy.js +9 -9
  172. package/dist/next/src/routing/outbound/determine-target.js +28 -44
  173. package/dist/next/src/routing/outbound/resolve-outbound.js +12 -16
  174. package/dist/next/src/routing/outbound/utils/derive-host-destination.js +5 -9
  175. package/dist/next/src/routing/outbound/utils/derive-query-destination.js +4 -7
  176. package/dist/next/src/routing/outbound/utils/is-external-destination.js +1 -7
  177. package/dist/next/src/routing/pathname/canonicalize-pathname.js +25 -67
  178. package/dist/next/src/routing/pathname/localize-pathname.js +12 -30
  179. package/dist/next/src/routing/pathname/materialize-pathname.js +9 -44
  180. package/dist/next/src/routing/pathname/standardize-pathname.js +6 -30
  181. package/dist/react/src/client/react/helpers/use-intor.js +25 -44
  182. package/dist/react/src/client/react/provider/effects/use-locale-effects.js +20 -25
  183. package/dist/react/src/client/react/provider/effects/use-messages-effects.js +17 -16
  184. package/dist/react/src/client/react/provider/intor-provider.js +63 -66
  185. package/dist/react/src/client/react/provider/use-intor-context.js +4 -4
  186. package/dist/react/src/client/react/render/create-react-renderer.js +18 -24
  187. package/dist/react/src/client/react/translator/create-t-rich.js +9 -22
  188. package/dist/react/src/client/react/translator/use-translator.js +11 -16
  189. package/dist/react/src/client/shared/messages/create-refetch-messages.js +41 -51
  190. package/dist/react/src/client/shared/provider/effective-state.js +2 -6
  191. package/dist/react/src/client/shared/utils/build-cookie-string.js +18 -27
  192. package/dist/react/src/client/shared/utils/locale/get-locale-from-cookie.js +5 -12
  193. package/dist/react/src/client/shared/utils/locale/set-document-locale.js +2 -8
  194. package/dist/react/src/client/shared/utils/locale/set-locale-cookie.js +2 -9
  195. package/dist/react/src/core/logger/get-logger.js +26 -31
  196. package/dist/react/src/core/logger/global-logger-pool.js +4 -4
  197. package/dist/react/src/core/messages/load-remote-messages/collect-remote-resources.js +13 -22
  198. package/dist/react/src/core/messages/load-remote-messages/fetch-remote-resource.js +30 -39
  199. package/dist/react/src/core/messages/load-remote-messages/load-remote-messages.js +72 -89
  200. package/dist/react/src/core/messages/load-remote-messages/resolve-remote-resources.js +7 -17
  201. package/dist/react/src/core/messages/merge-messages.js +17 -28
  202. package/dist/react/src/core/messages/utils/is-valid-messages.js +22 -37
  203. package/dist/react/src/core/messages/utils/nest-object-from-path.js +5 -17
  204. package/dist/react/src/core/utils/deep-merge.js +24 -42
  205. package/dist/react/src/core/utils/resolve-loader-options.js +6 -29
  206. package/dist/react/src/policies/should-persist-on-first-visit.js +1 -4
  207. package/dist/svelte/export/svelte/index.js +0 -6
  208. package/dist/svelte/src/client/shared/messages/create-refetch-messages.js +41 -51
  209. package/dist/svelte/src/client/shared/provider/effective-state.js +2 -6
  210. package/dist/svelte/src/client/shared/utils/build-cookie-string.js +18 -27
  211. package/dist/svelte/src/client/shared/utils/locale/get-locale-from-cookie.js +5 -12
  212. package/dist/svelte/src/client/shared/utils/locale/set-document-locale.js +2 -8
  213. package/dist/svelte/src/client/shared/utils/locale/set-locale-cookie.js +2 -9
  214. package/dist/svelte/src/client/svelte/provider/create-intor-store.js +59 -63
  215. package/dist/svelte/src/client/svelte/provider/effects/attach-locale-effects.js +20 -25
  216. package/dist/svelte/src/client/svelte/provider/effects/attach-messages-effects.js +21 -18
  217. package/dist/svelte/src/client/svelte/provider/get-intor-context.js +4 -4
  218. package/dist/svelte/src/client/svelte/translator/use-translator.js +11 -16
  219. package/dist/svelte/src/core/logger/get-logger.js +26 -31
  220. package/dist/svelte/src/core/logger/global-logger-pool.js +4 -4
  221. package/dist/svelte/src/core/messages/load-remote-messages/collect-remote-resources.js +13 -22
  222. package/dist/svelte/src/core/messages/load-remote-messages/fetch-remote-resource.js +30 -39
  223. package/dist/svelte/src/core/messages/load-remote-messages/load-remote-messages.js +72 -89
  224. package/dist/svelte/src/core/messages/load-remote-messages/resolve-remote-resources.js +7 -17
  225. package/dist/svelte/src/core/messages/merge-messages.js +17 -28
  226. package/dist/svelte/src/core/messages/utils/is-valid-messages.js +22 -37
  227. package/dist/svelte/src/core/messages/utils/nest-object-from-path.js +5 -17
  228. package/dist/svelte/src/core/render/create-html-renderer.js +29 -37
  229. package/dist/svelte/src/core/render/utils/escape-html.js +1 -6
  230. package/dist/svelte/src/core/render/utils/render-attributes.js +6 -11
  231. package/dist/svelte/src/core/translator/create-t-rich.js +6 -15
  232. package/dist/svelte/src/core/utils/deep-merge.js +24 -42
  233. package/dist/svelte/src/core/utils/resolve-loader-options.js +6 -29
  234. package/dist/svelte/src/policies/should-persist-on-first-visit.js +1 -4
  235. package/dist/svelte-kit/src/adapters/svelte-kit/create-intor-handler.js +37 -57
  236. package/dist/svelte-kit/src/adapters/svelte-kit/use-navigation.js +29 -27
  237. package/dist/svelte-kit/src/adapters/svelte-kit/utils/is-svelte-kit-ssg.js +4 -11
  238. package/dist/svelte-kit/src/client/shared/navigation/execute-navigation.js +19 -37
  239. package/dist/svelte-kit/src/client/shared/utils/build-cookie-string.js +18 -27
  240. package/dist/svelte-kit/src/client/shared/utils/locale/set-locale-cookie.js +2 -9
  241. package/dist/svelte-kit/src/core/constants/locale-placeholder.js +0 -1
  242. package/dist/svelte-kit/src/core/locale/canonicalize-locale.js +7 -18
  243. package/dist/svelte-kit/src/core/locale/match-locale.js +24 -50
  244. package/dist/svelte-kit/src/core/locale/parse-locale.js +12 -22
  245. package/dist/svelte-kit/src/core/utils/normalizers/normalize-pathname.js +19 -37
  246. package/dist/svelte-kit/src/core/utils/normalizers/normalize-query.js +6 -20
  247. package/dist/svelte-kit/src/core/utils/resolve-loader-options.js +6 -29
  248. package/dist/svelte-kit/src/policies/shoud-full-reload.js +2 -5
  249. package/dist/svelte-kit/src/policies/should-sync-locale.js +1 -4
  250. package/dist/svelte-kit/src/routing/inbound/resolve-inbound.js +22 -37
  251. package/dist/svelte-kit/src/routing/inbound/resolve-locale/resolve-locale.js +22 -39
  252. package/dist/svelte-kit/src/routing/inbound/resolve-pathname/resolve-pathname.js +24 -30
  253. package/dist/svelte-kit/src/routing/inbound/resolve-pathname/strategies/all.js +10 -23
  254. package/dist/svelte-kit/src/routing/inbound/resolve-pathname/strategies/except-default.js +11 -24
  255. package/dist/svelte-kit/src/routing/inbound/resolve-pathname/strategies/none.js +1 -4
  256. package/dist/svelte-kit/src/routing/locale/get-locale-from-accept-language.js +21 -36
  257. package/dist/svelte-kit/src/routing/locale/get-locale-from-host.js +5 -28
  258. package/dist/svelte-kit/src/routing/locale/get-locale-from-pathname.js +11 -37
  259. package/dist/svelte-kit/src/routing/locale/get-locale-from-query.js +2 -17
  260. package/dist/svelte-kit/src/routing/outbound/decide-strategy.js +9 -9
  261. package/dist/svelte-kit/src/routing/outbound/determine-target.js +28 -44
  262. package/dist/svelte-kit/src/routing/outbound/resolve-outbound.js +12 -16
  263. package/dist/svelte-kit/src/routing/outbound/utils/derive-host-destination.js +5 -9
  264. package/dist/svelte-kit/src/routing/outbound/utils/derive-query-destination.js +4 -7
  265. package/dist/svelte-kit/src/routing/outbound/utils/is-external-destination.js +1 -7
  266. package/dist/svelte-kit/src/routing/pathname/canonicalize-pathname.js +25 -67
  267. package/dist/svelte-kit/src/routing/pathname/localize-pathname.js +12 -30
  268. package/dist/svelte-kit/src/routing/pathname/materialize-pathname.js +9 -44
  269. package/dist/svelte-kit/src/routing/pathname/standardize-pathname.js +6 -30
  270. package/dist/types/export/index.d.ts +1 -1
  271. package/dist/types/export/index.d.ts.map +1 -1
  272. package/dist/types/export/next/server/index.d.ts +1 -1
  273. package/dist/types/export/next/server/index.d.ts.map +1 -1
  274. package/dist/types/src/adapters/fastify/intor-fastify-plugin.d.ts.map +1 -1
  275. package/dist/types/src/adapters/next/create-intor-handler.d.ts.map +1 -1
  276. package/dist/types/src/{core/constants/headers.d.ts → adapters/next/header-keys.d.ts} +3 -2
  277. package/dist/types/src/adapters/next/header-keys.d.ts.map +1 -0
  278. package/dist/types/src/adapters/next/server/get-locale.d.ts.map +1 -1
  279. package/dist/types/src/adapters/next/server/index.d.ts +1 -0
  280. package/dist/types/src/adapters/next/server/index.d.ts.map +1 -1
  281. package/dist/types/src/adapters/next/server/read-intor-url-state.d.ts +13 -0
  282. package/dist/types/src/adapters/next/server/read-intor-url-state.d.ts.map +1 -0
  283. package/dist/types/src/core/constants/index.d.ts +0 -1
  284. package/dist/types/src/core/constants/index.d.ts.map +1 -1
  285. package/dist/types/src/core/constants/locale-placeholder.d.ts +5 -0
  286. package/dist/types/src/core/constants/locale-placeholder.d.ts.map +1 -1
  287. package/dist/types/src/core/index.d.ts +1 -1
  288. package/dist/types/src/core/index.d.ts.map +1 -1
  289. package/dist/types/src/edge/translator/init-translator.d.ts.map +1 -1
  290. package/dist/types/src/routing/outbound/decide-strategy.d.ts +1 -1
  291. package/dist/types/src/routing/outbound/decide-strategy.d.ts.map +1 -1
  292. package/dist/types/src/server/translator/init-translator.d.ts.map +1 -1
  293. package/dist/vue/src/client/shared/messages/create-refetch-messages.js +41 -51
  294. package/dist/vue/src/client/shared/provider/effective-state.js +2 -6
  295. package/dist/vue/src/client/shared/utils/build-cookie-string.js +18 -27
  296. package/dist/vue/src/client/shared/utils/locale/get-locale-from-cookie.js +5 -12
  297. package/dist/vue/src/client/shared/utils/locale/set-document-locale.js +2 -8
  298. package/dist/vue/src/client/shared/utils/locale/set-locale-cookie.js +2 -9
  299. package/dist/vue/src/client/vue/helpers/use-intor.js +20 -42
  300. package/dist/vue/src/client/vue/provider/effects/use-locale-effects.js +23 -24
  301. package/dist/vue/src/client/vue/provider/effects/use-messages-effects.js +15 -24
  302. package/dist/vue/src/client/vue/provider/inject-intor-context.js +4 -4
  303. package/dist/vue/src/client/vue/provider/intor-provider.js +61 -66
  304. package/dist/vue/src/client/vue/render/create-vue-renderer.js +18 -24
  305. package/dist/vue/src/client/vue/translator/create-t-rich.js +5 -17
  306. package/dist/vue/src/client/vue/translator/trans.js +24 -31
  307. package/dist/vue/src/client/vue/translator/use-translator.js +12 -17
  308. package/dist/vue/src/core/logger/get-logger.js +26 -31
  309. package/dist/vue/src/core/logger/global-logger-pool.js +4 -4
  310. package/dist/vue/src/core/messages/load-remote-messages/collect-remote-resources.js +13 -22
  311. package/dist/vue/src/core/messages/load-remote-messages/fetch-remote-resource.js +30 -39
  312. package/dist/vue/src/core/messages/load-remote-messages/load-remote-messages.js +72 -89
  313. package/dist/vue/src/core/messages/load-remote-messages/resolve-remote-resources.js +7 -17
  314. package/dist/vue/src/core/messages/merge-messages.js +17 -28
  315. package/dist/vue/src/core/messages/utils/is-valid-messages.js +22 -37
  316. package/dist/vue/src/core/messages/utils/nest-object-from-path.js +5 -17
  317. package/dist/vue/src/core/utils/deep-merge.js +24 -42
  318. package/dist/vue/src/core/utils/resolve-loader-options.js +6 -29
  319. package/dist/vue/src/policies/should-persist-on-first-visit.js +1 -4
  320. package/package.json +53 -65
  321. package/dist/next/src/core/constants/headers.js +0 -8
  322. package/dist/types/src/core/constants/headers.d.ts.map +0 -1
@@ -1,61 +1,35 @@
1
1
  import { canonicalizeLocale } from './canonicalize-locale.js';
2
2
  import { parseLocale } from './parse-locale.js';
3
3
 
4
- /**
5
- * Matches a locale candidate against a list of supported locales.
6
- *
7
- * Resolution order:
8
- * 1. Exact canonical match
9
- * 2. Same language + same script
10
- * 3. Same language only (only if candidate has no script)
11
- *
12
- * Returns one of the original `supportedLocales` values if matched.
13
- * Returns `undefined` if no match is found.
14
- *
15
- * Notes:
16
- * - Matching is deterministic and order-sensitive.
17
- * - Does not perform automatic fallback to a default locale.
18
- * Consumers are responsible for applying fallback logic.
19
- * - If the candidate includes a script subtag, language-only fallback is skipped.
20
- *
21
- * @public
22
- */
23
4
  function matchLocale(locale, supportedLocales = []) {
24
- if (!locale || supportedLocales.length === 0)
25
- return;
26
- const canonicalCandidate = canonicalizeLocale(locale);
27
- if (!canonicalCandidate)
28
- return;
29
- const candidateParts = parseLocale(canonicalCandidate);
30
- const supportedCanonical = supportedLocales.flatMap((original) => {
31
- const canonical = canonicalizeLocale(original);
32
- if (!canonical)
33
- return [];
34
- return [{ original, canonical, parts: parseLocale(canonical) }];
35
- });
36
- // 1. Exact match
37
- for (const s of supportedCanonical) {
38
- if (s.canonical === canonicalCandidate) {
39
- return s.original;
40
- }
41
- }
42
- // 2. Same language + same script
43
- if (candidateParts.script) {
44
- for (const s of supportedCanonical) {
45
- if (s.parts.language === candidateParts.language &&
46
- s.parts.script === candidateParts.script) {
47
- return s.original;
48
- }
49
- }
50
- return;
5
+ if (!locale || supportedLocales.length === 0) return;
6
+ const canonicalCandidate = canonicalizeLocale(locale);
7
+ if (!canonicalCandidate) return;
8
+ const candidateParts = parseLocale(canonicalCandidate);
9
+ const supportedCanonical = supportedLocales.flatMap((original) => {
10
+ const canonical = canonicalizeLocale(original);
11
+ if (!canonical) return [];
12
+ return [{ original, canonical, parts: parseLocale(canonical) }];
13
+ });
14
+ for (const s of supportedCanonical) {
15
+ if (s.canonical === canonicalCandidate) {
16
+ return s.original;
51
17
  }
52
- // 3. Same language only
18
+ }
19
+ if (candidateParts.script) {
53
20
  for (const s of supportedCanonical) {
54
- if (s.parts.language === candidateParts.language) {
55
- return s.original;
56
- }
21
+ if (s.parts.language === candidateParts.language && s.parts.script === candidateParts.script) {
22
+ return s.original;
23
+ }
57
24
  }
58
25
  return;
26
+ }
27
+ for (const s of supportedCanonical) {
28
+ if (s.parts.language === candidateParts.language) {
29
+ return s.original;
30
+ }
31
+ }
32
+ return;
59
33
  }
60
34
 
61
35
  export { matchLocale };
@@ -1,27 +1,17 @@
1
- /**
2
- * Parses a canonical locale tag into structural components.
3
- *
4
- * - Uses `Intl.Locale` when available.
5
- * - Falls back to minimal parsing (language only) if unavailable.
6
- *
7
- * This function does not validate or match locales.
8
- */
9
1
  function parseLocale(tag) {
10
- try {
11
- if (typeof Intl !== "undefined" && typeof Intl.Locale === "function") {
12
- const locale = new Intl.Locale(tag);
13
- return {
14
- language: locale.language,
15
- ...(locale.script !== undefined ? { script: locale.script } : {}),
16
- ...(locale.region !== undefined ? { region: locale.region } : {}),
17
- };
18
- }
2
+ try {
3
+ if (typeof Intl !== "undefined" && typeof Intl.Locale === "function") {
4
+ const locale = new Intl.Locale(tag);
5
+ return {
6
+ language: locale.language,
7
+ ...locale.script !== void 0 ? { script: locale.script } : {},
8
+ ...locale.region !== void 0 ? { region: locale.region } : {}
9
+ };
19
10
  }
20
- catch {
21
- // fallback below
22
- }
23
- const parts = tag.split("-");
24
- return { language: parts[0].toLowerCase() };
11
+ } catch {
12
+ }
13
+ const parts = tag.split("-");
14
+ return { language: parts[0].toLowerCase() };
25
15
  }
26
16
 
27
17
  export { parseLocale };
@@ -2,41 +2,36 @@ import { logry } from 'logry';
2
2
  import { getGlobalLoggerPool } from './global-logger-pool.js';
3
3
 
4
4
  const DEFAULT_FORMAT_CONFIG = {
5
- timestamp: { withDate: false },
5
+ timestamp: { withDate: false }
6
6
  };
7
7
  const DEFAULT_RENDER_CONFIG = {
8
- id: { visible: true, prefix: "<", suffix: ">" },
9
- meta: { lineBreaksAfter: 1 },
8
+ id: { visible: true, prefix: "<", suffix: ">" },
9
+ meta: { lineBreaksAfter: 1 }
10
10
  };
11
- /**
12
- * Get a shared logger instance by id.
13
- * - Safe across hot reloads
14
- * - Prevents unbounded memory usage via soft LRU
15
- */
16
- function getLogger({ id = "default", preset, ...options }) {
17
- const pool = getGlobalLoggerPool();
18
- const existing = pool.get(id);
19
- if (existing)
20
- return existing;
21
- const baseConfig = preset === undefined
22
- ? {
23
- formatConfig: DEFAULT_FORMAT_CONFIG,
24
- renderConfig: DEFAULT_RENDER_CONFIG,
25
- }
26
- : { preset };
27
- const logger = logry({
28
- id,
29
- ...baseConfig,
30
- ...options,
31
- });
32
- pool.set(id, logger);
33
- // Soft LRU: keep pool size under control
34
- if (pool.size > 1000) {
35
- for (const key of [...pool.keys()].slice(0, 200)) {
36
- pool.delete(key);
37
- }
11
+ function getLogger({
12
+ id = "default",
13
+ preset,
14
+ ...options
15
+ }) {
16
+ const pool = getGlobalLoggerPool();
17
+ const existing = pool.get(id);
18
+ if (existing) return existing;
19
+ const baseConfig = preset === void 0 ? {
20
+ formatConfig: DEFAULT_FORMAT_CONFIG,
21
+ renderConfig: DEFAULT_RENDER_CONFIG
22
+ } : { preset };
23
+ const logger = logry({
24
+ id,
25
+ ...baseConfig,
26
+ ...options
27
+ });
28
+ pool.set(id, logger);
29
+ if (pool.size > 1e3) {
30
+ for (const key of [...pool.keys()].slice(0, 200)) {
31
+ pool.delete(key);
38
32
  }
39
- return logger;
33
+ }
34
+ return logger;
40
35
  }
41
36
 
42
37
  export { getLogger };
@@ -1,8 +1,8 @@
1
1
  function getGlobalLoggerPool() {
2
- if (!globalThis.__INTOR_LOGGER_POOL__) {
3
- globalThis.__INTOR_LOGGER_POOL__ = new Map();
4
- }
5
- return globalThis.__INTOR_LOGGER_POOL__;
2
+ if (!globalThis.__INTOR_LOGGER_POOL__) {
3
+ globalThis.__INTOR_LOGGER_POOL__ = /* @__PURE__ */ new Map();
4
+ }
5
+ return globalThis.__INTOR_LOGGER_POOL__;
6
6
  }
7
7
 
8
8
  export { getGlobalLoggerPool };
@@ -1,7 +1,7 @@
1
1
  const INTOR_PREFIX = "__intor_";
2
2
  const INTOR_MESSAGES_KIND_KEY = `${INTOR_PREFIX}kind`;
3
3
  const INTOR_MESSAGES_KIND = {
4
- markdown: "markdown",
4
+ markdown: "markdown"
5
5
  };
6
6
 
7
7
  export { INTOR_MESSAGES_KIND, INTOR_MESSAGES_KIND_KEY, INTOR_PREFIX };
@@ -1,25 +1,16 @@
1
- /**
2
- * Collect remote message resources for a given locale.
3
- *
4
- * - Always includes the root `index.json`
5
- * - Optionally includes namespace-specific resources
6
- * - Produces semantic paths for later message nesting
7
- *
8
- * This function performs no I/O and does not validate resource existence.
9
- */
10
- function collectRemoteResources({ locale, baseUrl, namespaces, }) {
11
- const basePath = `${baseUrl}/${locale}`;
12
- // Root translation resource (always loaded)
13
- const indexResource = { url: `${basePath}/index.json`, path: [] };
14
- // When no namespaces are provided, the locale domain consists of index only
15
- if (!namespaces || namespaces.length === 0)
16
- return [indexResource];
17
- // Namespace-specific resources are nested under their namespace key
18
- const nsResources = namespaces.map((ns) => ({
19
- url: `${basePath}/${ns}.json`,
20
- path: [ns],
21
- }));
22
- return [indexResource, ...nsResources];
1
+ function collectRemoteResources({
2
+ locale,
3
+ baseUrl,
4
+ namespaces
5
+ }) {
6
+ const basePath = `${baseUrl}/${locale}`;
7
+ const indexResource = { url: `${basePath}/index.json`, path: [] };
8
+ if (!namespaces || namespaces.length === 0) return [indexResource];
9
+ const nsResources = namespaces.map((ns) => ({
10
+ url: `${basePath}/${ns}.json`,
11
+ path: [ns]
12
+ }));
13
+ return [indexResource, ...nsResources];
23
14
  }
24
15
 
25
16
  export { collectRemoteResources };
@@ -1,47 +1,38 @@
1
1
  import { getLogger } from '../../logger/get-logger.js';
2
2
  import { isValidMessages } from '../utils/is-valid-messages.js';
3
3
 
4
- /**
5
- * Fetch a single remote messages resource.
6
- *
7
- * This function performs a single HTTP request to retrieve
8
- * a remote translation messages payload.
9
- *
10
- * It is responsible for:
11
- * - Issuing the network request
12
- * - Validating the returned message structure
13
- * - Handling abort and network errors
14
- */
15
- async function fetchRemoteResource({ fetch, url, headers, signal, loggerOptions, }) {
16
- const baseLogger = getLogger(loggerOptions);
17
- const logger = baseLogger.child({ scope: "fetch-locale-messages" });
18
- try {
19
- // Fetch
20
- const response = await fetch(url, {
21
- method: "GET",
22
- headers: { "Content-Type": "application/json", ...headers },
23
- cache: "no-store",
24
- ...(signal !== undefined ? { signal } : {}),
25
- });
26
- if (!response.ok) {
27
- throw new Error(`HTTP ${response.status} ${response.statusText}`);
28
- }
29
- // Parse JSON body
30
- const data = (await response.json());
31
- // Validate messages structure
32
- if (!isValidMessages(data)) {
33
- throw new Error("Invalid messages structure");
34
- }
35
- return data;
4
+ async function fetchRemoteResource({
5
+ fetch,
6
+ url,
7
+ headers,
8
+ signal,
9
+ loggerOptions
10
+ }) {
11
+ const baseLogger = getLogger(loggerOptions);
12
+ const logger = baseLogger.child({ scope: "fetch-locale-messages" });
13
+ try {
14
+ const response = await fetch(url, {
15
+ method: "GET",
16
+ headers: { "Content-Type": "application/json", ...headers },
17
+ cache: "no-store",
18
+ ...signal !== void 0 ? { signal } : {}
19
+ });
20
+ if (!response.ok) {
21
+ throw new Error(`HTTP ${response.status} ${response.statusText}`);
36
22
  }
37
- catch (error) {
38
- if (error instanceof Error && error.name === "AbortError") {
39
- logger.debug("Remote fetch aborted.", { url });
40
- return;
41
- }
42
- logger.warn("Failed to fetch remote messages.", { url, error });
43
- return;
23
+ const data = await response.json();
24
+ if (!isValidMessages(data)) {
25
+ throw new Error("Invalid messages structure");
44
26
  }
27
+ return data;
28
+ } catch (error) {
29
+ if (error instanceof Error && error.name === "AbortError") {
30
+ logger.debug("Remote fetch aborted.", { url });
31
+ return;
32
+ }
33
+ logger.warn("Failed to fetch remote messages.", { url, error });
34
+ return;
35
+ }
45
36
  }
46
37
 
47
38
  export { fetchRemoteResource };
@@ -4,98 +4,81 @@ import { collectRemoteResources } from './collect-remote-resources.js';
4
4
  import { fetchRemoteResource } from './fetch-remote-resource.js';
5
5
  import { resolveRemoteResources } from './resolve-remote-resources.js';
6
6
 
7
- /**
8
- * Load locale messages from a remote source.
9
- *
10
- * This function serves as the orchestration layer for remote message loading.
11
- * It coordinates:
12
- *
13
- * - Locale resolution with fallbacks
14
- * - Concurrency control for network requests
15
- * - Remote resource fetching and message merging
16
- *
17
- * Remote messages are fetched on demand and are not memoized at the process level.
18
- *
19
- * Network requests and response validation are delegated to lower-level utilities.
20
- */
21
- const loadRemoteMessages = async ({ locale, fallbackLocales, namespaces, concurrency, fetch, url: baseUrl, headers, signal, loggerOptions, }) => {
22
- const baseLogger = getLogger(loggerOptions);
23
- const logger = baseLogger.child({ scope: "load-remote-messages" });
24
- // Abort early if the request has already been cancelled
25
- if (signal?.aborted) {
26
- logger.debug("Remote message loading aborted before fetch.");
7
+ const loadRemoteMessages = async ({
8
+ locale,
9
+ fallbackLocales,
10
+ namespaces,
11
+ concurrency,
12
+ fetch,
13
+ url: baseUrl,
14
+ headers,
15
+ signal,
16
+ loggerOptions
17
+ }) => {
18
+ const baseLogger = getLogger(loggerOptions);
19
+ const logger = baseLogger.child({ scope: "load-remote-messages" });
20
+ if (signal?.aborted) {
21
+ logger.debug("Remote message loading aborted before fetch.");
22
+ return;
23
+ }
24
+ const start = performance.now();
25
+ logger.debug("Loading remote messages.", { baseUrl });
26
+ const limit = concurrency ? pLimit(concurrency) : void 0;
27
+ const candidateLocales = [locale, ...fallbackLocales || []];
28
+ let messages;
29
+ for (const candidateLocale of candidateLocales) {
30
+ const isLast = candidateLocale === candidateLocales[candidateLocales.length - 1];
31
+ try {
32
+ const resources = collectRemoteResources({
33
+ locale: candidateLocale,
34
+ baseUrl,
35
+ ...namespaces !== void 0 ? { namespaces } : {}
36
+ });
37
+ const fetchUrl = (url) => fetchRemoteResource({
38
+ url,
39
+ ...headers !== void 0 ? { headers } : {},
40
+ ...signal !== void 0 ? { signal } : {},
41
+ loggerOptions,
42
+ fetch
43
+ });
44
+ const results = await Promise.all(
45
+ resources.map(
46
+ ({ url }) => limit ? limit(() => fetchUrl(url)) : fetchUrl(url)
47
+ )
48
+ );
49
+ if (!results.some(Boolean)) continue;
50
+ const resolved = resolveRemoteResources(
51
+ resources.map((res, i) => {
52
+ const data = results[i];
53
+ return { path: res.path, ...data !== void 0 ? { data } : {} };
54
+ })
55
+ );
56
+ messages = { [candidateLocale]: resolved };
57
+ break;
58
+ } catch {
59
+ if (signal?.aborted) {
60
+ logger.debug("Remote message loading aborted.");
27
61
  return;
28
- }
29
- const start = performance.now();
30
- logger.debug("Loading remote messages.", { baseUrl });
31
- // ----------------------------------------------------------------
32
- // Resolve locale messages with ordered fallback strategy
33
- // ----------------------------------------------------------------
34
- const limit = concurrency ? pLimit(concurrency) : undefined;
35
- const candidateLocales = [locale, ...(fallbackLocales || [])];
36
- let messages;
37
- for (const candidateLocale of candidateLocales) {
38
- const isLast = candidateLocale === candidateLocales[candidateLocales.length - 1];
39
- try {
40
- // -----------------------------------------------------------------
41
- // Collect remote message resources for the locale
42
- // -----------------------------------------------------------------
43
- const resources = collectRemoteResources({
44
- locale: candidateLocale,
45
- baseUrl,
46
- ...(namespaces !== undefined ? { namespaces } : {}),
47
- });
48
- // -----------------------------------------------------------------
49
- // Fetch all message chunks in parallel
50
- // -----------------------------------------------------------------
51
- const fetchUrl = (url) => fetchRemoteResource({
52
- url,
53
- ...(headers !== undefined ? { headers } : {}),
54
- ...(signal !== undefined ? { signal } : {}),
55
- loggerOptions,
56
- fetch,
57
- });
58
- const results = await Promise.all(resources.map(({ url }) => limit ? limit(() => fetchUrl(url)) : fetchUrl(url)));
59
- // Guard: no valid remote resources
60
- if (!results.some(Boolean))
61
- continue;
62
- // -----------------------------------------------------------------
63
- // Resolve and merge remote message resources
64
- // -----------------------------------------------------------------
65
- const resolved = resolveRemoteResources(resources.map((res, i) => {
66
- const data = results[i];
67
- return { path: res.path, ...(data !== undefined ? { data } : {}) };
68
- }));
69
- // -----------------------------------------------------------------
70
- // Wrap resolved messages into locale-scoped LocaleMessages
71
- // -----------------------------------------------------------------
72
- messages = { [candidateLocale]: resolved };
73
- break;
74
- }
75
- catch {
76
- if (signal?.aborted) {
77
- logger.debug("Remote message loading aborted.");
78
- return;
79
- }
80
- if (isLast) {
81
- logger.warn("Failed to load messages for all candidate locales.", {
82
- locale,
83
- fallbackLocales,
84
- });
85
- }
86
- else {
87
- logger.warn(`Failed to load locale messages for "${candidateLocale}", trying next fallback.`);
88
- }
89
- }
90
- }
91
- // Final success log with resolved locale and timing
92
- if (messages) {
93
- logger.trace("Finished loading remote messages.", {
94
- loadedLocale: Object.keys(messages)[0],
95
- duration: `${Math.round(performance.now() - start)} ms`,
62
+ }
63
+ if (isLast) {
64
+ logger.warn("Failed to load messages for all candidate locales.", {
65
+ locale,
66
+ fallbackLocales
96
67
  });
68
+ } else {
69
+ logger.warn(
70
+ `Failed to load locale messages for "${candidateLocale}", trying next fallback.`
71
+ );
72
+ }
97
73
  }
98
- return messages;
74
+ }
75
+ if (messages) {
76
+ logger.trace("Finished loading remote messages.", {
77
+ loadedLocale: Object.keys(messages)[0],
78
+ duration: `${Math.round(performance.now() - start)} ms`
79
+ });
80
+ }
81
+ return messages;
99
82
  };
100
83
 
101
84
  export { loadRemoteMessages };
@@ -1,24 +1,14 @@
1
1
  import { deepMerge } from '../../utils/deep-merge.js';
2
2
  import { nestObjectFromPath } from '../utils/nest-object-from-path.js';
3
3
 
4
- /**
5
- * Resolve remote message resources into a single MessageObject.
6
- *
7
- * - Applies semantic nesting based on resource path
8
- * - Merges all resolved message chunks
9
- *
10
- * Always returns a MessageObject.
11
- * An empty object represents an empty translation domain.
12
- */
13
4
  function resolveRemoteResources(resources) {
14
- let result = {};
15
- for (const { path, data } of resources) {
16
- if (!data)
17
- continue;
18
- const resolved = path.length > 0 ? nestObjectFromPath(path, data) : data;
19
- result = deepMerge(result, resolved);
20
- }
21
- return result;
5
+ let result = {};
6
+ for (const { path, data } of resources) {
7
+ if (!data) continue;
8
+ const resolved = path.length > 0 ? nestObjectFromPath(path, data) : data;
9
+ result = deepMerge(result, resolved);
10
+ }
11
+ return result;
22
12
  }
23
13
 
24
14
  export { resolveRemoteResources };
@@ -1,35 +1,24 @@
1
1
  import { getLogger } from '../logger/get-logger.js';
2
2
  import { deepMerge } from '../utils/deep-merge.js';
3
3
 
4
- /**
5
- * Merge locale-specific messages with runtime overrides.
6
- *
7
- * - Only merges messages under the given locale
8
- * - Emits debug logs for add / override events
9
- *
10
- * @public
11
- */
12
4
  function mergeMessages(a, b, { config, locale, onEvent }) {
13
- const baseLogger = getLogger({ ...config.logger, id: config.id });
14
- const logger = baseLogger.child({ scope: "merge-messages" });
15
- // Merge messages for the active locale only
16
- const merged = deepMerge(a?.[locale] ?? {}, b?.[locale] ?? {}, {
17
- onOverride: (event) => {
18
- if (onEvent) {
19
- onEvent(event);
20
- return;
21
- }
22
- const { kind, path, next, prev } = event;
23
- if (kind === "add")
24
- return;
25
- logger.debug(`Override | ${locale}: "${path}"`, { prev, next });
26
- },
27
- });
28
- // Preserve other locales, update only the target one
29
- return {
30
- ...a,
31
- [locale]: merged,
32
- };
5
+ const baseLogger = getLogger({ ...config.logger, id: config.id });
6
+ const logger = baseLogger.child({ scope: "merge-messages" });
7
+ const merged = deepMerge(a?.[locale] ?? {}, b?.[locale] ?? {}, {
8
+ onOverride: (event) => {
9
+ if (onEvent) {
10
+ onEvent(event);
11
+ return;
12
+ }
13
+ const { kind, path, next, prev } = event;
14
+ if (kind === "add") return;
15
+ logger.debug(`Override | ${locale}: "${path}"`, { prev, next });
16
+ }
17
+ });
18
+ return {
19
+ ...a,
20
+ [locale]: merged
21
+ };
33
22
  }
34
23
 
35
24
  export { mergeMessages };
@@ -1,44 +1,29 @@
1
- /** Check if a value is a plain object (not null, not array) */
2
1
  function isPlainObject(value) {
3
- return typeof value === "object" && value !== null && !Array.isArray(value);
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4
3
  }
5
- /**
6
- * Check if a value is a valid MessageObject.
7
- *
8
- * - Supports all MessageValue variants (primitive, array, object).
9
- * - Uses an iterative approach to avoid stack overflow.
10
- */
11
4
  function isValidMessages(value) {
12
- if (!isPlainObject(value))
13
- return false;
14
- const stack = [value];
15
- while (stack.length > 0) {
16
- const current = stack.pop();
17
- // primitives are always valid
18
- if (current === null ||
19
- typeof current === "string" ||
20
- typeof current === "number" ||
21
- typeof current === "boolean") {
22
- continue;
23
- }
24
- // array → validate each item
25
- if (Array.isArray(current)) {
26
- for (const item of current) {
27
- stack.push(item);
28
- }
29
- continue;
30
- }
31
- // object → validate each value
32
- if (isPlainObject(current)) {
33
- for (const v of Object.values(current)) {
34
- stack.push(v);
35
- }
36
- continue;
37
- }
38
- // everything else is invalid
39
- return false;
5
+ if (!isPlainObject(value)) return false;
6
+ const stack = [value];
7
+ while (stack.length > 0) {
8
+ const current = stack.pop();
9
+ if (current === null || typeof current === "string" || typeof current === "number" || typeof current === "boolean") {
10
+ continue;
40
11
  }
41
- return true;
12
+ if (Array.isArray(current)) {
13
+ for (const item of current) {
14
+ stack.push(item);
15
+ }
16
+ continue;
17
+ }
18
+ if (isPlainObject(current)) {
19
+ for (const v of Object.values(current)) {
20
+ stack.push(v);
21
+ }
22
+ continue;
23
+ }
24
+ return false;
25
+ }
26
+ return true;
42
27
  }
43
28
 
44
29
  export { isPlainObject, isValidMessages };