UNPKG

@ui18n/svelte

Version:

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

1,211 lines (1,204 loc) 41.6 kB
import { writable, derived, get } from 'svelte/store'; import { createUI18n } from '@ui18n/core'; export { createUI18n } from '@ui18n/core'; /** * 创建UI18n Store */ function createUI18nStore(config) { // 创建UI18n核心实例 const ui18nInstance = createUI18n(config); // 创建响应式stores const currentLanguage = writable(config.defaultLanguage); const loading = writable(false); const error = writable(null); // 高级功能stores const batchState = writable({ translations: {}, translationArray: [], loading: false, error: null, progress: 0, completedCount: 0, totalCount: 0, failedTexts: [] }); const realTimeSyncStatus = writable({ enabled: false, connected: false, method: 'polling', syncErrors: 0 }); const cacheStats = writable(null); const syncErrors = writable(0); // 创建派生store,包含所有状态 const 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']) || 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 || 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 || 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 || get(currentLanguage); return ui18nInstance.getLanguageDisplayName(language, displayLang); }; /** * 检测并设置系统语言 */ const detectAndSetSystemLanguage = async () => { try { ui18nInstance.detectAndSetSystemLanguage(); const newLanguage = ui18nInstance.getCurrentLanguage(); if (newLanguage !== get(currentLanguage)) { currentLanguage.set(newLanguage); } } catch (err) { console.warn('系统语言检测失败:', err); } }; /** * 搜索语言 */ const searchLanguages = (query, availableLanguages) => { if (!query.trim()) { return []; } const searchTerm = query.toLowerCase(); const currentLang = 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: get(syncErrors) }; } } catch (err) { console.warn('获取实时同步状态失败:', err); } return { enabled: false, connected: false, method: 'polling', syncErrors: 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.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; } /** * Create useTranslation store * Provides translation functionality with reactive state */ function createUseTranslationStore(ui18n) { // Base state stores const translatedText = writable(''); const isLoading = writable(false); const error = writable(null); // Derived store combining all state const state = 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$1(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 = writable(ui18n?.getCurrentLanguage() || 'en'); const supportedLanguages = writable(ui18n?.getSupportedLanguages() || []); const isChanging = writable(false); const error = writable(null); // Derived store combining all state const state = 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 === 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 = get(supportedLanguages); return supported.includes(language); }; /** * Get recommended languages based on current language */ const getRecommendedLanguages = () => { const current = get(currentLanguage); const all = 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 get(supportedLanguages); } try { return await ui18n.getAvailableLanguages(); } catch (err) { console.warn('Failed to get available languages:', err); return 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: () => get(currentLanguage), getSupportedLanguages: () => get(supportedLanguages), getIsChanging: () => get(isChanging), getError: () => 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; } /** * Svelte浏览器专用入口点 * * 🎯 基于 .ui18n 核心哲学的浏览器优化版本 * * 特性: * - ✅ 浏览器适配器:localStorage模拟.ui18n目录 * - ✅ Svelte优化:原生支持reactive stores和Svelte 4/5 * - ✅ 轻量级:移除Node.js专用功能 * - ✅ SvelteKit友好:SSR/SSG兼容性 */ // 重新导出所有公共API /** * 创建浏览器优化的Svelte UI18N Store * * 遵循.ui18n核心哲学: * 1. 尝试从/.ui18n/languages.json发现可用语言 * 2. 使用localStorage模拟.ui18n目录进行持久化 * 3. 集成Svelte的reactive stores系统 */ function createBrowserUI18nStore(config = {}) { const { enableUI18nDiscovery = true, ui18nDiscoveryPath = "/.ui18n/languages.json", enablePersistence = true, debug = false, defaultLanguage = 'en', sveltekit = {}, ui18nConfig = {} } = config; // 创建UI18n实例(浏览器环境会自动使用浏览器适配器) const ui18n = createUI18n({ defaultLanguage, ...ui18nConfig }); // 创建响应式stores const currentLanguage = writable(defaultLanguage); const supportedLanguages = writable(['en', 'zh', 'es', 'fr', 'de', 'ja', 'ko']); const isLoading = writable(false); const isInitialized = writable(false); // 派生状态 const isReady = derived([isInitialized, isLoading], ([$isInitialized, $isLoading]) => $isInitialized && !$isLoading); // 初始化逻辑 let initPromise = null; const initialize = async () => { if (initPromise) return initPromise; initPromise = (async () => { try { isLoading.set(true); // 设置初始语言 const initialLang = ui18n.getCurrentLanguage(); currentLanguage.set(initialLang); // 自动发现和恢复 await autoSetup(); // 标记为已初始化 isInitialized.set(true); if (debug) { console.log('[UI18N Svelte Browser] Store已初始化,遵循.ui18n核心哲学 ✅', { ui18nDiscovery: enableUI18nDiscovery ? `启用 (${ui18nDiscoveryPath})` : '禁用', persistence: enablePersistence ? 'localStorage模拟.ui18n目录' : '禁用', sveltekit: sveltekit.enableSSR ? 'SSR模式' : '客户端模式', version: 'browser', compliance: '.ui18n核心哲学 ✅' }); } } catch (error) { console.error('[UI18N Svelte Browser] 初始化失败:', error); } finally { isLoading.set(false); } })(); return initPromise; }; // 自动发现和恢复功能 const autoSetup = async () => { // 1. 尝试.ui18n发现 if (enableUI18nDiscovery && typeof fetch !== 'undefined') { try { const response = await fetch(ui18nDiscoveryPath); if (response.ok) { const discoveredConfig = await response.json(); if (discoveredConfig.languages && Array.isArray(discoveredConfig.languages)) { supportedLanguages.set(discoveredConfig.languages); if (debug) { console.log('[UI18N Svelte Browser] 发现.ui18n配置:', discoveredConfig); } } } } catch (error) { if (debug) { console.warn('[UI18N Svelte Browser] .ui18n发现失败:', error); } } } // 2. 恢复之前保存的语言选择 if (enablePersistence && typeof localStorage !== 'undefined') { try { const saved = localStorage.getItem('ui18n_svelte_selected_language'); if (saved && get(supportedLanguages).includes(saved)) { await setLanguage(saved); if (debug) { console.log(`[UI18N Svelte Browser] 从localStorage恢复语言: ${saved}`); } } } catch (error) { if (debug) { console.warn('[UI18N Svelte Browser] 恢复语言选择失败:', error); } } } }; // 设置语言 const setLanguage = async (language) => { try { await ui18n.setLanguage(language); currentLanguage.set(language); // 持久化到localStorage(模拟.ui18n目录) if (enablePersistence && typeof localStorage !== 'undefined') { localStorage.setItem('ui18n_svelte_selected_language', language); if (debug) { console.log(`[UI18N Svelte Browser] 语言已保存到 localStorage: ${language}`); } } } catch (error) { console.error('[UI18N Svelte Browser] 设置语言失败:', error); } }; // 翻译函数 const translate = async (text, options) => { if (!ui18n) { return text; } return ui18n.t(text, options); }; // 自动初始化(如果在浏览器环境) if (typeof window !== 'undefined') { initialize(); } return { currentLanguage, supportedLanguages, isReady, isLoading, setLanguage, translate, t: translate }; } /** * 全局浏览器UI18N store实例 */ let globalBrowserStore = null; /** * 设置全局浏览器UI18N store */ function setGlobalBrowserUI18nStore(store) { globalBrowserStore = store; } /** * 获取全局浏览器UI18N store */ function getGlobalBrowserUI18nStore() { if (!globalBrowserStore) { globalBrowserStore = createBrowserUI18nStore(); } return globalBrowserStore; } /** * 便捷的翻译函数(使用全局store) */ async function t(text, options) { const store = getGlobalBrowserUI18nStore(); return store.translate(text, options); } // 框架逻辑验证函数 function validateSvelteBrowserFrameworkCompliance() { const hasLocalStorage = typeof localStorage !== 'undefined'; const hasSvelte = typeof writable !== 'undefined'; const isSSR = typeof window === 'undefined'; return { ui18nDirectory: true, // localStorage模拟.ui18n目录 svelteCompatibility: hasSvelte, browserSafe: true, // 纯浏览器环境 zeroConfig: true, // 提供默认配置 persistence: hasLocalStorage, autoDiscovery: true, // 自动发现/.ui18n/languages.json reactiveStores: hasSvelte, ssrCompatible: true, // 支持SSR recommendations: [ '✅ 使用/.ui18n/languages.json来定义可用语言', '✅ 选择的语言会自动保存到localStorage', hasLocalStorage ? '✅ 浏览器存储可用,支持语言偏好持久化' : '⚠️ 浏览器存储不可用,语言选择不会持久化', hasSvelte ? '✅ Svelte环境检测成功' : '⚠️ Svelte环境未检测到', isSSR ? '⚠️ SSR环境检测,部分功能受限' : '✅ 客户端环境检测成功', '💡 SvelteKit项目建议在onMount中初始化store' ] }; } // 浏览器版本标识 const __BROWSER_VERSION__ = true; /** * Standalone Svelte版本 - 完全自包含CDN友好版本 * * 🎯 基于 .ui18n 核心哲学的零配置Svelte集成 * * 特性: * - ✅ 零配置:自动检测和发现 .ui18n/languages.json * - ✅ 浏览器友好:localStorage 模拟 .ui18n 目录持久化 * - ✅ Svelte优化:原生支持reactive stores和组件 * - ✅ 一行可用:import即用,零配置开始 * - ✅ CDN友好:支持unpkg、jsDelivr等CDN直接引用 * * 使用场景: * - Svelte快速原型开发 * - 零构建环境 * - CDN直接使用 * - 演示和测试 */ // 重新导出所有浏览器优化的功能 /** * Standalone Svelte UI18N Store - 完全自包含版本 * * 自动遵循 .ui18n 核心哲学: * 1. 尝试从 /.ui18n/languages.json 发现可用语言 * 2. 使用 localStorage 模拟 .ui18n 目录进行持久化 * 3. 提供默认的Svelte reactive stores,零配置可用 */ function createStandaloneUI18nStore(config = {}) { const { enableUI18nDiscovery = true, ui18nDiscoveryPath = "/.ui18n/languages.json", enablePersistence = true, debug = false, defaultLanguage = "en", supportedLanguages: initialLanguages = ["en", "zh", "es", "fr", "de", "ja", "ko"] } = config; // 创建响应式stores const currentLanguage = writable(defaultLanguage); const supportedLanguages = writable(initialLanguages); const isLoading = writable(false); const isInitialized = writable(false); const translationCache = writable(new Map()); // 派生状态 const isReady = derived([isInitialized, isLoading], ([$isInitialized, $isLoading]) => $isInitialized && !$isLoading); // 初始化逻辑 let initPromise = null; const initialize = async () => { if (initPromise) return initPromise; initPromise = (async () => { try { isLoading.set(true); // 自动发现和恢复 await autoSetup(); // 标记为已初始化 isInitialized.set(true); if (debug) { console.log('[UI18N Svelte Standalone] Store已初始化,遵循.ui18n核心哲学 ✅', { ui18nDiscovery: enableUI18nDiscovery ? `启用 (${ui18nDiscoveryPath})` : '禁用', persistence: enablePersistence ? 'localStorage模拟.ui18n目录' : '禁用', version: 'standalone', compliance: '.ui18n核心哲学 ✅' }); } } catch (error) { console.error('[UI18N Svelte Standalone] 初始化失败:', error); } finally { isLoading.set(false); } })(); return initPromise; }; // 自动发现和恢复功能 const autoSetup = async () => { // 1. 尝试.ui18n发现 if (enableUI18nDiscovery && typeof fetch !== 'undefined') { try { const response = await fetch(ui18nDiscoveryPath); if (response.ok) { const discoveredConfig = await response.json(); if (discoveredConfig.languages && Array.isArray(discoveredConfig.languages)) { supportedLanguages.set(discoveredConfig.languages); if (debug) { console.log('[UI18N Svelte Standalone] 发现.ui18n配置:', discoveredConfig); } } } } catch (error) { if (debug) { console.warn('[UI18N Svelte Standalone] .ui18n发现失败,使用默认配置:', error); } } } // 2. 恢复之前保存的语言选择 if (enablePersistence && typeof localStorage !== 'undefined') { try { const saved = localStorage.getItem('ui18n_svelte_standalone_language'); if (saved && get(supportedLanguages).includes(saved)) { await setLanguage(saved); if (debug) { console.log(`[UI18N Svelte Standalone] 从localStorage恢复语言: ${saved}`); } } } catch (error) { if (debug) { console.warn('[UI18N Svelte Standalone] 恢复语言选择失败:', error); } } } }; // 设置语言 const setLanguage = async (language) => { currentLanguage.set(language); // 持久化到localStorage(模拟.ui18n目录) if (enablePersistence && typeof localStorage !== 'undefined') { try { localStorage.setItem('ui18n_svelte_standalone_language', language); if (debug) { console.log(`[UI18N Svelte Standalone] 语言已保存到 localStorage: ${language}`); } } catch (error) { if (debug) { console.warn('[UI18N Svelte Standalone] 保存语言选择失败:', error); } } } }; // 简化的翻译函数(基于缓存和本地规则) const translate = async (text, options) => { const targetLanguage = options?.language || get(currentLanguage); const cacheKey = `${text}_${targetLanguage}_${options?.context || ''}`; // 检查缓存 const cache = get(translationCache); if (cache.has(cacheKey)) { return cache.get(cacheKey); } // 简化的翻译逻辑(实际项目中会调用AI服务) let translated = text; // 基本语言标记处理 if (targetLanguage !== 'en' && text.includes('[')) { // 示例:处理 [Hello] 这样的标记 translated = text.replace(/\[([^\]]+)\]/g, (match, content) => { // 这里可以集成实际的翻译服务 return content; // 简化版本直接返回原内容 }); } // 缓存结果 const newCache = new Map(cache); newCache.set(cacheKey, translated); translationCache.set(newCache); return translated; }; // 自动初始化(如果在浏览器环境) if (typeof window !== 'undefined') { initialize(); } return { currentLanguage, supportedLanguages, isReady, isLoading, cache: derived(translationCache, $cache => $cache), setLanguage, translate, t: translate }; } /** * 全局standalone store实例 */ let globalStandaloneStore = null; /** * 设置全局standalone UI18N store */ function setGlobalStandaloneUI18nStore(store) { globalStandaloneStore = store; } /** * 获取全局standalone UI18N store */ function getGlobalStandaloneUI18nStore() { if (!globalStandaloneStore) { globalStandaloneStore = createStandaloneUI18nStore(); } return globalStandaloneStore; } /** * 便捷的翻译函数(使用全局standalone store) */ async function standaloneT(text, options) { const store = getGlobalStandaloneUI18nStore(); return store.translate(text, options); } // 默认导出为便于CDN使用 var standalone = { createStandaloneUI18nStore, setGlobalStandaloneUI18nStore, getGlobalStandaloneUI18nStore, standaloneT }; // 添加开发模式警告 if (typeof console !== 'undefined') { try { if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production') { console.warn('[@ui18n/svelte/standalone] ' + 'You are using the standalone version. ' + 'For production with bundlers, use the regular version to optimize bundle size.'); } } catch (e) { // process可能在某些环境中不可用,忽略错误 } } // 框架逻辑验证函数 function validateStandaloneSvelteFrameworkCompliance() { const hasLocalStorage = typeof localStorage !== 'undefined'; const hasSvelte = typeof writable !== 'undefined'; const isSSR = typeof window === 'undefined'; return { ui18nDirectory: true, // standalone版本默认支持.ui18n发现 svelteCompatibility: hasSvelte, browserSafe: true, zeroConfig: true, // 提供默认配置 persistence: hasLocalStorage, // localStorage模拟.ui18n目录 autoDiscovery: true, // 自动发现/.ui18n/languages.json reactiveStores: hasSvelte, ssrCompatible: true, recommendations: [ '✅ 使用 /.ui18n/languages.json 来定义可用语言', '✅ 选择的语言会自动保存到 localStorage', hasLocalStorage ? '✅ 浏览器存储可用,支持语言偏好持久化' : '⚠️ 浏览器存储不可用,语言选择不会持久化', hasSvelte ? '✅ Svelte环境检测成功' : '⚠️ Svelte环境未检测到', isSSR ? '⚠️ SSR环境检测,部分功能受限' : '✅ 客户端环境检测成功', '💡 生产环境建议使用常规版本配合构建工具' ] }; } // 为standalone版本添加特殊标识和元数据 const __STANDALONE_VERSION__ = true; const __FRAMEWORK_COMPLIANCE__ = { ui18nCorePhilosophy: true, svelteCompatible: true, reactiveStores: true, ssrCompatible: true, browserSafe: true, zeroConfig: true, selfContained: true }; export { __BROWSER_VERSION__, __FRAMEWORK_COMPLIANCE__, __STANDALONE_VERSION__, createBrowserUI18nStore, createStandaloneUI18nStore, createUI18nStore, createUseLanguageStore, createUseTranslationStore, standalone as default, getGlobalBrowserUI18nStore, getGlobalLanguageStore, getGlobalStandaloneUI18nStore, getGlobalTranslationStore, getGlobalUI18nStore, setGlobalBrowserUI18nStore, setGlobalLanguageStore, setGlobalStandaloneUI18nStore, setGlobalTranslationStore, setGlobalUI18nStore, standaloneT, t, t$1 as useTranslationT, validateStandaloneSvelteFrameworkCompliance, validateSvelteBrowserFrameworkCompliance };