@lovalingo/lovalingo 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +6 -3
- package/dist/components/AixsterProvider.js +46 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/logger.js +17 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
LOVALINGO COMMERCIAL LICENSE
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 Lovalingo Swiss. All rights reserved.
|
|
4
4
|
|
|
5
5
|
NOTICE: This software and associated documentation files (the "Software") are the
|
|
6
6
|
proprietary and confidential information of Lovalingo Swiss.
|
|
@@ -143,6 +143,6 @@ please contact Lovalingo Swiss.
|
|
|
143
143
|
|
|
144
144
|
MERTENS ADVIES
|
|
145
145
|
Lovalingo Translation Platform
|
|
146
|
-
©
|
|
146
|
+
© 2026 All Rights Reserved
|
|
147
147
|
|
|
148
148
|
Website: [Contact Lovalingo Swiss for licensing information]
|
package/README.md
CHANGED
|
@@ -21,7 +21,10 @@ The runtime now marks translatable text nodes deterministically and exposes mark
|
|
|
21
21
|
- Coverage is enforced server-side (jobs fail if marker coverage is below the threshold).
|
|
22
22
|
- This is a breaking change: older runtimes will be rejected by the pipeline.
|
|
23
23
|
|
|
24
|
-
Debug (runtime logs):
|
|
24
|
+
Debug (runtime logs):
|
|
25
|
+
- append `?lovalingoDebug=1` to the URL (works across reloads)
|
|
26
|
+
- or run `localStorage.setItem("Lovalingo_debug","1")` and reload
|
|
27
|
+
- or set `window.__lovalingoDebug = true` (same-tab only; not persistent)
|
|
25
28
|
|
|
26
29
|
## Installation
|
|
27
30
|
|
|
@@ -137,7 +140,7 @@ You still need to serve `/sitemap.xml` on your own domain (recommended: reverse-
|
|
|
137
140
|
|
|
138
141
|
## License
|
|
139
142
|
|
|
140
|
-
Commercial license (not open source). See `
|
|
143
|
+
Commercial license (not open source). See `LICENSE`.
|
|
141
144
|
|
|
142
145
|
Manual translation control:
|
|
143
146
|
|
|
@@ -349,7 +352,7 @@ export async function GET() {
|
|
|
349
352
|
|
|
350
353
|
**COMMERCIAL LICENSE - NOT OPEN SOURCE**
|
|
351
354
|
|
|
352
|
-
Copyright (c)
|
|
355
|
+
Copyright (c) 2026 Lovalingo Swiss. All rights reserved.
|
|
353
356
|
|
|
354
357
|
### For Agencies & Developers
|
|
355
358
|
|
|
@@ -641,6 +641,7 @@ navigateRef, // For path mode routing
|
|
|
641
641
|
if (previousLocale && previousLocale !== defaultLocale) {
|
|
642
642
|
logDebug(`[Lovalingo] Switching from ${previousLocale} to ${targetLocale}`);
|
|
643
643
|
}
|
|
644
|
+
let revealedViaCachedCritical = false;
|
|
644
645
|
const cachedCritical = readCriticalCache(targetLocale, normalizedPath);
|
|
645
646
|
if (cachedCritical?.loading_bg_color) {
|
|
646
647
|
setCachedLoadingBgColor(cachedCritical.loading_bg_color);
|
|
@@ -656,6 +657,7 @@ navigateRef, // For path mode routing
|
|
|
656
657
|
applyActiveTranslations(document.body);
|
|
657
658
|
}
|
|
658
659
|
disablePrehide();
|
|
660
|
+
revealedViaCachedCritical = true;
|
|
659
661
|
}
|
|
660
662
|
const bootstrap = await apiRef.current.fetchBootstrap(targetLocale, currentPath);
|
|
661
663
|
const nextEntitlements = bootstrap?.entitlements || apiRef.current.getEntitlements();
|
|
@@ -694,6 +696,7 @@ navigateRef, // For path mode routing
|
|
|
694
696
|
const criticalMap = bootstrap?.critical?.map && typeof bootstrap.critical.map === "object" && !Array.isArray(bootstrap.critical.map)
|
|
695
697
|
? bootstrap.critical.map
|
|
696
698
|
: {};
|
|
699
|
+
const hasBootstrapCritical = Object.keys(criticalMap).length > 0;
|
|
697
700
|
if (Object.keys(criticalMap).length > 0) {
|
|
698
701
|
setActiveTranslations(toTranslations(criticalMap, targetLocale));
|
|
699
702
|
if (mode === "dom") {
|
|
@@ -714,6 +717,37 @@ navigateRef, // For path mode routing
|
|
|
714
717
|
exclusions,
|
|
715
718
|
loading_bg_color: bootstrap?.loading_bg_color && /^#[0-9a-fA-F]{6}$/.test(bootstrap.loading_bg_color) ? bootstrap.loading_bg_color : null,
|
|
716
719
|
});
|
|
720
|
+
const shouldWaitForBundle = !revealedViaCachedCritical && !hasBootstrapCritical;
|
|
721
|
+
if (shouldWaitForBundle) {
|
|
722
|
+
// Why: if there's no critical slice for first paint, wait for the bundle (within the prehide failsafe) to avoid a visible flash.
|
|
723
|
+
const bundle = await apiRef.current.fetchBundle(targetLocale, currentPath);
|
|
724
|
+
if (bundle?.map && typeof bundle.map === "object") {
|
|
725
|
+
const translations = toTranslations(bundle.map, targetLocale);
|
|
726
|
+
if (translations.length > 0) {
|
|
727
|
+
translationCacheRef.current.set(cacheKey, { translations });
|
|
728
|
+
setActiveTranslations(translations);
|
|
729
|
+
if (mode === "dom") {
|
|
730
|
+
applyActiveTranslations(document.body);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
// Lazy-load the full page bundle after first paint.
|
|
737
|
+
void (async () => {
|
|
738
|
+
const bundle = await apiRef.current.fetchBundle(targetLocale, currentPath);
|
|
739
|
+
if (!bundle || !bundle.map)
|
|
740
|
+
return;
|
|
741
|
+
const translations = toTranslations(bundle.map, targetLocale);
|
|
742
|
+
if (translations.length === 0)
|
|
743
|
+
return;
|
|
744
|
+
translationCacheRef.current.set(cacheKey, { translations });
|
|
745
|
+
setActiveTranslations(translations);
|
|
746
|
+
if (mode === "dom") {
|
|
747
|
+
applyActiveTranslations(document.body);
|
|
748
|
+
}
|
|
749
|
+
})();
|
|
750
|
+
}
|
|
717
751
|
disablePrehide();
|
|
718
752
|
// Delayed retry scan to catch late-rendering content
|
|
719
753
|
retryTimeoutRef.current = setTimeout(() => {
|
|
@@ -730,20 +764,6 @@ navigateRef, // For path mode routing
|
|
|
730
764
|
applyDomRules(rules);
|
|
731
765
|
}
|
|
732
766
|
}, 500);
|
|
733
|
-
// Lazy-load the full page bundle after first paint.
|
|
734
|
-
void (async () => {
|
|
735
|
-
const bundle = await apiRef.current.fetchBundle(targetLocale, currentPath);
|
|
736
|
-
if (!bundle || !bundle.map)
|
|
737
|
-
return;
|
|
738
|
-
const translations = toTranslations(bundle.map, targetLocale);
|
|
739
|
-
if (translations.length === 0)
|
|
740
|
-
return;
|
|
741
|
-
translationCacheRef.current.set(cacheKey, { translations });
|
|
742
|
-
setActiveTranslations(translations);
|
|
743
|
-
if (mode === "dom") {
|
|
744
|
-
applyActiveTranslations(document.body);
|
|
745
|
-
}
|
|
746
|
-
})();
|
|
747
767
|
}
|
|
748
768
|
catch (error) {
|
|
749
769
|
errorDebug('Error loading translations:', error);
|
|
@@ -903,14 +923,23 @@ navigateRef, // For path mode routing
|
|
|
903
923
|
});
|
|
904
924
|
}, [allLocales, defaultLocale, locale, routing, loadData, navigateRef, routingConfig.nonLocalizedPaths]);
|
|
905
925
|
// No string-level "misses" from the client: the pipeline (Browser Rendering) is source-of-truth for string discovery.
|
|
926
|
+
// Why: prevent init/load effects from re-running (and calling bootstrap/bundle again) when loadData changes due to state updates.
|
|
927
|
+
const loadDataRef = useRef(loadData);
|
|
928
|
+
useEffect(() => {
|
|
929
|
+
loadDataRef.current = loadData;
|
|
930
|
+
}, [loadData]);
|
|
931
|
+
const detectLocaleRef = useRef(detectLocale);
|
|
932
|
+
useEffect(() => {
|
|
933
|
+
detectLocaleRef.current = detectLocale;
|
|
934
|
+
}, [detectLocale]);
|
|
906
935
|
// Initialize
|
|
907
936
|
useEffect(() => {
|
|
908
|
-
const initialLocale =
|
|
937
|
+
const initialLocale = detectLocaleRef.current();
|
|
909
938
|
lastNormalizedPathRef.current = processPath(window.location.pathname, enhancedPathConfig);
|
|
910
939
|
// Track initial page (fallback discovery for pages not present in the routes feed).
|
|
911
940
|
trackPageviewOnce(window.location.pathname + window.location.search);
|
|
912
941
|
// Always prefetch artifacts for the initial locale (pipeline-produced translations + rules).
|
|
913
|
-
|
|
942
|
+
loadDataRef.current(initialLocale);
|
|
914
943
|
// Set up keyboard shortcut for edit mode
|
|
915
944
|
const handleKeyPress = (e) => {
|
|
916
945
|
if (e.code === editKey && (e.ctrlKey || e.metaKey)) {
|
|
@@ -926,7 +955,7 @@ navigateRef, // For path mode routing
|
|
|
926
955
|
clearTimeout(retryTimeoutRef.current);
|
|
927
956
|
}
|
|
928
957
|
};
|
|
929
|
-
}, [
|
|
958
|
+
}, [editKey, enhancedPathConfig, trackPageviewOnce]);
|
|
930
959
|
// Auto-inject sitemap link tag
|
|
931
960
|
useEffect(() => {
|
|
932
961
|
if (sitemap && resolvedApiKey && isSeoActive()) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @Lovalingo/Lovalingo - Proprietary Translation Library
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c)
|
|
4
|
+
* Copyright (c) 2026 Lovalingo Swiss. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* This software is the intellectual property of Lovalingo Swiss.
|
|
7
7
|
* NOT OPEN SOURCE - All rights reserved.
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @Lovalingo/Lovalingo - Proprietary Translation Library
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c)
|
|
4
|
+
* Copyright (c) 2026 Lovalingo Swiss. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* This software is the intellectual property of Lovalingo Swiss.
|
|
7
7
|
* NOT OPEN SOURCE - All rights reserved.
|
package/dist/utils/logger.js
CHANGED
|
@@ -4,6 +4,23 @@ function isDebugEnabled() {
|
|
|
4
4
|
const value = globalThis.__lovalingoDebug;
|
|
5
5
|
if (value === true || value === "true" || value === 1)
|
|
6
6
|
return true;
|
|
7
|
+
try {
|
|
8
|
+
const params = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
|
|
9
|
+
const query = params?.get("lovalingoDebug") || params?.get("lovalingo_debug") || "";
|
|
10
|
+
if (query === "1" || query === "true")
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// ignore
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const stored = typeof window !== "undefined" ? window.localStorage?.getItem("Lovalingo_debug") : null;
|
|
18
|
+
if (stored === "1" || stored === "true")
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// ignore
|
|
23
|
+
}
|
|
7
24
|
return false;
|
|
8
25
|
}
|
|
9
26
|
export function logDebug(...args) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.5.
|
|
1
|
+
export declare const VERSION = "0.5.5";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.5.
|
|
1
|
+
export const VERSION = "0.5.5";
|
package/package.json
CHANGED