gptrans 1.2.0 → 1.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.
@@ -1,9 +0,0 @@
1
- {
2
- "topup_uzdh5y": "تعبئة رصيد",
3
- "transf_176pc1a": "تحويل",
4
- "deposi_wg2ec5": "إيداع",
5
- "balanc_1rv8if7": "رصيد",
6
- "transa_1wtqm5d": "معاملة",
7
- "accoun_x1y0v8": "حساب",
8
- "card_yis1ox": "بطاقة"
9
- }
@@ -0,0 +1,10 @@
1
+ {
2
+ "hello_name_1987p1n": "Ciao, {name}!",
3
+ "topup_uzdh5y": "Ricarica",
4
+ "transf_176pc1a": "Trasferimento",
5
+ "deposi_wg2ec5": "Deposito",
6
+ "balanc_1rv8if7": "Saldo",
7
+ "transa_1wtqm5d": "Transazione",
8
+ "accoun_x1y0v8": "Conto",
9
+ "card_yis1ox": "Carta"
10
+ }
package/demo/case_2.js CHANGED
@@ -2,18 +2,20 @@ import GPTrans from '../index.js';
2
2
 
3
3
  try {
4
4
  const gptrans = new GPTrans({
5
- target: 'ar',
6
- model: 'claude-3-7-sonnet-20250219',
5
+ target: 'it',
6
+ model: 'gpt-4o-mini',
7
7
  });
8
8
 
9
+ await gptrans.preload();
10
+ console.log('ready');
11
+
9
12
  console.log(gptrans.t('Top-up'));
10
13
  console.log(gptrans.t('Transfer'));
11
14
  console.log(gptrans.t('Deposit'));
12
15
  console.log(gptrans.t('Balance'));
13
16
  console.log(gptrans.t('Transaction'));
14
17
  console.log(gptrans.t('Account'));
15
- console.log(gptrans.t('Card'));
18
+ console.log(gptrans.t('Card'));
16
19
  } catch (e) {
17
20
  console.error(e);
18
- }
19
-
21
+ }
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 Gptrans {
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: 5,
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
@@ -118,10 +125,12 @@ class Gptrans {
118
125
  batch.forEach(([key], index) => {
119
126
  this.dbTarget.set(key, translatedTexts[index].trim());
120
127
  });
128
+
129
+ this.processing = false;
121
130
  }
122
131
 
123
132
  async _translate(text) {
124
- const model = Gptrans.mmix.create(this.modelKey, this.modelConfig);
133
+ const model = GPTrans.mmix.create(this.modelKey, this.modelConfig);
125
134
 
126
135
  model.setSystem("You are an expert translator specialized in literary translation between FROM_LANG and TARGET_DENONYM TARGET_LANG.");
127
136
 
@@ -153,6 +162,37 @@ class Gptrans {
153
162
  key += stringHash(text + this.context).toString(36);
154
163
  return key;
155
164
  }
165
+
166
+ async preload({ target = this.replace_target.TARGET_ISO, model = this.modelKey, from = this.replace_from.FROM_ISO, batchThreshold = this.batchThreshold, debounceTimeout = this.debounceTimeout } = {}) {
167
+
168
+ // Create new GPTrans instance for the target language
169
+ const translator = new GPTrans({
170
+ from,
171
+ target,
172
+ model,
173
+ batchThreshold,
174
+ debounceTimeout,
175
+ });
176
+
177
+ // Process all entries in batches
178
+ for (const [key, text] of this.dbFrom.entries()) {
179
+ translator.get(key, text);
180
+ }
181
+
182
+ // Wait for any pending translations to complete
183
+ if (translator.pendingTranslations.size > 0) {
184
+ await new Promise(resolve => {
185
+ const checkInterval = setInterval(() => {
186
+ if (translator.processing === false && translator.pendingTranslations.size === 0) {
187
+ clearInterval(checkInterval);
188
+ resolve();
189
+ }
190
+ }, 1000);
191
+ });
192
+ }
193
+
194
+ return translator;
195
+ }
156
196
  }
157
197
 
158
- export default Gptrans;
198
+ 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.0",
4
+ "version": "1.2.2",
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": {