@belocal/js-sdk 0.3.1 → 0.4.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/browser.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';var jsMd5=require('js-md5');function f(t){return async({text:e,lang:o,ctx:s})=>{t.debug&&console.log(`[BeLocal Single Transport] Translating "${e}" to ${o}`);try{let a=await t.baseTransport.post({text:e,lang:o,ctx:s},"/v1/translate");return t.debug&&console.log(`[BeLocal Single Transport] Translation successful: "${a.text||e}"`),a.text||e}catch(a){throw t.debug&&console.error("[BeLocal Single Transport] Request failed:",a),a}}}function m(t,e,o){return jsMd5.md5(JSON.stringify({text:t,lang:e,ctx:o||null}))}async function y(t,e,o){t.debug&&console.log(`[BeLocal Batch Transport] Sending batch of ${e.length} requests`);try{let s=e.map(r=>({requestId:r.requestId,payload:r.payload})),a=await t.baseTransport.post({batch:s},"/v1/translate/batch");t.debug&&console.log(`[BeLocal Batch Transport] Batch response received with ${a.results.length} results`);let n=new Map;a.results.forEach(r=>{n.set(r.requestId,{data:r.data,error:r.error});}),e.forEach(r=>{let i=n.get(r.requestId);if(!i){t.debug&&console.error(`[BeLocal Batch Transport] No result found for requestId: ${r.requestId}`),r.reject(new Error(`No result found for request ${r.requestId}`));return}i.error?(t.debug&&console.error(`[BeLocal Batch Transport] Error for requestId ${r.requestId}:`,i.error.message),r.reject(new Error(i.error.message))):i.data?(t.debug&&console.log(`[BeLocal Batch Transport] Success for requestId ${r.requestId}: "${i.data.text}"`),r.resolve(i.data.text)):(t.debug&&console.warn(`[BeLocal Batch Transport] No data or error for requestId ${r.requestId}, returning original text`),r.resolve(r.payload.text));});}catch(s){t.debug&&console.error("[BeLocal Batch Transport] Batch request error:",s);let a=s instanceof Error?s:new Error(String(s));e.forEach(n=>n.reject(a));}finally{}}function B(t,e){if(e.currentBatch.length===0||e.isRequestInFlight)return;let o=[...e.currentBatch];e.currentBatch=[],e.batchTimer=null,e.isRequestInFlight=true,y(t,o).finally(()=>{if(e.isRequestInFlight=false,e.currentBatch.length>0){let s=t.batchWindowMs??50;e.batchTimer=setTimeout(()=>B(t,e),s);}});}function d(t){let e=t.batchWindowMs??50,o={currentBatch:[],batchTimer:null,isRequestInFlight:false};return ({text:s,lang:a,ctx:n})=>new Promise((r,i)=>{let c=m(s,a,n);t.debug&&console.log(`[BeLocal Batch Transport] Queuing request ${c}: "${s}" to ${a}`);let u={requestId:c,payload:{text:s,lang:a,ctx:n},resolve:r,reject:i};o.currentBatch.push(u),o.batchTimer===null&&!o.isRequestInFlight&&(o.batchTimer=setTimeout(()=>B(t,o),e));})}var p=class{constructor(e){this.config=e;}async post(e,o){let s=`${this.config.baseUrl}${o}`,a=new AbortController,n=this.config.timeoutMs?setTimeout(()=>a.abort(),this.config.timeoutMs):null;this.config.debug&&console.log(`[Base Browser Transport] POST request to ${s}`,e);try{let r=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",...this.config.headers},body:JSON.stringify(e),signal:a.signal});if(!r.ok){let c=`HTTP ${r.status}: ${r.statusText}`;throw this.config.debug&&console.error("[Base Browser Transport] Request failed:",c),new Error(c)}let i=await r.json();return this.config.debug&&console.log("[Base Browser Transport] Request successful:",i),i}finally{n&&clearTimeout(n);}}};function g(t){return new p(t)}var l=class{constructor(e="belocal_"){this.prefix=e;}get(e){try{return localStorage.getItem(this.prefix+e)}catch{return null}}set(e,o){try{localStorage.setItem(this.prefix+e,o);}catch{}}isAvailable(){try{let e=this.prefix+"__test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}};var h=class{constructor(){this.storage=new Map;}get(e){return this.storage.get(e)||null}set(e,o){this.storage.set(e,o);}isAvailable(){return true}};var T=class{constructor(e){let{apiKey:o,baseUrl:s="https://dynamic.belocal.dev",batchWindowMs:a=50,timeoutMs:n=1e4,debug:r=false}=e;this.debug=r;let i=new l("belocal_translations_");i.isAvailable()?this.cache=i:this.cache=new h,this.isCacheAvailable=this.cache.isAvailable();let c={Authorization:`Bearer ${o}`},u=g({baseUrl:s,headers:c,timeoutMs:n,debug:this.debug});a>0?(this.transport=d({baseTransport:u,debug:this.debug,batchWindowMs:a}),this.debug&&console.log("[BeLocal Engine] Batch transport created with config:",{baseUrl:s,timeoutMs:n,batchWindowMs:a})):(this.transport=f({baseTransport:u,debug:this.debug}),this.debug&&console.log("[BeLocal Engine] Single transport created with config:",{baseUrl:s,timeoutMs:n})),this.debug&&console.log("[BeLocal Engine] Cache available:",this.isCacheAvailable);}async t(e,o,s){let a=this.generateCacheKey(e,o,s);if(this.isCacheAvailable){let r=this.cache.get(a);if(r){if(this.debug){let i=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from ${i} cache:`,e);}return r}}let n=await this.transport({text:e,lang:o,ctx:s});if(this.isCacheAvailable){if(this.cache.set(a,n),this.debug){let r=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from API, cached in ${r}:`,e);}}else this.debug&&console.log("[BeLocal Engine] Translation from API (no cache):",e);return n}generateCacheKey(e,o,s){return jsMd5.md5(JSON.stringify({text:e,lang:o,ctx:s||null}))}};
2
- exports.BaseBrowserTransport=p;exports.BelocalEngine=T;exports.createBaseBrowserTransport=g;exports.createBatchTransport=d;exports.createSingleTransport=f;//# sourceMappingURL=browser.cjs.map
1
+ 'use strict';var jsMd5=require('js-md5');function d(s){return async({text:e,lang:o,source_lang:t,ctx:a})=>{s.debug&&console.log(`[BeLocal Single Transport] Translating "${e}" to ${o}`);try{let n=await s.baseTransport.post({text:e,lang:o,source_lang:t,ctx:a},"/v1/translate");return s.debug&&console.log(`[BeLocal Single Transport] Translation successful: "${n.text||e}"`),n.text||e}catch(n){throw s.debug&&console.error("[BeLocal Single Transport] Request failed:",n),n}}}function I(s,e,o,t){return jsMd5.md5(JSON.stringify({text:s,lang:e,source_lang:o||null,ctx:t||null}))}async function S(s,e,o){s.debug&&console.log(`[BeLocal Batch Transport] Sending batch of ${e.length} requests`);try{let t=e.map(r=>({requestId:r.requestId,payload:r.payload})),a=await s.baseTransport.post({batch:t},"/v1/translate/batch");s.debug&&console.log(`[BeLocal Batch Transport] Batch response received with ${a.results.length} results`);let n=new Map;a.results.forEach(r=>{n.set(r.requestId,{data:r.data,error:r.error});}),e.forEach(r=>{let i=n.get(r.requestId);if(!i){s.debug&&console.error(`[BeLocal Batch Transport] No result found for requestId: ${r.requestId}`),r.reject(new Error(`No result found for request ${r.requestId}`));return}i.error?(s.debug&&console.error(`[BeLocal Batch Transport] Error for requestId ${r.requestId}:`,i.error.message),r.reject(new Error(i.error.message))):i.data?(s.debug&&console.log(`[BeLocal Batch Transport] Success for requestId ${r.requestId}: "${i.data.text}"`),r.resolve(i.data.text)):(s.debug&&console.warn(`[BeLocal Batch Transport] No data or error for requestId ${r.requestId}, returning original text`),r.resolve(r.payload.text));});}catch(t){s.debug&&console.error("[BeLocal Batch Transport] Batch request error:",t);let a=t instanceof Error?t:new Error(String(t));e.forEach(n=>n.reject(a));}finally{}}function B(s,e){if(e.currentBatch.length===0||e.isRequestInFlight)return;let o=[...e.currentBatch];e.currentBatch=[],e.batchTimer=null,e.isRequestInFlight=true,S(s,o).finally(()=>{if(e.isRequestInFlight=false,e.currentBatch.length>0){let t=s.batchWindowMs??50;e.batchTimer=setTimeout(()=>B(s,e),t);}});}function f(s){let e=s.batchWindowMs??50,o={currentBatch:[],batchTimer:null,isRequestInFlight:false};return ({text:t,lang:a,source_lang:n,ctx:r})=>new Promise((i,c)=>{let u=I(t,a,n,r);s.debug&&console.log(`[BeLocal Batch Transport] Queuing request ${u}: "${t}" to ${a}`);let y={requestId:u,payload:{text:t,lang:a,source_lang:n,ctx:r},resolve:i,reject:c};o.currentBatch.push(y),o.batchTimer===null&&!o.isRequestInFlight&&(o.batchTimer=setTimeout(()=>B(s,o),e));})}var T=(()=>{try{return "0.4.0"}catch{return "undefined"}})(),b="js";var g=class{constructor(e){this.config=e;}async post(e,o){let t=`${this.config.baseUrl}${o}`,a=new AbortController,n=this.config.timeoutMs?setTimeout(()=>a.abort(),this.config.timeoutMs):null;this.config.debug&&console.log(`[Base Browser Transport] POST request to ${t}`,e);try{let r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","x-sdk":b,"x-sdk-version":T,...this.config.headers},body:JSON.stringify(e),signal:a.signal});if(!r.ok){let c=`HTTP ${r.status}: ${r.statusText}`;throw this.config.debug&&console.error("[Base Browser Transport] Request failed:",c),new Error(c)}let i=await r.json();return this.config.debug&&console.log("[Base Browser Transport] Request successful:",i),i}finally{n&&clearTimeout(n);}}};function p(s){return new g(s)}var l=class{constructor(e="belocal_"){this.prefix=e;}get(e){try{return localStorage.getItem(this.prefix+e)}catch{return null}}set(e,o){try{localStorage.setItem(this.prefix+e,o);}catch{}}isAvailable(){try{let e=this.prefix+"__test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}};var h=class{constructor(){this.storage=new Map;}get(e){return this.storage.get(e)||null}set(e,o){this.storage.set(e,o);}isAvailable(){return true}};var m=class{constructor(e){let{apiKey:o,baseUrl:t="https://dynamic.belocal.dev",batchWindowMs:a=50,timeoutMs:n=1e4,debug:r=false}=e;this.debug=r;let i=new l("belocal_translations_");i.isAvailable()?this.cache=i:this.cache=new h,this.isCacheAvailable=this.cache.isAvailable();let c={Authorization:`Bearer ${o}`},u=p({baseUrl:t,headers:c,timeoutMs:n,debug:this.debug});a>0?(this.transport=f({baseTransport:u,debug:this.debug,batchWindowMs:a}),this.debug&&console.log("[BeLocal Engine] Batch transport created with config:",{baseUrl:t,timeoutMs:n,batchWindowMs:a})):(this.transport=d({baseTransport:u,debug:this.debug}),this.debug&&console.log("[BeLocal Engine] Single transport created with config:",{baseUrl:t,timeoutMs:n})),this.debug&&console.log("[BeLocal Engine] Cache available:",this.isCacheAvailable);}async translate(e,o,t,a){let n=this.generateCacheKey(e,o,t,a);if(this.isCacheAvailable){let i=this.cache.get(n);if(i){if(this.debug){let c=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from ${c} cache:`,e);}return i}}let r=await this.transport({text:e,lang:o,source_lang:t,ctx:a});if(this.isCacheAvailable){if(this.cache.set(n,r),this.debug){let i=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from API, cached in ${i}:`,e);}}else this.debug&&console.log("[BeLocal Engine] Translation from API (no cache):",e);return r}async t(e,o,t,a){return this.translate(e,o,t,{user_ctx:a})}generateCacheKey(e,o,t,a){return jsMd5.md5(JSON.stringify({text:e,lang:o,source_lang:t||null,ctx:a||null}))}};
2
+ exports.BaseBrowserTransport=g;exports.BelocalEngine=m;exports.createBaseBrowserTransport=p;exports.createBatchTransport=f;exports.createSingleTransport=d;//# sourceMappingURL=browser.cjs.map
3
3
  //# sourceMappingURL=browser.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transports/single.ts","../src/transports/batch.ts","../src/transports/base/browser.ts","../src/cache/localStorage.ts","../src/cache/local.ts","../src/core/engine/browser.ts"],"names":["createSingleTransport","config","text","lang","ctx","result","error","generateRequestId","md5","sendBatch","batch","state","batchRequests","item","batchResponse","resultMap","errorToReject","processBatch","batchToSend","windowMs","createBatchTransport","resolve","reject","requestId","requestItem","BaseBrowserTransport","data","endpointPath","url","controller","timeoutId","response","errorMsg","createBaseBrowserTransport","LocalStorageCache","prefix","key","value","testKey","LocalCache","BelocalEngine","options","apiKey","baseUrl","batchWindowMs","timeoutMs","debug","localStorageCache","authHeaders","baseTransport","cacheKey","cachedResult","cacheType"],"mappings":"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","file":"browser.cjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","import type { BaseTransport } from '../../core/types';\n\nexport interface BaseBrowserTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n debug?: boolean;\n}\n\nexport class BaseBrowserTransport implements BaseTransport {\n constructor(private config: BaseBrowserTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const url = `${this.config.baseUrl}${endpointPath}`;\n const controller = new AbortController();\n const timeoutId = this.config.timeoutMs \n ? setTimeout(() => controller.abort(), this.config.timeoutMs) \n : null;\n\n if (this.config.debug) {\n console.log(`[Base Browser Transport] POST request to ${url}`, data);\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify(data),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n if (this.config.debug) {\n console.error(`[Base Browser Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = await response.json();\n if (this.config.debug) {\n console.log(`[Base Browser Transport] Request successful:`, result);\n }\n \n return result;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n}\n\nexport function createBaseBrowserTransport(config: BaseBrowserTransportConfig): BaseBrowserTransport {\n return new BaseBrowserTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalStorageCache implements Cache {\n private prefix: string;\n\n constructor(prefix: string = 'belocal_') {\n this.prefix = prefix;\n }\n\n get(key: string): string | null {\n try {\n return localStorage.getItem(this.prefix + key);\n } catch {\n // localStorage might not be available in some environments\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(this.prefix + key, value);\n } catch {\n // localStorage might not be available or quota exceeded\n // Silently fail\n }\n }\n\n isAvailable(): boolean {\n try {\n const testKey = this.prefix + '__test__';\n localStorage.setItem(testKey, 'test');\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createBaseBrowserTransport } from '../../transports/base/browser';\nimport { LocalStorageCache } from '../../cache/localStorage';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n private isCacheAvailable: boolean;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Try localStorage first, fallback to local cache\n const localStorageCache = new LocalStorageCache('belocal_translations_');\n if (localStorageCache.isAvailable()) {\n this.cache = localStorageCache;\n } else {\n this.cache = new LocalCache();\n }\n this.isCacheAvailable = this.cache.isAvailable();\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base browser transport\n const baseTransport = createBaseBrowserTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with browser base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with browser base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n \n if (this.debug) {\n console.log('[BeLocal Engine] Cache available:', this.isCacheAvailable);\n }\n }\n\n async t(text: string, lang: Lang, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, ctx);\n \n // Try to get from cache first\n if (this.isCacheAvailable) {\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from ${cacheType} cache:`, text);\n }\n return cachedResult;\n }\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, ctx });\n \n // Store in cache\n if (this.isCacheAvailable) {\n this.cache.set(cacheKey, result);\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from API, cached in ${cacheType}:`, text);\n }\n } else {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API (no cache):', text);\n }\n }\n\n return result;\n }\n\n private generateCacheKey(text: string, lang: Lang, ctx?: KV): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { createSingleTransport } from '../../transports/single';\nexport { createBatchTransport } from '../../transports/batch';\nexport { BaseBrowserTransport, createBaseBrowserTransport } from '../../transports/base';\n"]}
1
+ {"version":3,"sources":["../src/transports/single.ts","../src/transports/batch.ts","../src/version.ts","../src/transports/base/browser.ts","../src/cache/localStorage.ts","../src/cache/local.ts","../src/core/engine/browser.ts"],"names":["createSingleTransport","config","text","lang","source_lang","ctx","result","error","generateRequestId","md5","sendBatch","batch","state","batchRequests","item","batchResponse","resultMap","errorToReject","processBatch","batchToSend","windowMs","createBatchTransport","resolve","reject","requestId","requestItem","SDK_VERSION","SDK_NAME","BaseBrowserTransport","data","endpointPath","url","controller","timeoutId","response","errorMsg","createBaseBrowserTransport","LocalStorageCache","prefix","key","value","testKey","LocalCache","BelocalEngine","options","apiKey","baseUrl","batchWindowMs","timeoutMs","debug","localStorageCache","authHeaders","baseTransport","cacheKey","cachedResult","cacheType","context"],"mappings":"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","file":"browser.cjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, source_lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, source_lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, source_lang?: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, source_lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, source_lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, source_lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","// SDK version - will be replaced during build with tsup define\ndeclare const __SDK_VERSION__: string | undefined;\n\n// Safely check if __SDK_VERSION__ is defined (replaced during build)\nexport const SDK_VERSION: string = \n (() => { try { return typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : 'undefined'; } catch { return 'undefined'; } })();\n\nexport const SDK_NAME = 'js';\n\n","import type { BaseTransport } from '../../core/types';\nimport { SDK_NAME, SDK_VERSION } from '../../version';\n\nexport interface BaseBrowserTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n debug?: boolean;\n}\n\nexport class BaseBrowserTransport implements BaseTransport {\n constructor(private config: BaseBrowserTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const url = `${this.config.baseUrl}${endpointPath}`;\n const controller = new AbortController();\n const timeoutId = this.config.timeoutMs \n ? setTimeout(() => controller.abort(), this.config.timeoutMs) \n : null;\n\n if (this.config.debug) {\n console.log(`[Base Browser Transport] POST request to ${url}`, data);\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk': SDK_NAME,\n 'x-sdk-version': SDK_VERSION,\n ...this.config.headers,\n },\n body: JSON.stringify(data),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n if (this.config.debug) {\n console.error(`[Base Browser Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = await response.json();\n if (this.config.debug) {\n console.log(`[Base Browser Transport] Request successful:`, result);\n }\n \n return result;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n}\n\nexport function createBaseBrowserTransport(config: BaseBrowserTransportConfig): BaseBrowserTransport {\n return new BaseBrowserTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalStorageCache implements Cache {\n private prefix: string;\n\n constructor(prefix: string = 'belocal_') {\n this.prefix = prefix;\n }\n\n get(key: string): string | null {\n try {\n return localStorage.getItem(this.prefix + key);\n } catch {\n // localStorage might not be available in some environments\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(this.prefix + key, value);\n } catch {\n // localStorage might not be available or quota exceeded\n // Silently fail\n }\n }\n\n isAvailable(): boolean {\n try {\n const testKey = this.prefix + '__test__';\n localStorage.setItem(testKey, 'test');\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createBaseBrowserTransport } from '../../transports/base/browser';\nimport { LocalStorageCache } from '../../cache/localStorage';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n private isCacheAvailable: boolean;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Try localStorage first, fallback to local cache\n const localStorageCache = new LocalStorageCache('belocal_translations_');\n if (localStorageCache.isAvailable()) {\n this.cache = localStorageCache;\n } else {\n this.cache = new LocalCache();\n }\n this.isCacheAvailable = this.cache.isAvailable();\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base browser transport\n const baseTransport = createBaseBrowserTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with browser base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with browser base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n \n if (this.debug) {\n console.log('[BeLocal Engine] Cache available:', this.isCacheAvailable);\n }\n }\n\n async translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n \n // Try to get from cache first\n if (this.isCacheAvailable) {\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from ${cacheType} cache:`, text);\n }\n return cachedResult;\n }\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, source_lang, ctx });\n \n // Store in cache\n if (this.isCacheAvailable) {\n this.cache.set(cacheKey, result);\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from API, cached in ${cacheType}:`, text);\n }\n } else {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API (no cache):', text);\n }\n }\n\n return result;\n }\n\n async t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string> {\n return this.translate(text, lang, source_lang, {user_ctx: context});\n }\n\n private generateCacheKey(text: string, lang: Lang, source_lang?: string, ctx?: KV): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { createSingleTransport } from '../../transports/single';\nexport { createBatchTransport } from '../../transports/batch';\nexport { BaseBrowserTransport, createBaseBrowserTransport } from '../../transports/base';\n"]}
package/dist/browser.d.ts CHANGED
@@ -6,6 +6,7 @@ interface BaseTransport {
6
6
  type Transport = (params: {
7
7
  text: string;
8
8
  lang: Lang;
9
+ source_lang?: string;
9
10
  ctx?: KV;
10
11
  }) => Promise<string>;
11
12
  interface BelocalEngineOptions {
@@ -48,7 +49,8 @@ declare class BelocalEngine {
48
49
  private cache;
49
50
  private isCacheAvailable;
50
51
  constructor(options: BelocalEngineOptions);
51
- t(text: string, lang: Lang, ctx?: KV): Promise<string>;
52
+ translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string>;
53
+ t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string>;
52
54
  private generateCacheKey;
53
55
  }
54
56
 
package/dist/browser.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import {md5}from'js-md5';function f(t){return async({text:e,lang:o,ctx:s})=>{t.debug&&console.log(`[BeLocal Single Transport] Translating "${e}" to ${o}`);try{let a=await t.baseTransport.post({text:e,lang:o,ctx:s},"/v1/translate");return t.debug&&console.log(`[BeLocal Single Transport] Translation successful: "${a.text||e}"`),a.text||e}catch(a){throw t.debug&&console.error("[BeLocal Single Transport] Request failed:",a),a}}}function m(t,e,o){return md5(JSON.stringify({text:t,lang:e,ctx:o||null}))}async function y(t,e,o){t.debug&&console.log(`[BeLocal Batch Transport] Sending batch of ${e.length} requests`);try{let s=e.map(r=>({requestId:r.requestId,payload:r.payload})),a=await t.baseTransport.post({batch:s},"/v1/translate/batch");t.debug&&console.log(`[BeLocal Batch Transport] Batch response received with ${a.results.length} results`);let n=new Map;a.results.forEach(r=>{n.set(r.requestId,{data:r.data,error:r.error});}),e.forEach(r=>{let i=n.get(r.requestId);if(!i){t.debug&&console.error(`[BeLocal Batch Transport] No result found for requestId: ${r.requestId}`),r.reject(new Error(`No result found for request ${r.requestId}`));return}i.error?(t.debug&&console.error(`[BeLocal Batch Transport] Error for requestId ${r.requestId}:`,i.error.message),r.reject(new Error(i.error.message))):i.data?(t.debug&&console.log(`[BeLocal Batch Transport] Success for requestId ${r.requestId}: "${i.data.text}"`),r.resolve(i.data.text)):(t.debug&&console.warn(`[BeLocal Batch Transport] No data or error for requestId ${r.requestId}, returning original text`),r.resolve(r.payload.text));});}catch(s){t.debug&&console.error("[BeLocal Batch Transport] Batch request error:",s);let a=s instanceof Error?s:new Error(String(s));e.forEach(n=>n.reject(a));}finally{}}function B(t,e){if(e.currentBatch.length===0||e.isRequestInFlight)return;let o=[...e.currentBatch];e.currentBatch=[],e.batchTimer=null,e.isRequestInFlight=true,y(t,o).finally(()=>{if(e.isRequestInFlight=false,e.currentBatch.length>0){let s=t.batchWindowMs??50;e.batchTimer=setTimeout(()=>B(t,e),s);}});}function d(t){let e=t.batchWindowMs??50,o={currentBatch:[],batchTimer:null,isRequestInFlight:false};return ({text:s,lang:a,ctx:n})=>new Promise((r,i)=>{let c=m(s,a,n);t.debug&&console.log(`[BeLocal Batch Transport] Queuing request ${c}: "${s}" to ${a}`);let u={requestId:c,payload:{text:s,lang:a,ctx:n},resolve:r,reject:i};o.currentBatch.push(u),o.batchTimer===null&&!o.isRequestInFlight&&(o.batchTimer=setTimeout(()=>B(t,o),e));})}var p=class{constructor(e){this.config=e;}async post(e,o){let s=`${this.config.baseUrl}${o}`,a=new AbortController,n=this.config.timeoutMs?setTimeout(()=>a.abort(),this.config.timeoutMs):null;this.config.debug&&console.log(`[Base Browser Transport] POST request to ${s}`,e);try{let r=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json",...this.config.headers},body:JSON.stringify(e),signal:a.signal});if(!r.ok){let c=`HTTP ${r.status}: ${r.statusText}`;throw this.config.debug&&console.error("[Base Browser Transport] Request failed:",c),new Error(c)}let i=await r.json();return this.config.debug&&console.log("[Base Browser Transport] Request successful:",i),i}finally{n&&clearTimeout(n);}}};function g(t){return new p(t)}var l=class{constructor(e="belocal_"){this.prefix=e;}get(e){try{return localStorage.getItem(this.prefix+e)}catch{return null}}set(e,o){try{localStorage.setItem(this.prefix+e,o);}catch{}}isAvailable(){try{let e=this.prefix+"__test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}};var h=class{constructor(){this.storage=new Map;}get(e){return this.storage.get(e)||null}set(e,o){this.storage.set(e,o);}isAvailable(){return true}};var T=class{constructor(e){let{apiKey:o,baseUrl:s="https://dynamic.belocal.dev",batchWindowMs:a=50,timeoutMs:n=1e4,debug:r=false}=e;this.debug=r;let i=new l("belocal_translations_");i.isAvailable()?this.cache=i:this.cache=new h,this.isCacheAvailable=this.cache.isAvailable();let c={Authorization:`Bearer ${o}`},u=g({baseUrl:s,headers:c,timeoutMs:n,debug:this.debug});a>0?(this.transport=d({baseTransport:u,debug:this.debug,batchWindowMs:a}),this.debug&&console.log("[BeLocal Engine] Batch transport created with config:",{baseUrl:s,timeoutMs:n,batchWindowMs:a})):(this.transport=f({baseTransport:u,debug:this.debug}),this.debug&&console.log("[BeLocal Engine] Single transport created with config:",{baseUrl:s,timeoutMs:n})),this.debug&&console.log("[BeLocal Engine] Cache available:",this.isCacheAvailable);}async t(e,o,s){let a=this.generateCacheKey(e,o,s);if(this.isCacheAvailable){let r=this.cache.get(a);if(r){if(this.debug){let i=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from ${i} cache:`,e);}return r}}let n=await this.transport({text:e,lang:o,ctx:s});if(this.isCacheAvailable){if(this.cache.set(a,n),this.debug){let r=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from API, cached in ${r}:`,e);}}else this.debug&&console.log("[BeLocal Engine] Translation from API (no cache):",e);return n}generateCacheKey(e,o,s){return md5(JSON.stringify({text:e,lang:o,ctx:s||null}))}};
2
- export{p as BaseBrowserTransport,T as BelocalEngine,g as createBaseBrowserTransport,d as createBatchTransport,f as createSingleTransport};//# sourceMappingURL=browser.mjs.map
1
+ import {md5}from'js-md5';function d(s){return async({text:e,lang:o,source_lang:t,ctx:a})=>{s.debug&&console.log(`[BeLocal Single Transport] Translating "${e}" to ${o}`);try{let n=await s.baseTransport.post({text:e,lang:o,source_lang:t,ctx:a},"/v1/translate");return s.debug&&console.log(`[BeLocal Single Transport] Translation successful: "${n.text||e}"`),n.text||e}catch(n){throw s.debug&&console.error("[BeLocal Single Transport] Request failed:",n),n}}}function I(s,e,o,t){return md5(JSON.stringify({text:s,lang:e,source_lang:o||null,ctx:t||null}))}async function S(s,e,o){s.debug&&console.log(`[BeLocal Batch Transport] Sending batch of ${e.length} requests`);try{let t=e.map(r=>({requestId:r.requestId,payload:r.payload})),a=await s.baseTransport.post({batch:t},"/v1/translate/batch");s.debug&&console.log(`[BeLocal Batch Transport] Batch response received with ${a.results.length} results`);let n=new Map;a.results.forEach(r=>{n.set(r.requestId,{data:r.data,error:r.error});}),e.forEach(r=>{let i=n.get(r.requestId);if(!i){s.debug&&console.error(`[BeLocal Batch Transport] No result found for requestId: ${r.requestId}`),r.reject(new Error(`No result found for request ${r.requestId}`));return}i.error?(s.debug&&console.error(`[BeLocal Batch Transport] Error for requestId ${r.requestId}:`,i.error.message),r.reject(new Error(i.error.message))):i.data?(s.debug&&console.log(`[BeLocal Batch Transport] Success for requestId ${r.requestId}: "${i.data.text}"`),r.resolve(i.data.text)):(s.debug&&console.warn(`[BeLocal Batch Transport] No data or error for requestId ${r.requestId}, returning original text`),r.resolve(r.payload.text));});}catch(t){s.debug&&console.error("[BeLocal Batch Transport] Batch request error:",t);let a=t instanceof Error?t:new Error(String(t));e.forEach(n=>n.reject(a));}finally{}}function B(s,e){if(e.currentBatch.length===0||e.isRequestInFlight)return;let o=[...e.currentBatch];e.currentBatch=[],e.batchTimer=null,e.isRequestInFlight=true,S(s,o).finally(()=>{if(e.isRequestInFlight=false,e.currentBatch.length>0){let t=s.batchWindowMs??50;e.batchTimer=setTimeout(()=>B(s,e),t);}});}function f(s){let e=s.batchWindowMs??50,o={currentBatch:[],batchTimer:null,isRequestInFlight:false};return ({text:t,lang:a,source_lang:n,ctx:r})=>new Promise((i,c)=>{let u=I(t,a,n,r);s.debug&&console.log(`[BeLocal Batch Transport] Queuing request ${u}: "${t}" to ${a}`);let y={requestId:u,payload:{text:t,lang:a,source_lang:n,ctx:r},resolve:i,reject:c};o.currentBatch.push(y),o.batchTimer===null&&!o.isRequestInFlight&&(o.batchTimer=setTimeout(()=>B(s,o),e));})}var T=(()=>{try{return "0.4.0"}catch{return "undefined"}})(),b="js";var g=class{constructor(e){this.config=e;}async post(e,o){let t=`${this.config.baseUrl}${o}`,a=new AbortController,n=this.config.timeoutMs?setTimeout(()=>a.abort(),this.config.timeoutMs):null;this.config.debug&&console.log(`[Base Browser Transport] POST request to ${t}`,e);try{let r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","x-sdk":b,"x-sdk-version":T,...this.config.headers},body:JSON.stringify(e),signal:a.signal});if(!r.ok){let c=`HTTP ${r.status}: ${r.statusText}`;throw this.config.debug&&console.error("[Base Browser Transport] Request failed:",c),new Error(c)}let i=await r.json();return this.config.debug&&console.log("[Base Browser Transport] Request successful:",i),i}finally{n&&clearTimeout(n);}}};function p(s){return new g(s)}var l=class{constructor(e="belocal_"){this.prefix=e;}get(e){try{return localStorage.getItem(this.prefix+e)}catch{return null}}set(e,o){try{localStorage.setItem(this.prefix+e,o);}catch{}}isAvailable(){try{let e=this.prefix+"__test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return false}}};var h=class{constructor(){this.storage=new Map;}get(e){return this.storage.get(e)||null}set(e,o){this.storage.set(e,o);}isAvailable(){return true}};var m=class{constructor(e){let{apiKey:o,baseUrl:t="https://dynamic.belocal.dev",batchWindowMs:a=50,timeoutMs:n=1e4,debug:r=false}=e;this.debug=r;let i=new l("belocal_translations_");i.isAvailable()?this.cache=i:this.cache=new h,this.isCacheAvailable=this.cache.isAvailable();let c={Authorization:`Bearer ${o}`},u=p({baseUrl:t,headers:c,timeoutMs:n,debug:this.debug});a>0?(this.transport=f({baseTransport:u,debug:this.debug,batchWindowMs:a}),this.debug&&console.log("[BeLocal Engine] Batch transport created with config:",{baseUrl:t,timeoutMs:n,batchWindowMs:a})):(this.transport=d({baseTransport:u,debug:this.debug}),this.debug&&console.log("[BeLocal Engine] Single transport created with config:",{baseUrl:t,timeoutMs:n})),this.debug&&console.log("[BeLocal Engine] Cache available:",this.isCacheAvailable);}async translate(e,o,t,a){let n=this.generateCacheKey(e,o,t,a);if(this.isCacheAvailable){let i=this.cache.get(n);if(i){if(this.debug){let c=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from ${c} cache:`,e);}return i}}let r=await this.transport({text:e,lang:o,source_lang:t,ctx:a});if(this.isCacheAvailable){if(this.cache.set(n,r),this.debug){let i=this.cache instanceof l?"localStorage":"local";console.log(`[BeLocal Engine] Translation from API, cached in ${i}:`,e);}}else this.debug&&console.log("[BeLocal Engine] Translation from API (no cache):",e);return r}async t(e,o,t,a){return this.translate(e,o,t,{user_ctx:a})}generateCacheKey(e,o,t,a){return md5(JSON.stringify({text:e,lang:o,source_lang:t||null,ctx:a||null}))}};
2
+ export{g as BaseBrowserTransport,m as BelocalEngine,p as createBaseBrowserTransport,f as createBatchTransport,d as createSingleTransport};//# sourceMappingURL=browser.mjs.map
3
3
  //# sourceMappingURL=browser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transports/single.ts","../src/transports/batch.ts","../src/transports/base/browser.ts","../src/cache/localStorage.ts","../src/cache/local.ts","../src/core/engine/browser.ts"],"names":["createSingleTransport","config","text","lang","ctx","result","error","generateRequestId","md5","sendBatch","batch","state","batchRequests","item","batchResponse","resultMap","errorToReject","processBatch","batchToSend","windowMs","createBatchTransport","resolve","reject","requestId","requestItem","BaseBrowserTransport","data","endpointPath","url","controller","timeoutId","response","errorMsg","createBaseBrowserTransport","LocalStorageCache","prefix","key","value","testKey","LocalCache","BelocalEngine","options","apiKey","baseUrl","batchWindowMs","timeoutMs","debug","localStorageCache","authHeaders","baseTransport","cacheKey","cachedResult","cacheType"],"mappings":"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","file":"browser.mjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","import type { BaseTransport } from '../../core/types';\n\nexport interface BaseBrowserTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n debug?: boolean;\n}\n\nexport class BaseBrowserTransport implements BaseTransport {\n constructor(private config: BaseBrowserTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const url = `${this.config.baseUrl}${endpointPath}`;\n const controller = new AbortController();\n const timeoutId = this.config.timeoutMs \n ? setTimeout(() => controller.abort(), this.config.timeoutMs) \n : null;\n\n if (this.config.debug) {\n console.log(`[Base Browser Transport] POST request to ${url}`, data);\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify(data),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n if (this.config.debug) {\n console.error(`[Base Browser Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = await response.json();\n if (this.config.debug) {\n console.log(`[Base Browser Transport] Request successful:`, result);\n }\n \n return result;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n}\n\nexport function createBaseBrowserTransport(config: BaseBrowserTransportConfig): BaseBrowserTransport {\n return new BaseBrowserTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalStorageCache implements Cache {\n private prefix: string;\n\n constructor(prefix: string = 'belocal_') {\n this.prefix = prefix;\n }\n\n get(key: string): string | null {\n try {\n return localStorage.getItem(this.prefix + key);\n } catch {\n // localStorage might not be available in some environments\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(this.prefix + key, value);\n } catch {\n // localStorage might not be available or quota exceeded\n // Silently fail\n }\n }\n\n isAvailable(): boolean {\n try {\n const testKey = this.prefix + '__test__';\n localStorage.setItem(testKey, 'test');\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createBaseBrowserTransport } from '../../transports/base/browser';\nimport { LocalStorageCache } from '../../cache/localStorage';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n private isCacheAvailable: boolean;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Try localStorage first, fallback to local cache\n const localStorageCache = new LocalStorageCache('belocal_translations_');\n if (localStorageCache.isAvailable()) {\n this.cache = localStorageCache;\n } else {\n this.cache = new LocalCache();\n }\n this.isCacheAvailable = this.cache.isAvailable();\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base browser transport\n const baseTransport = createBaseBrowserTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with browser base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with browser base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n \n if (this.debug) {\n console.log('[BeLocal Engine] Cache available:', this.isCacheAvailable);\n }\n }\n\n async t(text: string, lang: Lang, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, ctx);\n \n // Try to get from cache first\n if (this.isCacheAvailable) {\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from ${cacheType} cache:`, text);\n }\n return cachedResult;\n }\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, ctx });\n \n // Store in cache\n if (this.isCacheAvailable) {\n this.cache.set(cacheKey, result);\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from API, cached in ${cacheType}:`, text);\n }\n } else {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API (no cache):', text);\n }\n }\n\n return result;\n }\n\n private generateCacheKey(text: string, lang: Lang, ctx?: KV): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { createSingleTransport } from '../../transports/single';\nexport { createBatchTransport } from '../../transports/batch';\nexport { BaseBrowserTransport, createBaseBrowserTransport } from '../../transports/base';\n"]}
1
+ {"version":3,"sources":["../src/transports/single.ts","../src/transports/batch.ts","../src/version.ts","../src/transports/base/browser.ts","../src/cache/localStorage.ts","../src/cache/local.ts","../src/core/engine/browser.ts"],"names":["createSingleTransport","config","text","lang","source_lang","ctx","result","error","generateRequestId","md5","sendBatch","batch","state","batchRequests","item","batchResponse","resultMap","errorToReject","processBatch","batchToSend","windowMs","createBatchTransport","resolve","reject","requestId","requestItem","SDK_VERSION","SDK_NAME","BaseBrowserTransport","data","endpointPath","url","controller","timeoutId","response","errorMsg","createBaseBrowserTransport","LocalStorageCache","prefix","key","value","testKey","LocalCache","BelocalEngine","options","apiKey","baseUrl","batchWindowMs","timeoutMs","debug","localStorageCache","authHeaders","baseTransport","cacheKey","cachedResult","cacheType","context"],"mappings":"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","file":"browser.mjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, source_lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, source_lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, source_lang?: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, source_lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, source_lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, source_lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","// SDK version - will be replaced during build with tsup define\ndeclare const __SDK_VERSION__: string | undefined;\n\n// Safely check if __SDK_VERSION__ is defined (replaced during build)\nexport const SDK_VERSION: string = \n (() => { try { return typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : 'undefined'; } catch { return 'undefined'; } })();\n\nexport const SDK_NAME = 'js';\n\n","import type { BaseTransport } from '../../core/types';\nimport { SDK_NAME, SDK_VERSION } from '../../version';\n\nexport interface BaseBrowserTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n debug?: boolean;\n}\n\nexport class BaseBrowserTransport implements BaseTransport {\n constructor(private config: BaseBrowserTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const url = `${this.config.baseUrl}${endpointPath}`;\n const controller = new AbortController();\n const timeoutId = this.config.timeoutMs \n ? setTimeout(() => controller.abort(), this.config.timeoutMs) \n : null;\n\n if (this.config.debug) {\n console.log(`[Base Browser Transport] POST request to ${url}`, data);\n }\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-sdk': SDK_NAME,\n 'x-sdk-version': SDK_VERSION,\n ...this.config.headers,\n },\n body: JSON.stringify(data),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorMsg = `HTTP ${response.status}: ${response.statusText}`;\n if (this.config.debug) {\n console.error(`[Base Browser Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = await response.json();\n if (this.config.debug) {\n console.log(`[Base Browser Transport] Request successful:`, result);\n }\n \n return result;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n}\n\nexport function createBaseBrowserTransport(config: BaseBrowserTransportConfig): BaseBrowserTransport {\n return new BaseBrowserTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalStorageCache implements Cache {\n private prefix: string;\n\n constructor(prefix: string = 'belocal_') {\n this.prefix = prefix;\n }\n\n get(key: string): string | null {\n try {\n return localStorage.getItem(this.prefix + key);\n } catch {\n // localStorage might not be available in some environments\n return null;\n }\n }\n\n set(key: string, value: string): void {\n try {\n localStorage.setItem(this.prefix + key, value);\n } catch {\n // localStorage might not be available or quota exceeded\n // Silently fail\n }\n }\n\n isAvailable(): boolean {\n try {\n const testKey = this.prefix + '__test__';\n localStorage.setItem(testKey, 'test');\n localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createBaseBrowserTransport } from '../../transports/base/browser';\nimport { LocalStorageCache } from '../../cache/localStorage';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n private isCacheAvailable: boolean;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Try localStorage first, fallback to local cache\n const localStorageCache = new LocalStorageCache('belocal_translations_');\n if (localStorageCache.isAvailable()) {\n this.cache = localStorageCache;\n } else {\n this.cache = new LocalCache();\n }\n this.isCacheAvailable = this.cache.isAvailable();\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base browser transport\n const baseTransport = createBaseBrowserTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with browser base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with browser base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n \n if (this.debug) {\n console.log('[BeLocal Engine] Cache available:', this.isCacheAvailable);\n }\n }\n\n async translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n \n // Try to get from cache first\n if (this.isCacheAvailable) {\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from ${cacheType} cache:`, text);\n }\n return cachedResult;\n }\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, source_lang, ctx });\n \n // Store in cache\n if (this.isCacheAvailable) {\n this.cache.set(cacheKey, result);\n if (this.debug) {\n const cacheType = this.cache instanceof LocalStorageCache ? 'localStorage' : 'local';\n console.log(`[BeLocal Engine] Translation from API, cached in ${cacheType}:`, text);\n }\n } else {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API (no cache):', text);\n }\n }\n\n return result;\n }\n\n async t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string> {\n return this.translate(text, lang, source_lang, {user_ctx: context});\n }\n\n private generateCacheKey(text: string, lang: Lang, source_lang?: string, ctx?: KV): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { createSingleTransport } from '../../transports/single';\nexport { createBatchTransport } from '../../transports/batch';\nexport { BaseBrowserTransport, createBaseBrowserTransport } from '../../transports/base';\n"]}
package/dist/node.cjs CHANGED
@@ -25,10 +25,11 @@ function _interopNamespace(e) {
25
25
  var http2__namespace = /*#__PURE__*/_interopNamespace(http2);
26
26
 
27
27
  // src/transports/batch.ts
28
- function generateRequestId(text, lang, ctx) {
28
+ function generateRequestId(text, lang, source_lang, ctx) {
29
29
  const data = {
30
30
  text,
31
31
  lang,
32
+ source_lang: source_lang || null,
32
33
  ctx: ctx || null
33
34
  };
34
35
  return jsMd5.md5(JSON.stringify(data));
@@ -108,15 +109,15 @@ function createBatchTransport(config) {
108
109
  batchTimer: null,
109
110
  isRequestInFlight: false
110
111
  };
111
- return ({ text, lang, ctx }) => {
112
+ return ({ text, lang, source_lang, ctx }) => {
112
113
  return new Promise((resolve, reject) => {
113
- const requestId = generateRequestId(text, lang, ctx);
114
+ const requestId = generateRequestId(text, lang, source_lang, ctx);
114
115
  if (config.debug) {
115
116
  console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: "${text}" to ${lang}`);
116
117
  }
117
118
  const requestItem = {
118
119
  requestId,
119
- payload: { text, lang, ctx },
120
+ payload: { text, lang, source_lang, ctx },
120
121
  resolve,
121
122
  reject
122
123
  };
@@ -130,12 +131,12 @@ function createBatchTransport(config) {
130
131
 
131
132
  // src/transports/single.ts
132
133
  function createSingleTransport(config) {
133
- return async ({ text, lang, ctx }) => {
134
+ return async ({ text, lang, source_lang, ctx }) => {
134
135
  if (config.debug) {
135
136
  console.log(`[BeLocal Single Transport] Translating "${text}" to ${lang}`);
136
137
  }
137
138
  try {
138
- const result = await config.baseTransport.post({ text, lang, ctx }, "/v1/translate");
139
+ const result = await config.baseTransport.post({ text, lang, source_lang, ctx }, "/v1/translate");
139
140
  if (config.debug) {
140
141
  console.log(`[BeLocal Single Transport] Translation successful: "${result.text || text}"`);
141
142
  }
@@ -148,6 +149,18 @@ function createSingleTransport(config) {
148
149
  }
149
150
  };
150
151
  }
152
+
153
+ // src/version.ts
154
+ var SDK_VERSION = (() => {
155
+ try {
156
+ return true ? "0.4.0" : "undefined";
157
+ } catch {
158
+ return "undefined";
159
+ }
160
+ })();
161
+ var SDK_NAME = "js";
162
+
163
+ // src/transports/base/node.ts
151
164
  var sessionCache = /* @__PURE__ */ new Map();
152
165
  function getOrCreateSession(baseUrl, debug) {
153
166
  if (sessionCache.has(baseUrl)) {
@@ -233,10 +246,15 @@ var BaseNodeTransport = class {
233
246
  try {
234
247
  const session = getOrCreateSession(this.config.baseUrl, this.config.debug);
235
248
  const body = JSON.stringify(data);
249
+ const headers = {
250
+ "x-sdk": SDK_NAME,
251
+ "x-sdk-version": SDK_VERSION,
252
+ ...this.config.headers
253
+ };
236
254
  const response = await makeHttp2Request(
237
255
  session,
238
256
  endpointPath,
239
- this.config.headers || {},
257
+ headers,
240
258
  body,
241
259
  this.config.timeoutMs
242
260
  );
@@ -334,8 +352,8 @@ var BelocalEngine = class {
334
352
  }
335
353
  }
336
354
  }
337
- async t(text, lang, ctx) {
338
- const cacheKey = this.generateCacheKey(text, lang, ctx);
355
+ async translate(text, lang, source_lang, ctx) {
356
+ const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);
339
357
  const cachedResult = this.cache.get(cacheKey);
340
358
  if (cachedResult) {
341
359
  if (this.debug) {
@@ -343,17 +361,21 @@ var BelocalEngine = class {
343
361
  }
344
362
  return cachedResult;
345
363
  }
346
- const result = await this.transport({ text, lang, ctx });
364
+ const result = await this.transport({ text, lang, source_lang, ctx });
347
365
  this.cache.set(cacheKey, result);
348
366
  if (this.debug) {
349
367
  console.log("[BeLocal Engine] Translation from API, cached in local:", text);
350
368
  }
351
369
  return result;
352
370
  }
353
- generateCacheKey(text, lang, ctx) {
371
+ async t(text, lang, source_lang, context) {
372
+ return this.translate(text, lang, source_lang, { user_ctx: context });
373
+ }
374
+ generateCacheKey(text, lang, source_lang, ctx) {
354
375
  const data = {
355
376
  text,
356
377
  lang,
378
+ source_lang: source_lang || null,
357
379
  ctx: ctx || null
358
380
  };
359
381
  return jsMd5.md5(JSON.stringify(data));
package/dist/node.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transports/batch.ts","../src/transports/single.ts","../src/transports/base/node.ts","../src/cache/local.ts","../src/core/engine/node.ts"],"names":["md5","session","URL","http2","headers"],"mappings":"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","file":"node.cjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","import * as http2 from 'node:http2';\nimport { URL } from 'node:url';\nimport type { BaseTransport } from '../../core/types';\n\nexport interface BaseNodeTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n retries?: number;\n debug?: boolean;\n}\n\n// Global session cache for HTTP/2 connections\nconst sessionCache = new Map<string, http2.ClientHttp2Session>();\n\nfunction getOrCreateSession(baseUrl: string, debug?: boolean): http2.ClientHttp2Session {\n if (sessionCache.has(baseUrl)) {\n const session = sessionCache.get(baseUrl)!;\n if (!session.destroyed) {\n return session;\n }\n sessionCache.delete(baseUrl);\n }\n\n const parsedUrl = new URL(baseUrl);\n const session = http2.connect(parsedUrl.origin);\n\n session.socket?.unref();\n \n // Set up session cleanup\n session.on('error', () => {\n sessionCache.delete(baseUrl);\n });\n \n session.on('close', () => {\n sessionCache.delete(baseUrl);\n });\n\n // Add debug logging if enabled\n if (debug) {\n session.on('connect', () => console.log('[Base Node Transport H2] new session connected'));\n session.on('goaway', (code, lastStreamID, opaque) =>\n console.log('[Base Node Transport H2] goaway', code, lastStreamID)\n );\n }\n \n sessionCache.set(baseUrl, session);\n return session;\n}\n\nfunction makeHttp2Request(\n session: http2.ClientHttp2Session,\n path: string,\n headers: Record<string, string>,\n body: string,\n timeoutMs?: number\n): Promise<{ statusCode: number; headers: Record<string, string>; body: string }> {\n return new Promise((resolve, reject) => {\n const req = session.request({\n ':method': 'POST',\n ':path': path,\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(body),\n ...headers,\n });\n\n let timeout: NodeJS.Timeout | null = null;\n if (timeoutMs) {\n timeout = setTimeout(() => {\n req.destroy();\n reject(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n }\n\n let responseData = '';\n let statusCode = 0;\n let responseHeaders: Record<string, string> = {};\n\n req.on('response', (headers) => {\n statusCode = headers[':status'] as number;\n responseHeaders = headers as Record<string, string>;\n });\n\n req.on('data', (chunk) => {\n responseData += chunk;\n });\n\n req.on('end', () => {\n if (timeout) clearTimeout(timeout);\n resolve({\n statusCode,\n headers: responseHeaders,\n body: responseData,\n });\n });\n\n req.on('error', (error) => {\n if (timeout) clearTimeout(timeout);\n reject(error);\n });\n\n req.write(body);\n req.end();\n });\n}\n\nexport class BaseNodeTransport implements BaseTransport {\n constructor(private config: BaseNodeTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const maxRetries = this.config.retries || 0;\n let attempt = 0;\n const url = `${this.config.baseUrl}${endpointPath}`;\n\n if (this.config.debug) {\n console.log(`[Base Node Transport] POST request to ${url}`, data);\n }\n\n while (attempt <= maxRetries) {\n try {\n const session = getOrCreateSession(this.config.baseUrl, this.config.debug);\n const body = JSON.stringify(data);\n \n const response = await makeHttp2Request(\n session,\n endpointPath,\n this.config.headers || {},\n body,\n this.config.timeoutMs\n );\n\n if (response.statusCode < 200 || response.statusCode >= 300) {\n const errorMsg = `HTTP ${response.statusCode}: Request failed`;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = JSON.parse(response.body);\n if (this.config.debug) {\n console.log(`[Base Node Transport] Request successful:`, result);\n }\n \n return result;\n } catch (error) {\n attempt++;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Attempt ${attempt} failed:`, error instanceof Error ? error.message : String(error));\n }\n if (attempt > maxRetries) {\n throw error;\n }\n\n // Exponential backoff\n await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw new Error('Max retries exceeded');\n }\n}\n\nexport function createBaseNodeTransport(config: BaseNodeTransportConfig): BaseNodeTransport {\n return new BaseNodeTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBaseNodeTransport } from '../../transports/base/node';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Use local cache for Node.js\n this.cache = new LocalCache();\n \n if (this.debug) {\n console.log('[BeLocal Engine] Using local (memory) cache');\n }\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base node transport\n const baseTransport = createBaseNodeTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with node base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with node base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n }\n\n async t(text: string, lang: Lang, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, ctx);\n \n // Try to get from cache first\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from local cache:', text);\n }\n return cachedResult;\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, ctx });\n \n // Store in cache\n this.cache.set(cacheKey, result);\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API, cached in local:', text);\n }\n return result;\n }\n\n private generateCacheKey(text: string, lang: Lang, ctx?: KV): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { BaseNodeTransport, createBaseNodeTransport } from '../../transports/base';\nexport { createBatchTransport } from '../../transports/batch';\nexport { createSingleTransport } from '../../transports/single';\n"]}
1
+ {"version":3,"sources":["../src/transports/batch.ts","../src/transports/single.ts","../src/version.ts","../src/transports/base/node.ts","../src/cache/local.ts","../src/core/engine/node.ts"],"names":["md5","session","URL","http2","headers"],"mappings":"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","file":"node.cjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, source_lang?: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, source_lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, source_lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, source_lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, source_lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, source_lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","// SDK version - will be replaced during build with tsup define\ndeclare const __SDK_VERSION__: string | undefined;\n\n// Safely check if __SDK_VERSION__ is defined (replaced during build)\nexport const SDK_VERSION: string = \n (() => { try { return typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : 'undefined'; } catch { return 'undefined'; } })();\n\nexport const SDK_NAME = 'js';\n\n","import * as http2 from 'node:http2';\nimport { URL } from 'node:url';\nimport type { BaseTransport } from '../../core/types';\nimport { SDK_NAME, SDK_VERSION } from '../../version';\n\nexport interface BaseNodeTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n retries?: number;\n debug?: boolean;\n}\n\n// Global session cache for HTTP/2 connections\nconst sessionCache = new Map<string, http2.ClientHttp2Session>();\n\nfunction getOrCreateSession(baseUrl: string, debug?: boolean): http2.ClientHttp2Session {\n if (sessionCache.has(baseUrl)) {\n const session = sessionCache.get(baseUrl)!;\n if (!session.destroyed) {\n return session;\n }\n sessionCache.delete(baseUrl);\n }\n\n const parsedUrl = new URL(baseUrl);\n const session = http2.connect(parsedUrl.origin);\n\n session.socket?.unref();\n \n // Set up session cleanup\n session.on('error', () => {\n sessionCache.delete(baseUrl);\n });\n \n session.on('close', () => {\n sessionCache.delete(baseUrl);\n });\n\n // Add debug logging if enabled\n if (debug) {\n session.on('connect', () => console.log('[Base Node Transport H2] new session connected'));\n session.on('goaway', (code, lastStreamID, opaque) =>\n console.log('[Base Node Transport H2] goaway', code, lastStreamID)\n );\n }\n \n sessionCache.set(baseUrl, session);\n return session;\n}\n\nfunction makeHttp2Request(\n session: http2.ClientHttp2Session,\n path: string,\n headers: Record<string, string>,\n body: string,\n timeoutMs?: number\n): Promise<{ statusCode: number; headers: Record<string, string>; body: string }> {\n return new Promise((resolve, reject) => {\n const req = session.request({\n ':method': 'POST',\n ':path': path,\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(body),\n ...headers,\n });\n\n let timeout: NodeJS.Timeout | null = null;\n if (timeoutMs) {\n timeout = setTimeout(() => {\n req.destroy();\n reject(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n }\n\n let responseData = '';\n let statusCode = 0;\n let responseHeaders: Record<string, string> = {};\n\n req.on('response', (headers) => {\n statusCode = headers[':status'] as number;\n responseHeaders = headers as Record<string, string>;\n });\n\n req.on('data', (chunk) => {\n responseData += chunk;\n });\n\n req.on('end', () => {\n if (timeout) clearTimeout(timeout);\n resolve({\n statusCode,\n headers: responseHeaders,\n body: responseData,\n });\n });\n\n req.on('error', (error) => {\n if (timeout) clearTimeout(timeout);\n reject(error);\n });\n\n req.write(body);\n req.end();\n });\n}\n\nexport class BaseNodeTransport implements BaseTransport {\n constructor(private config: BaseNodeTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const maxRetries = this.config.retries || 0;\n let attempt = 0;\n const url = `${this.config.baseUrl}${endpointPath}`;\n\n if (this.config.debug) {\n console.log(`[Base Node Transport] POST request to ${url}`, data);\n }\n\n while (attempt <= maxRetries) {\n try {\n const session = getOrCreateSession(this.config.baseUrl, this.config.debug);\n const body = JSON.stringify(data);\n \n // Add SDK headers\n const headers = {\n 'x-sdk': SDK_NAME,\n 'x-sdk-version': SDK_VERSION,\n ...this.config.headers,\n };\n\n const response = await makeHttp2Request(\n session,\n endpointPath,\n headers,\n body,\n this.config.timeoutMs\n );\n\n if (response.statusCode < 200 || response.statusCode >= 300) {\n const errorMsg = `HTTP ${response.statusCode}: Request failed`;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = JSON.parse(response.body);\n if (this.config.debug) {\n console.log(`[Base Node Transport] Request successful:`, result);\n }\n \n return result;\n } catch (error) {\n attempt++;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Attempt ${attempt} failed:`, error instanceof Error ? error.message : String(error));\n }\n if (attempt > maxRetries) {\n throw error;\n }\n\n // Exponential backoff\n await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw new Error('Max retries exceeded');\n }\n}\n\nexport function createBaseNodeTransport(config: BaseNodeTransportConfig): BaseNodeTransport {\n return new BaseNodeTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBaseNodeTransport } from '../../transports/base/node';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Use local cache for Node.js\n this.cache = new LocalCache();\n \n if (this.debug) {\n console.log('[BeLocal Engine] Using local (memory) cache');\n }\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base node transport\n const baseTransport = createBaseNodeTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with node base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with node base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n }\n\n async translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n \n // Try to get from cache first\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from local cache:', text);\n }\n return cachedResult;\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, source_lang, ctx });\n \n // Store in cache\n this.cache.set(cacheKey, result);\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API, cached in local:', text);\n }\n return result;\n }\n\n async t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string> {\n return this.translate(text, lang, source_lang, {user_ctx: context});\n }\n\n private generateCacheKey(text: string, lang: Lang, source_lang?: string, ctx?: KV): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { BaseNodeTransport, createBaseNodeTransport } from '../../transports/base';\nexport { createBatchTransport } from '../../transports/batch';\nexport { createSingleTransport } from '../../transports/single';\n"]}
package/dist/node.d.ts CHANGED
@@ -6,6 +6,7 @@ interface BaseTransport {
6
6
  type Transport = (params: {
7
7
  text: string;
8
8
  lang: Lang;
9
+ source_lang?: string;
9
10
  ctx?: KV;
10
11
  }) => Promise<string>;
11
12
  interface BelocalEngineOptions {
@@ -48,7 +49,8 @@ declare class BelocalEngine {
48
49
  private debug;
49
50
  private cache;
50
51
  constructor(options: BelocalEngineOptions);
51
- t(text: string, lang: Lang, ctx?: KV): Promise<string>;
52
+ translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string>;
53
+ t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string>;
52
54
  private generateCacheKey;
53
55
  }
54
56
 
package/dist/node.mjs CHANGED
@@ -3,10 +3,11 @@ import * as http2 from 'http2';
3
3
  import { URL } from 'url';
4
4
 
5
5
  // src/transports/batch.ts
6
- function generateRequestId(text, lang, ctx) {
6
+ function generateRequestId(text, lang, source_lang, ctx) {
7
7
  const data = {
8
8
  text,
9
9
  lang,
10
+ source_lang: source_lang || null,
10
11
  ctx: ctx || null
11
12
  };
12
13
  return md5(JSON.stringify(data));
@@ -86,15 +87,15 @@ function createBatchTransport(config) {
86
87
  batchTimer: null,
87
88
  isRequestInFlight: false
88
89
  };
89
- return ({ text, lang, ctx }) => {
90
+ return ({ text, lang, source_lang, ctx }) => {
90
91
  return new Promise((resolve, reject) => {
91
- const requestId = generateRequestId(text, lang, ctx);
92
+ const requestId = generateRequestId(text, lang, source_lang, ctx);
92
93
  if (config.debug) {
93
94
  console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: "${text}" to ${lang}`);
94
95
  }
95
96
  const requestItem = {
96
97
  requestId,
97
- payload: { text, lang, ctx },
98
+ payload: { text, lang, source_lang, ctx },
98
99
  resolve,
99
100
  reject
100
101
  };
@@ -108,12 +109,12 @@ function createBatchTransport(config) {
108
109
 
109
110
  // src/transports/single.ts
110
111
  function createSingleTransport(config) {
111
- return async ({ text, lang, ctx }) => {
112
+ return async ({ text, lang, source_lang, ctx }) => {
112
113
  if (config.debug) {
113
114
  console.log(`[BeLocal Single Transport] Translating "${text}" to ${lang}`);
114
115
  }
115
116
  try {
116
- const result = await config.baseTransport.post({ text, lang, ctx }, "/v1/translate");
117
+ const result = await config.baseTransport.post({ text, lang, source_lang, ctx }, "/v1/translate");
117
118
  if (config.debug) {
118
119
  console.log(`[BeLocal Single Transport] Translation successful: "${result.text || text}"`);
119
120
  }
@@ -126,6 +127,18 @@ function createSingleTransport(config) {
126
127
  }
127
128
  };
128
129
  }
130
+
131
+ // src/version.ts
132
+ var SDK_VERSION = (() => {
133
+ try {
134
+ return true ? "0.4.0" : "undefined";
135
+ } catch {
136
+ return "undefined";
137
+ }
138
+ })();
139
+ var SDK_NAME = "js";
140
+
141
+ // src/transports/base/node.ts
129
142
  var sessionCache = /* @__PURE__ */ new Map();
130
143
  function getOrCreateSession(baseUrl, debug) {
131
144
  if (sessionCache.has(baseUrl)) {
@@ -211,10 +224,15 @@ var BaseNodeTransport = class {
211
224
  try {
212
225
  const session = getOrCreateSession(this.config.baseUrl, this.config.debug);
213
226
  const body = JSON.stringify(data);
227
+ const headers = {
228
+ "x-sdk": SDK_NAME,
229
+ "x-sdk-version": SDK_VERSION,
230
+ ...this.config.headers
231
+ };
214
232
  const response = await makeHttp2Request(
215
233
  session,
216
234
  endpointPath,
217
- this.config.headers || {},
235
+ headers,
218
236
  body,
219
237
  this.config.timeoutMs
220
238
  );
@@ -312,8 +330,8 @@ var BelocalEngine = class {
312
330
  }
313
331
  }
314
332
  }
315
- async t(text, lang, ctx) {
316
- const cacheKey = this.generateCacheKey(text, lang, ctx);
333
+ async translate(text, lang, source_lang, ctx) {
334
+ const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);
317
335
  const cachedResult = this.cache.get(cacheKey);
318
336
  if (cachedResult) {
319
337
  if (this.debug) {
@@ -321,17 +339,21 @@ var BelocalEngine = class {
321
339
  }
322
340
  return cachedResult;
323
341
  }
324
- const result = await this.transport({ text, lang, ctx });
342
+ const result = await this.transport({ text, lang, source_lang, ctx });
325
343
  this.cache.set(cacheKey, result);
326
344
  if (this.debug) {
327
345
  console.log("[BeLocal Engine] Translation from API, cached in local:", text);
328
346
  }
329
347
  return result;
330
348
  }
331
- generateCacheKey(text, lang, ctx) {
349
+ async t(text, lang, source_lang, context) {
350
+ return this.translate(text, lang, source_lang, { user_ctx: context });
351
+ }
352
+ generateCacheKey(text, lang, source_lang, ctx) {
332
353
  const data = {
333
354
  text,
334
355
  lang,
356
+ source_lang: source_lang || null,
335
357
  ctx: ctx || null
336
358
  };
337
359
  return md5(JSON.stringify(data));
package/dist/node.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/transports/batch.ts","../src/transports/single.ts","../src/transports/base/node.ts","../src/cache/local.ts","../src/core/engine/node.ts"],"names":["session","headers","md5"],"mappings":"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","file":"node.mjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","import * as http2 from 'node:http2';\nimport { URL } from 'node:url';\nimport type { BaseTransport } from '../../core/types';\n\nexport interface BaseNodeTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n retries?: number;\n debug?: boolean;\n}\n\n// Global session cache for HTTP/2 connections\nconst sessionCache = new Map<string, http2.ClientHttp2Session>();\n\nfunction getOrCreateSession(baseUrl: string, debug?: boolean): http2.ClientHttp2Session {\n if (sessionCache.has(baseUrl)) {\n const session = sessionCache.get(baseUrl)!;\n if (!session.destroyed) {\n return session;\n }\n sessionCache.delete(baseUrl);\n }\n\n const parsedUrl = new URL(baseUrl);\n const session = http2.connect(parsedUrl.origin);\n\n session.socket?.unref();\n \n // Set up session cleanup\n session.on('error', () => {\n sessionCache.delete(baseUrl);\n });\n \n session.on('close', () => {\n sessionCache.delete(baseUrl);\n });\n\n // Add debug logging if enabled\n if (debug) {\n session.on('connect', () => console.log('[Base Node Transport H2] new session connected'));\n session.on('goaway', (code, lastStreamID, opaque) =>\n console.log('[Base Node Transport H2] goaway', code, lastStreamID)\n );\n }\n \n sessionCache.set(baseUrl, session);\n return session;\n}\n\nfunction makeHttp2Request(\n session: http2.ClientHttp2Session,\n path: string,\n headers: Record<string, string>,\n body: string,\n timeoutMs?: number\n): Promise<{ statusCode: number; headers: Record<string, string>; body: string }> {\n return new Promise((resolve, reject) => {\n const req = session.request({\n ':method': 'POST',\n ':path': path,\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(body),\n ...headers,\n });\n\n let timeout: NodeJS.Timeout | null = null;\n if (timeoutMs) {\n timeout = setTimeout(() => {\n req.destroy();\n reject(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n }\n\n let responseData = '';\n let statusCode = 0;\n let responseHeaders: Record<string, string> = {};\n\n req.on('response', (headers) => {\n statusCode = headers[':status'] as number;\n responseHeaders = headers as Record<string, string>;\n });\n\n req.on('data', (chunk) => {\n responseData += chunk;\n });\n\n req.on('end', () => {\n if (timeout) clearTimeout(timeout);\n resolve({\n statusCode,\n headers: responseHeaders,\n body: responseData,\n });\n });\n\n req.on('error', (error) => {\n if (timeout) clearTimeout(timeout);\n reject(error);\n });\n\n req.write(body);\n req.end();\n });\n}\n\nexport class BaseNodeTransport implements BaseTransport {\n constructor(private config: BaseNodeTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const maxRetries = this.config.retries || 0;\n let attempt = 0;\n const url = `${this.config.baseUrl}${endpointPath}`;\n\n if (this.config.debug) {\n console.log(`[Base Node Transport] POST request to ${url}`, data);\n }\n\n while (attempt <= maxRetries) {\n try {\n const session = getOrCreateSession(this.config.baseUrl, this.config.debug);\n const body = JSON.stringify(data);\n \n const response = await makeHttp2Request(\n session,\n endpointPath,\n this.config.headers || {},\n body,\n this.config.timeoutMs\n );\n\n if (response.statusCode < 200 || response.statusCode >= 300) {\n const errorMsg = `HTTP ${response.statusCode}: Request failed`;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = JSON.parse(response.body);\n if (this.config.debug) {\n console.log(`[Base Node Transport] Request successful:`, result);\n }\n \n return result;\n } catch (error) {\n attempt++;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Attempt ${attempt} failed:`, error instanceof Error ? error.message : String(error));\n }\n if (attempt > maxRetries) {\n throw error;\n }\n\n // Exponential backoff\n await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw new Error('Max retries exceeded');\n }\n}\n\nexport function createBaseNodeTransport(config: BaseNodeTransportConfig): BaseNodeTransport {\n return new BaseNodeTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBaseNodeTransport } from '../../transports/base/node';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Use local cache for Node.js\n this.cache = new LocalCache();\n \n if (this.debug) {\n console.log('[BeLocal Engine] Using local (memory) cache');\n }\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base node transport\n const baseTransport = createBaseNodeTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with node base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with node base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n }\n\n async t(text: string, lang: Lang, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, ctx);\n \n // Try to get from cache first\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from local cache:', text);\n }\n return cachedResult;\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, ctx });\n \n // Store in cache\n this.cache.set(cacheKey, result);\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API, cached in local:', text);\n }\n return result;\n }\n\n private generateCacheKey(text: string, lang: Lang, ctx?: KV): string {\n const data = {\n text,\n lang,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { BaseNodeTransport, createBaseNodeTransport } from '../../transports/base';\nexport { createBatchTransport } from '../../transports/batch';\nexport { createSingleTransport } from '../../transports/single';\n"]}
1
+ {"version":3,"sources":["../src/transports/batch.ts","../src/transports/single.ts","../src/version.ts","../src/transports/base/node.ts","../src/cache/local.ts","../src/core/engine/node.ts"],"names":["session","headers","md5"],"mappings":"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","file":"node.mjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface BatchTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface BatchRequest {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n}\n\ninterface BatchRequestItem {\n requestId: string;\n payload: { text: string; lang: string; source_lang?: string; ctx?: Record<string, unknown> };\n resolve: (value: string) => void;\n reject: (error: Error) => void;\n}\n\ninterface BatchResponse {\n results: Array<{\n requestId: string;\n data?: { text: string };\n error?: { message: string };\n }>;\n}\n\ninterface BatchState {\n currentBatch: BatchRequestItem[];\n batchTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(text: string, lang: string, source_lang?: string, ctx?: Record<string, unknown>): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n}\n\nasync function sendBatch(\n config: BatchTransportConfig,\n batch: BatchRequestItem[],\n state: BatchState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Sending batch of ${batch.length} requests`);\n }\n\n try {\n const batchRequests: BatchRequest[] = batch.map(item => ({\n requestId: item.requestId,\n payload: item.payload,\n }));\n\n const batchResponse: BatchResponse = await config.baseTransport.post({ batch: batchRequests }, '/v1/translate/batch');\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Batch response received with ${batchResponse.results.length} results`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { data?: { text: string }; error?: { message: string } }>();\n batchResponse.results.forEach(result => {\n resultMap.set(result.requestId, { data: result.data, error: result.error });\n });\n\n // Раздаем результаты каждому промису\n batch.forEach(item => {\n const result = resultMap.get(item.requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] No result found for requestId: ${item.requestId}`);\n }\n item.reject(new Error(`No result found for request ${item.requestId}`));\n return;\n }\n\n if (result.error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Error for requestId ${item.requestId}:`, result.error.message);\n }\n item.reject(new Error(result.error.message));\n } else if (result.data) {\n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Success for requestId ${item.requestId}: \"${result.data.text}\"`);\n }\n item.resolve(result.data.text);\n } else {\n // Фоллбэк: если нет ни data, ни error, возвращаем оригинальный текст\n if (config.debug) {\n console.warn(`[BeLocal Batch Transport] No data or error for requestId ${item.requestId}, returning original text`);\n }\n item.resolve(item.payload.text);\n }\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Batch Transport] Batch request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы в батче\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n batch.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processBatch(config: BatchTransportConfig, state: BatchState): void {\n if (state.currentBatch.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const batchToSend = [...state.currentBatch];\n state.currentBatch = [];\n state.batchTimer = null;\n state.isRequestInFlight = true;\n\n sendBatch(config, batchToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentBatch.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n}\n\nexport function createBatchTransport(config: BatchTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: BatchState = {\n currentBatch: [],\n batchTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, source_lang, ctx }) => {\n return new Promise<string>((resolve, reject) => {\n const requestId = generateRequestId(text, lang, source_lang, ctx);\n \n if (config.debug) {\n console.log(`[BeLocal Batch Transport] Queuing request ${requestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: BatchRequestItem = {\n requestId,\n payload: { text, lang, source_lang, ctx },\n resolve,\n reject,\n };\n\n state.currentBatch.push(requestItem);\n\n if (state.batchTimer === null && !state.isRequestInFlight) {\n state.batchTimer = setTimeout(() => processBatch(config, state), windowMs);\n }\n });\n };\n}\n","import type { Transport, BaseTransport } from '../core/types';\n\nexport interface SingleTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n}\n\ninterface TranslationResponse {\n text?: string;\n}\n\nexport function createSingleTransport(config: SingleTransportConfig): Transport {\n return async ({ text, lang, source_lang, ctx }) => {\n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translating \"${text}\" to ${lang}`);\n }\n\n try {\n const result: TranslationResponse = await config.baseTransport.post({ text, lang, source_lang, ctx }, '/v1/translate');\n \n if (config.debug) {\n console.log(`[BeLocal Single Transport] Translation successful: \"${result.text || text}\"`);\n }\n \n return result.text || text;\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Single Transport] Request failed:`, error);\n }\n throw error;\n }\n };\n}\n","// SDK version - will be replaced during build with tsup define\ndeclare const __SDK_VERSION__: string | undefined;\n\n// Safely check if __SDK_VERSION__ is defined (replaced during build)\nexport const SDK_VERSION: string = \n (() => { try { return typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : 'undefined'; } catch { return 'undefined'; } })();\n\nexport const SDK_NAME = 'js';\n\n","import * as http2 from 'node:http2';\nimport { URL } from 'node:url';\nimport type { BaseTransport } from '../../core/types';\nimport { SDK_NAME, SDK_VERSION } from '../../version';\n\nexport interface BaseNodeTransportConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n retries?: number;\n debug?: boolean;\n}\n\n// Global session cache for HTTP/2 connections\nconst sessionCache = new Map<string, http2.ClientHttp2Session>();\n\nfunction getOrCreateSession(baseUrl: string, debug?: boolean): http2.ClientHttp2Session {\n if (sessionCache.has(baseUrl)) {\n const session = sessionCache.get(baseUrl)!;\n if (!session.destroyed) {\n return session;\n }\n sessionCache.delete(baseUrl);\n }\n\n const parsedUrl = new URL(baseUrl);\n const session = http2.connect(parsedUrl.origin);\n\n session.socket?.unref();\n \n // Set up session cleanup\n session.on('error', () => {\n sessionCache.delete(baseUrl);\n });\n \n session.on('close', () => {\n sessionCache.delete(baseUrl);\n });\n\n // Add debug logging if enabled\n if (debug) {\n session.on('connect', () => console.log('[Base Node Transport H2] new session connected'));\n session.on('goaway', (code, lastStreamID, opaque) =>\n console.log('[Base Node Transport H2] goaway', code, lastStreamID)\n );\n }\n \n sessionCache.set(baseUrl, session);\n return session;\n}\n\nfunction makeHttp2Request(\n session: http2.ClientHttp2Session,\n path: string,\n headers: Record<string, string>,\n body: string,\n timeoutMs?: number\n): Promise<{ statusCode: number; headers: Record<string, string>; body: string }> {\n return new Promise((resolve, reject) => {\n const req = session.request({\n ':method': 'POST',\n ':path': path,\n 'content-type': 'application/json',\n 'content-length': Buffer.byteLength(body),\n ...headers,\n });\n\n let timeout: NodeJS.Timeout | null = null;\n if (timeoutMs) {\n timeout = setTimeout(() => {\n req.destroy();\n reject(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n }\n\n let responseData = '';\n let statusCode = 0;\n let responseHeaders: Record<string, string> = {};\n\n req.on('response', (headers) => {\n statusCode = headers[':status'] as number;\n responseHeaders = headers as Record<string, string>;\n });\n\n req.on('data', (chunk) => {\n responseData += chunk;\n });\n\n req.on('end', () => {\n if (timeout) clearTimeout(timeout);\n resolve({\n statusCode,\n headers: responseHeaders,\n body: responseData,\n });\n });\n\n req.on('error', (error) => {\n if (timeout) clearTimeout(timeout);\n reject(error);\n });\n\n req.write(body);\n req.end();\n });\n}\n\nexport class BaseNodeTransport implements BaseTransport {\n constructor(private config: BaseNodeTransportConfig) {}\n\n async post(data: any, endpointPath: string): Promise<any> {\n const maxRetries = this.config.retries || 0;\n let attempt = 0;\n const url = `${this.config.baseUrl}${endpointPath}`;\n\n if (this.config.debug) {\n console.log(`[Base Node Transport] POST request to ${url}`, data);\n }\n\n while (attempt <= maxRetries) {\n try {\n const session = getOrCreateSession(this.config.baseUrl, this.config.debug);\n const body = JSON.stringify(data);\n \n // Add SDK headers\n const headers = {\n 'x-sdk': SDK_NAME,\n 'x-sdk-version': SDK_VERSION,\n ...this.config.headers,\n };\n\n const response = await makeHttp2Request(\n session,\n endpointPath,\n headers,\n body,\n this.config.timeoutMs\n );\n\n if (response.statusCode < 200 || response.statusCode >= 300) {\n const errorMsg = `HTTP ${response.statusCode}: Request failed`;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Request failed:`, errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n const result = JSON.parse(response.body);\n if (this.config.debug) {\n console.log(`[Base Node Transport] Request successful:`, result);\n }\n \n return result;\n } catch (error) {\n attempt++;\n if (this.config.debug) {\n console.error(`[Base Node Transport] Attempt ${attempt} failed:`, error instanceof Error ? error.message : String(error));\n }\n if (attempt > maxRetries) {\n throw error;\n }\n\n // Exponential backoff\n await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw new Error('Max retries exceeded');\n }\n}\n\nexport function createBaseNodeTransport(config: BaseNodeTransportConfig): BaseNodeTransport {\n return new BaseNodeTransport(config);\n}\n","import type { Cache } from './types';\n\nexport class LocalCache implements Cache {\n private storage = new Map<string, string>();\n\n get(key: string): string | null {\n return this.storage.get(key) || null;\n }\n\n set(key: string, value: string): void {\n this.storage.set(key, value);\n }\n\n isAvailable(): boolean {\n return true;\n }\n}\n","import type { BelocalEngineOptions, KV, Lang, Transport } from '../types';\nimport { createBatchTransport } from '../../transports/batch';\nimport { createSingleTransport } from '../../transports/single';\nimport { createBaseNodeTransport } from '../../transports/base/node';\nimport { LocalCache } from '../../cache/local';\nimport type { Cache } from '../../cache/types';\nimport { md5 } from 'js-md5';\n\nexport class BelocalEngine {\n private transport: Transport;\n private debug: boolean;\n private cache: Cache;\n\n constructor(options: BelocalEngineOptions) {\n const {\n apiKey,\n baseUrl = 'https://dynamic.belocal.dev',\n batchWindowMs = 50,\n timeoutMs = 10000,\n debug = false\n } = options;\n\n this.debug = debug;\n \n // Use local cache for Node.js\n this.cache = new LocalCache();\n \n if (this.debug) {\n console.log('[BeLocal Engine] Using local (memory) cache');\n }\n\n const authHeaders = {\n 'Authorization': `Bearer ${apiKey}`\n };\n\n // Create base node transport\n const baseTransport = createBaseNodeTransport({\n baseUrl,\n headers: authHeaders,\n timeoutMs,\n debug: this.debug\n });\n\n // Create appropriate transport based on batchWindowMs config\n if (batchWindowMs > 0) {\n // Use batch transport with node base transport\n this.transport = createBatchTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Batch transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\n });\n }\n } else {\n // Use single transport with node base transport\n this.transport = createSingleTransport({\n baseTransport,\n debug: this.debug\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Single transport created with config:', {\n baseUrl,\n timeoutMs\n });\n }\n }\n }\n\n async translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string> {\n // Generate cache key from parameters\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n \n // Try to get from cache first\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from local cache:', text);\n }\n return cachedResult;\n }\n\n // Cache miss, get translation from transport\n const result = await this.transport({ text, lang, source_lang, ctx });\n \n // Store in cache\n this.cache.set(cacheKey, result);\n if (this.debug) {\n console.log('[BeLocal Engine] Translation from API, cached in local:', text);\n }\n return result;\n }\n\n async t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string> {\n return this.translate(text, lang, source_lang, {user_ctx: context});\n }\n\n private generateCacheKey(text: string, lang: Lang, source_lang?: string, ctx?: KV): string {\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: ctx || null\n };\n return md5(JSON.stringify(data));\n }\n}\n\n// Re-export types and transports\nexport type { BelocalEngineOptions, Lang, KV, BaseTransport } from '../types';\nexport { BaseNodeTransport, createBaseNodeTransport } from '../../transports/base';\nexport { createBatchTransport } from '../../transports/batch';\nexport { createSingleTransport } from '../../transports/single';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@belocal/js-sdk",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "BeLocal runtime JS SDK for on-demand translation (browser + node)",
5
5
  "scripts": {
6
6
  "test": "vitest run",