@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/legacy/index.mjs
CHANGED
|
@@ -52,6 +52,9 @@ var Config = class _Config {
|
|
|
52
52
|
setToolName(name) {
|
|
53
53
|
this.toolName = name;
|
|
54
54
|
}
|
|
55
|
+
isBackendTranslationStrategy() {
|
|
56
|
+
return this.ToolConfig.strategy === "backend_translations";
|
|
57
|
+
}
|
|
55
58
|
getToolName() {
|
|
56
59
|
return this.toolName;
|
|
57
60
|
}
|
|
@@ -245,10 +248,10 @@ var Hash = class {
|
|
|
245
248
|
var QueueManager = class {
|
|
246
249
|
constructor() {
|
|
247
250
|
if (!globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__) {
|
|
248
|
-
globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__ = /* @__PURE__ */ new
|
|
251
|
+
globalThis.__AI_TRANSLATION_FRONTEND_QUEUE__ = /* @__PURE__ */ new Map();
|
|
249
252
|
}
|
|
250
253
|
if (!globalThis.__AI_TRANSLATION_BACKEND_QUEUE__) {
|
|
251
|
-
globalThis.__AI_TRANSLATION_BACKEND_QUEUE__ = /* @__PURE__ */ new
|
|
254
|
+
globalThis.__AI_TRANSLATION_BACKEND_QUEUE__ = /* @__PURE__ */ new Map();
|
|
252
255
|
}
|
|
253
256
|
}
|
|
254
257
|
getQueue(strategy) {
|
|
@@ -261,42 +264,20 @@ var QueueManager = class {
|
|
|
261
264
|
return void 0;
|
|
262
265
|
}
|
|
263
266
|
add(entry) {
|
|
264
|
-
|
|
265
|
-
(
|
|
266
|
-
|
|
267
|
-
*generateBatches(strategy, config2) {
|
|
268
|
-
const queue = this.getQueue(strategy);
|
|
269
|
-
if (!queue) {
|
|
270
|
-
throw new Error("Invalid translation strategy");
|
|
271
|
-
}
|
|
272
|
-
if (queue.size === 0) {
|
|
273
|
-
console.warn("No translations to process");
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
const batch = config2.getToolConfig().translationBatchSize;
|
|
277
|
-
let batches = [];
|
|
278
|
-
for (const entry of queue.values()) {
|
|
279
|
-
batches.push(entry);
|
|
280
|
-
if (batches.length >= batch) {
|
|
281
|
-
yield batches;
|
|
282
|
-
batches = [];
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
if (batches.length > 0) {
|
|
286
|
-
queue.clear();
|
|
287
|
-
yield batches;
|
|
288
|
-
}
|
|
267
|
+
const queue = this.getQueue(entry.translationStrategy);
|
|
268
|
+
if (!queue || queue.has(entry.id)) return;
|
|
269
|
+
queue.set(entry.id, entry);
|
|
289
270
|
}
|
|
290
|
-
*
|
|
271
|
+
*generateBatches(config2) {
|
|
291
272
|
const queue = this.getQueue(config2.getToolConfig().strategy);
|
|
292
273
|
if (!queue) throw new Error("Invalid translation strategy");
|
|
293
274
|
const batchSize = config2.getToolConfig().translationBatchSize;
|
|
294
275
|
while (queue.size > 0) {
|
|
295
276
|
const batch = [];
|
|
296
277
|
while (batch.length < batchSize && queue.size > 0) {
|
|
297
|
-
const
|
|
298
|
-
queue.delete(
|
|
299
|
-
batch.push(
|
|
278
|
+
const [key, entry] = queue.entries().next().value;
|
|
279
|
+
queue.delete(key);
|
|
280
|
+
batch.push(entry);
|
|
300
281
|
}
|
|
301
282
|
yield batch;
|
|
302
283
|
}
|
|
@@ -415,6 +396,19 @@ var _Storage = class _Storage {
|
|
|
415
396
|
}
|
|
416
397
|
}
|
|
417
398
|
// ------------------------------------
|
|
399
|
+
// 🗑️ Clear Translation by ID
|
|
400
|
+
// ------------------------------------
|
|
401
|
+
static async deleteById(id) {
|
|
402
|
+
try {
|
|
403
|
+
const db = await _Storage.getDB();
|
|
404
|
+
await db.delete(_Storage.STORE_NAME, id);
|
|
405
|
+
return true;
|
|
406
|
+
} catch (error) {
|
|
407
|
+
console.error("[Storage] Failed to delete by id:", error);
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// ------------------------------------
|
|
418
412
|
// 🗑️ Clear All Translations
|
|
419
413
|
// ------------------------------------
|
|
420
414
|
static async clearAll() {
|
|
@@ -489,10 +483,42 @@ var _TranslationRegistry = class _TranslationRegistry {
|
|
|
489
483
|
isNonRetryable(key) {
|
|
490
484
|
return _TranslationRegistry.nonRetryableTexts.has(key);
|
|
491
485
|
}
|
|
492
|
-
|
|
486
|
+
enqueue(enqueuedKey) {
|
|
487
|
+
_TranslationRegistry.enqueuedItems.add(enqueuedKey);
|
|
488
|
+
}
|
|
489
|
+
isEnqueued(enqueuedKey) {
|
|
490
|
+
return _TranslationRegistry.enqueuedItems.has(enqueuedKey);
|
|
491
|
+
}
|
|
492
|
+
clearEnqueued() {
|
|
493
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
494
|
+
}
|
|
495
|
+
async removeTextsFromEnqueued(texts, targetLanguage, strategy) {
|
|
496
|
+
for (const text of texts) {
|
|
497
|
+
const id = await Storage.generateId(text, targetLanguage, this.tool);
|
|
498
|
+
_TranslationRegistry.enqueuedItems.delete(
|
|
499
|
+
this.generateEnqueuedKey(id, strategy)
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
static removeFromEnqueued(key) {
|
|
504
|
+
_TranslationRegistry.enqueuedItems.delete(key);
|
|
505
|
+
}
|
|
506
|
+
generateEnqueuedKey(id, strategy) {
|
|
507
|
+
return `${id}:${strategy}`;
|
|
508
|
+
}
|
|
509
|
+
async get(text, targetLanguage, tool, config2) {
|
|
493
510
|
const key = await Hash.generateFromMultiple([text, targetLanguage, tool]);
|
|
494
|
-
|
|
495
|
-
|
|
511
|
+
const cached = _TranslationRegistry.memoryCache.get(key);
|
|
512
|
+
if (cached) {
|
|
513
|
+
if (cached.translationStrategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
|
|
514
|
+
_TranslationRegistry.memoryCache.delete(key);
|
|
515
|
+
if (cached.translatedText) {
|
|
516
|
+
_TranslationRegistry.originalTextIndex.delete(cached.translatedText);
|
|
517
|
+
}
|
|
518
|
+
await Storage.deleteById(key);
|
|
519
|
+
return void 0;
|
|
520
|
+
}
|
|
521
|
+
return cached;
|
|
496
522
|
}
|
|
497
523
|
const translation = await Storage.getTranslation(
|
|
498
524
|
text,
|
|
@@ -500,6 +526,10 @@ var _TranslationRegistry = class _TranslationRegistry {
|
|
|
500
526
|
tool
|
|
501
527
|
);
|
|
502
528
|
if (translation !== void 0) {
|
|
529
|
+
if (translation.translation_strategy === "frontend_translations" && config2.isBackendTranslationStrategy()) {
|
|
530
|
+
await Storage.deleteById(translation.id);
|
|
531
|
+
return void 0;
|
|
532
|
+
}
|
|
503
533
|
return this.toTranslationRegistryEntry(translation);
|
|
504
534
|
}
|
|
505
535
|
return void 0;
|
|
@@ -514,6 +544,7 @@ var _TranslationRegistry = class _TranslationRegistry {
|
|
|
514
544
|
async clear() {
|
|
515
545
|
_TranslationRegistry.memoryCache.clear();
|
|
516
546
|
_TranslationRegistry.originalTextIndex.clear();
|
|
547
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
517
548
|
await Storage.clearAll();
|
|
518
549
|
return;
|
|
519
550
|
}
|
|
@@ -521,6 +552,7 @@ var _TranslationRegistry = class _TranslationRegistry {
|
|
|
521
552
|
await Storage.deleteByToolAndStrategy(tool, strategy);
|
|
522
553
|
_TranslationRegistry.memoryCache.clear();
|
|
523
554
|
_TranslationRegistry.originalTextIndex.clear();
|
|
555
|
+
_TranslationRegistry.enqueuedItems.clear();
|
|
524
556
|
return;
|
|
525
557
|
}
|
|
526
558
|
toTranslationRegistryEntry(translation) {
|
|
@@ -542,10 +574,16 @@ var _TranslationRegistry = class _TranslationRegistry {
|
|
|
542
574
|
translation.id
|
|
543
575
|
);
|
|
544
576
|
const newTranslation = this.toTranslationRegistryEntry(translation);
|
|
577
|
+
const enqueuedKey = this.generateEnqueuedKey(
|
|
578
|
+
translation.id,
|
|
579
|
+
translation.translation_strategy
|
|
580
|
+
);
|
|
545
581
|
if (currentTranslation && !this.shouldUpdateTranslation(currentTranslation, newTranslation)) {
|
|
582
|
+
_TranslationRegistry.removeFromEnqueued(enqueuedKey);
|
|
546
583
|
continue;
|
|
547
584
|
}
|
|
548
585
|
this.setTranslationToRegistry(newTranslation);
|
|
586
|
+
_TranslationRegistry.removeFromEnqueued(enqueuedKey);
|
|
549
587
|
}
|
|
550
588
|
return;
|
|
551
589
|
}
|
|
@@ -588,6 +626,7 @@ var _TranslationRegistry = class _TranslationRegistry {
|
|
|
588
626
|
__publicField(_TranslationRegistry, "memoryCache", /* @__PURE__ */ new Map());
|
|
589
627
|
__publicField(_TranslationRegistry, "originalTextIndex", /* @__PURE__ */ new Map());
|
|
590
628
|
__publicField(_TranslationRegistry, "nonRetryableTexts", /* @__PURE__ */ new Set());
|
|
629
|
+
__publicField(_TranslationRegistry, "enqueuedItems", /* @__PURE__ */ new Set());
|
|
591
630
|
var TranslationRegistry = _TranslationRegistry;
|
|
592
631
|
|
|
593
632
|
// src/utils/eventHandler.ts
|
|
@@ -608,12 +647,13 @@ var EventHandler = class {
|
|
|
608
647
|
this.aiTranslationEvents = new SystemEvents(this.sourceEventIdentifier);
|
|
609
648
|
this.toolName = toolName;
|
|
610
649
|
}
|
|
611
|
-
publishTranslationCompleteEvent(sourceTranslatedTexts, nonRetryableTexts) {
|
|
650
|
+
publishTranslationCompleteEvent(sourceTranslatedTexts, nonRetryableTexts, retryableFailedTexts = []) {
|
|
612
651
|
this.aiTranslationEvents.publish(
|
|
613
652
|
this.withEventName(TRANSLATION_COMPLETE_EVENT_NAME),
|
|
614
653
|
{
|
|
615
654
|
sourceTranslatedTexts,
|
|
616
|
-
nonRetryableTexts
|
|
655
|
+
nonRetryableTexts,
|
|
656
|
+
retryableFailedTexts
|
|
617
657
|
}
|
|
618
658
|
);
|
|
619
659
|
}
|
|
@@ -621,12 +661,19 @@ var EventHandler = class {
|
|
|
621
661
|
return this.aiTranslationEvents.subscribe(
|
|
622
662
|
this.withEventName(TRANSLATION_COMPLETE_EVENT_NAME),
|
|
623
663
|
(detail) => {
|
|
624
|
-
var _a, _b;
|
|
664
|
+
var _a, _b, _c;
|
|
625
665
|
const sourceTranslatedTexts = Array.isArray(
|
|
626
666
|
(_a = detail.data) == null ? void 0 : _a.sourceTranslatedTexts
|
|
627
667
|
) ? detail.data.sourceTranslatedTexts : [];
|
|
628
668
|
const nonRetryableTexts = Array.isArray((_b = detail.data) == null ? void 0 : _b.nonRetryableTexts) ? detail.data.nonRetryableTexts : [];
|
|
629
|
-
|
|
669
|
+
const retryableFailedTexts = Array.isArray(
|
|
670
|
+
(_c = detail.data) == null ? void 0 : _c.retryableFailedTexts
|
|
671
|
+
) ? detail.data.retryableFailedTexts : [];
|
|
672
|
+
callback(
|
|
673
|
+
sourceTranslatedTexts,
|
|
674
|
+
nonRetryableTexts,
|
|
675
|
+
retryableFailedTexts
|
|
676
|
+
);
|
|
630
677
|
}
|
|
631
678
|
);
|
|
632
679
|
}
|
|
@@ -727,6 +774,7 @@ var TranslationManager = class {
|
|
|
727
774
|
__publicField(this, "currentTranslatorStrategy");
|
|
728
775
|
__publicField(this, "sourceTexts", /* @__PURE__ */ new Map());
|
|
729
776
|
__publicField(this, "nonRetryableTexts", /* @__PURE__ */ new Set());
|
|
777
|
+
__publicField(this, "retryableFailedTexts", /* @__PURE__ */ new Map());
|
|
730
778
|
__publicField(this, "progressEventHandler");
|
|
731
779
|
__publicField(this, "translationProgress", {
|
|
732
780
|
progress: 0,
|
|
@@ -754,19 +802,21 @@ var TranslationManager = class {
|
|
|
754
802
|
this.translationProgress.total = queueManager.queueSize(
|
|
755
803
|
this.currentTranslatorStrategy
|
|
756
804
|
);
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
805
|
+
do {
|
|
806
|
+
for (const batch of queueManager.generateBatches(
|
|
807
|
+
this.translator.getConfig()
|
|
808
|
+
)) {
|
|
809
|
+
batch.forEach((entry) => this.mfeToBeNotified.add(entry.tool));
|
|
810
|
+
const result = await this.translator.processTranslations(
|
|
811
|
+
batch.map(
|
|
812
|
+
(entry) => this.convertTranslationQueueEntryToTranslationRequest(entry)
|
|
813
|
+
)
|
|
814
|
+
);
|
|
815
|
+
this.setTranslationProgress(batch.length);
|
|
816
|
+
await this.updateDatabaseWithTranslations(result);
|
|
817
|
+
await this.notifyTranslationCompleted();
|
|
818
|
+
}
|
|
819
|
+
} while (queueManager.queueSize(this.currentTranslatorStrategy) > 0);
|
|
770
820
|
this.resetTranslationProgress();
|
|
771
821
|
this.publishTranslationProgress();
|
|
772
822
|
if (this.currentTranslatorStrategy === "frontend_translations") {
|
|
@@ -785,6 +835,7 @@ var TranslationManager = class {
|
|
|
785
835
|
continue;
|
|
786
836
|
}
|
|
787
837
|
if (!translation.isTranslated) {
|
|
838
|
+
this.addRetryableFailedText(response.tool, translation.sourceText);
|
|
788
839
|
continue;
|
|
789
840
|
}
|
|
790
841
|
this.addSourceTextToMap(response.tool, translation.sourceText);
|
|
@@ -804,12 +855,14 @@ var TranslationManager = class {
|
|
|
804
855
|
const eventhandler = new EventHandler(mfe);
|
|
805
856
|
eventhandler.publishTranslationCompleteEvent(
|
|
806
857
|
Array.from(this.sourceTexts.get(mfe) ?? /* @__PURE__ */ new Set()),
|
|
807
|
-
Array.from(this.nonRetryableTexts)
|
|
858
|
+
Array.from(this.nonRetryableTexts),
|
|
859
|
+
Array.from(this.retryableFailedTexts.get(mfe) ?? /* @__PURE__ */ new Set())
|
|
808
860
|
);
|
|
809
861
|
}
|
|
810
862
|
this.mfeToBeNotified.clear();
|
|
811
863
|
this.sourceTexts.clear();
|
|
812
864
|
this.nonRetryableTexts.clear();
|
|
865
|
+
this.retryableFailedTexts.clear();
|
|
813
866
|
}
|
|
814
867
|
setTranslationProgress(batchSize) {
|
|
815
868
|
this.translationProgress.current += batchSize;
|
|
@@ -846,6 +899,11 @@ var TranslationManager = class {
|
|
|
846
899
|
existing.add(sourceText);
|
|
847
900
|
this.sourceTexts.set(tool, existing);
|
|
848
901
|
}
|
|
902
|
+
addRetryableFailedText(tool, sourceText) {
|
|
903
|
+
const existing = this.retryableFailedTexts.get(tool) ?? /* @__PURE__ */ new Set();
|
|
904
|
+
existing.add(sourceText);
|
|
905
|
+
this.retryableFailedTexts.set(tool, existing);
|
|
906
|
+
}
|
|
849
907
|
publishTranslationProgress() {
|
|
850
908
|
this.progressEventHandler.publishTranslationProgressEvent(
|
|
851
909
|
this.translationProgress.progress,
|
|
@@ -912,8 +970,16 @@ var Client = class {
|
|
|
912
970
|
method: "POST",
|
|
913
971
|
body: JSON.stringify(requests)
|
|
914
972
|
});
|
|
973
|
+
const responseBody = Array.isArray(data) ? data.map((group) => ({
|
|
974
|
+
...group,
|
|
975
|
+
translations: Array.isArray(group.translations) ? group.translations.map((t) => ({
|
|
976
|
+
...t,
|
|
977
|
+
isTranslated: t.isTranslated ?? (!!t.translation && t.translation !== ""),
|
|
978
|
+
retryable: t.retryable ?? true
|
|
979
|
+
})) : []
|
|
980
|
+
})) : data;
|
|
915
981
|
return {
|
|
916
|
-
responseBody
|
|
982
|
+
responseBody,
|
|
917
983
|
success: true
|
|
918
984
|
};
|
|
919
985
|
} catch (error) {
|
|
@@ -991,11 +1057,54 @@ var getModelDownloadEventHandler = () => {
|
|
|
991
1057
|
}
|
|
992
1058
|
return _modelDownloadEventHandler;
|
|
993
1059
|
};
|
|
1060
|
+
var SUPPORTED_LANGUAGES = /* @__PURE__ */ new Set([
|
|
1061
|
+
"ar",
|
|
1062
|
+
"bn",
|
|
1063
|
+
"bg",
|
|
1064
|
+
"zh",
|
|
1065
|
+
"hr",
|
|
1066
|
+
"cs",
|
|
1067
|
+
"da",
|
|
1068
|
+
"nl",
|
|
1069
|
+
"en",
|
|
1070
|
+
"fi",
|
|
1071
|
+
"fr",
|
|
1072
|
+
"de",
|
|
1073
|
+
"el",
|
|
1074
|
+
"he",
|
|
1075
|
+
"hi",
|
|
1076
|
+
"hu",
|
|
1077
|
+
"id",
|
|
1078
|
+
"it",
|
|
1079
|
+
"ja",
|
|
1080
|
+
"kn",
|
|
1081
|
+
"ko",
|
|
1082
|
+
"lt",
|
|
1083
|
+
"mr",
|
|
1084
|
+
"no",
|
|
1085
|
+
"pl",
|
|
1086
|
+
"pt",
|
|
1087
|
+
"ro",
|
|
1088
|
+
"ru",
|
|
1089
|
+
"sk",
|
|
1090
|
+
"sl",
|
|
1091
|
+
"es",
|
|
1092
|
+
"sv",
|
|
1093
|
+
"ta",
|
|
1094
|
+
"te",
|
|
1095
|
+
"th",
|
|
1096
|
+
"tr",
|
|
1097
|
+
"uk",
|
|
1098
|
+
"vi"
|
|
1099
|
+
]);
|
|
994
1100
|
var _ChromeTranslator = class _ChromeTranslator {
|
|
995
1101
|
constructor(translator) {
|
|
996
1102
|
__publicField(this, "translator");
|
|
997
1103
|
this.translator = translator;
|
|
998
1104
|
}
|
|
1105
|
+
static isSupportedLanguage(lang) {
|
|
1106
|
+
return SUPPORTED_LANGUAGES.has(lang) || SUPPORTED_LANGUAGES.has(lang.split("-")[0] ?? "");
|
|
1107
|
+
}
|
|
999
1108
|
static ensureRegistry() {
|
|
1000
1109
|
if (!globalThis.chromeTranslatorRegistry) {
|
|
1001
1110
|
globalThis.chromeTranslatorRegistry = /* @__PURE__ */ new Map();
|
|
@@ -1017,30 +1126,31 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1017
1126
|
);
|
|
1018
1127
|
}
|
|
1019
1128
|
static async createTranslator(source, target) {
|
|
1129
|
+
const key = this.generateKey(source, target);
|
|
1020
1130
|
let resolveReady;
|
|
1021
|
-
|
|
1131
|
+
const readyPromise = new Promise((resolve) => {
|
|
1022
1132
|
resolveReady = resolve;
|
|
1023
1133
|
});
|
|
1134
|
+
this.translatorReadyPromises.set(key, readyPromise);
|
|
1024
1135
|
let isDownloading = false;
|
|
1025
1136
|
const translator = await Translator.create({
|
|
1026
1137
|
sourceLanguage: source,
|
|
1027
1138
|
targetLanguage: target,
|
|
1028
1139
|
monitor(m) {
|
|
1029
|
-
m.addEventListener(
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1140
|
+
m.addEventListener("downloadprogress", (e) => {
|
|
1141
|
+
isDownloading = true;
|
|
1142
|
+
const loaded = e.loaded ?? 0;
|
|
1143
|
+
const total = e.total ?? 0;
|
|
1144
|
+
const progress = total > 0 ? Math.round(loaded / total * 100) : 0;
|
|
1145
|
+
getModelDownloadEventHandler().publishModelDownloadProgressEvent(
|
|
1146
|
+
loaded,
|
|
1147
|
+
total,
|
|
1148
|
+
progress
|
|
1149
|
+
);
|
|
1150
|
+
if (total > 0 && loaded >= total) {
|
|
1151
|
+
resolveReady();
|
|
1042
1152
|
}
|
|
1043
|
-
);
|
|
1153
|
+
});
|
|
1044
1154
|
}
|
|
1045
1155
|
});
|
|
1046
1156
|
if (!isDownloading) {
|
|
@@ -1048,8 +1158,8 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1048
1158
|
}
|
|
1049
1159
|
return translator;
|
|
1050
1160
|
}
|
|
1051
|
-
static waitForReady() {
|
|
1052
|
-
return this.
|
|
1161
|
+
static waitForReady(key) {
|
|
1162
|
+
return this.translatorReadyPromises.get(key) ?? Promise.resolve();
|
|
1053
1163
|
}
|
|
1054
1164
|
static async translate(text, targetLanguage) {
|
|
1055
1165
|
var _a;
|
|
@@ -1058,8 +1168,17 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1058
1168
|
const detector = await ChromeLanguageDetector.getInstance();
|
|
1059
1169
|
const sourceLanguage = await detector.detectLanguage(text);
|
|
1060
1170
|
const key = this.generateKey(sourceLanguage, targetLanguage);
|
|
1061
|
-
|
|
1062
|
-
|
|
1171
|
+
if (!this.isSupportedLanguage(sourceLanguage) || !this.isSupportedLanguage(targetLanguage)) {
|
|
1172
|
+
return {
|
|
1173
|
+
translation: text,
|
|
1174
|
+
sourceLanguage,
|
|
1175
|
+
success: false,
|
|
1176
|
+
retryable: false,
|
|
1177
|
+
errorMessage: `Unsupported language pair: ${sourceLanguage} \u2192 ${targetLanguage}`
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
const existingInstance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1181
|
+
if (!existingInstance) {
|
|
1063
1182
|
const translatorCapabilities = await Translator.availability({
|
|
1064
1183
|
sourceLanguage,
|
|
1065
1184
|
targetLanguage
|
|
@@ -1077,10 +1196,16 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1077
1196
|
sourceLanguage,
|
|
1078
1197
|
targetLanguage
|
|
1079
1198
|
);
|
|
1080
|
-
|
|
1081
|
-
|
|
1199
|
+
if (!globalThis.chromeTranslatorRegistry.has(key)) {
|
|
1200
|
+
globalThis.chromeTranslatorRegistry.set(
|
|
1201
|
+
key,
|
|
1202
|
+
new _ChromeTranslator(chromeTranslator)
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1082
1205
|
}
|
|
1083
|
-
|
|
1206
|
+
const instance = globalThis.chromeTranslatorRegistry.get(key);
|
|
1207
|
+
await this.waitForReady(key);
|
|
1208
|
+
this.translatorReadyPromises.delete(key);
|
|
1084
1209
|
const translation = await ((_a = instance.translator) == null ? void 0 : _a.translate(text));
|
|
1085
1210
|
if (!translation) {
|
|
1086
1211
|
return {
|
|
@@ -1088,7 +1213,7 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1088
1213
|
sourceLanguage,
|
|
1089
1214
|
success: false,
|
|
1090
1215
|
errorMessage: "Translation failed",
|
|
1091
|
-
retryable:
|
|
1216
|
+
retryable: false
|
|
1092
1217
|
};
|
|
1093
1218
|
}
|
|
1094
1219
|
return {
|
|
@@ -1098,11 +1223,12 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1098
1223
|
retryable: true
|
|
1099
1224
|
};
|
|
1100
1225
|
} catch (error) {
|
|
1226
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1101
1227
|
return {
|
|
1102
1228
|
translation: text,
|
|
1103
1229
|
sourceLanguage: targetLanguage,
|
|
1104
1230
|
success: false,
|
|
1105
|
-
errorMessage:
|
|
1231
|
+
errorMessage: message,
|
|
1106
1232
|
retryable: true
|
|
1107
1233
|
};
|
|
1108
1234
|
}
|
|
@@ -1111,7 +1237,7 @@ var _ChromeTranslator = class _ChromeTranslator {
|
|
|
1111
1237
|
return `${sourceLanguage.toUpperCase()}-${targetLanguage.toUpperCase()}`;
|
|
1112
1238
|
}
|
|
1113
1239
|
};
|
|
1114
|
-
__publicField(_ChromeTranslator, "
|
|
1240
|
+
__publicField(_ChromeTranslator, "translatorReadyPromises", /* @__PURE__ */ new Map());
|
|
1115
1241
|
var ChromeTranslator = _ChromeTranslator;
|
|
1116
1242
|
|
|
1117
1243
|
// src/translators/frontend_translators/chrome/client.ts
|
|
@@ -1261,13 +1387,22 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
|
|
|
1261
1387
|
const existingByOriginal = await translationRegistry.get(
|
|
1262
1388
|
text,
|
|
1263
1389
|
targetLanguage,
|
|
1264
|
-
tool
|
|
1390
|
+
tool,
|
|
1391
|
+
config2
|
|
1265
1392
|
);
|
|
1266
1393
|
if (existingByOriginal && existingByOriginal.isTranslated && existingByOriginal.translatedText && existingByOriginal.translatedText.trim() !== "") {
|
|
1267
1394
|
return existingByOriginal.translatedText;
|
|
1268
1395
|
}
|
|
1269
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);
|
|
1270
1404
|
queueManager.add({
|
|
1405
|
+
id,
|
|
1271
1406
|
originalText: text,
|
|
1272
1407
|
targetLanguage,
|
|
1273
1408
|
tool,
|
|
@@ -1331,12 +1466,17 @@ function AITranslationInnerProvider(props) {
|
|
|
1331
1466
|
});
|
|
1332
1467
|
useEffect(() => {
|
|
1333
1468
|
const unsubscribe = eventHandler.current.subscribeToTranslationCompleteEvent(
|
|
1334
|
-
async (sourceTranslatedTexts, nonRetryableTexts) => {
|
|
1469
|
+
async (sourceTranslatedTexts, nonRetryableTexts, retryableFailedTexts) => {
|
|
1335
1470
|
try {
|
|
1336
1471
|
await translationRegistry.current.populateRegistryFromDatabase();
|
|
1337
1472
|
translationRegistry.current.populateNonRetryableTexts(
|
|
1338
1473
|
nonRetryableTexts
|
|
1339
1474
|
);
|
|
1475
|
+
translationRegistry.current.removeTextsFromEnqueued(
|
|
1476
|
+
retryableFailedTexts,
|
|
1477
|
+
locale,
|
|
1478
|
+
config2.getToolConfig().strategy
|
|
1479
|
+
);
|
|
1340
1480
|
eventHandler.current.publishRerenderEvent(sourceTranslatedTexts);
|
|
1341
1481
|
} catch (error) {
|
|
1342
1482
|
console.error(
|
|
@@ -1347,7 +1487,7 @@ function AITranslationInnerProvider(props) {
|
|
|
1347
1487
|
}
|
|
1348
1488
|
);
|
|
1349
1489
|
return () => unsubscribe();
|
|
1350
|
-
}, []);
|
|
1490
|
+
}, [locale, config2]);
|
|
1351
1491
|
useEffect(() => {
|
|
1352
1492
|
const unsubscribe = eventHandler.current.subscribeToTranslationProgressEvent(
|
|
1353
1493
|
(progress, current, total) => {
|
|
@@ -1365,15 +1505,15 @@ function AITranslationInnerProvider(props) {
|
|
|
1365
1505
|
return () => unsubscribe();
|
|
1366
1506
|
}, []);
|
|
1367
1507
|
useEffect(() => {
|
|
1368
|
-
if (isFetched
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
}
|
|
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
|
+
});
|
|
1377
1517
|
}, [tool, remoteConfig, isFetched, locale]);
|
|
1378
1518
|
config2.setTargetLanguage(locale);
|
|
1379
1519
|
config2.setToolName(tool);
|
|
@@ -1436,6 +1576,7 @@ var TranslatedIcon = ({
|
|
|
1436
1576
|
className,
|
|
1437
1577
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1438
1578
|
"aria-hidden": "true",
|
|
1579
|
+
style: { marginRight: "10px", flexShrink: 0 },
|
|
1439
1580
|
children: /* @__PURE__ */ jsx2(
|
|
1440
1581
|
"path",
|
|
1441
1582
|
{
|
|
@@ -1470,12 +1611,14 @@ var AITranslateText = ({
|
|
|
1470
1611
|
return;
|
|
1471
1612
|
}
|
|
1472
1613
|
if (sourceTexts.includes(text)) {
|
|
1473
|
-
|
|
1614
|
+
const translatedText = await context.ait(text);
|
|
1615
|
+
setDisplayText(translatedText);
|
|
1616
|
+
setShowHighlightState(showHighlight && translatedText !== text);
|
|
1474
1617
|
}
|
|
1475
1618
|
}
|
|
1476
1619
|
);
|
|
1477
1620
|
return () => unsubscribe();
|
|
1478
|
-
}, [context, text]);
|
|
1621
|
+
}, [context, text, showHighlight]);
|
|
1479
1622
|
const reset = useCallback2(
|
|
1480
1623
|
(displayValue = text) => {
|
|
1481
1624
|
setDisplayText(displayValue);
|
|
@@ -1498,7 +1641,7 @@ var AITranslateText = ({
|
|
|
1498
1641
|
const translatedText = await context.ait(text);
|
|
1499
1642
|
if (cancelled) return;
|
|
1500
1643
|
setDisplayText(translatedText);
|
|
1501
|
-
setShowHighlightState(showHighlight);
|
|
1644
|
+
setShowHighlightState(showHighlight && translatedText !== text);
|
|
1502
1645
|
} catch {
|
|
1503
1646
|
if (cancelled) return;
|
|
1504
1647
|
reset();
|
|
@@ -1510,8 +1653,8 @@ var AITranslateText = ({
|
|
|
1510
1653
|
};
|
|
1511
1654
|
}, [text, shouldTranslate, context, showHighlight, reset]);
|
|
1512
1655
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1513
|
-
|
|
1514
|
-
|
|
1656
|
+
showHighlightState && /* @__PURE__ */ jsx3(TranslatedIcon, { ...translatedIconProps }),
|
|
1657
|
+
displayText
|
|
1515
1658
|
] });
|
|
1516
1659
|
};
|
|
1517
1660
|
|
package/dist/modern/index.d.mts
CHANGED
|
@@ -17,6 +17,7 @@ interface TranslationProgress {
|
|
|
17
17
|
total: number;
|
|
18
18
|
}
|
|
19
19
|
interface TranslationQueueEntry {
|
|
20
|
+
id: string;
|
|
20
21
|
originalText: string;
|
|
21
22
|
isTranslated: boolean;
|
|
22
23
|
targetLanguage: string;
|
|
@@ -170,8 +171,8 @@ declare const AI_TRANSLATION_FEATURE_FLAG_KEY = "ai-translation";
|
|
|
170
171
|
declare const getAITranslationLDId: (domain: string) => "67e17b925ace3c08088c4bd2" | "570f2f6e348a2806d7006b6f" | "570e9423348a2806d7004354" | "570f37b4eee8b907140070c5";
|
|
171
172
|
|
|
172
173
|
declare global {
|
|
173
|
-
var __AI_TRANSLATION_FRONTEND_QUEUE__:
|
|
174
|
-
var __AI_TRANSLATION_BACKEND_QUEUE__:
|
|
174
|
+
var __AI_TRANSLATION_FRONTEND_QUEUE__: Map<string, TranslationQueueEntry> | undefined;
|
|
175
|
+
var __AI_TRANSLATION_BACKEND_QUEUE__: Map<string, TranslationQueueEntry> | undefined;
|
|
175
176
|
var _FRONTEND_AI_TRANSLATION_IN_PROGRESS_: boolean;
|
|
176
177
|
var _BACKEND_AI_TRANSLATION_IN_PROGRESS_: boolean;
|
|
177
178
|
}
|
package/dist/modern/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ interface TranslationProgress {
|
|
|
17
17
|
total: number;
|
|
18
18
|
}
|
|
19
19
|
interface TranslationQueueEntry {
|
|
20
|
+
id: string;
|
|
20
21
|
originalText: string;
|
|
21
22
|
isTranslated: boolean;
|
|
22
23
|
targetLanguage: string;
|
|
@@ -170,8 +171,8 @@ declare const AI_TRANSLATION_FEATURE_FLAG_KEY = "ai-translation";
|
|
|
170
171
|
declare const getAITranslationLDId: (domain: string) => "67e17b925ace3c08088c4bd2" | "570f2f6e348a2806d7006b6f" | "570e9423348a2806d7004354" | "570f37b4eee8b907140070c5";
|
|
171
172
|
|
|
172
173
|
declare global {
|
|
173
|
-
var __AI_TRANSLATION_FRONTEND_QUEUE__:
|
|
174
|
-
var __AI_TRANSLATION_BACKEND_QUEUE__:
|
|
174
|
+
var __AI_TRANSLATION_FRONTEND_QUEUE__: Map<string, TranslationQueueEntry> | undefined;
|
|
175
|
+
var __AI_TRANSLATION_BACKEND_QUEUE__: Map<string, TranslationQueueEntry> | undefined;
|
|
175
176
|
var _FRONTEND_AI_TRANSLATION_IN_PROGRESS_: boolean;
|
|
176
177
|
var _BACKEND_AI_TRANSLATION_IN_PROGRESS_: boolean;
|
|
177
178
|
}
|