@ui18n/svelte
Version:
🧡 Lightning-fast Svelte internationalization with reactive stores, SvelteKit support, and zero-bundle overhead
797 lines (790 loc) • 28.7 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ui18n/core'), require('svelte/store')) :
typeof define === 'function' && define.amd ? define(['exports', '@ui18n/core', 'svelte/store'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.UI18nSvelte = {}, global.UI18nCore, global.svelteStore));
})(this, (function (exports, core, store) { 'use strict';
/**
* 创建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;
Object.defineProperty(exports, '__esModule', { value: true });
}));