UNPKG

@ui18n/svelte

Version:

🧡 Lightning-fast Svelte internationalization with reactive stores, SvelteKit support, and zero-bundle overhead

794 lines (787 loc) 25.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var core = require('@ui18n/core'); var store = require('svelte/store'); /** * 创建UI18n Store */ function createUI18nStore(config) { // 创建UI18n核心实例 const ui18nInstance = core.createUI18n(config); // 创建响应式stores const currentLanguage = store.writable(config.defaultLanguage); const loading = store.writable(false); const error = store.writable(null); // 高级功能stores const batchState = store.writable({ translations: {}, translationArray: [], loading: false, error: null, progress: 0, completedCount: 0, totalCount: 0, failedTexts: [] }); const realTimeSyncStatus = store.writable({ enabled: false, connected: false, method: 'polling', syncErrors: 0 }); const cacheStats = store.writable(null); const syncErrors = store.writable(0); // 创建派生store,包含所有状态 const store$1 = store.derived([currentLanguage, loading, error, batchState, realTimeSyncStatus, cacheStats, syncErrors], ([$currentLanguage, $loading, $error, $batchState, $realTimeSyncStatus, $cacheStats, $syncErrors]) => ({ ui18n: ui18nInstance, currentLanguage: $currentLanguage, loading: $loading, error: $error, batchState: $batchState, realTimeSyncStatus: $realTimeSyncStatus, cacheStats: $cacheStats, syncErrors: $syncErrors })); /** * 切换语言 */ const setLanguage = async (language) => { try { loading.set(true); error.set(null); await ui18nInstance.setLanguage(language); currentLanguage.set(language); } catch (err) { const errorMessage = err instanceof Error ? err.message : '语言切换失败'; error.set(errorMessage); console.error('UI18n语言切换失败:', err); } finally { loading.set(false); } }; /** * 翻译文本 */ const translate = async (text, options = {}) => { try { loading.set(true); error.set(null); const targetLanguage = (options && options['language']) || store.get(currentLanguage); const result = await ui18nInstance.translate(text, targetLanguage, { context: options && options['context'] }); return result.text; } catch (err) { const errorMessage = err instanceof Error ? err.message : '翻译失败'; error.set(errorMessage); console.error('UI18n翻译失败:', err); return text; // 翻译失败时返回原文 } finally { loading.set(false); } }; /** * 批量翻译(基础版本) */ const translateBatch = async (texts, options = {}) => { try { loading.set(true); error.set(null); const targetLanguage = options.language || store.get(currentLanguage); const results = await ui18nInstance.translateBatch(texts, targetLanguage, { context: options.context, maxConcurrency: options.maxConcurrency }); return results; } catch (err) { const errorMessage = err instanceof Error ? err.message : '批量翻译失败'; error.set(errorMessage); console.error('UI18n批量翻译失败:', err); throw err; } finally { loading.set(false); } }; /** * 智能批量翻译(增强版本) */ const translateBatchOptimized = async (texts, options = {}) => { const { language, context, maxConcurrency, priority = 'normal', useOptimizer = true, enableProgressTracking = true } = options; const targetLanguage = language || store.get(currentLanguage); try { if (enableProgressTracking) { batchState.update(state => ({ ...state, loading: true, progress: 0, error: null })); } let results; if (useOptimizer) { // 使用智能批量优化器 results = await ui18nInstance.translateBatch(texts, targetLanguage, { context, maxConcurrency, useOptimizer: true, priority: priority }); } else { // 传统批量翻译 results = await ui18nInstance.translateBatch(texts, targetLanguage, { context, maxConcurrency }); } if (enableProgressTracking) { // 构建翻译映射和数组 const translations = {}; const translationArray = []; results.forEach((result, index) => { const originalText = texts[index]; const translatedText = result.text; translations[originalText] = translatedText; translationArray.push(translatedText); }); batchState.set({ translations, translationArray, loading: false, error: null, progress: 1, completedCount: results.length, totalCount: texts.length, failedTexts: [] }); } return results; } catch (err) { const errorMessage = err instanceof Error ? err.message : '批量翻译失败'; if (enableProgressTracking) { batchState.update(state => ({ ...state, loading: false, error: errorMessage, progress: 0 })); } console.error('UI18n智能批量翻译失败:', err); throw err; } }; /** * 获取语言显示名称 */ const getLanguageDisplayName = (language, displayLanguage) => { const displayLang = displayLanguage || store.get(currentLanguage); return ui18nInstance.getLanguageDisplayName(language, displayLang); }; /** * 检测并设置系统语言 */ const detectAndSetSystemLanguage = async () => { try { ui18nInstance.detectAndSetSystemLanguage(); const newLanguage = ui18nInstance.getCurrentLanguage(); if (newLanguage !== store.get(currentLanguage)) { currentLanguage.set(newLanguage); } } catch (err) { console.warn('系统语言检测失败:', err); } }; /** * 搜索语言 */ const searchLanguages = (query, availableLanguages) => { if (!query.trim()) { return []; } const searchTerm = query.toLowerCase(); const currentLang = store.get(currentLanguage); return availableLanguages.filter((lang) => { const displayName = getLanguageDisplayName(lang, currentLang).toLowerCase(); const nativeName = getLanguageDisplayName(lang, lang).toLowerCase(); const langCode = lang.toLowerCase(); return displayName.includes(searchTerm) || nativeName.includes(searchTerm) || langCode.includes(searchTerm); }); }; /** * 连接实时同步 */ const connectRealTimeSync = async (options = {}) => { try { const versionControlManager = ui18nInstance.versionControlManager; if (versionControlManager && versionControlManager.reconnectRealTimeSync) { const success = await versionControlManager.reconnectRealTimeSync(); updateRealTimeSyncStatus(); return success; } return false; } catch (err) { console.error('连接实时同步失败:', err); syncErrors.update(count => count + 1); return false; } }; /** * 断开实时同步 */ const disconnectRealTimeSync = () => { try { const versionControlManager = ui18nInstance.versionControlManager; if (versionControlManager) { console.log('断开实时同步连接'); updateRealTimeSyncStatus(); } } catch (err) { console.error('断开实时同步失败:', err); } }; /** * 手动同步 */ const manualSync = async (language) => { try { const versionControlManager = ui18nInstance.versionControlManager; if (versionControlManager) { if (language) { if (versionControlManager.syncLanguagePack) { await versionControlManager.syncLanguagePack(language); } } else { if (versionControlManager.syncAllLanguagePacks) { await versionControlManager.syncAllLanguagePacks(); } } updateRealTimeSyncStatus(); return true; } return false; } catch (err) { console.error('手动同步失败:', err); syncErrors.update(count => count + 1); return false; } }; /** * 清理缓存 */ const clearCache = async (pattern) => { try { await ui18nInstance.clearCache(pattern); updateCacheStats(); } catch (err) { console.error('清理缓存失败:', err); throw err; } }; /** * 优化缓存 */ const optimizeCache = async () => { try { const optimizedCacheManager = ui18nInstance.optimizedCache; if (optimizedCacheManager && optimizedCacheManager.cleanup) { await optimizedCacheManager.cleanup(); } updateCacheStats(); } catch (err) { console.error('优化缓存失败:', err); throw err; } }; /** * 预加载语言 */ const preloadLanguage = async (language) => { const commonPhrases = [ 'Hello', 'Thank you', 'Please', 'Yes', 'No', 'Save', 'Cancel', 'Delete', 'Edit', 'View', 'Login', 'Logout', 'Settings', 'Help', 'About' ]; for (const phrase of commonPhrases) { try { await ui18nInstance.translate(phrase, language); } catch (err) { console.warn(`预加载短语失败: ${phrase}`, err); } } updateCacheStats(); }; /** * 获取缓存统计 */ const getCacheStats = () => { if (!ui18nInstance || !ui18nInstance.getCacheStats) { return null; } try { const stats = ui18nInstance.getCacheStats(); return { totalItems: stats.totalItems || 0, memoryUsageMB: stats.memoryUsageMB || 0, memoryLimitMB: stats.memoryLimitMB || 50, memoryUtilization: stats.memoryUtilization || 0, hits: stats.hits || 0, misses: stats.misses || 0, hitRate: stats.hitRate || 0, type: stats.type || 'memory' }; } catch (err) { console.warn('获取缓存统计失败:', err); return null; } }; /** * 获取实时同步状态 */ const getRealTimeSyncStatus = () => { try { const versionControlManager = ui18nInstance.versionControlManager; if (versionControlManager && versionControlManager.getRealTimeSyncStatus) { const status = versionControlManager.getRealTimeSyncStatus(); return { enabled: status.enabled, connected: status.connected, method: status.method, lastEvent: status.lastEvent, syncErrors: store.get(syncErrors) }; } } catch (err) { console.warn('获取实时同步状态失败:', err); } return { enabled: false, connected: false, method: 'polling', syncErrors: store.get(syncErrors) }; }; /** * 更新缓存统计 */ const updateCacheStats = () => { const stats = getCacheStats(); cacheStats.set(stats); }; /** * 更新实时同步状态 */ const updateRealTimeSyncStatus = () => { const status = getRealTimeSyncStatus(); realTimeSyncStatus.set(status); }; // 定期更新统计信息 setInterval(() => { updateCacheStats(); updateRealTimeSyncStatus(); }, 5000); // 返回store和相关方法 return { // 响应式store subscribe: store$1.subscribe, // 状态管理方法 setLanguage, translate, translateBatch, translateBatchOptimized, getLanguageDisplayName, detectAndSetSystemLanguage, searchLanguages, // 高级功能方法 connectRealTimeSync, disconnectRealTimeSync, manualSync, clearCache, optimizeCache, preloadLanguage, getCacheStats, getRealTimeSyncStatus, // 直接访问stores(用于高级用法) stores: { currentLanguage, loading, error, batchState, realTimeSyncStatus, cacheStats, syncErrors }, // 直接访问UI18n实例 ui18n: ui18nInstance }; } /** * 全局UI18n Store实例(可选) */ let globalUI18nStore = null; /** * 设置全局UI18n Store */ function setGlobalUI18nStore(config) { globalUI18nStore = createUI18nStore(config); return globalUI18nStore; } /** * 获取全局UI18n Store */ function getGlobalUI18nStore() { if (!globalUI18nStore) { throw new Error('全局UI18n Store未初始化。请先调用 setGlobalUI18nStore()'); } return globalUI18nStore; } /** * 便捷的翻译函数(使用全局store) */ async function t$1(text, options = {}) { const store = getGlobalUI18nStore(); return store.translate(text, options); } /** * Create useTranslation store * Provides translation functionality with reactive state */ function createUseTranslationStore(ui18n) { // Base state stores const translatedText = store.writable(''); const isLoading = store.writable(false); const error = store.writable(null); // Derived store combining all state const state = store.derived([translatedText, isLoading, error], ([$translatedText, $isLoading, $error]) => ({ translatedText: $translatedText, isLoading: $isLoading, error: $error })); /** * Translate text with reactive state management */ const translate = async (text, options) => { if (!ui18n) { error.set('UI18n instance not available'); return text; } try { isLoading.set(true); error.set(null); const result = await ui18n.translate(text, options?.targetLanguage || ui18n.getCurrentLanguage(), { context: options?.context, forceAI: options?.forceAI, skipCache: options?.skipCache }); translatedText.set(result.text); return result.text; } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Translation failed'; error.set(errorMessage); console.error('Translation error:', err); translatedText.set(text); // fallback to original text return text; } finally { isLoading.set(false); } }; /** * Translate multiple texts at once */ const translateBatch = async (texts, options) => { if (!ui18n) { error.set('UI18n instance not available'); return texts; } try { isLoading.set(true); error.set(null); const targetLanguage = options?.targetLanguage || ui18n.getCurrentLanguage(); const results = await ui18n.translateBatch(texts, targetLanguage, { context: options?.context, maxConcurrency: 5 }); const translatedTexts = results.map(result => result.text); return translatedTexts; } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Batch translation failed'; error.set(errorMessage); console.error('Batch translation error:', err); return texts; // fallback to original texts } finally { isLoading.set(false); } }; /** * Get current language */ const getCurrentLanguage = () => { return ui18n?.getCurrentLanguage() || 'en'; }; /** * Get supported languages */ const getSupportedLanguages = () => { return ui18n?.getSupportedLanguages() || []; }; /** * Clear error state */ const clearError = () => { error.set(null); }; /** * Refresh translation with force cache skip */ const refresh = async (text, options) => { return translate(text, { ...options, skipCache: true }); }; return { // Reactive state subscribe: state.subscribe, // Individual stores for advanced usage stores: { translatedText, isLoading, error }, // Methods translate, translateBatch, getCurrentLanguage, getSupportedLanguages, clearError, refresh, // Alias for consistency with React/Vue t: translate }; } /** * Global translation store instance */ let globalTranslationStore = null; /** * Set global translation store */ function setGlobalTranslationStore(ui18n) { globalTranslationStore = createUseTranslationStore(ui18n); return globalTranslationStore; } /** * Get global translation store */ function getGlobalTranslationStore() { if (!globalTranslationStore) { throw new Error('Global translation store not initialized. Call setGlobalTranslationStore() first.'); } return globalTranslationStore; } /** * Convenience function for global translation */ async function t(text, options) { const store = getGlobalTranslationStore(); return store.translate(text, options); } /** * Create useLanguage store * Provides language management functionality with reactive state */ function createUseLanguageStore(ui18n) { // Base state stores const currentLanguage = store.writable(ui18n?.getCurrentLanguage() || 'en'); const supportedLanguages = store.writable(ui18n?.getSupportedLanguages() || []); const isChanging = store.writable(false); const error = store.writable(null); // Derived store combining all state const state = store.derived([currentLanguage, supportedLanguages, isChanging, error], ([$currentLanguage, $supportedLanguages, $isChanging, $error]) => ({ currentLanguage: $currentLanguage, supportedLanguages: $supportedLanguages, isChanging: $isChanging, error: $error })); /** * Switch to a new language */ const switchLanguage = async (language) => { if (!ui18n || language === store.get(currentLanguage)) return; try { isChanging.set(true); error.set(null); ui18n.setLanguage(language); currentLanguage.set(language); // Preload translations for the new language if storage adapter is available if (ui18n.loadPersistedTranslation) { await ui18n.loadPersistedTranslation(language); } } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Language switch failed'; error.set(errorMessage); console.error('Language switch error:', err); throw err; } finally { isChanging.set(false); } }; /** * Get display name for a language */ const getLanguageDisplayName = (language) => { return ui18n?.getLanguageDisplayName?.(language) || language; }; /** * Detect language from text */ const detectLanguage = (text) => { if (!text || typeof text !== 'string') { throw new Error('Input must be a string'); } return ui18n?.detectLanguage?.(text) || 'en'; }; /** * Check if a language is supported */ const isLanguageSupported = (language) => { const supported = store.get(supportedLanguages); return supported.includes(language); }; /** * Get recommended languages based on current language */ const getRecommendedLanguages = () => { const current = store.get(currentLanguage); const all = store.get(supportedLanguages); // Put current language first, then others return [current, ...all.filter((lang) => lang !== current)].slice(0, 5); }; /** * Get available language packs */ const getAvailableLanguages = async () => { if (!ui18n?.getAvailableLanguages) { return store.get(supportedLanguages); } try { return await ui18n.getAvailableLanguages(); } catch (err) { console.warn('Failed to get available languages:', err); return store.get(supportedLanguages); } }; /** * Refresh supported languages from UI18n instance */ const refreshSupportedLanguages = () => { if (ui18n) { const languages = ui18n.getSupportedLanguages() || []; supportedLanguages.set(languages); } }; /** * Sync current language with UI18n instance */ const syncCurrentLanguage = () => { if (ui18n) { const language = ui18n.getCurrentLanguage(); currentLanguage.set(language); } }; /** * Clear error state */ const clearError = () => { error.set(null); }; /** * Initialize language state */ const initialize = () => { refreshSupportedLanguages(); syncCurrentLanguage(); }; // Auto-initialize initialize(); return { // Reactive state subscribe: state.subscribe, // Individual stores for advanced usage stores: { currentLanguage, supportedLanguages, isChanging, error }, // Methods switchLanguage, getLanguageDisplayName, detectLanguage, isLanguageSupported, getRecommendedLanguages, getAvailableLanguages, refreshSupportedLanguages, syncCurrentLanguage, clearError, initialize, // Utility getters (non-reactive for immediate access) getCurrentLanguage: () => store.get(currentLanguage), getSupportedLanguages: () => store.get(supportedLanguages), getIsChanging: () => store.get(isChanging), getError: () => store.get(error) }; } /** * Global language store instance */ let globalLanguageStore = null; /** * Set global language store */ function setGlobalLanguageStore(ui18n) { globalLanguageStore = createUseLanguageStore(ui18n); return globalLanguageStore; } /** * Get global language store */ function getGlobalLanguageStore() { if (!globalLanguageStore) { throw new Error('Global language store not initialized. Call setGlobalLanguageStore() first.'); } return globalLanguageStore; } Object.defineProperty(exports, 'UI18n', { enumerable: true, get: function () { return core.UI18n; } }); Object.defineProperty(exports, 'createUI18n', { enumerable: true, get: function () { return core.createUI18n; } }); exports.createUI18nStore = createUI18nStore; exports.createUseLanguageStore = createUseLanguageStore; exports.createUseTranslationStore = createUseTranslationStore; exports.default = createUI18nStore; exports.getGlobalLanguageStore = getGlobalLanguageStore; exports.getGlobalTranslationStore = getGlobalTranslationStore; exports.getGlobalUI18nStore = getGlobalUI18nStore; exports.setGlobalLanguageStore = setGlobalLanguageStore; exports.setGlobalTranslationStore = setGlobalTranslationStore; exports.setGlobalUI18nStore = setGlobalUI18nStore; exports.t = t$1; exports.useTranslationT = t;