@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.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
|
}
|
|
@@ -239,10 +242,10 @@ var Hash = class {
|
|
|
239
242
|
var QueueManager = class {
|
|
240
243
|
constructor() {
|
|
241
244
|
if (!globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__) {
|
|
242
|
-
globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__ = /* @__PURE__ */ new
|
|
245
|
+
globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__ = /* @__PURE__ */ new Map();
|
|
243
246
|
}
|
|
244
247
|
if (!globalThis.__AI_TRANSLATION_BACKEND_QUEUE__) {
|
|
245
|
-
globalThis.__AI_TRANSLATION_BACKEND_QUEUE__ = /* @__PURE__ */ new
|
|
248
|
+
globalThis.__AI_TRANSLATION_BACKEND_QUEUE__ = /* @__PURE__ */ new Map();
|
|
246
249
|
}
|
|
247
250
|
}
|
|
248
251
|
getQueue(strategy) {
|
|
@@ -255,41 +258,20 @@ var QueueManager = class {
|
|
|
255
258
|
return void 0;
|
|
256
259
|
}
|
|
257
260
|
add(entry) {
|
|
258
|
-
this.getQueue(entry.translationStrategy)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const queue = this.getQueue(strategy);
|
|
262
|
-
if (!queue) {
|
|
263
|
-
throw new Error("Invalid translation strategy");
|
|
264
|
-
}
|
|
265
|
-
if (queue.size === 0) {
|
|
266
|
-
console.warn("No translations to process");
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
const batch = config2.getToolConfig().translationBatchSize;
|
|
270
|
-
let batches = [];
|
|
271
|
-
for (const entry of queue.values()) {
|
|
272
|
-
batches.push(entry);
|
|
273
|
-
if (batches.length >= batch) {
|
|
274
|
-
yield batches;
|
|
275
|
-
batches = [];
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (batches.length > 0) {
|
|
279
|
-
queue.clear();
|
|
280
|
-
yield batches;
|
|
281
|
-
}
|
|
261
|
+
const queue = this.getQueue(entry.translationStrategy);
|
|
262
|
+
if (!queue || queue.has(entry.id)) return;
|
|
263
|
+
queue.set(entry.id, entry);
|
|
282
264
|
}
|
|
283
|
-
*
|
|
265
|
+
*generateBatches(config2) {
|
|
284
266
|
const queue = this.getQueue(config2.getToolConfig().strategy);
|
|
285
267
|
if (!queue) throw new Error("Invalid translation strategy");
|
|
286
268
|
const batchSize = config2.getToolConfig().translationBatchSize;
|
|
287
269
|
while (queue.size > 0) {
|
|
288
270
|
const batch = [];
|
|
289
271
|
while (batch.length < batchSize && queue.size > 0) {
|
|
290
|
-
const
|
|
291
|
-
queue.delete(
|
|
292
|
-
batch.push(
|
|
272
|
+
const [key, entry] = queue.entries().next().value;
|
|
273
|
+
queue.delete(key);
|
|
274
|
+
batch.push(entry);
|
|
293
275
|
}
|
|
294
276
|
yield batch;
|
|
295
277
|
}
|
|
@@ -410,6 +392,19 @@ var Storage = class _Storage {
|
|
|
410
392
|
}
|
|
411
393
|
}
|
|
412
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
|
+
// ------------------------------------
|
|
413
408
|
// 🗑️ Clear All Translations
|
|
414
409
|
// ------------------------------------
|
|
415
410
|
static async clearAll() {
|
|
@@ -438,6 +433,7 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
438
433
|
static memoryCache = /* @__PURE__ */ new Map();
|
|
439
434
|
static originalTextIndex = /* @__PURE__ */ new Map();
|
|
440
435
|
static nonRetryableTexts = /* @__PURE__ */ new Set();
|
|
436
|
+
static enqueuedItems = /* @__PURE__ */ new Set();
|
|
441
437
|
tool;
|
|
442
438
|
constructor(tool) {
|
|
443
439
|
this.tool = tool;
|
|
@@ -491,10 +487,42 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
491
487
|
isNonRetryable(key) {
|
|
492
488
|
return _TranslationRegistry.nonRetryableTexts.has(key);
|
|
493
489
|
}
|
|
494
|
-
|
|
490
|
+
enqueue(enqueuedKey) {
|
|
491
|
+
_TranslationRegistry.enqueuedItems.add(enqueuedKey);
|
|
492
|
+
}
|
|
493
|
+
isEnqueued(enqueuedKey) {
|
|
494
|
+
return _TranslationRegistry.enqueuedItems.has(enqueuedKey);
|
|
495
|
+
}
|
|
496
|
+
clearEnqueued() {
|
|
497
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
498
|
+
}
|
|
499
|
+
async removeTextsFromEnqueued(texts, targetLanguage, strategy) {
|
|
500
|
+
for (const text of texts) {
|
|
501
|
+
const id = await Storage.generateId(text, targetLanguage, this.tool);
|
|
502
|
+
_TranslationRegistry.enqueuedItems.delete(
|
|
503
|
+
this.generateEnqueuedKey(id, strategy)
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
static removeFromEnqueued(key) {
|
|
508
|
+
_TranslationRegistry.enqueuedItems.delete(key);
|
|
509
|
+
}
|
|
510
|
+
generateEnqueuedKey(id, strategy) {
|
|
511
|
+
return `${id}:${strategy}`;
|
|
512
|
+
}
|
|
513
|
+
async get(text, targetLanguage, tool, config2) {
|
|
495
514
|
const key = await Hash.generateFromMultiple([text, targetLanguage, tool]);
|
|
496
|
-
|
|
497
|
-
|
|
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;
|
|
498
526
|
}
|
|
499
527
|
const translation = await Storage.getTranslation(
|
|
500
528
|
text,
|
|
@@ -502,6 +530,10 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
502
530
|
tool
|
|
503
531
|
);
|
|
504
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
|
+
}
|
|
505
537
|
return this.toTranslationRegistryEntry(translation);
|
|
506
538
|
}
|
|
507
539
|
return void 0;
|
|
@@ -516,6 +548,7 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
516
548
|
async clear() {
|
|
517
549
|
_TranslationRegistry.memoryCache.clear();
|
|
518
550
|
_TranslationRegistry.originalTextIndex.clear();
|
|
551
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
519
552
|
await Storage.clearAll();
|
|
520
553
|
return;
|
|
521
554
|
}
|
|
@@ -523,6 +556,7 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
523
556
|
await Storage.deleteByToolAndStrategy(tool, strategy);
|
|
524
557
|
_TranslationRegistry.memoryCache.clear();
|
|
525
558
|
_TranslationRegistry.originalTextIndex.clear();
|
|
559
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
526
560
|
return;
|
|
527
561
|
}
|
|
528
562
|
toTranslationRegistryEntry(translation) {
|
|
@@ -544,10 +578,16 @@ var TranslationRegistry = class _TranslationRegistry {
|
|
|
544
578
|
translation.id
|
|
545
579
|
);
|
|
546
580
|
const newTranslation = this.toTranslationRegistryEntry(translation);
|
|
581
|
+
const enqueuedKey = this.generateEnqueuedKey(
|
|
582
|
+
translation.id,
|
|
583
|
+
translation.translation_strategy
|
|
584
|
+
);
|
|
547
585
|
if (currentTranslation && !this.shouldUpdateTranslation(currentTranslation, newTranslation)) {
|
|
586
|
+
_TranslationRegistry.removeFromEnqueued(enqueuedKey);
|
|
548
587
|
continue;
|
|
549
588
|
}
|
|
550
589
|
this.setTranslationToRegistry(newTranslation);
|
|
590
|
+
_TranslationRegistry.removeFromEnqueued(enqueuedKey);
|
|
551
591
|
}
|
|
552
592
|
return;
|
|
553
593
|
}
|
|
@@ -597,12 +637,13 @@ var EventHandler = class {
|
|
|
597
637
|
this.aiTranslationEvents = new SystemEvents(this.sourceEventIdentifier);
|
|
598
638
|
this.toolName = toolName;
|
|
599
639
|
}
|
|
600
|
-
publishTranslationCompleteEvent(sourceTranslatedTexts, nonRetryableTexts) {
|
|
640
|
+
publishTranslationCompleteEvent(sourceTranslatedTexts, nonRetryableTexts, retryableFailedTexts = []) {
|
|
601
641
|
this.aiTranslationEvents.publish(
|
|
602
642
|
this.withEventName(TRANSLATION_COMPLETE_EVENT_NAME),
|
|
603
643
|
{
|
|
604
644
|
sourceTranslatedTexts,
|
|
605
|
-
nonRetryableTexts
|
|
645
|
+
nonRetryableTexts,
|
|
646
|
+
retryableFailedTexts
|
|
606
647
|
}
|
|
607
648
|
);
|
|
608
649
|
}
|
|
@@ -614,7 +655,14 @@ var EventHandler = class {
|
|
|
614
655
|
detail.data?.sourceTranslatedTexts
|
|
615
656
|
) ? detail.data.sourceTranslatedTexts : [];
|
|
616
657
|
const nonRetryableTexts = Array.isArray(detail.data?.nonRetryableTexts) ? detail.data.nonRetryableTexts : [];
|
|
617
|
-
|
|
658
|
+
const retryableFailedTexts = Array.isArray(
|
|
659
|
+
detail.data?.retryableFailedTexts
|
|
660
|
+
) ? detail.data.retryableFailedTexts : [];
|
|
661
|
+
callback(
|
|
662
|
+
sourceTranslatedTexts,
|
|
663
|
+
nonRetryableTexts,
|
|
664
|
+
retryableFailedTexts
|
|
665
|
+
);
|
|
618
666
|
}
|
|
619
667
|
);
|
|
620
668
|
}
|
|
@@ -703,6 +751,7 @@ var TranslationManager = class {
|
|
|
703
751
|
currentTranslatorStrategy;
|
|
704
752
|
sourceTexts = /* @__PURE__ */ new Map();
|
|
705
753
|
nonRetryableTexts = /* @__PURE__ */ new Set();
|
|
754
|
+
retryableFailedTexts = /* @__PURE__ */ new Map();
|
|
706
755
|
progressEventHandler;
|
|
707
756
|
translationProgress = {
|
|
708
757
|
progress: 0,
|
|
@@ -731,19 +780,21 @@ var TranslationManager = class {
|
|
|
731
780
|
this.translationProgress.total = queueManager.queueSize(
|
|
732
781
|
this.currentTranslatorStrategy
|
|
733
782
|
);
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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);
|
|
747
798
|
this.resetTranslationProgress();
|
|
748
799
|
this.publishTranslationProgress();
|
|
749
800
|
if (this.currentTranslatorStrategy === "frontend_translations") {
|
|
@@ -762,6 +813,7 @@ var TranslationManager = class {
|
|
|
762
813
|
continue;
|
|
763
814
|
}
|
|
764
815
|
if (!translation.isTranslated) {
|
|
816
|
+
this.addRetryableFailedText(response.tool, translation.sourceText);
|
|
765
817
|
continue;
|
|
766
818
|
}
|
|
767
819
|
this.addSourceTextToMap(response.tool, translation.sourceText);
|
|
@@ -781,12 +833,14 @@ var TranslationManager = class {
|
|
|
781
833
|
const eventhandler = new EventHandler(mfe);
|
|
782
834
|
eventhandler.publishTranslationCompleteEvent(
|
|
783
835
|
Array.from(this.sourceTexts.get(mfe) ?? /* @__PURE__ */ new Set()),
|
|
784
|
-
Array.from(this.nonRetryableTexts)
|
|
836
|
+
Array.from(this.nonRetryableTexts),
|
|
837
|
+
Array.from(this.retryableFailedTexts.get(mfe) ?? /* @__PURE__ */ new Set())
|
|
785
838
|
);
|
|
786
839
|
}
|
|
787
840
|
this.mfeToBeNotified.clear();
|
|
788
841
|
this.sourceTexts.clear();
|
|
789
842
|
this.nonRetryableTexts.clear();
|
|
843
|
+
this.retryableFailedTexts.clear();
|
|
790
844
|
}
|
|
791
845
|
setTranslationProgress(batchSize) {
|
|
792
846
|
this.translationProgress.current += batchSize;
|
|
@@ -823,6 +877,11 @@ var TranslationManager = class {
|
|
|
823
877
|
existing.add(sourceText);
|
|
824
878
|
this.sourceTexts.set(tool, existing);
|
|
825
879
|
}
|
|
880
|
+
addRetryableFailedText(tool, sourceText) {
|
|
881
|
+
const existing = this.retryableFailedTexts.get(tool) ?? /* @__PURE__ */ new Set();
|
|
882
|
+
existing.add(sourceText);
|
|
883
|
+
this.retryableFailedTexts.set(tool, existing);
|
|
884
|
+
}
|
|
826
885
|
publishTranslationProgress() {
|
|
827
886
|
this.progressEventHandler.publishTranslationProgressEvent(
|
|
828
887
|
this.translationProgress.progress,
|
|
@@ -889,8 +948,16 @@ var Client = class {
|
|
|
889
948
|
method: "POST",
|
|
890
949
|
body: JSON.stringify(requests)
|
|
891
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;
|
|
892
959
|
return {
|
|
893
|
-
responseBody
|
|
960
|
+
responseBody,
|
|
894
961
|
success: true
|
|
895
962
|
};
|
|
896
963
|
} catch (error) {
|
|
@@ -967,12 +1034,55 @@ var getModelDownloadEventHandler = () => {
|
|
|
967
1034
|
}
|
|
968
1035
|
return _modelDownloadEventHandler;
|
|
969
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
|
+
]);
|
|
970
1077
|
var ChromeTranslator = class _ChromeTranslator {
|
|
971
1078
|
translator;
|
|
972
1079
|
constructor(translator) {
|
|
973
1080
|
this.translator = translator;
|
|
974
1081
|
}
|
|
975
|
-
static
|
|
1082
|
+
static translatorReadyPromises = /* @__PURE__ */ new Map();
|
|
1083
|
+
static isSupportedLanguage(lang) {
|
|
1084
|
+
return SUPPORTED_LANGUAGES.has(lang) || SUPPORTED_LANGUAGES.has(lang.split("-")[0] ?? "");
|
|
1085
|
+
}
|
|
976
1086
|
static ensureRegistry() {
|
|
977
1087
|
if (!globalThis.chromeTranslatorRegistry) {
|
|
978
1088
|
globalThis.chromeTranslatorRegistry = /* @__PURE__ */ new Map();
|
|
@@ -994,30 +1104,31 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
994
1104
|
);
|
|
995
1105
|
}
|
|
996
1106
|
static async createTranslator(source, target) {
|
|
1107
|
+
const key = this.generateKey(source, target);
|
|
997
1108
|
let resolveReady;
|
|
998
|
-
|
|
1109
|
+
const readyPromise = new Promise((resolve) => {
|
|
999
1110
|
resolveReady = resolve;
|
|
1000
1111
|
});
|
|
1112
|
+
this.translatorReadyPromises.set(key, readyPromise);
|
|
1001
1113
|
let isDownloading = false;
|
|
1002
1114
|
const translator = await Translator.create({
|
|
1003
1115
|
sourceLanguage: source,
|
|
1004
1116
|
targetLanguage: target,
|
|
1005
1117
|
monitor(m) {
|
|
1006
|
-
m.addEventListener(
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
}
|
|
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();
|
|
1019
1130
|
}
|
|
1020
|
-
);
|
|
1131
|
+
});
|
|
1021
1132
|
}
|
|
1022
1133
|
});
|
|
1023
1134
|
if (!isDownloading) {
|
|
@@ -1025,8 +1136,8 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1025
1136
|
}
|
|
1026
1137
|
return translator;
|
|
1027
1138
|
}
|
|
1028
|
-
static waitForReady() {
|
|
1029
|
-
return this.
|
|
1139
|
+
static waitForReady(key) {
|
|
1140
|
+
return this.translatorReadyPromises.get(key) ?? Promise.resolve();
|
|
1030
1141
|
}
|
|
1031
1142
|
static async translate(text, targetLanguage) {
|
|
1032
1143
|
this.ensureRegistry();
|
|
@@ -1034,8 +1145,17 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1034
1145
|
const detector = await ChromeLanguageDetector.getInstance();
|
|
1035
1146
|
const sourceLanguage = await detector.detectLanguage(text);
|
|
1036
1147
|
const key = this.generateKey(sourceLanguage, targetLanguage);
|
|
1037
|
-
|
|
1038
|
-
|
|
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) {
|
|
1039
1159
|
const translatorCapabilities = await Translator.availability({
|
|
1040
1160
|
sourceLanguage,
|
|
1041
1161
|
targetLanguage
|
|
@@ -1053,10 +1173,16 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1053
1173
|
sourceLanguage,
|
|
1054
1174
|
targetLanguage
|
|
1055
1175
|
);
|
|
1056
|
-
|
|
1057
|
-
|
|
1176
|
+
if (!globalThis.chromeTranslatorRegistry.has(key)) {
|
|
1177
|
+
globalThis.chromeTranslatorRegistry.set(
|
|
1178
|
+
key,
|
|
1179
|
+
new _ChromeTranslator(chromeTranslator)
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1058
1182
|
}
|
|
1059
|
-
|
|
1183
|
+
const instance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1184
|
+
await this.waitForReady(key);
|
|
1185
|
+
this.translatorReadyPromises.delete(key);
|
|
1060
1186
|
const translation = await instance.translator?.translate(text);
|
|
1061
1187
|
if (!translation) {
|
|
1062
1188
|
return {
|
|
@@ -1064,7 +1190,7 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1064
1190
|
sourceLanguage,
|
|
1065
1191
|
success: false,
|
|
1066
1192
|
errorMessage: "Translation failed",
|
|
1067
|
-
retryable:
|
|
1193
|
+
retryable: false
|
|
1068
1194
|
};
|
|
1069
1195
|
}
|
|
1070
1196
|
return {
|
|
@@ -1074,11 +1200,12 @@ var ChromeTranslator = class _ChromeTranslator {
|
|
|
1074
1200
|
retryable: true
|
|
1075
1201
|
};
|
|
1076
1202
|
} catch (error) {
|
|
1203
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1077
1204
|
return {
|
|
1078
1205
|
translation: text,
|
|
1079
1206
|
sourceLanguage: targetLanguage,
|
|
1080
1207
|
success: false,
|
|
1081
|
-
errorMessage:
|
|
1208
|
+
errorMessage: message,
|
|
1082
1209
|
retryable: true
|
|
1083
1210
|
};
|
|
1084
1211
|
}
|
|
@@ -1235,13 +1362,22 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
|
|
|
1235
1362
|
const existingByOriginal = await translationRegistry.get(
|
|
1236
1363
|
text,
|
|
1237
1364
|
targetLanguage,
|
|
1238
|
-
tool
|
|
1365
|
+
tool,
|
|
1366
|
+
config2
|
|
1239
1367
|
);
|
|
1240
1368
|
if (existingByOriginal && existingByOriginal.isTranslated && existingByOriginal.translatedText && existingByOriginal.translatedText.trim() !== "") {
|
|
1241
1369
|
return existingByOriginal.translatedText;
|
|
1242
1370
|
}
|
|
1243
1371
|
if (!existingByOriginal) {
|
|
1372
|
+
const id = await Storage.generateId(text, targetLanguage, tool);
|
|
1373
|
+
const strategy = config2.getToolConfig().strategy;
|
|
1374
|
+
const enqueuedKey = translationRegistry.generateEnqueuedKey(id, strategy);
|
|
1375
|
+
if (translationRegistry.isEnqueued(enqueuedKey)) {
|
|
1376
|
+
return text;
|
|
1377
|
+
}
|
|
1378
|
+
translationRegistry.enqueue(enqueuedKey);
|
|
1244
1379
|
queueManager.add({
|
|
1380
|
+
id,
|
|
1245
1381
|
originalText: text,
|
|
1246
1382
|
targetLanguage,
|
|
1247
1383
|
tool,
|
|
@@ -1305,12 +1441,17 @@ function AITranslationInnerProvider(props) {
|
|
|
1305
1441
|
});
|
|
1306
1442
|
useEffect(() => {
|
|
1307
1443
|
const unsubscribe = eventHandler.current.subscribeToTranslationCompleteEvent(
|
|
1308
|
-
async (sourceTranslatedTexts, nonRetryableTexts) => {
|
|
1444
|
+
async (sourceTranslatedTexts, nonRetryableTexts, retryableFailedTexts) => {
|
|
1309
1445
|
try {
|
|
1310
1446
|
await translationRegistry.current.populateRegistryFromDatabase();
|
|
1311
1447
|
translationRegistry.current.populateNonRetryableTexts(
|
|
1312
1448
|
nonRetryableTexts
|
|
1313
1449
|
);
|
|
1450
|
+
translationRegistry.current.removeTextsFromEnqueued(
|
|
1451
|
+
retryableFailedTexts,
|
|
1452
|
+
locale,
|
|
1453
|
+
config2.getToolConfig().strategy
|
|
1454
|
+
);
|
|
1314
1455
|
eventHandler.current.publishRerenderEvent(sourceTranslatedTexts);
|
|
1315
1456
|
} catch (error) {
|
|
1316
1457
|
console.error(
|
|
@@ -1321,7 +1462,7 @@ function AITranslationInnerProvider(props) {
|
|
|
1321
1462
|
}
|
|
1322
1463
|
);
|
|
1323
1464
|
return () => unsubscribe();
|
|
1324
|
-
}, []);
|
|
1465
|
+
}, [locale, config2]);
|
|
1325
1466
|
useEffect(() => {
|
|
1326
1467
|
const unsubscribe = eventHandler.current.subscribeToTranslationProgressEvent(
|
|
1327
1468
|
(progress, current, total) => {
|
|
@@ -1339,15 +1480,15 @@ function AITranslationInnerProvider(props) {
|
|
|
1339
1480
|
return () => unsubscribe();
|
|
1340
1481
|
}, []);
|
|
1341
1482
|
useEffect(() => {
|
|
1342
|
-
if (isFetched
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
}
|
|
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
|
+
});
|
|
1351
1492
|
}, [tool, remoteConfig, isFetched, locale]);
|
|
1352
1493
|
config2.setTargetLanguage(locale);
|
|
1353
1494
|
config2.setToolName(tool);
|
|
@@ -1410,6 +1551,7 @@ var TranslatedIcon = ({
|
|
|
1410
1551
|
className,
|
|
1411
1552
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1412
1553
|
"aria-hidden": "true",
|
|
1554
|
+
style: { marginRight: "10px", flexShrink: 0 },
|
|
1413
1555
|
children: /* @__PURE__ */ jsx2(
|
|
1414
1556
|
"path",
|
|
1415
1557
|
{
|
|
@@ -1444,12 +1586,14 @@ var AITranslateText = ({
|
|
|
1444
1586
|
return;
|
|
1445
1587
|
}
|
|
1446
1588
|
if (sourceTexts.includes(text)) {
|
|
1447
|
-
|
|
1589
|
+
const translatedText = await context.ait(text);
|
|
1590
|
+
setDisplayText(translatedText);
|
|
1591
|
+
setShowHighlightState(showHighlight && translatedText !== text);
|
|
1448
1592
|
}
|
|
1449
1593
|
}
|
|
1450
1594
|
);
|
|
1451
1595
|
return () => unsubscribe();
|
|
1452
|
-
}, [context, text]);
|
|
1596
|
+
}, [context, text, showHighlight]);
|
|
1453
1597
|
const reset = useCallback2(
|
|
1454
1598
|
(displayValue = text) => {
|
|
1455
1599
|
setDisplayText(displayValue);
|
|
@@ -1472,7 +1616,7 @@ var AITranslateText = ({
|
|
|
1472
1616
|
const translatedText = await context.ait(text);
|
|
1473
1617
|
if (cancelled) return;
|
|
1474
1618
|
setDisplayText(translatedText);
|
|
1475
|
-
setShowHighlightState(showHighlight);
|
|
1619
|
+
setShowHighlightState(showHighlight && translatedText !== text);
|
|
1476
1620
|
} catch {
|
|
1477
1621
|
if (cancelled) return;
|
|
1478
1622
|
reset();
|
|
@@ -1484,8 +1628,8 @@ var AITranslateText = ({
|
|
|
1484
1628
|
};
|
|
1485
1629
|
}, [text, shouldTranslate, context, showHighlight, reset]);
|
|
1486
1630
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1487
|
-
|
|
1488
|
-
|
|
1631
|
+
showHighlightState && /* @__PURE__ */ jsx3(TranslatedIcon, { ...translatedIconProps }),
|
|
1632
|
+
displayText
|
|
1489
1633
|
] });
|
|
1490
1634
|
};
|
|
1491
1635
|
|
package/package.json
CHANGED