gptrans 1.2.0 → 1.2.4
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/README.md +8 -0
- package/db/gptrans_ar.json +0 -9
- package/db/gptrans_it.json +0 -0
- package/demo/case_2.js +6 -5
- package/index.js +55 -11
- package/isoAssoc.js +22 -16
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -102,6 +102,14 @@ GPTrans stands out by combining advanced AI capabilities with efficient batching
|
|
|
102
102
|
|
|
103
103
|
If you're looking to streamline your translation workflow and bring your applications to a global audience effortlessly, GPTrans is the perfect choice!
|
|
104
104
|
|
|
105
|
+
## 🔄 Preloading Translations
|
|
106
|
+
|
|
107
|
+
You can preload translations for specific languages using the `preload` method. This is particularly useful when you want to initialize translations based on dynamically generated keys:
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
await gptrans.preload({target:'ar'});
|
|
111
|
+
```
|
|
112
|
+
|
|
105
113
|
## Contributing
|
|
106
114
|
|
|
107
115
|
Contributions are welcome! Please open an issue or submit a pull request on GitHub to contribute improvements or fixes.
|
package/db/gptrans_ar.json
CHANGED
|
File without changes
|
package/demo/case_2.js
CHANGED
|
@@ -2,18 +2,19 @@ import GPTrans from '../index.js';
|
|
|
2
2
|
|
|
3
3
|
try {
|
|
4
4
|
const gptrans = new GPTrans({
|
|
5
|
-
target: '
|
|
6
|
-
model: 'claude-3-7-sonnet-20250219',
|
|
5
|
+
target: 'it',
|
|
7
6
|
});
|
|
8
7
|
|
|
8
|
+
await gptrans.preload();
|
|
9
|
+
console.log('ready');
|
|
10
|
+
|
|
9
11
|
console.log(gptrans.t('Top-up'));
|
|
10
12
|
console.log(gptrans.t('Transfer'));
|
|
11
13
|
console.log(gptrans.t('Deposit'));
|
|
12
14
|
console.log(gptrans.t('Balance'));
|
|
13
15
|
console.log(gptrans.t('Transaction'));
|
|
14
16
|
console.log(gptrans.t('Account'));
|
|
15
|
-
console.log(gptrans.t('Card'));
|
|
17
|
+
console.log(gptrans.t('Card'));
|
|
16
18
|
} catch (e) {
|
|
17
19
|
console.error(e);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
+
}
|
package/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import DeepBase from 'deepbase';
|
|
2
2
|
import stringHash from 'string-hash';
|
|
3
3
|
import { ModelMix, MixOpenAI, MixAnthropic } from 'modelmix';
|
|
4
|
+
import { isoAssoc, isLanguageAvailable } from './isoAssoc.js';
|
|
4
5
|
import dotenv from 'dotenv';
|
|
5
6
|
|
|
6
|
-
import { isoAssoc } from './isoAssoc.js';
|
|
7
7
|
dotenv.config();
|
|
8
8
|
|
|
9
|
-
class
|
|
9
|
+
class GPTrans {
|
|
10
10
|
static #mmixInstance = null;
|
|
11
11
|
|
|
12
12
|
static get mmix() {
|
|
@@ -21,10 +21,14 @@ class Gptrans {
|
|
|
21
21
|
return this.#mmixInstance;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
static isLanguageAvailable(langCode) {
|
|
25
|
+
return isLanguageAvailable(langCode);
|
|
26
|
+
}
|
|
27
|
+
|
|
24
28
|
constructor({ from = 'en-US', target = 'es-AR', model = 'claude-3-7-sonnet-20250219', batchThreshold = 1000, debounceTimeout = 500, promptFile = null, context = '' }) {
|
|
25
29
|
this.dbTarget = new DeepBase({ name: 'gptrans_' + target });
|
|
26
30
|
this.dbFrom = new DeepBase({ name: 'gptrans_from_' + from });
|
|
27
|
-
|
|
31
|
+
|
|
28
32
|
try {
|
|
29
33
|
this.replace_target = isoAssoc(target, 'TARGET_');
|
|
30
34
|
this.replace_from = isoAssoc(from, 'FROM_');
|
|
@@ -45,11 +49,12 @@ class Gptrans {
|
|
|
45
49
|
max_history: 1,
|
|
46
50
|
debug: false,
|
|
47
51
|
bottleneck: {
|
|
48
|
-
maxConcurrent:
|
|
52
|
+
maxConcurrent: 2,
|
|
49
53
|
}
|
|
50
54
|
},
|
|
51
55
|
options: { max_tokens: batchThreshold }
|
|
52
56
|
};
|
|
57
|
+
this.processing = false;
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
setContext(context = '') {
|
|
@@ -103,6 +108,8 @@ class Gptrans {
|
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
async _processBatch() {
|
|
111
|
+
this.processing = true;
|
|
112
|
+
|
|
106
113
|
const batch = Array.from(this.pendingTranslations.entries());
|
|
107
114
|
|
|
108
115
|
// Clear pending translations and character count before awaiting translation
|
|
@@ -111,17 +118,23 @@ class Gptrans {
|
|
|
111
118
|
this.pendingCharCount = 0;
|
|
112
119
|
|
|
113
120
|
const textsToTranslate = batch.map(([_, text]) => text).join('\n---\n');
|
|
114
|
-
|
|
121
|
+
try {
|
|
122
|
+
const translations = await this._translate(textsToTranslate);
|
|
123
|
+
const translatedTexts = translations.split('\n---\n');
|
|
115
124
|
|
|
116
|
-
|
|
125
|
+
batch.forEach(([key], index) => {
|
|
126
|
+
this.dbTarget.set(key, translatedTexts[index].trim());
|
|
127
|
+
});
|
|
117
128
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
console.error(e);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.processing = false;
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
async _translate(text) {
|
|
124
|
-
const model =
|
|
137
|
+
const model = GPTrans.mmix.create(this.modelKey, this.modelConfig);
|
|
125
138
|
|
|
126
139
|
model.setSystem("You are an expert translator specialized in literary translation between FROM_LANG and TARGET_DENONYM TARGET_LANG.");
|
|
127
140
|
|
|
@@ -153,6 +166,37 @@ class Gptrans {
|
|
|
153
166
|
key += stringHash(text + this.context).toString(36);
|
|
154
167
|
return key;
|
|
155
168
|
}
|
|
169
|
+
|
|
170
|
+
async preload({ target = this.replace_target.TARGET_ISO, model = this.modelKey, from = this.replace_from.FROM_ISO, batchThreshold = this.batchThreshold, debounceTimeout = this.debounceTimeout } = {}) {
|
|
171
|
+
|
|
172
|
+
// Create new GPTrans instance for the target language
|
|
173
|
+
const translator = new GPTrans({
|
|
174
|
+
from,
|
|
175
|
+
target,
|
|
176
|
+
model,
|
|
177
|
+
batchThreshold,
|
|
178
|
+
debounceTimeout,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Process all entries in batches
|
|
182
|
+
for (const [key, text] of this.dbFrom.entries()) {
|
|
183
|
+
translator.get(key, text);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Wait for any pending translations to complete
|
|
187
|
+
if (translator.pendingTranslations.size > 0) {
|
|
188
|
+
await new Promise(resolve => {
|
|
189
|
+
const checkInterval = setInterval(() => {
|
|
190
|
+
if (translator.processing === false && translator.pendingTranslations.size === 0) {
|
|
191
|
+
clearInterval(checkInterval);
|
|
192
|
+
resolve();
|
|
193
|
+
}
|
|
194
|
+
}, 1000);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return translator;
|
|
199
|
+
}
|
|
156
200
|
}
|
|
157
201
|
|
|
158
|
-
export default
|
|
202
|
+
export default GPTrans;
|
package/isoAssoc.js
CHANGED
|
@@ -152,38 +152,44 @@ const langName = {
|
|
|
152
152
|
'ms': 'Malay'
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
+
export function isLanguageAvailable(isoCode) {
|
|
156
|
+
if (!isoCode) return false;
|
|
157
|
+
|
|
158
|
+
const parts = isoCode.toLowerCase().split('-');
|
|
159
|
+
const lang = parts[0];
|
|
160
|
+
const country = parts.length > 1 ? parts[1] : null;
|
|
161
|
+
|
|
162
|
+
// Verificar si el idioma existe
|
|
163
|
+
if (!langName[lang]) return false;
|
|
164
|
+
|
|
165
|
+
// Si hay código de país, verificar si existe
|
|
166
|
+
if (country && !countryName[country]) return false;
|
|
167
|
+
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
|
|
155
171
|
export function isoAssoc(iso, prefix = '') {
|
|
156
172
|
if (!iso) {
|
|
157
173
|
throw new Error('ISO code is required');
|
|
158
174
|
}
|
|
175
|
+
|
|
176
|
+
// Usar la nueva función para validar el ISO
|
|
177
|
+
if (!isLanguageAvailable(iso)) {
|
|
178
|
+
throw new Error(`Invalid ISO code: ${iso}`);
|
|
179
|
+
}
|
|
159
180
|
|
|
160
181
|
const parts = iso.toLowerCase().split('-');
|
|
161
182
|
const lang = parts[0];
|
|
162
183
|
const country = parts.length > 1 ? parts[1] : null;
|
|
163
184
|
|
|
164
|
-
if (!langName[lang]) {
|
|
165
|
-
throw new Error(`Invalid language code: ${lang}`);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (country && !countryName[country]) {
|
|
169
|
-
throw new Error(`Invalid country code: ${country}`);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Special handling for languages with variants
|
|
173
185
|
let denonym = country ? countryDenonym[country] : 'Neutral';
|
|
174
|
-
|
|
175
|
-
// Handle Chinese without specified dialect (use "Simplified" instead of "Neutral")
|
|
186
|
+
|
|
176
187
|
if (lang === 'zh' && !country) {
|
|
177
188
|
denonym = 'Simplified';
|
|
178
189
|
}
|
|
179
|
-
// Handle Arabic without specified dialect (use "Standard" instead of "Neutral")
|
|
180
190
|
else if (lang === 'ar' && !country) {
|
|
181
191
|
denonym = 'Standard';
|
|
182
192
|
}
|
|
183
|
-
// Handle Portuguese without specified dialect (use "European" instead of "Neutral")
|
|
184
|
-
else if (lang === 'pt' && !country) {
|
|
185
|
-
denonym = 'European';
|
|
186
|
-
}
|
|
187
193
|
|
|
188
194
|
return {
|
|
189
195
|
[prefix + 'ISO']: iso,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gptrans",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.4",
|
|
5
5
|
"description": "🚆 GPTrans - The smarter AI-powered way to translate.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"translate",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"language",
|
|
15
15
|
"translation",
|
|
16
16
|
"translator",
|
|
17
|
+
"magic",
|
|
17
18
|
"clasen"
|
|
18
19
|
],
|
|
19
20
|
"repository": {
|