@lovalingo/lovalingo 0.5.29 → 0.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 (148) hide show
  1. package/README.md +34 -0
  2. package/dist/chunk-2FZR2AKF.mjs +88 -0
  3. package/dist/chunk-7D5LBV45.mjs +46 -0
  4. package/dist/chunk-CJOSN7RA.mjs +90 -0
  5. package/dist/chunk-VAHA2TOX.mjs +3440 -0
  6. package/dist/chunk-ZMRCSUM7.mjs +26 -0
  7. package/dist/chunk-ZVYKEEUF.mjs +220 -0
  8. package/dist/core.d.mts +131 -0
  9. package/dist/core.d.ts +131 -0
  10. package/dist/core.js +3561 -0
  11. package/dist/core.mjs +19 -0
  12. package/dist/index.d.mts +5 -0
  13. package/dist/index.d.ts +5 -25
  14. package/dist/index.js +3885 -28
  15. package/dist/index.mjs +33 -0
  16. package/dist/react-router.d.mts +101 -0
  17. package/dist/react-router.d.ts +101 -0
  18. package/dist/react-router.js +353 -0
  19. package/dist/react-router.mjs +14 -0
  20. package/dist/tanstack-router.d.mts +22 -0
  21. package/dist/tanstack-router.d.ts +22 -0
  22. package/dist/tanstack-router.js +162 -0
  23. package/dist/tanstack-router.mjs +8 -0
  24. package/package.json +34 -3
  25. package/dist/__tests__/languageFlags.test.d.ts +0 -1
  26. package/dist/__tests__/languageFlags.test.js +0 -42
  27. package/dist/__tests__/mergeEntitlements.test.d.ts +0 -1
  28. package/dist/__tests__/mergeEntitlements.test.js +0 -27
  29. package/dist/components/AixsterProvider.d.ts +0 -1
  30. package/dist/components/AixsterProvider.js +0 -1
  31. package/dist/components/LangLink.d.ts +0 -20
  32. package/dist/components/LangLink.js +0 -38
  33. package/dist/components/LangRouter.d.ts +0 -37
  34. package/dist/components/LangRouter.js +0 -191
  35. package/dist/components/LanguageSwitcher.d.ts +0 -17
  36. package/dist/components/LanguageSwitcher.js +0 -257
  37. package/dist/components/LovalingoProvider.d.ts +0 -10
  38. package/dist/components/LovalingoProvider.js +0 -413
  39. package/dist/components/NavigationOverlay.d.ts +0 -6
  40. package/dist/components/NavigationOverlay.js +0 -22
  41. package/dist/components/provider/__tests__/seoUtils.test.d.ts +0 -1
  42. package/dist/components/provider/__tests__/seoUtils.test.js +0 -13
  43. package/dist/components/provider/editModeUtils.d.ts +0 -6
  44. package/dist/components/provider/editModeUtils.js +0 -59
  45. package/dist/components/provider/localeUtils.d.ts +0 -8
  46. package/dist/components/provider/localeUtils.js +0 -46
  47. package/dist/components/provider/providerConstants.d.ts +0 -12
  48. package/dist/components/provider/providerConstants.js +0 -11
  49. package/dist/components/provider/seoUtils.d.ts +0 -8
  50. package/dist/components/provider/seoUtils.js +0 -118
  51. package/dist/components/provider/useEditModeOverlay.d.ts +0 -7
  52. package/dist/components/provider/useEditModeOverlay.js +0 -134
  53. package/dist/components/provider/useHistoryNavigationPatch.d.ts +0 -3
  54. package/dist/components/provider/useHistoryNavigationPatch.js +0 -47
  55. package/dist/components/provider/useProviderCache.d.ts +0 -12
  56. package/dist/components/provider/useProviderCache.js +0 -82
  57. package/dist/context/AixsterContext.d.ts +0 -3
  58. package/dist/context/AixsterContext.js +0 -2
  59. package/dist/context/LangContext.d.ts +0 -1
  60. package/dist/context/LangContext.js +0 -2
  61. package/dist/context/LangRoutingContext.d.ts +0 -8
  62. package/dist/context/LangRoutingContext.js +0 -7
  63. package/dist/context/LovalingoContext.d.ts +0 -1
  64. package/dist/context/LovalingoContext.js +0 -1
  65. package/dist/hooks/provider/useBundleLoading.d.ts +0 -33
  66. package/dist/hooks/provider/useBundleLoading.js +0 -380
  67. package/dist/hooks/provider/useDomRules.d.ts +0 -15
  68. package/dist/hooks/provider/useDomRules.js +0 -38
  69. package/dist/hooks/provider/useLinkAutoPrefix.d.ts +0 -12
  70. package/dist/hooks/provider/useLinkAutoPrefix.js +0 -146
  71. package/dist/hooks/provider/useNavigationPrefetch.d.ts +0 -12
  72. package/dist/hooks/provider/useNavigationPrefetch.js +0 -82
  73. package/dist/hooks/provider/usePageviewTracking.d.ts +0 -10
  74. package/dist/hooks/provider/usePageviewTracking.js +0 -44
  75. package/dist/hooks/provider/usePrehide.d.ts +0 -5
  76. package/dist/hooks/provider/usePrehide.js +0 -72
  77. package/dist/hooks/provider/useSitemapLinkTag.d.ts +0 -7
  78. package/dist/hooks/provider/useSitemapLinkTag.js +0 -28
  79. package/dist/hooks/provider/useStringMissReporting.d.ts +0 -14
  80. package/dist/hooks/provider/useStringMissReporting.js +0 -155
  81. package/dist/hooks/useAixster.d.ts +0 -6
  82. package/dist/hooks/useAixster.js +0 -14
  83. package/dist/hooks/useAixsterEdit.d.ts +0 -5
  84. package/dist/hooks/useAixsterEdit.js +0 -13
  85. package/dist/hooks/useAixsterTranslate.d.ts +0 -4
  86. package/dist/hooks/useAixsterTranslate.js +0 -12
  87. package/dist/hooks/useLang.d.ts +0 -16
  88. package/dist/hooks/useLang.js +0 -23
  89. package/dist/hooks/useLangNavigate.d.ts +0 -24
  90. package/dist/hooks/useLangNavigate.js +0 -40
  91. package/dist/hooks/useLovalingo.d.ts +0 -1
  92. package/dist/hooks/useLovalingo.js +0 -1
  93. package/dist/hooks/useLovalingoEdit.d.ts +0 -1
  94. package/dist/hooks/useLovalingoEdit.js +0 -1
  95. package/dist/hooks/useLovalingoTranslate.d.ts +0 -1
  96. package/dist/hooks/useLovalingoTranslate.js +0 -1
  97. package/dist/types.d.ts +0 -76
  98. package/dist/types.js +0 -1
  99. package/dist/utils/api.d.ts +0 -42
  100. package/dist/utils/api.js +0 -395
  101. package/dist/utils/apiTypes.d.ts +0 -78
  102. package/dist/utils/apiTypes.js +0 -1
  103. package/dist/utils/apiUtils.d.ts +0 -4
  104. package/dist/utils/apiUtils.js +0 -54
  105. package/dist/utils/domRules.d.ts +0 -2
  106. package/dist/utils/domRules.js +0 -150
  107. package/dist/utils/hash.d.ts +0 -9
  108. package/dist/utils/hash.js +0 -27
  109. package/dist/utils/languageFlags.d.ts +0 -7
  110. package/dist/utils/languageFlags.js +0 -90
  111. package/dist/utils/logger.d.ts +0 -3
  112. package/dist/utils/logger.js +0 -40
  113. package/dist/utils/markerEngine.d.ts +0 -12
  114. package/dist/utils/markerEngine.js +0 -109
  115. package/dist/utils/markerEngineApply.d.ts +0 -3
  116. package/dist/utils/markerEngineApply.js +0 -136
  117. package/dist/utils/markerEngineConstants.d.ts +0 -10
  118. package/dist/utils/markerEngineConstants.js +0 -12
  119. package/dist/utils/markerEngineCritical.d.ts +0 -2
  120. package/dist/utils/markerEngineCritical.js +0 -98
  121. package/dist/utils/markerEngineDomUtils.d.ts +0 -8
  122. package/dist/utils/markerEngineDomUtils.js +0 -74
  123. package/dist/utils/markerEngineFilters.d.ts +0 -2
  124. package/dist/utils/markerEngineFilters.js +0 -26
  125. package/dist/utils/markerEngineMisses.d.ts +0 -5
  126. package/dist/utils/markerEngineMisses.js +0 -81
  127. package/dist/utils/markerEngineOriginals.d.ts +0 -5
  128. package/dist/utils/markerEngineOriginals.js +0 -29
  129. package/dist/utils/markerEngineScan.d.ts +0 -5
  130. package/dist/utils/markerEngineScan.js +0 -162
  131. package/dist/utils/markerEngineState.d.ts +0 -4
  132. package/dist/utils/markerEngineState.js +0 -14
  133. package/dist/utils/markerEngineStats.d.ts +0 -3
  134. package/dist/utils/markerEngineStats.js +0 -28
  135. package/dist/utils/markerEngineTranslations.d.ts +0 -3
  136. package/dist/utils/markerEngineTranslations.js +0 -49
  137. package/dist/utils/markerEngineTypes.d.ts +0 -62
  138. package/dist/utils/markerEngineTypes.js +0 -1
  139. package/dist/utils/markerEngineViewport.d.ts +0 -2
  140. package/dist/utils/markerEngineViewport.js +0 -27
  141. package/dist/utils/mergeEntitlements.d.ts +0 -2
  142. package/dist/utils/mergeEntitlements.js +0 -7
  143. package/dist/utils/nonLocalizedPaths.d.ts +0 -12
  144. package/dist/utils/nonLocalizedPaths.js +0 -136
  145. package/dist/utils/pathNormalizer.d.ts +0 -49
  146. package/dist/utils/pathNormalizer.js +0 -115
  147. package/dist/version.d.ts +0 -1
  148. package/dist/version.js +0 -1
@@ -0,0 +1,26 @@
1
+ // src/components/provider/providerConstants.ts
2
+ var LOCALE_STORAGE_KEY = "Lovalingo_locale";
3
+ var LOADING_BG_STORAGE_PREFIX = "Lovalingo_loading_bg_color";
4
+ var BRANDING_STORAGE_PREFIX = "Lovalingo_branding_enabled";
5
+ var EDIT_MODE_PARAM = "edit_mode";
6
+ var EDIT_KEY_PARAM = "edit_key";
7
+ var LIVE_MISSES_QUERY_PARAM = "lovalingo_live_misses";
8
+ var DEFAULT_PATH_NORMALIZATION = { enabled: true };
9
+ var EDIT_MODE_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
10
+ var EDIT_UI_ATTR = "data-lovalingo-edit-ui";
11
+ var EDIT_HIGHLIGHT_ID = "lovalingo-edit-highlight";
12
+ var EDIT_HINT_ID = "lovalingo-edit-hint";
13
+
14
+ export {
15
+ LOCALE_STORAGE_KEY,
16
+ LOADING_BG_STORAGE_PREFIX,
17
+ BRANDING_STORAGE_PREFIX,
18
+ EDIT_MODE_PARAM,
19
+ EDIT_KEY_PARAM,
20
+ LIVE_MISSES_QUERY_PARAM,
21
+ DEFAULT_PATH_NORMALIZATION,
22
+ EDIT_MODE_VALUES,
23
+ EDIT_UI_ATTR,
24
+ EDIT_HIGHLIGHT_ID,
25
+ EDIT_HINT_ID
26
+ };
@@ -0,0 +1,220 @@
1
+ import {
2
+ LangRoutingContext,
3
+ logDebug
4
+ } from "./chunk-7D5LBV45.mjs";
5
+ import {
6
+ isNonLocalizedPath,
7
+ parseBootstrapInactivePages,
8
+ parseBootstrapNonLocalizedPaths
9
+ } from "./chunk-2FZR2AKF.mjs";
10
+
11
+ // src/components/LangRouter.tsx
12
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
13
+ import { BrowserRouter, Routes, Route, Navigate, Outlet, useLocation, useNavigate } from "react-router-dom";
14
+
15
+ // src/context/LangContext.ts
16
+ import { createContext } from "react";
17
+ var LangContext = createContext(null);
18
+
19
+ // src/components/LangRouter.tsx
20
+ function NavigateExporter({ navigateRef }) {
21
+ const navigate = useNavigate();
22
+ useEffect(() => {
23
+ if (navigateRef) {
24
+ navigateRef.current = navigate;
25
+ }
26
+ }, [navigate, navigateRef]);
27
+ return null;
28
+ }
29
+ function LangGuard({
30
+ lang,
31
+ nonLocalizedPaths,
32
+ defaultLang
33
+ }) {
34
+ const location = useLocation();
35
+ const prefix = `/${lang}`;
36
+ const restPath = location.pathname.startsWith(prefix) ? location.pathname.slice(prefix.length) || "/" : location.pathname;
37
+ if (isNonLocalizedPath(restPath, nonLocalizedPaths)) {
38
+ const nextPath = `${restPath}${location.search}${location.hash}`;
39
+ return /* @__PURE__ */ React.createElement(Navigate, { to: nextPath, replace: true });
40
+ }
41
+ return /* @__PURE__ */ React.createElement(LangContext.Provider, { value: lang }, /* @__PURE__ */ React.createElement(Outlet, { context: { lang } }));
42
+ }
43
+ function RedirectToDefaultLang({
44
+ defaultLang,
45
+ children,
46
+ nonLocalizedPaths,
47
+ routingStatus
48
+ }) {
49
+ const location = useLocation();
50
+ const navigate = useNavigate();
51
+ const shouldSkip = isNonLocalizedPath(location.pathname, nonLocalizedPaths);
52
+ useEffect(() => {
53
+ if (shouldSkip) return;
54
+ if (routingStatus === "loading") return;
55
+ const nextPath = location.pathname === "/" || location.pathname === "" ? `/${defaultLang}${location.search}${location.hash}` : `/${defaultLang}${location.pathname}${location.search}${location.hash}`;
56
+ const current = `${location.pathname}${location.search}${location.hash}`;
57
+ if (nextPath === current) return;
58
+ navigate(nextPath, { replace: true });
59
+ }, [defaultLang, location.hash, location.pathname, location.search, navigate, routingStatus, shouldSkip]);
60
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
61
+ }
62
+ function LangRouter({ children, defaultLang, langs, navigateRef, apiBase, apiKey, publicAnonKey }) {
63
+ const metaKey = typeof document !== "undefined" ? document.querySelector('meta[name="lovalingo-public-anon-key"]')?.content?.trim() || "" : "";
64
+ const globals = globalThis;
65
+ const resolvedApiKey = (typeof apiKey === "string" && apiKey.trim().length > 0 ? apiKey : typeof publicAnonKey === "string" && publicAnonKey.trim().length > 0 ? publicAnonKey : globals.__LOVALINGO_PUBLIC_ANON_KEY__ || globals.__LOVALINGO_API_KEY__ || metaKey || "").trim();
66
+ const resolvedApiBase = typeof apiBase === "string" && apiBase.trim().length > 0 ? apiBase.trim() : "https://cdn.lovalingo.com";
67
+ const nonLocalizedStorageKey = useMemo(
68
+ () => `Lovalingo_non_localized_paths:${resolvedApiKey || "anonymous"}`,
69
+ [resolvedApiKey]
70
+ );
71
+ const inactivePagesStorageKey = useMemo(
72
+ () => `Lovalingo_inactive_pages:${resolvedApiKey || "anonymous"}`,
73
+ [resolvedApiKey]
74
+ );
75
+ const [nonLocalizedPaths, setNonLocalizedPaths] = useState(() => {
76
+ if (typeof window === "undefined") return [];
77
+ if (!resolvedApiKey) return [];
78
+ try {
79
+ const raw = localStorage.getItem(nonLocalizedStorageKey);
80
+ if (!raw) return [];
81
+ const parsed = JSON.parse(raw);
82
+ return parseBootstrapNonLocalizedPaths(parsed);
83
+ } catch {
84
+ return [];
85
+ }
86
+ });
87
+ const [inactivePages, setInactivePages] = useState(() => {
88
+ if (typeof window === "undefined") return [];
89
+ if (!resolvedApiKey) return [];
90
+ try {
91
+ const raw = localStorage.getItem(inactivePagesStorageKey);
92
+ if (!raw) return [];
93
+ const parsed = JSON.parse(raw);
94
+ return parseBootstrapInactivePages(parsed);
95
+ } catch {
96
+ return [];
97
+ }
98
+ });
99
+ const [routingStatus, setRoutingStatus] = useState(() => {
100
+ if (!resolvedApiKey) return "unknown";
101
+ return nonLocalizedPaths.length > 0 || inactivePages.length > 0 ? "ready" : "loading";
102
+ });
103
+ const fetchRoutingConfig = useCallback(async () => {
104
+ if (typeof window === "undefined") return;
105
+ if (!resolvedApiKey) return;
106
+ const pathParam = window.location.pathname + window.location.search;
107
+ const requestUrl = `${resolvedApiBase}/functions/v1/bootstrap?key=${encodeURIComponent(resolvedApiKey)}&locale=${encodeURIComponent(defaultLang)}&path=${encodeURIComponent(pathParam)}`;
108
+ const response = await fetch(requestUrl);
109
+ const resolvedResponse = response.status === 304 ? await fetch(requestUrl, { cache: "force-cache" }) : response;
110
+ if (!resolvedResponse.ok) throw new Error(`bootstrap HTTP ${resolvedResponse.status}`);
111
+ const data = await resolvedResponse.json();
112
+ const record = data || {};
113
+ return {
114
+ nonLocalizedPaths: parseBootstrapNonLocalizedPaths(record["non_localized_paths"]),
115
+ inactivePages: parseBootstrapInactivePages(record["inactive_pages"])
116
+ };
117
+ }, [defaultLang, resolvedApiBase, resolvedApiKey]);
118
+ useEffect(() => {
119
+ let cancelled = false;
120
+ void (async () => {
121
+ if (!resolvedApiKey) return;
122
+ setRoutingStatus((prev) => prev === "ready" ? prev : "loading");
123
+ try {
124
+ const next = await fetchRoutingConfig();
125
+ if (cancelled || !next) return;
126
+ setNonLocalizedPaths(next.nonLocalizedPaths);
127
+ setInactivePages(next.inactivePages);
128
+ setRoutingStatus("ready");
129
+ try {
130
+ localStorage.setItem(nonLocalizedStorageKey, JSON.stringify(next.nonLocalizedPaths));
131
+ localStorage.setItem(inactivePagesStorageKey, JSON.stringify(next.inactivePages));
132
+ } catch {
133
+ }
134
+ } catch (err) {
135
+ if (cancelled) return;
136
+ setRoutingStatus("error");
137
+ logDebug("[Lovalingo] Failed to fetch routing config:", err);
138
+ }
139
+ })();
140
+ return () => {
141
+ cancelled = true;
142
+ };
143
+ }, [fetchRoutingConfig, inactivePagesStorageKey, nonLocalizedStorageKey, resolvedApiKey]);
144
+ return /* @__PURE__ */ React.createElement(BrowserRouter, null, /* @__PURE__ */ React.createElement(NavigateExporter, { navigateRef }), /* @__PURE__ */ React.createElement(LangRoutingContext.Provider, { value: { defaultLang, nonLocalizedPaths, inactivePages, status: routingStatus } }, /* @__PURE__ */ React.createElement(Routes, null, langs.map((lang) => /* @__PURE__ */ React.createElement(
145
+ Route,
146
+ {
147
+ key: lang,
148
+ path: `${lang}/*`,
149
+ element: /* @__PURE__ */ React.createElement(LangGuard, { lang, nonLocalizedPaths, defaultLang })
150
+ },
151
+ /* @__PURE__ */ React.createElement(Route, { index: true, element: /* @__PURE__ */ React.createElement(React.Fragment, null, children) }),
152
+ /* @__PURE__ */ React.createElement(Route, { path: "*", element: /* @__PURE__ */ React.createElement(React.Fragment, null, children) })
153
+ )), /* @__PURE__ */ React.createElement(
154
+ Route,
155
+ {
156
+ path: "*",
157
+ element: /* @__PURE__ */ React.createElement(
158
+ RedirectToDefaultLang,
159
+ {
160
+ defaultLang,
161
+ nonLocalizedPaths,
162
+ routingStatus
163
+ },
164
+ children
165
+ )
166
+ }
167
+ ))));
168
+ }
169
+
170
+ // src/components/LangLink.tsx
171
+ import React2 from "react";
172
+ import { Link } from "react-router-dom";
173
+
174
+ // src/hooks/useLang.ts
175
+ import { useParams } from "react-router-dom";
176
+ import { useContext } from "react";
177
+ function useLang() {
178
+ const ctxLang = useContext(LangContext);
179
+ const { lang } = useParams();
180
+ return ctxLang ?? lang ?? "en";
181
+ }
182
+
183
+ // src/components/LangLink.tsx
184
+ import { useContext as useContext2 } from "react";
185
+ function LangLink({ to, ...props }) {
186
+ const lang = useLang();
187
+ const routing = useContext2(LangRoutingContext);
188
+ const langTo = typeof to === "string" ? (() => {
189
+ const trimmed = (to || "").toString().trim();
190
+ const normalized = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
191
+ return isNonLocalizedPath(normalized, routing.nonLocalizedPaths) ? normalized : `/${lang}${normalized}`;
192
+ })() : to;
193
+ return /* @__PURE__ */ React2.createElement(Link, { ...props, to: langTo });
194
+ }
195
+
196
+ // src/hooks/useLangNavigate.ts
197
+ import { useNavigate as useNavigate2 } from "react-router-dom";
198
+ import { useCallback as useCallback2, useContext as useContext3 } from "react";
199
+ function useLangNavigate() {
200
+ const navigate = useNavigate2();
201
+ const lang = useLang();
202
+ const routing = useContext3(LangRoutingContext);
203
+ return useCallback2(
204
+ (path, options) => {
205
+ const trimmed = (path || "").toString().trim();
206
+ if (!trimmed) return;
207
+ const normalized = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
208
+ const fullPath = isNonLocalizedPath(normalized, routing.nonLocalizedPaths) ? normalized : `/${lang}${normalized}`;
209
+ navigate(fullPath, options);
210
+ },
211
+ [lang, navigate, routing.nonLocalizedPaths]
212
+ );
213
+ }
214
+
215
+ export {
216
+ LangRouter,
217
+ useLang,
218
+ LangLink,
219
+ useLangNavigate
220
+ };
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+
3
+ /**
4
+ * Path Normalization Utility
5
+ *
6
+ * Normalizes URL paths by replacing dynamic segments (UUIDs, IDs, slugs)
7
+ * with placeholders to enable translation bundle sharing across similar pages.
8
+ *
9
+ * Example:
10
+ * /dashboard/projects/4458eb10-608c-4622-a92e-ec3ed2eeb524/setup
11
+ * → /dashboard/projects/:id/setup
12
+ */
13
+ interface PathNormalizationRule {
14
+ pattern: string;
15
+ replacement: string;
16
+ includeSubpaths?: boolean;
17
+ }
18
+ interface PathNormalizationConfig {
19
+ enabled: boolean;
20
+ rules?: PathNormalizationRule[];
21
+ supportedLocales?: string[];
22
+ }
23
+
24
+ interface LovalingoConfig {
25
+ /**
26
+ * Public project key (safe to expose in the browser).
27
+ */
28
+ publicAnonKey?: string;
29
+ apiKey?: string;
30
+ defaultLocale: string;
31
+ locales: string[];
32
+ apiBase?: string;
33
+ routing?: 'query' | 'path';
34
+ autoPrefixLinks?: boolean;
35
+ overlayBgColor?: string;
36
+ switcherPosition?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
37
+ switcherOffsetY?: number;
38
+ switcherTheme?: 'dark' | 'light';
39
+ editMode?: boolean;
40
+ editKey?: string;
41
+ pathNormalization?: PathNormalizationConfig;
42
+ mode?: 'dom';
43
+ autoApplyRules?: boolean;
44
+ }
45
+ interface LovalingoContextValue {
46
+ locale: string;
47
+ setLocale: (locale: string) => void;
48
+ isLoading: boolean;
49
+ translationMap: Record<string, string>;
50
+ config: LovalingoConfig;
51
+ translateElement: (element: HTMLElement) => void;
52
+ translateDOM: () => void;
53
+ editMode: boolean;
54
+ toggleEditMode: () => void;
55
+ excludeElement: (selector: string) => Promise<void>;
56
+ }
57
+ interface Translation {
58
+ source_text: string;
59
+ translated_text: string;
60
+ source_locale: string;
61
+ target_locale: string;
62
+ content_hash?: string;
63
+ }
64
+ interface Exclusion {
65
+ selector: string;
66
+ type: 'css' | 'xpath';
67
+ }
68
+ type DomRuleType = 'replace_text' | 'set_attribute' | 'set_html' | 'add_class' | 'remove' | 'css' | 'script';
69
+ interface DomRule {
70
+ id: string;
71
+ rule_type: DomRuleType;
72
+ selector?: string | null;
73
+ page_path?: string | null;
74
+ locale?: string | null;
75
+ payload?: {
76
+ matchText?: string;
77
+ text?: string;
78
+ attribute?: string;
79
+ value?: string;
80
+ html?: string;
81
+ className?: string;
82
+ css?: string;
83
+ script?: string;
84
+ };
85
+ }
86
+
87
+ interface LovalingoProviderProps extends LovalingoConfig {
88
+ children: React.ReactNode;
89
+ sitemap?: boolean;
90
+ seo?: boolean;
91
+ navigateRef?: React.MutableRefObject<((path: string) => void) | undefined>;
92
+ }
93
+ declare const LovalingoProvider: React.FC<LovalingoProviderProps>;
94
+
95
+ interface LanguageSwitcherProps {
96
+ locales: string[];
97
+ currentLocale: string;
98
+ onLocaleChange: (locale: string) => void;
99
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
100
+ offsetY?: number;
101
+ theme?: 'dark' | 'light';
102
+ branding?: {
103
+ required?: boolean;
104
+ enabled?: boolean;
105
+ label?: string;
106
+ href?: string;
107
+ };
108
+ }
109
+ declare const LanguageSwitcher: React.FC<LanguageSwitcherProps>;
110
+
111
+ declare const useLovalingo: () => {
112
+ locale: string;
113
+ setLocale: (locale: string) => void;
114
+ isLoading: boolean;
115
+ config: LovalingoConfig;
116
+ };
117
+
118
+ declare const useLovalingoTranslate: () => {
119
+ translateElement: (element: HTMLElement) => void;
120
+ translateDOM: () => void;
121
+ };
122
+
123
+ declare const useLovalingoEdit: () => {
124
+ editMode: boolean;
125
+ toggleEditMode: () => void;
126
+ excludeElement: (selector: string) => Promise<void>;
127
+ };
128
+
129
+ declare const VERSION = "0.6.0";
130
+
131
+ export { type DomRule, type DomRuleType, type Exclusion, LanguageSwitcher, type LovalingoConfig, type LovalingoContextValue, LovalingoProvider, type Translation, VERSION, useLovalingo, useLovalingoEdit, useLovalingoTranslate };
package/dist/core.d.ts ADDED
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+
3
+ /**
4
+ * Path Normalization Utility
5
+ *
6
+ * Normalizes URL paths by replacing dynamic segments (UUIDs, IDs, slugs)
7
+ * with placeholders to enable translation bundle sharing across similar pages.
8
+ *
9
+ * Example:
10
+ * /dashboard/projects/4458eb10-608c-4622-a92e-ec3ed2eeb524/setup
11
+ * → /dashboard/projects/:id/setup
12
+ */
13
+ interface PathNormalizationRule {
14
+ pattern: string;
15
+ replacement: string;
16
+ includeSubpaths?: boolean;
17
+ }
18
+ interface PathNormalizationConfig {
19
+ enabled: boolean;
20
+ rules?: PathNormalizationRule[];
21
+ supportedLocales?: string[];
22
+ }
23
+
24
+ interface LovalingoConfig {
25
+ /**
26
+ * Public project key (safe to expose in the browser).
27
+ */
28
+ publicAnonKey?: string;
29
+ apiKey?: string;
30
+ defaultLocale: string;
31
+ locales: string[];
32
+ apiBase?: string;
33
+ routing?: 'query' | 'path';
34
+ autoPrefixLinks?: boolean;
35
+ overlayBgColor?: string;
36
+ switcherPosition?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
37
+ switcherOffsetY?: number;
38
+ switcherTheme?: 'dark' | 'light';
39
+ editMode?: boolean;
40
+ editKey?: string;
41
+ pathNormalization?: PathNormalizationConfig;
42
+ mode?: 'dom';
43
+ autoApplyRules?: boolean;
44
+ }
45
+ interface LovalingoContextValue {
46
+ locale: string;
47
+ setLocale: (locale: string) => void;
48
+ isLoading: boolean;
49
+ translationMap: Record<string, string>;
50
+ config: LovalingoConfig;
51
+ translateElement: (element: HTMLElement) => void;
52
+ translateDOM: () => void;
53
+ editMode: boolean;
54
+ toggleEditMode: () => void;
55
+ excludeElement: (selector: string) => Promise<void>;
56
+ }
57
+ interface Translation {
58
+ source_text: string;
59
+ translated_text: string;
60
+ source_locale: string;
61
+ target_locale: string;
62
+ content_hash?: string;
63
+ }
64
+ interface Exclusion {
65
+ selector: string;
66
+ type: 'css' | 'xpath';
67
+ }
68
+ type DomRuleType = 'replace_text' | 'set_attribute' | 'set_html' | 'add_class' | 'remove' | 'css' | 'script';
69
+ interface DomRule {
70
+ id: string;
71
+ rule_type: DomRuleType;
72
+ selector?: string | null;
73
+ page_path?: string | null;
74
+ locale?: string | null;
75
+ payload?: {
76
+ matchText?: string;
77
+ text?: string;
78
+ attribute?: string;
79
+ value?: string;
80
+ html?: string;
81
+ className?: string;
82
+ css?: string;
83
+ script?: string;
84
+ };
85
+ }
86
+
87
+ interface LovalingoProviderProps extends LovalingoConfig {
88
+ children: React.ReactNode;
89
+ sitemap?: boolean;
90
+ seo?: boolean;
91
+ navigateRef?: React.MutableRefObject<((path: string) => void) | undefined>;
92
+ }
93
+ declare const LovalingoProvider: React.FC<LovalingoProviderProps>;
94
+
95
+ interface LanguageSwitcherProps {
96
+ locales: string[];
97
+ currentLocale: string;
98
+ onLocaleChange: (locale: string) => void;
99
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
100
+ offsetY?: number;
101
+ theme?: 'dark' | 'light';
102
+ branding?: {
103
+ required?: boolean;
104
+ enabled?: boolean;
105
+ label?: string;
106
+ href?: string;
107
+ };
108
+ }
109
+ declare const LanguageSwitcher: React.FC<LanguageSwitcherProps>;
110
+
111
+ declare const useLovalingo: () => {
112
+ locale: string;
113
+ setLocale: (locale: string) => void;
114
+ isLoading: boolean;
115
+ config: LovalingoConfig;
116
+ };
117
+
118
+ declare const useLovalingoTranslate: () => {
119
+ translateElement: (element: HTMLElement) => void;
120
+ translateDOM: () => void;
121
+ };
122
+
123
+ declare const useLovalingoEdit: () => {
124
+ editMode: boolean;
125
+ toggleEditMode: () => void;
126
+ excludeElement: (selector: string) => Promise<void>;
127
+ };
128
+
129
+ declare const VERSION = "0.6.0";
130
+
131
+ export { type DomRule, type DomRuleType, type Exclusion, LanguageSwitcher, type LovalingoConfig, type LovalingoContextValue, LovalingoProvider, type Translation, VERSION, useLovalingo, useLovalingoEdit, useLovalingoTranslate };