@procore/ai-translations 0.5.0 → 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.
- package/dist/legacy/index.js +158 -55
- package/dist/legacy/index.mjs +158 -55
- package/dist/modern/index.js +158 -55
- package/dist/modern/index.mjs +158 -55
- package/package.json +1 -1
package/dist/modern/index.mjs
CHANGED
|
@@ -46,6 +46,9 @@ var Config = class _Config {
|
|
|
46
46
|
setToolName(name) {
|
|
47
47
|
this.toolName = name;
|
|
48
48
|
}
|
|
49
|
+
isBackendTranslationStrategy() {
|
|
50
|
+
return this.ToolConfig.strategy === "backend_translations";
|
|
51
|
+
}
|
|
49
52
|
getToolName() {
|
|
50
53
|
return this.toolName;
|
|
51
54
|
}
|
|
@@ -389,6 +392,19 @@ var Storage = class _Storage {
|
|
|
389
392
|
}
|
|
390
393
|
}
|
|
391
394
|
// ------------------------------------
|
|
395
|
+
// 🗑️ Clear Translation by ID
|
|
396
|
+
// ------------------------------------
|
|
397
|
+
static async deleteById(id) {
|
|
398
|
+
try {
|
|
399
|
+
const db = await _Storage.getDB();
|
|
400
|
+
await db.delete(_Storage.STORE_NAME, id);
|
|
401
|
+
return true;
|
|
402
|
+
} catch (error) {
|
|
403
|
+
console.error("[Storage] Failed to delete by id:", error);
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// ------------------------------------
|
|
392
408
|
// 🗑️ Clear All Translations
|
|
393
409
|
// ------------------------------------
|
|
394
410
|
static async clearAll() {
|
|
@@ -483,7 +499,9 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
483
499
|
async removeTextsFromEnqueued(texts, targetLanguage, strategy) {
|
|
484
500
|
for (const text of texts) {
|
|
485
501
|
const id = await Storage.generateId(text, targetLanguage, this.tool);
|
|
486
|
-
_TranslationRegistry.enqueuedItems.delete(
|
|
502
|
+
_TranslationRegistry.enqueuedItems.delete(
|
|
503
|
+
this.generateEnqueuedKey(id, strategy)
|
|
504
|
+
);
|
|
487
505
|
}
|
|
488
506
|
}
|
|
489
507
|
static removeFromEnqueued(key) {
|
|
@@ -492,10 +510,19 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
492
510
|
generateEnqueuedKey(id, strategy) {
|
|
493
511
|
return `${id}:${strategy}`;
|
|
494
512
|
}
|
|
495
|
-
async get(text, targetLanguage, tool) {
|
|
513
|
+
async get(text, targetLanguage, tool, config2) {
|
|
496
514
|
const key = await Hash.generateFromMultiple([text, targetLanguage, tool]);
|
|
497
|
-
|
|
498
|
-
|
|
515
|
+
const cached = _TranslationRegistry.memoryCache.get(key);
|
|
516
|
+
if (cached) {
|
|
517
|
+
if (cached.translationStrategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
|
|
518
|
+
_TranslationRegistry.memoryCache.delete(key);
|
|
519
|
+
if (cached.translatedText) {
|
|
520
|
+
_TranslationRegistry.originalTextIndex.delete(cached.translatedText);
|
|
521
|
+
}
|
|
522
|
+
await Storage.deleteById(key);
|
|
523
|
+
return void 0;
|
|
524
|
+
}
|
|
525
|
+
return cached;
|
|
499
526
|
}
|
|
500
527
|
const translation = await Storage.getTranslation(
|
|
501
528
|
text,
|
|
@@ -503,6 +530,10 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
503
530
|
tool
|
|
504
531
|
);
|
|
505
532
|
if (translation !== void 0) {
|
|
533
|
+
if (translation.translation_strategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
|
|
534
|
+
await Storage.deleteById(translation.id);
|
|
535
|
+
return void 0;
|
|
536
|
+
}
|
|
506
537
|
return this.toTranslationRegistryEntry(translation);
|
|
507
538
|
}
|
|
508
539
|
return void 0;
|
|
@@ -749,19 +780,21 @@ var TranslationManager = class {
|
|
|
749
780
|
this.translationProgress.total = queueManager.queueSize(
|
|
750
781
|
this.currentTranslatorStrategy
|
|
751
782
|
);
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
783
|
+
do {
|
|
784
|
+
for (const batch of queueManager.generateBatches(
|
|
785
|
+
this.translator.getConfig()
|
|
786
|
+
)) {
|
|
787
|
+
batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
|
|
788
|
+
const result = await this.translator.processTranslations(
|
|
789
|
+
batch.map(
|
|
790
|
+
(entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
|
|
791
|
+
)
|
|
792
|
+
);
|
|
793
|
+
this.setTranslationProgress(batch.length);
|
|
794
|
+
await this.updateDatabaseWithTranslations(result);
|
|
795
|
+
await this.notifyTranslationCompleted();
|
|
796
|
+
}
|
|
797
|
+
} while (queueManager.queueSize(this.currentTranslatorStrategy) > 0);
|
|
765
798
|
this.resetTranslationProgress();
|
|
766
799
|
this.publishTranslationProgress();
|
|
767
800
|
if (this.currentTranslatorStrategy === "frontend_translations") {
|
|
@@ -915,8 +948,16 @@ var Client = class {
|
|
|
915
948
|
method: "POST",
|
|
916
949
|
body: JSON.stringify(requests)
|
|
917
950
|
});
|
|
951
|
+
const responseBody = Array.isArray(data) ? data.map((group) => ({
|
|
952
|
+
...group,
|
|
953
|
+
translations: Array.isArray(group.translations) ? group.translations.map((t) => ({
|
|
954
|
+
...t,
|
|
955
|
+
isTranslated: t.isTranslated ?? (!!t.translation && t.translation !== ""),
|
|
956
|
+
retryable: t.retryable ?? true
|
|
957
|
+
})) : []
|
|
958
|
+
})) : data;
|
|
918
959
|
return {
|
|
919
|
-
responseBody
|
|
960
|
+
responseBody,
|
|
920
961
|
success: true
|
|
921
962
|
};
|
|
922
963
|
} catch (error) {
|
|
@@ -993,12 +1034,55 @@ var getModelDownloadEventHandler = () => {
|
|
|
993
1034
|
}
|
|
994
1035
|
return _modelDownloadEventHandler;
|
|
995
1036
|
};
|
|
1037
|
+
var SUPPORTED_LANGUAGES = /* @__PURE__ */ new Set([
|
|
1038
|
+
"ar",
|
|
1039
|
+
"bn",
|
|
1040
|
+
"bg",
|
|
1041
|
+
"zh",
|
|
1042
|
+
"hr",
|
|
1043
|
+
"cs",
|
|
1044
|
+
"da",
|
|
1045
|
+
"nl",
|
|
1046
|
+
"en",
|
|
1047
|
+
"fi",
|
|
1048
|
+
"fr",
|
|
1049
|
+
"de",
|
|
1050
|
+
"el",
|
|
1051
|
+
"he",
|
|
1052
|
+
"hi",
|
|
1053
|
+
"hu",
|
|
1054
|
+
"id",
|
|
1055
|
+
"it",
|
|
1056
|
+
"ja",
|
|
1057
|
+
"kn",
|
|
1058
|
+
"ko",
|
|
1059
|
+
"lt",
|
|
1060
|
+
"mr",
|
|
1061
|
+
"no",
|
|
1062
|
+
"pl",
|
|
1063
|
+
"pt",
|
|
1064
|
+
"ro",
|
|
1065
|
+
"ru",
|
|
1066
|
+
"sk",
|
|
1067
|
+
"sl",
|
|
1068
|
+
"es",
|
|
1069
|
+
"sv",
|
|
1070
|
+
"ta",
|
|
1071
|
+
"te",
|
|
1072
|
+
"th",
|
|
1073
|
+
"tr",
|
|
1074
|
+
"uk",
|
|
1075
|
+
"vi"
|
|
1076
|
+
]);
|
|
996
1077
|
var ChromeTranslator = class _ChromeTranslator {
|
|
997
1078
|
translator;
|
|
998
1079
|
constructor(translator) {
|
|
999
1080
|
this.translator = translator;
|
|
1000
1081
|
}
|
|
1001
|
-
static
|
|
1082
|
+
static translatorReadyPromises = /* @__PURE__ */ new Map();
|
|
1083
|
+
static isSupportedLanguage(lang) {
|
|
1084
|
+
return SUPPORTED_LANGUAGES.has(lang) || SUPPORTED_LANGUAGES.has(lang.split("-")[0] ?? "");
|
|
1085
|
+
}
|
|
1002
1086
|
static ensureRegistry() {
|
|
1003
1087
|
if (!globalThis.chromeTranslatorRegistry) {
|
|
1004
1088
|
globalThis.chromeTranslatorRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1020,30 +1104,31 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1020
1104
|
);
|
|
1021
1105
|
}
|
|
1022
1106
|
static async createTranslator(source, target) {
|
|
1107
|
+
const key = this.generateKey(source, target);
|
|
1023
1108
|
let resolveReady;
|
|
1024
|
-
|
|
1109
|
+
const readyPromise = new Promise((resolve) => {
|
|
1025
1110
|
resolveReady = resolve;
|
|
1026
1111
|
});
|
|
1112
|
+
this.translatorReadyPromises.set(key, readyPromise);
|
|
1027
1113
|
let isDownloading = false;
|
|
1028
1114
|
const translator = await Translator.create({
|
|
1029
1115
|
sourceLanguage: source,
|
|
1030
1116
|
targetLanguage: target,
|
|
1031
1117
|
monitor(m) {
|
|
1032
|
-
m.addEventListener(
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
}
|
|
1118
|
+
m.addEventListener("downloadprogress", (e) => {
|
|
1119
|
+
isDownloading = true;
|
|
1120
|
+
const loaded = e.loaded ?? 0;
|
|
1121
|
+
const total = e.total ?? 0;
|
|
1122
|
+
const progress = total > 0 ? Math.round(loaded / total * 100) : 0;
|
|
1123
|
+
getModelDownloadEventHandler().publishModelDownloadProgressEvent(
|
|
1124
|
+
loaded,
|
|
1125
|
+
total,
|
|
1126
|
+
progress
|
|
1127
|
+
);
|
|
1128
|
+
if (total > 0 && loaded >= total) {
|
|
1129
|
+
resolveReady();
|
|
1045
1130
|
}
|
|
1046
|
-
);
|
|
1131
|
+
});
|
|
1047
1132
|
}
|
|
1048
1133
|
});
|
|
1049
1134
|
if (!isDownloading) {
|
|
@@ -1051,8 +1136,8 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1051
1136
|
}
|
|
1052
1137
|
return translator;
|
|
1053
1138
|
}
|
|
1054
|
-
static waitForReady() {
|
|
1055
|
-
return this.
|
|
1139
|
+
static waitForReady(key) {
|
|
1140
|
+
return this.translatorReadyPromises.get(key) ?? Promise.resolve();
|
|
1056
1141
|
}
|
|
1057
1142
|
static async translate(text, targetLanguage) {
|
|
1058
1143
|
this.ensureRegistry();
|
|
@@ -1060,8 +1145,17 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1060
1145
|
const detector = await ChromeLanguageDetector.getInstance();
|
|
1061
1146
|
const sourceLanguage = await detector.detectLanguage(text);
|
|
1062
1147
|
const key = this.generateKey(sourceLanguage, targetLanguage);
|
|
1063
|
-
|
|
1064
|
-
|
|
1148
|
+
if (!this.isSupportedLanguage(sourceLanguage) || !this.isSupportedLanguage(targetLanguage)) {
|
|
1149
|
+
return {
|
|
1150
|
+
translation: text,
|
|
1151
|
+
sourceLanguage,
|
|
1152
|
+
success: false,
|
|
1153
|
+
retryable: false,
|
|
1154
|
+
errorMessage: `Unsupported language pair: ${sourceLanguage} \u2192 ${targetLanguage}`
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
const existingInstance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1158
|
+
if (!existingInstance) {
|
|
1065
1159
|
const translatorCapabilities = await Translator.availability({
|
|
1066
1160
|
sourceLanguage,
|
|
1067
1161
|
targetLanguage
|
|
@@ -1079,10 +1173,16 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1079
1173
|
sourceLanguage,
|
|
1080
1174
|
targetLanguage
|
|
1081
1175
|
);
|
|
1082
|
-
|
|
1083
|
-
|
|
1176
|
+
if (!globalThis.chromeTranslatorRegistry.has(key)) {
|
|
1177
|
+
globalThis.chromeTranslatorRegistry.set(
|
|
1178
|
+
key,
|
|
1179
|
+
new _ChromeTranslator(chromeTranslator)
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1084
1182
|
}
|
|
1085
|
-
|
|
1183
|
+
const instance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1184
|
+
await this.waitForReady(key);
|
|
1185
|
+
this.translatorReadyPromises.delete(key);
|
|
1086
1186
|
const translation = await instance.translator?.translate(text);
|
|
1087
1187
|
if (!translation) {
|
|
1088
1188
|
return {
|
|
@@ -1090,7 +1190,7 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1090
1190
|
sourceLanguage,
|
|
1091
1191
|
success: false,
|
|
1092
1192
|
errorMessage: "Translation failed",
|
|
1093
|
-
retryable:
|
|
1193
|
+
retryable: false
|
|
1094
1194
|
};
|
|
1095
1195
|
}
|
|
1096
1196
|
return {
|
|
@@ -1100,11 +1200,12 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1100
1200
|
retryable: true
|
|
1101
1201
|
};
|
|
1102
1202
|
} catch (error) {
|
|
1203
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1103
1204
|
return {
|
|
1104
1205
|
translation: text,
|
|
1105
1206
|
sourceLanguage: targetLanguage,
|
|
1106
1207
|
success: false,
|
|
1107
|
-
errorMessage:
|
|
1208
|
+
errorMessage: message,
|
|
1108
1209
|
retryable: true
|
|
1109
1210
|
};
|
|
1110
1211
|
}
|
|
@@ -1261,7 +1362,8 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
|
|
|
1261
1362
|
const existingByOriginal = await translationRegistry.get(
|
|
1262
1363
|
text,
|
|
1263
1364
|
targetLanguage,
|
|
1264
|
-
tool
|
|
1365
|
+
tool,
|
|
1366
|
+
config2
|
|
1265
1367
|
);
|
|
1266
1368
|
if (existingByOriginal && existingByOriginal.isTranslated && existingByOriginal.translatedText && existingByOriginal.translatedText.trim() !== "") {
|
|
1267
1369
|
return existingByOriginal.translatedText;
|
|
@@ -1378,15 +1480,15 @@ function AITranslationInnerProvider(props) {
|
|
|
1378
1480
|
return () => unsubscribe();
|
|
1379
1481
|
}, []);
|
|
1380
1482
|
useEffect(() => {
|
|
1381
|
-
if (isFetched
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
}
|
|
1483
|
+
if (!isFetched || !remoteConfig) return;
|
|
1484
|
+
const toolConfig = remoteConfig[tool] ?? remoteConfig;
|
|
1485
|
+
setConfig((prevConfig) => {
|
|
1486
|
+
const clonedConfig = prevConfig.clone();
|
|
1487
|
+
clonedConfig.setTargetLanguage(locale);
|
|
1488
|
+
clonedConfig.setToolConfig(toolConfig);
|
|
1489
|
+
translator.current.updateConfig(clonedConfig);
|
|
1490
|
+
return clonedConfig;
|
|
1491
|
+
});
|
|
1390
1492
|
}, [tool, remoteConfig, isFetched, locale]);
|
|
1391
1493
|
config2.setTargetLanguage(locale);
|
|
1392
1494
|
config2.setToolName(tool);
|
|
@@ -1449,6 +1551,7 @@ var TranslatedIcon = ({
|
|
|
1449
1551
|
className,
|
|
1450
1552
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1451
1553
|
"aria-hidden": "true",
|
|
1554
|
+
style: { marginRight: "10px", flexShrink: 0 },
|
|
1452
1555
|
children: /* @__PURE__ */ jsx2(
|
|
1453
1556
|
"path",
|
|
1454
1557
|
{
|
|
@@ -1525,8 +1628,8 @@ var AITranslateText = ({
|
|
|
1525
1628
|
};
|
|
1526
1629
|
}, [text, shouldTranslate, context, showHighlight, reset]);
|
|
1527
1630
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1528
|
-
|
|
1529
|
-
|
|
1631
|
+
showHighlightState && /* @__PURE__ */ jsx3(TranslatedIcon, { ...translatedIconProps }),
|
|
1632
|
+
displayText
|
|
1530
1633
|
] });
|
|
1531
1634
|
};
|
|
1532
1635
|
|
package/package.json
CHANGED