@procore/ai-translations 0.4.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.d.mts +3 -2
- package/dist/legacy/index.d.ts +3 -2
- package/dist/legacy/index.js +238 -95
- package/dist/legacy/index.mjs +238 -95
- package/dist/modern/index.d.mts +3 -2
- package/dist/modern/index.d.ts +3 -2
- package/dist/modern/index.js +237 -93
- package/dist/modern/index.mjs +237 -93
- package/package.json +1 -1
package/dist/modern/index.js
CHANGED
|
@@ -77,6 +77,9 @@ var Config = class _Config {
|
|
|
77
77
|
setToolName(name) {
|
|
78
78
|
this.toolName = name;
|
|
79
79
|
}
|
|
80
|
+
isBackendTranslationStrategy() {
|
|
81
|
+
return this.ToolConfig.strategy === "backend_translations";
|
|
82
|
+
}
|
|
80
83
|
getToolName() {
|
|
81
84
|
return this.toolName;
|
|
82
85
|
}
|
|
@@ -264,10 +267,10 @@ var Hash = class {
|
|
|
264
267
|
var QueueManager = class {
|
|
265
268
|
constructor() {
|
|
266
269
|
if (!globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__) {
|
|
267
|
-
globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__ = /* @__PURE__ */ new
|
|
270
|
+
globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__ = /* @__PURE__ */ new Map();
|
|
268
271
|
}
|
|
269
272
|
if (!globalThis.__AI_TRANSLATION_BACKEND_QUEUE__) {
|
|
270
|
-
globalThis.__AI_TRANSLATION_BACKEND_QUEUE__ = /* @__PURE__ */ new
|
|
273
|
+
globalThis.__AI_TRANSLATION_BACKEND_QUEUE__ = /* @__PURE__ */ new Map();
|
|
271
274
|
}
|
|
272
275
|
}
|
|
273
276
|
getQueue(strategy) {
|
|
@@ -280,41 +283,20 @@ var QueueManager = class {
|
|
|
280
283
|
return void 0;
|
|
281
284
|
}
|
|
282
285
|
add(entry) {
|
|
283
|
-
this.getQueue(entry.translationStrategy)
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const queue = this.getQueue(strategy);
|
|
287
|
-
if (!queue) {
|
|
288
|
-
throw new Error("Invalid translation strategy");
|
|
289
|
-
}
|
|
290
|
-
if (queue.size === 0) {
|
|
291
|
-
console.warn("No translations to process");
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
const batch = config2.getToolConfig().translationBatchSize;
|
|
295
|
-
let batches = [];
|
|
296
|
-
for (const entry of queue.values()) {
|
|
297
|
-
batches.push(entry);
|
|
298
|
-
if (batches.length >= batch) {
|
|
299
|
-
yield batches;
|
|
300
|
-
batches = [];
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (batches.length > 0) {
|
|
304
|
-
queue.clear();
|
|
305
|
-
yield batches;
|
|
306
|
-
}
|
|
286
|
+
const queue = this.getQueue(entry.translationStrategy);
|
|
287
|
+
if (!queue || queue.has(entry.id)) return;
|
|
288
|
+
queue.set(entry.id, entry);
|
|
307
289
|
}
|
|
308
|
-
*
|
|
290
|
+
*generateBatches(config2) {
|
|
309
291
|
const queue = this.getQueue(config2.getToolConfig().strategy);
|
|
310
292
|
if (!queue) throw new Error("Invalid translation strategy");
|
|
311
293
|
const batchSize = config2.getToolConfig().translationBatchSize;
|
|
312
294
|
while (queue.size > 0) {
|
|
313
295
|
const batch = [];
|
|
314
296
|
while (batch.length < batchSize && queue.size > 0) {
|
|
315
|
-
const
|
|
316
|
-
queue.delete(
|
|
317
|
-
batch.push(
|
|
297
|
+
const [key, entry] = queue.entries().next().value;
|
|
298
|
+
queue.delete(key);
|
|
299
|
+
batch.push(entry);
|
|
318
300
|
}
|
|
319
301
|
yield batch;
|
|
320
302
|
}
|
|
@@ -435,6 +417,19 @@ var Storage = class _Storage {
|
|
|
435
417
|
}
|
|
436
418
|
}
|
|
437
419
|
// ------------------------------------
|
|
420
|
+
// 🗑️ Clear Translation by ID
|
|
421
|
+
// ------------------------------------
|
|
422
|
+
static async deleteById(id) {
|
|
423
|
+
try {
|
|
424
|
+
const db = await _Storage.getDB();
|
|
425
|
+
await db.delete(_Storage.STORE_NAME, id);
|
|
426
|
+
return true;
|
|
427
|
+
} catch (error) {
|
|
428
|
+
console.error("[Storage] Failed to delete by id:", error);
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// ------------------------------------
|
|
438
433
|
// 🗑️ Clear All Translations
|
|
439
434
|
// ------------------------------------
|
|
440
435
|
static async clearAll() {
|
|
@@ -463,6 +458,7 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
463
458
|
static memoryCache = /* @__PURE__ */ new Map();
|
|
464
459
|
static originalTextIndex = /* @__PURE__ */ new Map();
|
|
465
460
|
static nonRetryableTexts = /* @__PURE__ */ new Set();
|
|
461
|
+
static enqueuedItems = /* @__PURE__ */ new Set();
|
|
466
462
|
tool;
|
|
467
463
|
constructor(tool) {
|
|
468
464
|
this.tool = tool;
|
|
@@ -516,10 +512,42 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
516
512
|
isNonRetryable(key) {
|
|
517
513
|
return _TranslationRegistry.nonRetryableTexts.has(key);
|
|
518
514
|
}
|
|
519
|
-
|
|
515
|
+
enqueue(enqueuedKey) {
|
|
516
|
+
_TranslationRegistry.enqueuedItems.add(enqueuedKey);
|
|
517
|
+
}
|
|
518
|
+
isEnqueued(enqueuedKey) {
|
|
519
|
+
return _TranslationRegistry.enqueuedItems.has(enqueuedKey);
|
|
520
|
+
}
|
|
521
|
+
clearEnqueued() {
|
|
522
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
523
|
+
}
|
|
524
|
+
async removeTextsFromEnqueued(texts, targetLanguage, strategy) {
|
|
525
|
+
for (const text of texts) {
|
|
526
|
+
const id = await Storage.generateId(text, targetLanguage, this.tool);
|
|
527
|
+
_TranslationRegistry.enqueuedItems.delete(
|
|
528
|
+
this.generateEnqueuedKey(id, strategy)
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
static removeFromEnqueued(key) {
|
|
533
|
+
_TranslationRegistry.enqueuedItems.delete(key);
|
|
534
|
+
}
|
|
535
|
+
generateEnqueuedKey(id, strategy) {
|
|
536
|
+
return `${id}:${strategy}`;
|
|
537
|
+
}
|
|
538
|
+
async get(text, targetLanguage, tool, config2) {
|
|
520
539
|
const key = await Hash.generateFromMultiple([text, targetLanguage, tool]);
|
|
521
|
-
|
|
522
|
-
|
|
540
|
+
const cached = _TranslationRegistry.memoryCache.get(key);
|
|
541
|
+
if (cached) {
|
|
542
|
+
if (cached.translationStrategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
|
|
543
|
+
_TranslationRegistry.memoryCache.delete(key);
|
|
544
|
+
if (cached.translatedText) {
|
|
545
|
+
_TranslationRegistry.originalTextIndex.delete(cached.translatedText);
|
|
546
|
+
}
|
|
547
|
+
await Storage.deleteById(key);
|
|
548
|
+
return void 0;
|
|
549
|
+
}
|
|
550
|
+
return cached;
|
|
523
551
|
}
|
|
524
552
|
const translation = await Storage.getTranslation(
|
|
525
553
|
text,
|
|
@@ -527,6 +555,10 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
527
555
|
tool
|
|
528
556
|
);
|
|
529
557
|
if (translation !== void 0) {
|
|
558
|
+
if (translation.translation_strategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
|
|
559
|
+
await Storage.deleteById(translation.id);
|
|
560
|
+
return void 0;
|
|
561
|
+
}
|
|
530
562
|
return this.toTranslationRegistryEntry(translation);
|
|
531
563
|
}
|
|
532
564
|
return void 0;
|
|
@@ -541,6 +573,7 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
541
573
|
async clear() {
|
|
542
574
|
_TranslationRegistry.memoryCache.clear();
|
|
543
575
|
_TranslationRegistry.originalTextIndex.clear();
|
|
576
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
544
577
|
await Storage.clearAll();
|
|
545
578
|
return;
|
|
546
579
|
}
|
|
@@ -548,6 +581,7 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
548
581
|
await Storage.deleteByToolAndStrategy(tool, strategy);
|
|
549
582
|
_TranslationRegistry.memoryCache.clear();
|
|
550
583
|
_TranslationRegistry.originalTextIndex.clear();
|
|
584
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
551
585
|
return;
|
|
552
586
|
}
|
|
553
587
|
toTranslationRegistryEntry(translation) {
|
|
@@ -569,10 +603,16 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
569
603
|
translation.id
|
|
570
604
|
);
|
|
571
605
|
const newTranslation = this.toTranslationRegistryEntry(translation);
|
|
606
|
+
const enqueuedKey = this.generateEnqueuedKey(
|
|
607
|
+
translation.id,
|
|
608
|
+
translation.translation_strategy
|
|
609
|
+
);
|
|
572
610
|
if (currentTranslation && !this.shouldUpdateTranslation(currentTranslation, newTranslation)) {
|
|
611
|
+
_TranslationRegistry.removeFromEnqueued(enqueuedKey);
|
|
573
612
|
continue;
|
|
574
613
|
}
|
|
575
614
|
this.setTranslationToRegistry(newTranslation);
|
|
615
|
+
_TranslationRegistry.removeFromEnqueued(enqueuedKey);
|
|
576
616
|
}
|
|
577
617
|
return;
|
|
578
618
|
}
|
|
@@ -622,12 +662,13 @@ var EventHandler = class {
|
|
|
622
662
|
this.aiTranslationEvents = new import_web_sdk_events.SystemEvents(this.sourceEventIdentifier);
|
|
623
663
|
this.toolName = toolName;
|
|
624
664
|
}
|
|
625
|
-
publishTranslationCompleteEvent(sourceTranslatedTexts, nonRetryableTexts) {
|
|
665
|
+
publishTranslationCompleteEvent(sourceTranslatedTexts, nonRetryableTexts, retryableFailedTexts = []) {
|
|
626
666
|
this.aiTranslationEvents.publish(
|
|
627
667
|
this.withEventName(TRANSLATION_COMPLETE_EVENT_NAME),
|
|
628
668
|
{
|
|
629
669
|
sourceTranslatedTexts,
|
|
630
|
-
nonRetryableTexts
|
|
670
|
+
nonRetryableTexts,
|
|
671
|
+
retryableFailedTexts
|
|
631
672
|
}
|
|
632
673
|
);
|
|
633
674
|
}
|
|
@@ -639,7 +680,14 @@ var EventHandler = class {
|
|
|
639
680
|
detail.data?.sourceTranslatedTexts
|
|
640
681
|
) ? detail.data.sourceTranslatedTexts : [];
|
|
641
682
|
const nonRetryableTexts = Array.isArray(detail.data?.nonRetryableTexts) ? detail.data.nonRetryableTexts : [];
|
|
642
|
-
|
|
683
|
+
const retryableFailedTexts = Array.isArray(
|
|
684
|
+
detail.data?.retryableFailedTexts
|
|
685
|
+
) ? detail.data.retryableFailedTexts : [];
|
|
686
|
+
callback(
|
|
687
|
+
sourceTranslatedTexts,
|
|
688
|
+
nonRetryableTexts,
|
|
689
|
+
retryableFailedTexts
|
|
690
|
+
);
|
|
643
691
|
}
|
|
644
692
|
);
|
|
645
693
|
}
|
|
@@ -728,6 +776,7 @@ var TranslationManager = class {
|
|
|
728
776
|
currentTranslatorStrategy;
|
|
729
777
|
sourceTexts = /* @__PURE__ */ new Map();
|
|
730
778
|
nonRetryableTexts = /* @__PURE__ */ new Set();
|
|
779
|
+
retryableFailedTexts = /* @__PURE__ */ new Map();
|
|
731
780
|
progressEventHandler;
|
|
732
781
|
translationProgress = {
|
|
733
782
|
progress: 0,
|
|
@@ -756,19 +805,21 @@ var TranslationManager = class {
|
|
|
756
805
|
this.translationProgress.total = queueManager.queueSize(
|
|
757
806
|
this.currentTranslatorStrategy
|
|
758
807
|
);
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
808
|
+
do {
|
|
809
|
+
for (const batch of queueManager.generateBatches(
|
|
810
|
+
this.translator.getConfig()
|
|
811
|
+
)) {
|
|
812
|
+
batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
|
|
813
|
+
const result = await this.translator.processTranslations(
|
|
814
|
+
batch.map(
|
|
815
|
+
(entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
|
|
816
|
+
)
|
|
817
|
+
);
|
|
818
|
+
this.setTranslationProgress(batch.length);
|
|
819
|
+
await this.updateDatabaseWithTranslations(result);
|
|
820
|
+
await this.notifyTranslationCompleted();
|
|
821
|
+
}
|
|
822
|
+
} while (queueManager.queueSize(this.currentTranslatorStrategy) > 0);
|
|
772
823
|
this.resetTranslationProgress();
|
|
773
824
|
this.publishTranslationProgress();
|
|
774
825
|
if (this.currentTranslatorStrategy === "frontend_translations") {
|
|
@@ -787,6 +838,7 @@ var TranslationManager = class {
|
|
|
787
838
|
continue;
|
|
788
839
|
}
|
|
789
840
|
if (!translation.isTranslated) {
|
|
841
|
+
this.addRetryableFailedText(response.tool, translation.sourceText);
|
|
790
842
|
continue;
|
|
791
843
|
}
|
|
792
844
|
this.addSourceTextToMap(response.tool, translation.sourceText);
|
|
@@ -806,12 +858,14 @@ var TranslationManager = class {
|
|
|
806
858
|
const eventhandler = new EventHandler(mfe);
|
|
807
859
|
eventhandler.publishTranslationCompleteEvent(
|
|
808
860
|
Array.from(this.sourceTexts.get(mfe) ?? /* @__PURE__ */ new Set()),
|
|
809
|
-
Array.from(this.nonRetryableTexts)
|
|
861
|
+
Array.from(this.nonRetryableTexts),
|
|
862
|
+
Array.from(this.retryableFailedTexts.get(mfe) ?? /* @__PURE__ */ new Set())
|
|
810
863
|
);
|
|
811
864
|
}
|
|
812
865
|
this.mfeToBeNotified.clear();
|
|
813
866
|
this.sourceTexts.clear();
|
|
814
867
|
this.nonRetryableTexts.clear();
|
|
868
|
+
this.retryableFailedTexts.clear();
|
|
815
869
|
}
|
|
816
870
|
setTranslationProgress(batchSize) {
|
|
817
871
|
this.translationProgress.current += batchSize;
|
|
@@ -848,6 +902,11 @@ var TranslationManager = class {
|
|
|
848
902
|
existing.add(sourceText);
|
|
849
903
|
this.sourceTexts.set(tool, existing);
|
|
850
904
|
}
|
|
905
|
+
addRetryableFailedText(tool, sourceText) {
|
|
906
|
+
const existing = this.retryableFailedTexts.get(tool) ?? /* @__PURE__ */ new Set();
|
|
907
|
+
existing.add(sourceText);
|
|
908
|
+
this.retryableFailedTexts.set(tool, existing);
|
|
909
|
+
}
|
|
851
910
|
publishTranslationProgress() {
|
|
852
911
|
this.progressEventHandler.publishTranslationProgressEvent(
|
|
853
912
|
this.translationProgress.progress,
|
|
@@ -914,8 +973,16 @@ var Client = class {
|
|
|
914
973
|
method: "POST",
|
|
915
974
|
body: JSON.stringify(requests)
|
|
916
975
|
});
|
|
976
|
+
const responseBody = Array.isArray(data) ? data.map((group) => ({
|
|
977
|
+
...group,
|
|
978
|
+
translations: Array.isArray(group.translations) ? group.translations.map((t) => ({
|
|
979
|
+
...t,
|
|
980
|
+
isTranslated: t.isTranslated ?? (!!t.translation && t.translation !== ""),
|
|
981
|
+
retryable: t.retryable ?? true
|
|
982
|
+
})) : []
|
|
983
|
+
})) : data;
|
|
917
984
|
return {
|
|
918
|
-
responseBody
|
|
985
|
+
responseBody,
|
|
919
986
|
success: true
|
|
920
987
|
};
|
|
921
988
|
} catch (error) {
|
|
@@ -992,12 +1059,55 @@ var getModelDownloadEventHandler = () => {
|
|
|
992
1059
|
}
|
|
993
1060
|
return _modelDownloadEventHandler;
|
|
994
1061
|
};
|
|
1062
|
+
var SUPPORTED_LANGUAGES = /* @__PURE__ */ new Set([
|
|
1063
|
+
"ar",
|
|
1064
|
+
"bn",
|
|
1065
|
+
"bg",
|
|
1066
|
+
"zh",
|
|
1067
|
+
"hr",
|
|
1068
|
+
"cs",
|
|
1069
|
+
"da",
|
|
1070
|
+
"nl",
|
|
1071
|
+
"en",
|
|
1072
|
+
"fi",
|
|
1073
|
+
"fr",
|
|
1074
|
+
"de",
|
|
1075
|
+
"el",
|
|
1076
|
+
"he",
|
|
1077
|
+
"hi",
|
|
1078
|
+
"hu",
|
|
1079
|
+
"id",
|
|
1080
|
+
"it",
|
|
1081
|
+
"ja",
|
|
1082
|
+
"kn",
|
|
1083
|
+
"ko",
|
|
1084
|
+
"lt",
|
|
1085
|
+
"mr",
|
|
1086
|
+
"no",
|
|
1087
|
+
"pl",
|
|
1088
|
+
"pt",
|
|
1089
|
+
"ro",
|
|
1090
|
+
"ru",
|
|
1091
|
+
"sk",
|
|
1092
|
+
"sl",
|
|
1093
|
+
"es",
|
|
1094
|
+
"sv",
|
|
1095
|
+
"ta",
|
|
1096
|
+
"te",
|
|
1097
|
+
"th",
|
|
1098
|
+
"tr",
|
|
1099
|
+
"uk",
|
|
1100
|
+
"vi"
|
|
1101
|
+
]);
|
|
995
1102
|
var ChromeTranslator = class _ChromeTranslator {
|
|
996
1103
|
translator;
|
|
997
1104
|
constructor(translator) {
|
|
998
1105
|
this.translator = translator;
|
|
999
1106
|
}
|
|
1000
|
-
static
|
|
1107
|
+
static translatorReadyPromises = /* @__PURE__ */ new Map();
|
|
1108
|
+
static isSupportedLanguage(lang) {
|
|
1109
|
+
return SUPPORTED_LANGUAGES.has(lang) || SUPPORTED_LANGUAGES.has(lang.split("-")[0] ?? "");
|
|
1110
|
+
}
|
|
1001
1111
|
static ensureRegistry() {
|
|
1002
1112
|
if (!globalThis.chromeTranslatorRegistry) {
|
|
1003
1113
|
globalThis.chromeTranslatorRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1019,30 +1129,31 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1019
1129
|
);
|
|
1020
1130
|
}
|
|
1021
1131
|
static async createTranslator(source, target) {
|
|
1132
|
+
const key = this.generateKey(source, target);
|
|
1022
1133
|
let resolveReady;
|
|
1023
|
-
|
|
1134
|
+
const readyPromise = new Promise((resolve) => {
|
|
1024
1135
|
resolveReady = resolve;
|
|
1025
1136
|
});
|
|
1137
|
+
this.translatorReadyPromises.set(key, readyPromise);
|
|
1026
1138
|
let isDownloading = false;
|
|
1027
1139
|
const translator = await Translator.create({
|
|
1028
1140
|
sourceLanguage: source,
|
|
1029
1141
|
targetLanguage: target,
|
|
1030
1142
|
monitor(m) {
|
|
1031
|
-
m.addEventListener(
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
}
|
|
1143
|
+
m.addEventListener("downloadprogress", (e) => {
|
|
1144
|
+
isDownloading = true;
|
|
1145
|
+
const loaded = e.loaded ?? 0;
|
|
1146
|
+
const total = e.total ?? 0;
|
|
1147
|
+
const progress = total > 0 ? Math.round(loaded / total * 100) : 0;
|
|
1148
|
+
getModelDownloadEventHandler().publishModelDownloadProgressEvent(
|
|
1149
|
+
loaded,
|
|
1150
|
+
total,
|
|
1151
|
+
progress
|
|
1152
|
+
);
|
|
1153
|
+
if (total > 0 && loaded >= total) {
|
|
1154
|
+
resolveReady();
|
|
1044
1155
|
}
|
|
1045
|
-
);
|
|
1156
|
+
});
|
|
1046
1157
|
}
|
|
1047
1158
|
});
|
|
1048
1159
|
if (!isDownloading) {
|
|
@@ -1050,8 +1161,8 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1050
1161
|
}
|
|
1051
1162
|
return translator;
|
|
1052
1163
|
}
|
|
1053
|
-
static waitForReady() {
|
|
1054
|
-
return this.
|
|
1164
|
+
static waitForReady(key) {
|
|
1165
|
+
return this.translatorReadyPromises.get(key) ?? Promise.resolve();
|
|
1055
1166
|
}
|
|
1056
1167
|
static async translate(text, targetLanguage) {
|
|
1057
1168
|
this.ensureRegistry();
|
|
@@ -1059,8 +1170,17 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1059
1170
|
const detector = await ChromeLanguageDetector.getInstance();
|
|
1060
1171
|
const sourceLanguage = await detector.detectLanguage(text);
|
|
1061
1172
|
const key = this.generateKey(sourceLanguage, targetLanguage);
|
|
1062
|
-
|
|
1063
|
-
|
|
1173
|
+
if (!this.isSupportedLanguage(sourceLanguage) || !this.isSupportedLanguage(targetLanguage)) {
|
|
1174
|
+
return {
|
|
1175
|
+
translation: text,
|
|
1176
|
+
sourceLanguage,
|
|
1177
|
+
success: false,
|
|
1178
|
+
retryable: false,
|
|
1179
|
+
errorMessage: `Unsupported language pair: ${sourceLanguage} \u2192 ${targetLanguage}`
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
const existingInstance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1183
|
+
if (!existingInstance) {
|
|
1064
1184
|
const translatorCapabilities = await Translator.availability({
|
|
1065
1185
|
sourceLanguage,
|
|
1066
1186
|
targetLanguage
|
|
@@ -1078,10 +1198,16 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1078
1198
|
sourceLanguage,
|
|
1079
1199
|
targetLanguage
|
|
1080
1200
|
);
|
|
1081
|
-
|
|
1082
|
-
|
|
1201
|
+
if (!globalThis.chromeTranslatorRegistry.has(key)) {
|
|
1202
|
+
globalThis.chromeTranslatorRegistry.set(
|
|
1203
|
+
key,
|
|
1204
|
+
new _ChromeTranslator(chromeTranslator)
|
|
1205
|
+
);
|
|
1206
|
+
}
|
|
1083
1207
|
}
|
|
1084
|
-
|
|
1208
|
+
const instance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1209
|
+
await this.waitForReady(key);
|
|
1210
|
+
this.translatorReadyPromises.delete(key);
|
|
1085
1211
|
const translation = await instance.translator?.translate(text);
|
|
1086
1212
|
if (!translation) {
|
|
1087
1213
|
return {
|
|
@@ -1089,7 +1215,7 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1089
1215
|
sourceLanguage,
|
|
1090
1216
|
success: false,
|
|
1091
1217
|
errorMessage: "Translation failed",
|
|
1092
|
-
retryable:
|
|
1218
|
+
retryable: false
|
|
1093
1219
|
};
|
|
1094
1220
|
}
|
|
1095
1221
|
return {
|
|
@@ -1099,11 +1225,12 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1099
1225
|
retryable: true
|
|
1100
1226
|
};
|
|
1101
1227
|
} catch (error) {
|
|
1228
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1102
1229
|
return {
|
|
1103
1230
|
translation: text,
|
|
1104
1231
|
sourceLanguage: targetLanguage,
|
|
1105
1232
|
success: false,
|
|
1106
|
-
errorMessage:
|
|
1233
|
+
errorMessage: message,
|
|
1107
1234
|
retryable: true
|
|
1108
1235
|
};
|
|
1109
1236
|
}
|
|
@@ -1260,13 +1387,22 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
|
|
|
1260
1387
|
const existingByOriginal = await translationRegistry.get(
|
|
1261
1388
|
text,
|
|
1262
1389
|
targetLanguage,
|
|
1263
|
-
tool
|
|
1390
|
+
tool,
|
|
1391
|
+
config2
|
|
1264
1392
|
);
|
|
1265
1393
|
if (existingByOriginal && existingByOriginal.isTranslated && existingByOriginal.translatedText && existingByOriginal.translatedText.trim() !== "") {
|
|
1266
1394
|
return existingByOriginal.translatedText;
|
|
1267
1395
|
}
|
|
1268
1396
|
if (!existingByOriginal) {
|
|
1397
|
+
const id = await Storage.generateId(text, targetLanguage, tool);
|
|
1398
|
+
const strategy = config2.getToolConfig().strategy;
|
|
1399
|
+
const enqueuedKey = translationRegistry.generateEnqueuedKey(id, strategy);
|
|
1400
|
+
if (translationRegistry.isEnqueued(enqueuedKey)) {
|
|
1401
|
+
return text;
|
|
1402
|
+
}
|
|
1403
|
+
translationRegistry.enqueue(enqueuedKey);
|
|
1269
1404
|
queueManager.add({
|
|
1405
|
+
id,
|
|
1270
1406
|
originalText: text,
|
|
1271
1407
|
targetLanguage,
|
|
1272
1408
|
tool,
|
|
@@ -1330,12 +1466,17 @@ function AITranslationInnerProvider(props) {
|
|
|
1330
1466
|
});
|
|
1331
1467
|
(0, import_react.useEffect)(() => {
|
|
1332
1468
|
const unsubscribe = eventHandler.current.subscribeToTranslationCompleteEvent(
|
|
1333
|
-
async (sourceTranslatedTexts, nonRetryableTexts) => {
|
|
1469
|
+
async (sourceTranslatedTexts, nonRetryableTexts, retryableFailedTexts) => {
|
|
1334
1470
|
try {
|
|
1335
1471
|
await translationRegistry.current.populateRegistryFromDatabase();
|
|
1336
1472
|
translationRegistry.current.populateNonRetryableTexts(
|
|
1337
1473
|
nonRetryableTexts
|
|
1338
1474
|
);
|
|
1475
|
+
translationRegistry.current.removeTextsFromEnqueued(
|
|
1476
|
+
retryableFailedTexts,
|
|
1477
|
+
locale,
|
|
1478
|
+
config2.getToolConfig().strategy
|
|
1479
|
+
);
|
|
1339
1480
|
eventHandler.current.publishRerenderEvent(sourceTranslatedTexts);
|
|
1340
1481
|
} catch (error) {
|
|
1341
1482
|
console.error(
|
|
@@ -1346,7 +1487,7 @@ function AITranslationInnerProvider(props) {
|
|
|
1346
1487
|
}
|
|
1347
1488
|
);
|
|
1348
1489
|
return () => unsubscribe();
|
|
1349
|
-
}, []);
|
|
1490
|
+
}, [locale, config2]);
|
|
1350
1491
|
(0, import_react.useEffect)(() => {
|
|
1351
1492
|
const unsubscribe = eventHandler.current.subscribeToTranslationProgressEvent(
|
|
1352
1493
|
(progress, current, total) => {
|
|
@@ -1364,15 +1505,15 @@ function AITranslationInnerProvider(props) {
|
|
|
1364
1505
|
return () => unsubscribe();
|
|
1365
1506
|
}, []);
|
|
1366
1507
|
(0, import_react.useEffect)(() => {
|
|
1367
|
-
if (isFetched
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1508
|
+
if (!isFetched || !remoteConfig) return;
|
|
1509
|
+
const toolConfig = remoteConfig[tool] ?? remoteConfig;
|
|
1510
|
+
setConfig((prevConfig) => {
|
|
1511
|
+
const clonedConfig = prevConfig.clone();
|
|
1512
|
+
clonedConfig.setTargetLanguage(locale);
|
|
1513
|
+
clonedConfig.setToolConfig(toolConfig);
|
|
1514
|
+
translator.current.updateConfig(clonedConfig);
|
|
1515
|
+
return clonedConfig;
|
|
1516
|
+
});
|
|
1376
1517
|
}, [tool, remoteConfig, isFetched, locale]);
|
|
1377
1518
|
config2.setTargetLanguage(locale);
|
|
1378
1519
|
config2.setToolName(tool);
|
|
@@ -1429,6 +1570,7 @@ var TranslatedIcon = ({
|
|
|
1429
1570
|
className,
|
|
1430
1571
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1431
1572
|
"aria-hidden": "true",
|
|
1573
|
+
style: { marginRight: "10px", flexShrink: 0 },
|
|
1432
1574
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1433
1575
|
"path",
|
|
1434
1576
|
{
|
|
@@ -1463,12 +1605,14 @@ var AITranslateText = ({
|
|
|
1463
1605
|
return;
|
|
1464
1606
|
}
|
|
1465
1607
|
if (sourceTexts.includes(text)) {
|
|
1466
|
-
|
|
1608
|
+
const translatedText = await context.ait(text);
|
|
1609
|
+
setDisplayText(translatedText);
|
|
1610
|
+
setShowHighlightState(showHighlight && translatedText !== text);
|
|
1467
1611
|
}
|
|
1468
1612
|
}
|
|
1469
1613
|
);
|
|
1470
1614
|
return () => unsubscribe();
|
|
1471
|
-
}, [context, text]);
|
|
1615
|
+
}, [context, text, showHighlight]);
|
|
1472
1616
|
const reset = (0, import_react4.useCallback)(
|
|
1473
1617
|
(displayValue = text) => {
|
|
1474
1618
|
setDisplayText(displayValue);
|
|
@@ -1491,7 +1635,7 @@ var AITranslateText = ({
|
|
|
1491
1635
|
const translatedText = await context.ait(text);
|
|
1492
1636
|
if (cancelled) return;
|
|
1493
1637
|
setDisplayText(translatedText);
|
|
1494
|
-
setShowHighlightState(showHighlight);
|
|
1638
|
+
setShowHighlightState(showHighlight && translatedText !== text);
|
|
1495
1639
|
} catch {
|
|
1496
1640
|
if (cancelled) return;
|
|
1497
1641
|
reset();
|
|
@@ -1503,8 +1647,8 @@ var AITranslateText = ({
|
|
|
1503
1647
|
};
|
|
1504
1648
|
}, [text, shouldTranslate, context, showHighlight, reset]);
|
|
1505
1649
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1506
|
-
|
|
1507
|
-
|
|
1650
|
+
showHighlightState && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TranslatedIcon, { ...translatedIconProps }),
|
|
1651
|
+
displayText
|
|
1508
1652
|
] });
|
|
1509
1653
|
};
|
|
1510
1654
|
|