@yxw007/translate 0.1.6 → 0.2.2
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/browser/index.cjs +123 -4
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.esm.js +123 -4
- package/dist/browser/index.esm.js.map +1 -1
- package/dist/browser/index.esm.min.js +1 -1
- package/dist/browser/index.esm.min.js.map +1 -1
- package/dist/browser/index.min.cjs +1 -1
- package/dist/browser/index.min.cjs.map +1 -1
- package/dist/browser/index.umd.js +124 -8
- package/dist/browser/index.umd.js.map +1 -1
- package/dist/browser/index.umd.min.js +1 -1
- package/dist/browser/index.umd.min.js.map +1 -1
- package/dist/index.d.ts +461 -451
- package/dist/index.d.ts.map +1 -1
- package/dist/node/index.cjs +123 -4
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +123 -4
- package/dist/node/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
// translate v0.
|
|
1
|
+
// translate v0.2.2 Copyright (c) 2025 Potter<aa4790139@gmail.com> and contributors
|
|
2
|
+
import 'fs/promises';
|
|
3
|
+
import 'fs';
|
|
4
|
+
import 'path';
|
|
2
5
|
import { TranslateClient, TranslateTextCommand } from '@aws-sdk/client-translate';
|
|
3
6
|
|
|
4
7
|
class TranslationError extends Error {
|
|
@@ -113,6 +116,9 @@ function useLogger(name = "") {
|
|
|
113
116
|
};
|
|
114
117
|
}
|
|
115
118
|
|
|
119
|
+
function sleep(ms) {
|
|
120
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
121
|
+
}
|
|
116
122
|
function getGapLine() {
|
|
117
123
|
return "-".repeat(20);
|
|
118
124
|
}
|
|
@@ -130,6 +136,66 @@ async function throwResponseError(name, res) {
|
|
|
130
136
|
catch (e) { }
|
|
131
137
|
return new TranslationError(name, `Translate fail ! ${res.status}: ${res.statusText} ${bodyRes?.message ?? ""}`);
|
|
132
138
|
}
|
|
139
|
+
function splitText(text, maxCharacterNum) {
|
|
140
|
+
const SPLIT_PRIORITY = [
|
|
141
|
+
/\n\n+/, // 段落分隔(优先保留空行)
|
|
142
|
+
/[.。!??!\n]/, // 中日韩句子结束符+英文标点+换行
|
|
143
|
+
/[;;]/, // 分号(中英文)
|
|
144
|
+
/[,,]/g, // 逗号(中英文)
|
|
145
|
+
/\s/, // 空格(避免切分单词)
|
|
146
|
+
];
|
|
147
|
+
const BEST_MATCH_RATIO = 0.7;
|
|
148
|
+
const chunks = [];
|
|
149
|
+
while (text.length > 0) {
|
|
150
|
+
const chunk = text.slice(0, maxCharacterNum);
|
|
151
|
+
// Scene 1:Prioritization of cases not subject to severance
|
|
152
|
+
if (text.length <= maxCharacterNum) {
|
|
153
|
+
chunks.push(text);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
// Scene 2:Finding Split Points by Priority
|
|
157
|
+
let splitPos = -1;
|
|
158
|
+
for (const delimiter of SPLIT_PRIORITY) {
|
|
159
|
+
const regex = new RegExp(delimiter.source + "(?=[^]*)", "g"); // back-to-front search
|
|
160
|
+
let m, longestMatch;
|
|
161
|
+
while ((m = regex.exec(chunk)) !== null) {
|
|
162
|
+
if (m.index === regex.lastIndex) {
|
|
163
|
+
regex.lastIndex++;
|
|
164
|
+
}
|
|
165
|
+
if (longestMatch != null) {
|
|
166
|
+
longestMatch = m.index > longestMatch.index ? m : longestMatch;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
longestMatch = m;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (longestMatch?.index !== undefined && longestMatch.index >= maxCharacterNum * BEST_MATCH_RATIO) {
|
|
173
|
+
splitPos = longestMatch.index;
|
|
174
|
+
break; // Finding Quality Split Points
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Scene 3:Conservative splitting in the absence of a suitable separator
|
|
178
|
+
if (splitPos === -1) {
|
|
179
|
+
splitPos = chunk.lastIndexOf(" ", maxCharacterNum); // look for the space
|
|
180
|
+
splitPos = splitPos === -1 ? maxCharacterNum : splitPos; // forcible division
|
|
181
|
+
}
|
|
182
|
+
if (splitPos == 0) {
|
|
183
|
+
text = text.slice(splitPos + 1);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
chunks.push(text.slice(0, splitPos));
|
|
187
|
+
text = text.slice(splitPos);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return chunks;
|
|
191
|
+
}
|
|
192
|
+
function isOverMaxCharacterNum(text, max_character_num) {
|
|
193
|
+
if (!text || text.length <= 0) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
const total = text.reduce((pre, cur) => pre + cur.length, 0);
|
|
197
|
+
return total > max_character_num;
|
|
198
|
+
}
|
|
133
199
|
|
|
134
200
|
function google(options) {
|
|
135
201
|
const base = "https://translate.googleapis.com/translate_a/single";
|
|
@@ -2375,15 +2441,20 @@ function getLanguage(engine) {
|
|
|
2375
2441
|
}
|
|
2376
2442
|
|
|
2377
2443
|
const appName = "Translate";
|
|
2444
|
+
const defaultMaxCharacterNum = 1000;
|
|
2378
2445
|
|
|
2379
2446
|
const logger = useLogger();
|
|
2380
2447
|
const cache = new Cache();
|
|
2381
2448
|
class Translator {
|
|
2382
2449
|
engines;
|
|
2383
2450
|
cache_time;
|
|
2384
|
-
|
|
2451
|
+
concurrencyMax;
|
|
2452
|
+
concurrencyDelay;
|
|
2453
|
+
constructor(cache_time = 60 * 1000, concurrencyMax = 4, concurrencyDelay = 20) {
|
|
2385
2454
|
this.engines = new Map();
|
|
2386
2455
|
this.cache_time = cache_time;
|
|
2456
|
+
this.concurrencyMax = concurrencyMax;
|
|
2457
|
+
this.concurrencyDelay = concurrencyDelay;
|
|
2387
2458
|
}
|
|
2388
2459
|
/**
|
|
2389
2460
|
* This method is obsolete, please use the addEngine method
|
|
@@ -2431,8 +2502,7 @@ class Translator {
|
|
|
2431
2502
|
if (cache.get(key)) {
|
|
2432
2503
|
return Promise.resolve(cache.get(key)?.value);
|
|
2433
2504
|
}
|
|
2434
|
-
return engineInstance
|
|
2435
|
-
.translate(text, options)
|
|
2505
|
+
return this.concurrencyHandle(engineInstance, text, options)
|
|
2436
2506
|
.then((translated) => {
|
|
2437
2507
|
cache.set(key, translated, cache_time ?? this.cache_time);
|
|
2438
2508
|
return translated;
|
|
@@ -2447,6 +2517,55 @@ class Translator {
|
|
|
2447
2517
|
}
|
|
2448
2518
|
});
|
|
2449
2519
|
}
|
|
2520
|
+
async concurrencyHandle(engine, text, options) {
|
|
2521
|
+
const { max_character_num = defaultMaxCharacterNum } = options;
|
|
2522
|
+
const maxCharacterNum = max_character_num > 0 ? max_character_num : defaultMaxCharacterNum;
|
|
2523
|
+
if (Array.isArray(text)) {
|
|
2524
|
+
if (isOverMaxCharacterNum(text, max_character_num)) {
|
|
2525
|
+
throw new TranslationError(appName, "String arrays do not support automatic character splitting, and the total number of characters in a string array exceeds the limit on the number of translated characters.");
|
|
2526
|
+
}
|
|
2527
|
+
return engine.translate(text, options);
|
|
2528
|
+
}
|
|
2529
|
+
else {
|
|
2530
|
+
return this.concurrencyTranslate(engine, text, options, maxCharacterNum);
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
async concurrencyTranslate(engine, text, options, maxCharacterMum) {
|
|
2534
|
+
const pendingTasks = splitText(text, maxCharacterMum).map((content, index) => ({ content, index }));
|
|
2535
|
+
const result = [];
|
|
2536
|
+
let activeTasks = 0;
|
|
2537
|
+
const concurrencyDelay = this.concurrencyDelay;
|
|
2538
|
+
const concurrencyMax = this.concurrencyMax;
|
|
2539
|
+
return new Promise((resolve, reject) => {
|
|
2540
|
+
function processTasks() {
|
|
2541
|
+
while (activeTasks < concurrencyMax && pendingTasks.length > 0) {
|
|
2542
|
+
const { content, index } = pendingTasks.shift();
|
|
2543
|
+
activeTasks++;
|
|
2544
|
+
engine
|
|
2545
|
+
.translate(content, options)
|
|
2546
|
+
.then((res) => {
|
|
2547
|
+
result.push({
|
|
2548
|
+
translated: res,
|
|
2549
|
+
index,
|
|
2550
|
+
});
|
|
2551
|
+
})
|
|
2552
|
+
.catch((error) => reject(error))
|
|
2553
|
+
.finally(async () => {
|
|
2554
|
+
activeTasks--;
|
|
2555
|
+
if (activeTasks === 0 && pendingTasks.length <= 0) {
|
|
2556
|
+
result.sort((a, b) => a.index - b.index);
|
|
2557
|
+
const arr = result.reduce((pre, cur) => pre.concat(cur.translated), []);
|
|
2558
|
+
return resolve([arr.join("")]);
|
|
2559
|
+
}
|
|
2560
|
+
await sleep(concurrencyDelay);
|
|
2561
|
+
processTasks();
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
processTasks();
|
|
2566
|
+
return result;
|
|
2567
|
+
});
|
|
2568
|
+
}
|
|
2450
2569
|
}
|
|
2451
2570
|
const translator = new Translator();
|
|
2452
2571
|
var index = {
|