@belocal/js-sdk 0.4.1 → 0.5.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 +2 -2
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +9 -11
- package/dist/browser.mjs +2 -2
- package/dist/browser.mjs.map +1 -1
- package/dist/node.cjs +146 -113
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +9 -11
- package/dist/node.mjs +146 -112
- package/dist/node.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var jsMd5=require('js-md5');function
|
|
2
|
-
exports.BaseBrowserTransport=
|
|
1
|
+
'use strict';var jsMd5=require('js-md5');function S(a,t,n,e){let o=[...a].sort(),i=null;if(e&&Object.keys(e).length>0){i={};let r=Object.keys(e).sort();for(let s of r)i[s]=e[s];}let l=JSON.stringify([o,t,n||null,i]);return jsMd5.md5(l)}async function v(a,t,n){a.debug&&console.log(`[BeLocal Multi Transport] Sending multi request with ${t.length} texts`);try{let e=new Map;t.forEach(r=>{let s=JSON.stringify({lang:r.lang,sourceLang:r.sourceLang||null,context:r.context||null});e.has(s)||e.set(s,[]),e.get(s).push(r);});let o=new Map,i=Array.from(e.entries()).map(([r,s])=>{let c=s[0],g=s.map(d=>d.text),p=S(g,c.lang,c.sourceLang,c.context);return o.set(p,s),{requestId:p,texts:g,lang:c.lang,sourceLang:c.sourceLang,context:c.context}}),u=await a.baseTransport.post({requests:i},"/v1/translate/multi");a.debug&&console.log(`[BeLocal Multi Transport] Multi response received with ${u.results.length} groups`);let l=new Map;u.results.forEach(r=>{l.set(r.requestId,{texts:r.data.texts,status:r.data.status});}),o.forEach((r,s)=>{let c=l.get(s);if(!c){a.debug&&console.error(`[BeLocal Multi Transport] No result found for requestId: ${s}`),r.forEach(g=>{g.reject(new Error(`No result found for request ${s}`));});return}if(c.texts.length!==r.length){let g=new Error(`Mismatch: expected ${r.length} texts, got ${c.texts.length} for requestId ${s}`);a.debug&&console.error("[BeLocal Multi Transport]",g.message),r.forEach(p=>p.reject(g));return}r.forEach((g,p)=>{let d=c.texts[p],R=c.status||"success";a.debug&&console.log(`[BeLocal Multi Transport] Success for requestId ${s}[${p}]: "${d}"`),g.resolve({text:d,status:R});});});}catch(e){a.debug&&console.error("[BeLocal Multi Transport] Multi request error:",e);let o=e instanceof Error?e:new Error(String(e));t.forEach(i=>i.reject(o));}finally{}}function M(a,t){if(t.currentMulti.length===0||t.isRequestInFlight)return;let n=[...t.currentMulti];t.currentMulti=[],t.multiTimer=null,t.isRequestInFlight=true,v(a,n).finally(()=>{if(t.isRequestInFlight=false,t.currentMulti.length>0){let e=a.batchWindowMs??50;t.multiTimer=setTimeout(()=>M(a,t),e);}});}function y(a){let t=a.batchWindowMs??50,n={currentMulti:[],multiTimer:null,isRequestInFlight:false};return ({text:e,lang:o,source_lang:i,ctx:u})=>new Promise((l,r)=>{if(a.debug){let c=jsMd5.md5(JSON.stringify([e,o,i||null,u||null]));console.log(`[BeLocal Multi Transport] Queuing request ${c}: "${e}" to ${o}`);}let s={text:e,lang:o,sourceLang:i,context:u,resolve:l,reject:r};n.currentMulti.push(s),n.multiTimer===null&&!n.isRequestInFlight&&(n.multiTimer=setTimeout(()=>M(a,n),t));})}var B=(()=>{try{return "0.5.0"}catch{return "undefined"}})(),w="js";var f=class{constructor(t){this.config=t;}async post(t,n){let e=`${this.config.baseUrl}${n}`,o=new AbortController,i=this.config.timeoutMs?setTimeout(()=>o.abort(),this.config.timeoutMs):null;this.config.debug&&console.log(`[Base Browser Transport] POST request to ${e}`,t);try{let u=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","x-sdk":w,"x-sdk-version":B,...this.config.headers},body:JSON.stringify(t),signal:o.signal});if(!u.ok){let r=`HTTP ${u.status}: ${u.statusText}`;throw this.config.debug&&console.error("[Base Browser Transport] Request failed:",r),new Error(r)}let l=await u.json();return this.config.debug&&console.log("[Base Browser Transport] Request successful:",l),l}finally{i&&clearTimeout(i);}}};function m(a){return new f(a)}var h=class{constructor(t="belocal_"){this.prefix=t;}get(t){try{return localStorage.getItem(this.prefix+t)}catch{return null}}set(t,n){try{localStorage.setItem(this.prefix+t,n);}catch{}}isAvailable(){try{let t=this.prefix+"__test__";return localStorage.setItem(t,"test"),localStorage.removeItem(t),!0}catch{return false}}};var T=class{constructor(){this.storage=new Map;}get(t){return this.storage.get(t)||null}set(t,n){this.storage.set(t,n);}isAvailable(){return true}};var x=class{constructor(t){let{apiKey:n,baseUrl:e="https://dynamic.belocal.dev",batchWindowMs:o=50,timeoutMs:i=1e4,debug:u=false}=t;this.debug=u;let l=new h("belocal_translations_");l.isAvailable()?this.cache=l:this.cache=new T,this.isCacheAvailable=this.cache.isAvailable();let r={Authorization:`Bearer ${n}`},s=m({baseUrl:e,headers:r,timeoutMs:i,debug:this.debug});this.transport=y({baseTransport:s,debug:this.debug,batchWindowMs:o}),this.debug&&console.log("[BeLocal Engine] Multi transport created with config:",{baseUrl:e,timeoutMs:i,batchWindowMs:o}),this.debug&&console.log("[BeLocal Engine] Cache available:",this.isCacheAvailable);}async translate(t,n,e,o){return (await this.translateMany([t],n,e,o))[0]}async translateMany(t,n,e,o){let i=new Array(t.length),u=[];for(let l=0;l<t.length;l++){let r=t[l],s=this.generateCacheKey(r,n,e,o);if(this.isCacheAvailable){let c=this.cache.get(s);if(c){if(i[l]=c,this.debug){let g=this.cache instanceof h?"localStorage":"local";console.log(`[BeLocal Engine] Translation from ${g} cache:`,r);}continue}}i[l]=null,u.push({index:l,text:r});}return u.length>0&&(await Promise.all(u.map(async({index:r,text:s})=>{let c=await this.transport({text:s,lang:n,source_lang:e,ctx:o});if(this.isCacheAvailable&&c.status!=="error"){let g=this.generateCacheKey(s,n,e,o);if(this.cache.set(g,c.text),this.debug){let p=this.cache instanceof h?"localStorage":"local";console.log(`[BeLocal Engine] Translation from API, cached in ${p}:`,s);}}else this.debug&&(c.status==="error"?console.log("[BeLocal Engine] Translation from API (not cached due to error status):",s):console.log("[BeLocal Engine] Translation from API (no cache):",s));return {index:r,translation:c.text}}))).forEach(({index:r,translation:s})=>{i[r]=s;}),i}async t(t,n,e,o){return o?this.translate(t,n,e,{user_ctx:o}):this.translate(t,n,e)}generateCacheKey(t,n,e,o){let i=o?Object.keys(o).sort().reduce((l,r)=>(l[r]=o[r],l),{}):null;return jsMd5.md5(JSON.stringify({text:t,lang:n,source_lang:e||null,ctx:i}))}};
|
|
2
|
+
exports.BaseBrowserTransport=f;exports.BelocalEngine=x;exports.createBaseBrowserTransport=m;exports.createMultiTransport=y;//# sourceMappingURL=browser.cjs.map
|
|
3
3
|
//# sourceMappingURL=browser.cjs.map
|
package/dist/browser.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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","sortedCtx","acc"],"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 sortedCtx = ctx ? Object.keys(ctx)\n .sort()\n .reduce((acc, key) => {\n acc[key] = ctx[key];\n return acc;\n }, {} as KV) : null;\n\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: sortedCtx\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/multi.ts","../src/version.ts","../src/transports/base/browser.ts","../src/cache/localStorage.ts","../src/cache/local.ts","../src/core/engine/browser.ts"],"names":["generateRequestId","texts","lang","sourceLang","context","sortedTexts","sortedContext","sortedKeys","key","json","md5","sendMulti","config","items","state","groups","item","groupKey","requestIdToGroupItems","requests","groupItems","firstItem","requestId","multiResponse","resultMap","result","error","index","translatedText","status","errorToReject","processMulti","itemsToSend","windowMs","createMultiTransport","text","source_lang","ctx","resolve","reject","tempRequestId","requestItem","SDK_VERSION","SDK_NAME","BaseBrowserTransport","data","endpointPath","url","controller","timeoutId","response","errorMsg","createBaseBrowserTransport","LocalStorageCache","prefix","value","testKey","LocalCache","BelocalEngine","options","apiKey","baseUrl","batchWindowMs","timeoutMs","debug","localStorageCache","authHeaders","baseTransport","results","cacheMisses","i","cacheKey","cachedResult","cacheType","translation","sortedCtx","acc"],"mappings":"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","file":"browser.cjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface MultiTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface MultiRequest {\n requestId: string;\n texts: string[];\n lang: string;\n sourceLang?: string;\n context?: Record<string, string>;\n}\n\ninterface MultiRequestItem {\n text: string;\n lang: string;\n sourceLang?: string;\n context?: Record<string, string>;\n resolve: (value: { text: string; status: string }) => void;\n reject: (error: Error) => void;\n}\n\ninterface MultiResponse {\n results: Array<{\n requestId: string;\n data: { texts: string[]; status: string };\n }>;\n}\n\ninterface MultiState {\n currentMulti: MultiRequestItem[];\n multiTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(texts: string[], lang: string, sourceLang?: string, context?: Record<string, string>): string {\n // Сортируем тексты (создаем копию, чтобы не изменять оригинал)\n const sortedTexts = [...texts].sort();\n \n // Сортируем ключи контекста (создаем копию, чтобы не изменять оригинал)\n let sortedContext: Record<string, string> | null = null;\n if (context && Object.keys(context).length > 0) {\n sortedContext = {};\n const sortedKeys = Object.keys(context).sort();\n for (const key of sortedKeys) {\n sortedContext[key] = context[key];\n }\n }\n \n // Создаем JSON массив: [sortedTexts, lang, sourceLang, context]\n // В PHP примере: [$sortedTexts, $this->lang, $context] (sourceLang не включен)\n // Но мы включаем sourceLang для правильной группировки запросов с разными sourceLang\n const data = [sortedTexts, lang, sourceLang || null, sortedContext];\n const json = JSON.stringify(data);\n \n return md5(json);\n}\n\nasync function sendMulti(\n config: MultiTransportConfig,\n items: MultiRequestItem[],\n state: MultiState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Multi Transport] Sending multi request with ${items.length} texts`);\n }\n\n try {\n // Группируем тексты по параметрам перевода (lang, sourceLang, context)\n const groups = new Map<string, MultiRequestItem[]>();\n \n items.forEach(item => {\n // Используем ключ для группировки без текстов (только параметры перевода)\n const groupKey = JSON.stringify({\n lang: item.lang,\n sourceLang: item.sourceLang || null,\n context: item.context || null\n });\n \n if (!groups.has(groupKey)) {\n groups.set(groupKey, []);\n }\n groups.get(groupKey)!.push(item);\n });\n\n // Создаем запросы для каждой группы и сохраняем соответствие requestId -> groupItems\n const requestIdToGroupItems = new Map<string, MultiRequestItem[]>();\n const requests: MultiRequest[] = Array.from(groups.entries()).map(([groupKey, groupItems]) => {\n const firstItem = groupItems[0];\n const texts = groupItems.map(item => item.text);\n \n // Генерируем requestId включая отсортированные тексты группы\n // Включаем sourceLang для правильной группировки запросов с разными sourceLang\n const requestId = generateRequestId(\n texts,\n firstItem.lang,\n firstItem.sourceLang,\n firstItem.context\n );\n \n // Сохраняем соответствие requestId -> groupItems\n requestIdToGroupItems.set(requestId, groupItems);\n \n return {\n requestId,\n texts,\n lang: firstItem.lang,\n sourceLang: firstItem.sourceLang,\n context: firstItem.context\n };\n });\n\n const multiResponse: MultiResponse = await config.baseTransport.post({ requests }, '/v1/translate/multi');\n \n if (config.debug) {\n console.log(`[BeLocal Multi Transport] Multi response received with ${multiResponse.results.length} groups`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { texts: string[]; status: string }>();\n multiResponse.results.forEach(result => {\n resultMap.set(result.requestId, { texts: result.data.texts, status: result.data.status });\n });\n\n // Раздаем результаты каждому промису\n requestIdToGroupItems.forEach((groupItems, requestId) => {\n const result = resultMap.get(requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Multi Transport] No result found for requestId: ${requestId}`);\n }\n groupItems.forEach(item => {\n item.reject(new Error(`No result found for request ${requestId}`));\n });\n return;\n }\n\n // Маппим тексты обратно на промисы по индексу\n if (result.texts.length !== groupItems.length) {\n const error = new Error(`Mismatch: expected ${groupItems.length} texts, got ${result.texts.length} for requestId ${requestId}`);\n if (config.debug) {\n console.error(`[BeLocal Multi Transport]`, error.message);\n }\n groupItems.forEach(item => item.reject(error));\n return;\n }\n\n groupItems.forEach((item, index) => {\n const translatedText = result.texts[index];\n const status = result.status || 'success';\n \n if (config.debug) {\n console.log(`[BeLocal Multi Transport] Success for requestId ${requestId}[${index}]: \"${translatedText}\"`);\n }\n \n item.resolve({ text: translatedText, status });\n });\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Multi Transport] Multi request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n items.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processMulti(config: MultiTransportConfig, state: MultiState): void {\n if (state.currentMulti.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const itemsToSend = [...state.currentMulti];\n state.currentMulti = [];\n state.multiTimer = null;\n state.isRequestInFlight = true;\n\n sendMulti(config, itemsToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentMulti.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.multiTimer = setTimeout(() => processMulti(config, state), windowMs);\n }\n });\n}\n\nexport function createMultiTransport(config: MultiTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: MultiState = {\n currentMulti: [],\n multiTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, source_lang, ctx }) => {\n return new Promise<{ text: string; status: string }>((resolve, reject) => {\n if (config.debug) {\n // Для отладки показываем временный requestId (будет пересчитан при группировке)\n const tempRequestId = md5(JSON.stringify([text, lang, source_lang || null, ctx || null]));\n console.log(`[BeLocal Multi Transport] Queuing request ${tempRequestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: MultiRequestItem = {\n text,\n lang,\n sourceLang: source_lang,\n context: ctx,\n resolve,\n reject,\n };\n\n state.currentMulti.push(requestItem);\n\n if (state.multiTimer === null && !state.isRequestInFlight) {\n state.multiTimer = setTimeout(() => processMulti(config, state), windowMs);\n }\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 { createMultiTransport } from '../../transports/multi';\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 // Always use multi transport\n this.transport = createMultiTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Multi transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\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 const results = await this.translateMany([text], lang, source_lang, ctx);\n return results[0];\n }\n\n async translateMany(texts: string[], lang: Lang, source_lang?: string, ctx?: KV): Promise<string[]> {\n const results: (string | null)[] = new Array(texts.length);\n const cacheMisses: Array<{ index: number; text: string }> = [];\n\n for (let i = 0; i < texts.length; i++) {\n const text = texts[i];\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n \n if (this.isCacheAvailable) {\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n results[i] = 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 continue;\n }\n }\n \n results[i] = null;\n cacheMisses.push({ index: i, text });\n }\n\n if (cacheMisses.length > 0) {\n const translations = await Promise.all(\n cacheMisses.map(async ({ index, text }) => {\n const result = await this.transport({ text, lang, source_lang, ctx });\n \n if (this.isCacheAvailable && result.status !== 'error') {\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n this.cache.set(cacheKey, result.text);\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 if (result.status === 'error') {\n console.log('[BeLocal Engine] Translation from API (not cached due to error status):', text);\n } else {\n console.log('[BeLocal Engine] Translation from API (no cache):', text);\n }\n }\n }\n \n return { index, translation: result.text };\n })\n );\n\n translations.forEach(({ index, translation }) => {\n results[index] = translation;\n });\n }\n\n return results as string[];\n }\n\n async t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string> {\n if (context) {\n return this.translate(text, lang, source_lang, {user_ctx: context});\n }\n return this.translate(text, lang, source_lang);\n }\n\n private generateCacheKey(text: string, lang: Lang, source_lang?: string, ctx?: KV): string {\n const sortedCtx = ctx ? Object.keys(ctx)\n .sort()\n .reduce((acc, key) => {\n acc[key] = ctx[key];\n return acc;\n }, {} as KV) : null;\n\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: sortedCtx\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 { createMultiTransport } from '../../transports/multi';\nexport { BaseBrowserTransport, createBaseBrowserTransport } from '../../transports/base';\n"]}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Lang = string;
|
|
2
|
-
type KV = Record<string,
|
|
2
|
+
type KV = Record<string, string>;
|
|
3
3
|
interface BaseTransport {
|
|
4
4
|
post(data: any, endpointPath: string): Promise<any>;
|
|
5
5
|
}
|
|
@@ -8,7 +8,10 @@ type Transport = (params: {
|
|
|
8
8
|
lang: Lang;
|
|
9
9
|
source_lang?: string;
|
|
10
10
|
ctx?: KV;
|
|
11
|
-
}) => Promise<
|
|
11
|
+
}) => Promise<{
|
|
12
|
+
text: string;
|
|
13
|
+
status: string;
|
|
14
|
+
}>;
|
|
12
15
|
interface BelocalEngineOptions {
|
|
13
16
|
apiKey: string;
|
|
14
17
|
baseUrl?: string;
|
|
@@ -17,18 +20,12 @@ interface BelocalEngineOptions {
|
|
|
17
20
|
debug?: boolean;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
interface
|
|
21
|
-
baseTransport: BaseTransport;
|
|
22
|
-
debug?: boolean;
|
|
23
|
-
}
|
|
24
|
-
declare function createSingleTransport(config: SingleTransportConfig): Transport;
|
|
25
|
-
|
|
26
|
-
interface BatchTransportConfig {
|
|
23
|
+
interface MultiTransportConfig {
|
|
27
24
|
baseTransport: BaseTransport;
|
|
28
25
|
debug?: boolean;
|
|
29
26
|
batchWindowMs?: number;
|
|
30
27
|
}
|
|
31
|
-
declare function
|
|
28
|
+
declare function createMultiTransport(config: MultiTransportConfig): Transport;
|
|
32
29
|
|
|
33
30
|
interface BaseBrowserTransportConfig {
|
|
34
31
|
baseUrl: string;
|
|
@@ -50,8 +47,9 @@ declare class BelocalEngine {
|
|
|
50
47
|
private isCacheAvailable;
|
|
51
48
|
constructor(options: BelocalEngineOptions);
|
|
52
49
|
translate(text: string, lang: Lang, source_lang?: string, ctx?: KV): Promise<string>;
|
|
50
|
+
translateMany(texts: string[], lang: Lang, source_lang?: string, ctx?: KV): Promise<string[]>;
|
|
53
51
|
t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string>;
|
|
54
52
|
private generateCacheKey;
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
export { BaseBrowserTransport, type BaseTransport, BelocalEngine, type BelocalEngineOptions, type KV, type Lang, createBaseBrowserTransport,
|
|
55
|
+
export { BaseBrowserTransport, type BaseTransport, BelocalEngine, type BelocalEngineOptions, type KV, type Lang, createBaseBrowserTransport, createMultiTransport };
|
package/dist/browser.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {md5}from'js-md5';function
|
|
2
|
-
export{
|
|
1
|
+
import {md5}from'js-md5';function S(a,t,n,e){let o=[...a].sort(),i=null;if(e&&Object.keys(e).length>0){i={};let r=Object.keys(e).sort();for(let s of r)i[s]=e[s];}let l=JSON.stringify([o,t,n||null,i]);return md5(l)}async function v(a,t,n){a.debug&&console.log(`[BeLocal Multi Transport] Sending multi request with ${t.length} texts`);try{let e=new Map;t.forEach(r=>{let s=JSON.stringify({lang:r.lang,sourceLang:r.sourceLang||null,context:r.context||null});e.has(s)||e.set(s,[]),e.get(s).push(r);});let o=new Map,i=Array.from(e.entries()).map(([r,s])=>{let c=s[0],g=s.map(d=>d.text),p=S(g,c.lang,c.sourceLang,c.context);return o.set(p,s),{requestId:p,texts:g,lang:c.lang,sourceLang:c.sourceLang,context:c.context}}),u=await a.baseTransport.post({requests:i},"/v1/translate/multi");a.debug&&console.log(`[BeLocal Multi Transport] Multi response received with ${u.results.length} groups`);let l=new Map;u.results.forEach(r=>{l.set(r.requestId,{texts:r.data.texts,status:r.data.status});}),o.forEach((r,s)=>{let c=l.get(s);if(!c){a.debug&&console.error(`[BeLocal Multi Transport] No result found for requestId: ${s}`),r.forEach(g=>{g.reject(new Error(`No result found for request ${s}`));});return}if(c.texts.length!==r.length){let g=new Error(`Mismatch: expected ${r.length} texts, got ${c.texts.length} for requestId ${s}`);a.debug&&console.error("[BeLocal Multi Transport]",g.message),r.forEach(p=>p.reject(g));return}r.forEach((g,p)=>{let d=c.texts[p],R=c.status||"success";a.debug&&console.log(`[BeLocal Multi Transport] Success for requestId ${s}[${p}]: "${d}"`),g.resolve({text:d,status:R});});});}catch(e){a.debug&&console.error("[BeLocal Multi Transport] Multi request error:",e);let o=e instanceof Error?e:new Error(String(e));t.forEach(i=>i.reject(o));}finally{}}function M(a,t){if(t.currentMulti.length===0||t.isRequestInFlight)return;let n=[...t.currentMulti];t.currentMulti=[],t.multiTimer=null,t.isRequestInFlight=true,v(a,n).finally(()=>{if(t.isRequestInFlight=false,t.currentMulti.length>0){let e=a.batchWindowMs??50;t.multiTimer=setTimeout(()=>M(a,t),e);}});}function y(a){let t=a.batchWindowMs??50,n={currentMulti:[],multiTimer:null,isRequestInFlight:false};return ({text:e,lang:o,source_lang:i,ctx:u})=>new Promise((l,r)=>{if(a.debug){let c=md5(JSON.stringify([e,o,i||null,u||null]));console.log(`[BeLocal Multi Transport] Queuing request ${c}: "${e}" to ${o}`);}let s={text:e,lang:o,sourceLang:i,context:u,resolve:l,reject:r};n.currentMulti.push(s),n.multiTimer===null&&!n.isRequestInFlight&&(n.multiTimer=setTimeout(()=>M(a,n),t));})}var B=(()=>{try{return "0.5.0"}catch{return "undefined"}})(),w="js";var f=class{constructor(t){this.config=t;}async post(t,n){let e=`${this.config.baseUrl}${n}`,o=new AbortController,i=this.config.timeoutMs?setTimeout(()=>o.abort(),this.config.timeoutMs):null;this.config.debug&&console.log(`[Base Browser Transport] POST request to ${e}`,t);try{let u=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","x-sdk":w,"x-sdk-version":B,...this.config.headers},body:JSON.stringify(t),signal:o.signal});if(!u.ok){let r=`HTTP ${u.status}: ${u.statusText}`;throw this.config.debug&&console.error("[Base Browser Transport] Request failed:",r),new Error(r)}let l=await u.json();return this.config.debug&&console.log("[Base Browser Transport] Request successful:",l),l}finally{i&&clearTimeout(i);}}};function m(a){return new f(a)}var h=class{constructor(t="belocal_"){this.prefix=t;}get(t){try{return localStorage.getItem(this.prefix+t)}catch{return null}}set(t,n){try{localStorage.setItem(this.prefix+t,n);}catch{}}isAvailable(){try{let t=this.prefix+"__test__";return localStorage.setItem(t,"test"),localStorage.removeItem(t),!0}catch{return false}}};var T=class{constructor(){this.storage=new Map;}get(t){return this.storage.get(t)||null}set(t,n){this.storage.set(t,n);}isAvailable(){return true}};var x=class{constructor(t){let{apiKey:n,baseUrl:e="https://dynamic.belocal.dev",batchWindowMs:o=50,timeoutMs:i=1e4,debug:u=false}=t;this.debug=u;let l=new h("belocal_translations_");l.isAvailable()?this.cache=l:this.cache=new T,this.isCacheAvailable=this.cache.isAvailable();let r={Authorization:`Bearer ${n}`},s=m({baseUrl:e,headers:r,timeoutMs:i,debug:this.debug});this.transport=y({baseTransport:s,debug:this.debug,batchWindowMs:o}),this.debug&&console.log("[BeLocal Engine] Multi transport created with config:",{baseUrl:e,timeoutMs:i,batchWindowMs:o}),this.debug&&console.log("[BeLocal Engine] Cache available:",this.isCacheAvailable);}async translate(t,n,e,o){return (await this.translateMany([t],n,e,o))[0]}async translateMany(t,n,e,o){let i=new Array(t.length),u=[];for(let l=0;l<t.length;l++){let r=t[l],s=this.generateCacheKey(r,n,e,o);if(this.isCacheAvailable){let c=this.cache.get(s);if(c){if(i[l]=c,this.debug){let g=this.cache instanceof h?"localStorage":"local";console.log(`[BeLocal Engine] Translation from ${g} cache:`,r);}continue}}i[l]=null,u.push({index:l,text:r});}return u.length>0&&(await Promise.all(u.map(async({index:r,text:s})=>{let c=await this.transport({text:s,lang:n,source_lang:e,ctx:o});if(this.isCacheAvailable&&c.status!=="error"){let g=this.generateCacheKey(s,n,e,o);if(this.cache.set(g,c.text),this.debug){let p=this.cache instanceof h?"localStorage":"local";console.log(`[BeLocal Engine] Translation from API, cached in ${p}:`,s);}}else this.debug&&(c.status==="error"?console.log("[BeLocal Engine] Translation from API (not cached due to error status):",s):console.log("[BeLocal Engine] Translation from API (no cache):",s));return {index:r,translation:c.text}}))).forEach(({index:r,translation:s})=>{i[r]=s;}),i}async t(t,n,e,o){return o?this.translate(t,n,e,{user_ctx:o}):this.translate(t,n,e)}generateCacheKey(t,n,e,o){let i=o?Object.keys(o).sort().reduce((l,r)=>(l[r]=o[r],l),{}):null;return md5(JSON.stringify({text:t,lang:n,source_lang:e||null,ctx:i}))}};
|
|
2
|
+
export{f as BaseBrowserTransport,x as BelocalEngine,m as createBaseBrowserTransport,y as createMultiTransport};//# sourceMappingURL=browser.mjs.map
|
|
3
3
|
//# sourceMappingURL=browser.mjs.map
|
package/dist/browser.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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","sortedCtx","acc"],"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 sortedCtx = ctx ? Object.keys(ctx)\n .sort()\n .reduce((acc, key) => {\n acc[key] = ctx[key];\n return acc;\n }, {} as KV) : null;\n\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: sortedCtx\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/multi.ts","../src/version.ts","../src/transports/base/browser.ts","../src/cache/localStorage.ts","../src/cache/local.ts","../src/core/engine/browser.ts"],"names":["generateRequestId","texts","lang","sourceLang","context","sortedTexts","sortedContext","sortedKeys","key","json","md5","sendMulti","config","items","state","groups","item","groupKey","requestIdToGroupItems","requests","groupItems","firstItem","requestId","multiResponse","resultMap","result","error","index","translatedText","status","errorToReject","processMulti","itemsToSend","windowMs","createMultiTransport","text","source_lang","ctx","resolve","reject","tempRequestId","requestItem","SDK_VERSION","SDK_NAME","BaseBrowserTransport","data","endpointPath","url","controller","timeoutId","response","errorMsg","createBaseBrowserTransport","LocalStorageCache","prefix","value","testKey","LocalCache","BelocalEngine","options","apiKey","baseUrl","batchWindowMs","timeoutMs","debug","localStorageCache","authHeaders","baseTransport","results","cacheMisses","i","cacheKey","cachedResult","cacheType","translation","sortedCtx","acc"],"mappings":"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","file":"browser.mjs","sourcesContent":["import type { Transport, BaseTransport } from '../core/types';\nimport { md5 } from 'js-md5';\n\nexport interface MultiTransportConfig {\n baseTransport: BaseTransport;\n debug?: boolean;\n batchWindowMs?: number;\n}\n\ninterface MultiRequest {\n requestId: string;\n texts: string[];\n lang: string;\n sourceLang?: string;\n context?: Record<string, string>;\n}\n\ninterface MultiRequestItem {\n text: string;\n lang: string;\n sourceLang?: string;\n context?: Record<string, string>;\n resolve: (value: { text: string; status: string }) => void;\n reject: (error: Error) => void;\n}\n\ninterface MultiResponse {\n results: Array<{\n requestId: string;\n data: { texts: string[]; status: string };\n }>;\n}\n\ninterface MultiState {\n currentMulti: MultiRequestItem[];\n multiTimer: ReturnType<typeof setTimeout> | null;\n isRequestInFlight: boolean;\n}\n\nfunction generateRequestId(texts: string[], lang: string, sourceLang?: string, context?: Record<string, string>): string {\n // Сортируем тексты (создаем копию, чтобы не изменять оригинал)\n const sortedTexts = [...texts].sort();\n \n // Сортируем ключи контекста (создаем копию, чтобы не изменять оригинал)\n let sortedContext: Record<string, string> | null = null;\n if (context && Object.keys(context).length > 0) {\n sortedContext = {};\n const sortedKeys = Object.keys(context).sort();\n for (const key of sortedKeys) {\n sortedContext[key] = context[key];\n }\n }\n \n // Создаем JSON массив: [sortedTexts, lang, sourceLang, context]\n // В PHP примере: [$sortedTexts, $this->lang, $context] (sourceLang не включен)\n // Но мы включаем sourceLang для правильной группировки запросов с разными sourceLang\n const data = [sortedTexts, lang, sourceLang || null, sortedContext];\n const json = JSON.stringify(data);\n \n return md5(json);\n}\n\nasync function sendMulti(\n config: MultiTransportConfig,\n items: MultiRequestItem[],\n state: MultiState\n): Promise<void> {\n if (config.debug) {\n console.log(`[BeLocal Multi Transport] Sending multi request with ${items.length} texts`);\n }\n\n try {\n // Группируем тексты по параметрам перевода (lang, sourceLang, context)\n const groups = new Map<string, MultiRequestItem[]>();\n \n items.forEach(item => {\n // Используем ключ для группировки без текстов (только параметры перевода)\n const groupKey = JSON.stringify({\n lang: item.lang,\n sourceLang: item.sourceLang || null,\n context: item.context || null\n });\n \n if (!groups.has(groupKey)) {\n groups.set(groupKey, []);\n }\n groups.get(groupKey)!.push(item);\n });\n\n // Создаем запросы для каждой группы и сохраняем соответствие requestId -> groupItems\n const requestIdToGroupItems = new Map<string, MultiRequestItem[]>();\n const requests: MultiRequest[] = Array.from(groups.entries()).map(([groupKey, groupItems]) => {\n const firstItem = groupItems[0];\n const texts = groupItems.map(item => item.text);\n \n // Генерируем requestId включая отсортированные тексты группы\n // Включаем sourceLang для правильной группировки запросов с разными sourceLang\n const requestId = generateRequestId(\n texts,\n firstItem.lang,\n firstItem.sourceLang,\n firstItem.context\n );\n \n // Сохраняем соответствие requestId -> groupItems\n requestIdToGroupItems.set(requestId, groupItems);\n \n return {\n requestId,\n texts,\n lang: firstItem.lang,\n sourceLang: firstItem.sourceLang,\n context: firstItem.context\n };\n });\n\n const multiResponse: MultiResponse = await config.baseTransport.post({ requests }, '/v1/translate/multi');\n \n if (config.debug) {\n console.log(`[BeLocal Multi Transport] Multi response received with ${multiResponse.results.length} groups`);\n }\n\n // Создаем map для быстрого поиска результатов по requestId\n const resultMap = new Map<string, { texts: string[]; status: string }>();\n multiResponse.results.forEach(result => {\n resultMap.set(result.requestId, { texts: result.data.texts, status: result.data.status });\n });\n\n // Раздаем результаты каждому промису\n requestIdToGroupItems.forEach((groupItems, requestId) => {\n const result = resultMap.get(requestId);\n \n if (!result) {\n if (config.debug) {\n console.error(`[BeLocal Multi Transport] No result found for requestId: ${requestId}`);\n }\n groupItems.forEach(item => {\n item.reject(new Error(`No result found for request ${requestId}`));\n });\n return;\n }\n\n // Маппим тексты обратно на промисы по индексу\n if (result.texts.length !== groupItems.length) {\n const error = new Error(`Mismatch: expected ${groupItems.length} texts, got ${result.texts.length} for requestId ${requestId}`);\n if (config.debug) {\n console.error(`[BeLocal Multi Transport]`, error.message);\n }\n groupItems.forEach(item => item.reject(error));\n return;\n }\n\n groupItems.forEach((item, index) => {\n const translatedText = result.texts[index];\n const status = result.status || 'success';\n \n if (config.debug) {\n console.log(`[BeLocal Multi Transport] Success for requestId ${requestId}[${index}]: \"${translatedText}\"`);\n }\n \n item.resolve({ text: translatedText, status });\n });\n });\n\n } catch (error) {\n if (config.debug) {\n console.error(`[BeLocal Multi Transport] Multi request error:`, error);\n }\n \n // При ошибке сети отклоняем все промисы\n const errorToReject = error instanceof Error ? error : new Error(String(error));\n items.forEach(item => item.reject(errorToReject));\n } finally {\n // Cleanup handled by base transport\n }\n}\n\nfunction processMulti(config: MultiTransportConfig, state: MultiState): void {\n if (state.currentMulti.length === 0 || state.isRequestInFlight) {\n return;\n }\n\n const itemsToSend = [...state.currentMulti];\n state.currentMulti = [];\n state.multiTimer = null;\n state.isRequestInFlight = true;\n\n sendMulti(config, itemsToSend, state).finally(() => {\n state.isRequestInFlight = false;\n \n if (state.currentMulti.length > 0) {\n const windowMs = config.batchWindowMs ?? 50;\n state.multiTimer = setTimeout(() => processMulti(config, state), windowMs);\n }\n });\n}\n\nexport function createMultiTransport(config: MultiTransportConfig): Transport {\n const windowMs = config.batchWindowMs ?? 50;\n\n const state: MultiState = {\n currentMulti: [],\n multiTimer: null,\n isRequestInFlight: false,\n };\n \n return ({ text, lang, source_lang, ctx }) => {\n return new Promise<{ text: string; status: string }>((resolve, reject) => {\n if (config.debug) {\n // Для отладки показываем временный requestId (будет пересчитан при группировке)\n const tempRequestId = md5(JSON.stringify([text, lang, source_lang || null, ctx || null]));\n console.log(`[BeLocal Multi Transport] Queuing request ${tempRequestId}: \"${text}\" to ${lang}`);\n }\n\n const requestItem: MultiRequestItem = {\n text,\n lang,\n sourceLang: source_lang,\n context: ctx,\n resolve,\n reject,\n };\n\n state.currentMulti.push(requestItem);\n\n if (state.multiTimer === null && !state.isRequestInFlight) {\n state.multiTimer = setTimeout(() => processMulti(config, state), windowMs);\n }\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 { createMultiTransport } from '../../transports/multi';\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 // Always use multi transport\n this.transport = createMultiTransport({\n baseTransport,\n debug: this.debug,\n batchWindowMs\n });\n \n if (this.debug) {\n console.log('[BeLocal Engine] Multi transport created with config:', {\n baseUrl,\n timeoutMs,\n batchWindowMs\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 const results = await this.translateMany([text], lang, source_lang, ctx);\n return results[0];\n }\n\n async translateMany(texts: string[], lang: Lang, source_lang?: string, ctx?: KV): Promise<string[]> {\n const results: (string | null)[] = new Array(texts.length);\n const cacheMisses: Array<{ index: number; text: string }> = [];\n\n for (let i = 0; i < texts.length; i++) {\n const text = texts[i];\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n \n if (this.isCacheAvailable) {\n const cachedResult = this.cache.get(cacheKey);\n if (cachedResult) {\n results[i] = 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 continue;\n }\n }\n \n results[i] = null;\n cacheMisses.push({ index: i, text });\n }\n\n if (cacheMisses.length > 0) {\n const translations = await Promise.all(\n cacheMisses.map(async ({ index, text }) => {\n const result = await this.transport({ text, lang, source_lang, ctx });\n \n if (this.isCacheAvailable && result.status !== 'error') {\n const cacheKey = this.generateCacheKey(text, lang, source_lang, ctx);\n this.cache.set(cacheKey, result.text);\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 if (result.status === 'error') {\n console.log('[BeLocal Engine] Translation from API (not cached due to error status):', text);\n } else {\n console.log('[BeLocal Engine] Translation from API (no cache):', text);\n }\n }\n }\n \n return { index, translation: result.text };\n })\n );\n\n translations.forEach(({ index, translation }) => {\n results[index] = translation;\n });\n }\n\n return results as string[];\n }\n\n async t(text: string, lang: Lang, source_lang?: string, context?: string): Promise<string> {\n if (context) {\n return this.translate(text, lang, source_lang, {user_ctx: context});\n }\n return this.translate(text, lang, source_lang);\n }\n\n private generateCacheKey(text: string, lang: Lang, source_lang?: string, ctx?: KV): string {\n const sortedCtx = ctx ? Object.keys(ctx)\n .sort()\n .reduce((acc, key) => {\n acc[key] = ctx[key];\n return acc;\n }, {} as KV) : null;\n\n const data = {\n text,\n lang,\n source_lang: source_lang || null,\n ctx: sortedCtx\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 { createMultiTransport } from '../../transports/multi';\nexport { BaseBrowserTransport, createBaseBrowserTransport } from '../../transports/base';\n"]}
|