Skip to content

Commit 3467418

Browse files
authored
ver: update to v1.8.72 (#36)
# v1.8.72(含迭代内容) ## 主要改动 ### 1. 功能增强 - ✅ 菜单功能完善 - 添加浏览器拓展右键菜单 - ✅ 重构 Service Worker 初始化逻辑: - **统一初始化入口**:创建了单一的 `initialize` 函数,用于处理扩展安装、浏览器启动和 Service Worker 意外重启时的状态恢复,确保了逻辑的一致性。 - **实现懒加载守卫**:引入 `ensureInitialized` 机制,在处理 `onMessage`、`onUpdated` 等事件前检查并确保初始化已完成,防止因 Service Worker 休眠后重启导致的状态丢失问题。 - ✅ 修复并发与竞态问题: - **引入互斥机制**:为 `updateHeaderRules` 添加 Promise 队列,确保规则更新操作串行执行,避免并发调用导致的状态不一致 - **防抖合并请求**:实现短时间内相同语言切换请求的自动合并,减少不必要的API调用和日志 - **优化缓存策略**:改进 `rulesCache` 机制,自动切换也能安全使用短路返回,因为规则仅由本扩展管理 - **状态同步增强**:确保 `lastAppliedLanguage` 和 `rulesCache` 在并发场景下的一致性 ### 2. 代码优化 - ✅ 清理无效代码 - 去除无效变量 err - ✅ 重构 createContextMenusOnce 使用 async/await(Promise API),符合代码规范 - ✅ 右键菜单统一使用英文,去除 i18n 化(简化实现) - ✅ 简化URL检查条件 - ✅ 优化动态规则ID数组创建逻辑,采用 `.some()` 方法以兼顾性能与代码表现力 - ✅ 将 `updateHeaderRules` 拆分为外部包装器和内部实现,提供更好的并发控制 - ✅ 修复重试逻辑中的递归调用问题,避免绕过并发控制机制,优化错误处理 - ✅ 优化按钮代码 - ✅ 优化 Chrome API 调用方式,移除不必要的 Promise 包装,直接使用 async/await - ✅ 重构调试 UI 的代码结构,将回调函数改为 async/await 方式,调整了部分变量和函数的命名,移除冗余的代码 ### 3. Bug 修复 - ✅ 修复 `tabs.onUpdated` 过滤条件 Bug,该 Bug 会导致 http 页面不触发自动切换 - ✅ 修复动态规则清理范围过宽问题,现在只移除与 `RULE_ID` 相关的规则,避免误删其他动态规则。 ## 文件变更清单 ### 新增文件 - Problems.md - LLM整理的现存问题(v1.8.67) - Wiki_EN.md - 英文版Wiki(v1.8.69) ### 重命名文件 - ### 修改文件 - manifest.json - 版本号更新(v1.8.67、v1.8.68、v1.8.69、v1.8.70、v1.8.71、v1.8.72);添加 contextMenus 权限(v1.8.67) - TODO.md - 修改待办事项(v1.8.67) - Update.md - 版本更新记录(v1.8.67、v1.8.68、v1.8.69、v1.8.70、v1.8.71、v1.8.72) - background.js - 添加右键菜单初始化标志(v1.8.67);重构 contextMenus 创建逻辑(async/await),右键菜单统一使用英文,去除 i18n 化(v1.8.68);修复 `tabs.onUpdated` 的 URL 过滤条件 Bug(v1.8.68);简化URL检查条件(v1.8.68);重构了初始化和事件处理逻辑(v1.8.69);修复动态规则清理范围过宽问题(v1.8.70);优化动态规则ID数组创建逻辑(v1.8.70);引入并发控制机制,添加 Promise 队列和防抖机制,修复并发与竞态问题(v1.8.71) - shared-i18n-base.js - 优化翻译加载机制,避免重复加载脚本文件,完善翻译回退(v1.8.68) - I18n_Usage_Guide.md - 内容更新(v1.8.67、v1.8.68) - .gitignore - git忽略文件更新(v1.8.67) - Problems.md - 问题列表更新(v1.8.68、v1.8.69、v1.8.70) - Wiki.md - Wiki更新(v1.8.69、v1.8.70) - Wiki_EN.md - 英文Wiki更新(v1.8.70) - i18n/background-*.js - 完善相关翻译(v1.8.71) - toggle.js - 优化按钮代码(v1.8.71) - popup.js - 优化 Chrome API 调用方式,直接使用 async/await(v1.8.72) - debug-ui.js - 优化代码结构,将回调函数改为 async/await 方式,调整了部分变量和函数的命名,移除冗余的代码(v1.8.72) - shared-utils.js - 完善fallback翻译键(v1.8.72) - Code_Style_Guide.md - 代码风格指南更新(v1.8.72) ### 移除内容 - 移除未使用的变量 chrome.runtime.lastError 读取语句 - 已完成的TODO / 已修复的问题 - 将 `performInitialization` 和 `handleAutoSwitchToggleRequest` 中的重复规则应用逻辑提取到新的共享函数 `applyLanguageRulesBasedOnState` 中 - 移除大量prromise包装
2 parents 93f17a9 + e104624 commit 3467418

8 files changed

Lines changed: 430 additions & 381 deletions

File tree

debug-ui.js

Lines changed: 305 additions & 288 deletions
Large diffs are not rendered by default.

docs/Code_Style_Guide.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,21 @@ console.log(`${i18n ? i18n.t('cache_preloaded') : 'Cache preloaded'}`);
966966
### 2. Chrome Extension API 使用
967967
968968
```javascript
969-
// 使用 Promise 包装 Chrome API
970-
const getChromeStorageData = (keys) => {
971-
return new Promise((resolve) => {
972-
chrome.storage.local.get(keys, resolve);
969+
// ✅ 推荐:直接使用 Promise 风格(Manifest V3 支持)
970+
const getChromeStorageData = async (keys) => {
971+
return await chrome.storage.local.get(keys);
972+
};
973+
974+
// ❌ 避免:基于回调的 Promise 包装(除非必要)
975+
const getChromeStorageDataOld = (keys) => {
976+
return new Promise((resolve, reject) => {
977+
chrome.storage.local.get(keys, (result) => {
978+
if (chrome.runtime.lastError) {
979+
reject(new Error(chrome.runtime.lastError.message));
980+
} else {
981+
resolve(result);
982+
}
983+
});
973984
});
974985
};
975986

docs/Update.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# v1.8.71(含迭代内容)
1+
# v1.8.72(含迭代内容)
22

33
## 主要改动
44

@@ -24,6 +24,8 @@
2424
- ✅ 将 `updateHeaderRules` 拆分为外部包装器和内部实现,提供更好的并发控制
2525
- ✅ 修复重试逻辑中的递归调用问题,避免绕过并发控制机制,优化错误处理
2626
- ✅ 优化按钮代码
27+
- ✅ 优化 Chrome API 调用方式,移除不必要的 Promise 包装,直接使用 async/await
28+
- ✅ 重构调试 UI 的代码结构,将回调函数改为 async/await 方式,调整了部分变量和函数的命名,移除冗余的代码
2729

2830
### 3. Bug 修复
2931

@@ -43,9 +45,9 @@
4345

4446
### 修改文件
4547

46-
- manifest.json - 版本号更新(v1.8.67、v1.8.68、v1.8.69、v1.8.70、v1.8.71);添加 contextMenus 权限(v1.8.67)
48+
- manifest.json - 版本号更新(v1.8.67、v1.8.68、v1.8.69、v1.8.70、v1.8.71、v1.8.72);添加 contextMenus 权限(v1.8.67)
4749
- TODO.md - 修改待办事项(v1.8.67)
48-
- Update.md - 版本更新记录(v1.8.67、v1.8.68、v1.8.69、v1.8.70、v1.8.71)
50+
- Update.md - 版本更新记录(v1.8.67、v1.8.68、v1.8.69、v1.8.70、v1.8.71、v1.8.72
4951
- background.js - 添加右键菜单初始化标志(v1.8.67);重构 contextMenus 创建逻辑(async/await),右键菜单统一使用英文,去除 i18n 化(v1.8.68);修复 `tabs.onUpdated` 的 URL 过滤条件 Bug(v1.8.68);简化URL检查条件(v1.8.68);重构了初始化和事件处理逻辑(v1.8.69);修复动态规则清理范围过宽问题(v1.8.70);优化动态规则ID数组创建逻辑(v1.8.70);引入并发控制机制,添加 Promise 队列和防抖机制,修复并发与竞态问题(v1.8.71)
5052
- shared-i18n-base.js - 优化翻译加载机制,避免重复加载脚本文件,完善翻译回退(v1.8.68)
5153
- I18n_Usage_Guide.md - 内容更新(v1.8.67、v1.8.68)
@@ -55,9 +57,14 @@
5557
- Wiki_EN.md - 英文Wiki更新(v1.8.70)
5658
- i18n/background-*.js - 完善相关翻译(v1.8.71)
5759
- toggle.js - 优化按钮代码(v1.8.71)
60+
- popup.js - 优化 Chrome API 调用方式,直接使用 async/await(v1.8.72)
61+
- debug-ui.js - 优化代码结构,将回调函数改为 async/await 方式,调整了部分变量和函数的命名,移除冗余的代码(v1.8.72)
62+
- shared-utils.js - 完善fallback翻译键(v1.8.72)
63+
- Code_Style_Guide.md - 代码风格指南更新(v1.8.72)
5864

5965
### 移除内容
6066

6167
- 移除未使用的变量 chrome.runtime.lastError 读取语句
6268
- 已完成的TODO / 已修复的问题
63-
-`performInitialization``handleAutoSwitchToggleRequest` 中的重复规则应用逻辑提取到新的共享函数 `applyLanguageRulesBasedOnState`
69+
-`performInitialization``handleAutoSwitchToggleRequest` 中的重复规则应用逻辑提取到新的共享函数 `applyLanguageRulesBasedOnState`
70+
- 移除大量prromise包装

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "MultiLangSwitcher",
4-
"version": "1.8.71",
4+
"version": "1.8.72",
55
"minimum_chrome_version": "88.0",
66
"description": "__MSG_extension_description__",
77
"default_locale": "zh",

popup.js

Lines changed: 35 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -156,18 +156,10 @@ const updateHeaderRules = async (language, autoCheck = false) => {
156156
const cleanLanguage = language.trim();
157157
sendDebugLog(`${popupI18n.t('trying_to_update_rules')} ${cleanLanguage}. ${popupI18n.t('auto_check')} ${autoCheck}.`, 'info');
158158

159-
// 使用Promise包装Chrome API调用
160-
const response = await new Promise((resolve, reject) => {
161-
chrome.runtime.sendMessage({
162-
type: 'UPDATE_RULES',
163-
language: cleanLanguage
164-
}, response => {
165-
if (chrome.runtime.lastError) {
166-
reject(new Error(chrome.runtime.lastError.message));
167-
return;
168-
}
169-
resolve(response);
170-
});
159+
// 使用直接的Promise调用
160+
const response = await chrome.runtime.sendMessage({
161+
type: 'UPDATE_RULES',
162+
language: cleanLanguage
171163
});
172164

173165
// 处理响应结果
@@ -357,15 +349,7 @@ const getCurrentLanguage = async () => {
357349
*/
358350
const getLanguageFromBackground = async () => {
359351
try {
360-
const response = await new Promise((resolve, reject) => {
361-
chrome.runtime.sendMessage({ type: 'GET_CURRENT_LANG' }, response => {
362-
if (chrome.runtime.lastError) {
363-
reject(new Error(chrome.runtime.lastError.message));
364-
return;
365-
}
366-
resolve(response);
367-
});
368-
});
352+
const response = await chrome.runtime.sendMessage({ type: 'GET_CURRENT_LANG' });
369353

370354
if (response?.currentLanguage) {
371355
sendDebugLog(popupI18n.t('get_current_language_from_background', { language: response.currentLanguage }), 'info');
@@ -385,19 +369,11 @@ const getLanguageFromBackground = async () => {
385369
*/
386370
const getLanguageFromStorage = async () => {
387371
try {
388-
const result = await new Promise((resolve, reject) => {
389-
chrome.runtime.sendMessage({ type: 'GET_STORAGE_DATA', keys: ['currentLanguage'] }, (result) => {
390-
if (chrome.runtime.lastError) {
391-
reject(new Error(chrome.runtime.lastError.message));
392-
return;
393-
}
394-
resolve(result);
395-
});
396-
});
372+
const result = await chrome.runtime.sendMessage({ type: 'GET_STORAGE_DATA', keys: ['currentLanguage'] });
397373

398-
if (result?.currentLanguage) {
399-
sendDebugLog(`${popupI18n.t('loaded_stored_language')} ${result.currentLanguage}.`, 'info');
400-
return result.currentLanguage;
374+
if (result?.data?.currentLanguage) {
375+
sendDebugLog(`${popupI18n.t('loaded_stored_language')} ${result.data.currentLanguage}.`, 'info');
376+
return result.data.currentLanguage;
401377
}
402378

403379
return null;
@@ -425,16 +401,8 @@ const getDefaultLanguage = () => {
425401
const getAutoSwitchStatus = async () => {
426402
try {
427403
// 从本地存储获取自动切换状态
428-
const result = await new Promise((resolve, reject) => {
429-
chrome.runtime.sendMessage({ type: 'GET_STORAGE_DATA', keys: ['autoSwitchEnabled'] }, (result) => {
430-
if (chrome.runtime.lastError) {
431-
reject(new Error(chrome.runtime.lastError.message));
432-
return;
433-
}
434-
resolve(result);
435-
});
436-
});
437-
return !!result.autoSwitchEnabled;
404+
const result = await chrome.runtime.sendMessage({ type: 'GET_STORAGE_DATA', keys: ['autoSwitchEnabled'] });
405+
return !!result.data?.autoSwitchEnabled;
438406
} catch (error) {
439407
sendDebugLog(popupI18n.t('error_getting_auto_switch_status', { message: error.message }), 'error');
440408
return false; // 默认返回false
@@ -449,23 +417,26 @@ const getAutoSwitchStatus = async () => {
449417
const setAutoSwitchStatus = async (enabled) => {
450418
try {
451419
// 保存自动切换状态到本地存储
452-
await new Promise((resolve, reject) => {
453-
chrome.runtime.sendMessage({ type: 'SET_STORAGE_DATA', data: { autoSwitchEnabled: enabled } }, (response) => {
454-
if (chrome.runtime.lastError) {
455-
reject(new Error(chrome.runtime.lastError.message));
456-
return;
457-
}
458-
resolve();
459-
});
460-
});
420+
await chrome.runtime.sendMessage({ type: 'SET_STORAGE_DATA', data: { autoSwitchEnabled: enabled } });
461421

462422
// 记录状态变更日志
463423
sendDebugLog(`${popupI18n.t('auto_switch_status_saved')} ${enabled ? popupI18n.t('enabled') : popupI18n.t('disabled')}.`, 'info');
464424

465425
// 通知background脚本状态变更
466-
chrome.runtime.sendMessage({ type: 'AUTO_SWITCH_TOGGLED', enabled: enabled }).catch((notifyError) => {
467-
sendDebugLog(`${popupI18n.t('failed_notify_background')}: ${notifyError.message}`, 'warning');
468-
});
426+
// 注意:此处使用 IIFE (立即调用函数表达式) 写法虽然可以实现"即发即弃"的异步调用,
427+
// 但略显冗余。可以直接调用 chrome.runtime.sendMessage 并链式附加 .catch() 来处理错误,
428+
// 这样代码会更简洁清晰:
429+
// chrome.runtime.sendMessage({ type: 'AUTO_SWITCH_TOGGLED', enabled: enabled })
430+
// .catch(notifyError => {
431+
// sendDebugLog(`${popupI18n.t('failed_notify_background')}: ${notifyError.message}`, 'warning');
432+
// });
433+
(async () => {
434+
try {
435+
await chrome.runtime.sendMessage({ type: 'AUTO_SWITCH_TOGGLED', enabled: enabled });
436+
} catch (notifyError) {
437+
sendDebugLog(`${popupI18n.t('failed_notify_background')}: ${notifyError.message}`, 'warning');
438+
}
439+
})();
469440

470441
return true;
471442
} catch (error) {
@@ -479,7 +450,7 @@ const setAutoSwitchStatus = async (enabled) => {
479450
/**
480451
* 保存当前语言设置
481452
* @param {string} language - 语言代码
482-
* @returns {Promise<void>}
453+
* @returns {Promise<void>}
483454
*/
484455
const saveLanguageSetting = async (language) => {
485456
// 验证输入
@@ -488,15 +459,7 @@ const saveLanguageSetting = async (language) => {
488459
}
489460

490461
// 保存语言设置到本地存储
491-
await new Promise((resolve, reject) => {
492-
chrome.runtime.sendMessage({ type: 'SET_STORAGE_DATA', data: { currentLanguage: language } }, (response) => {
493-
if (chrome.runtime.lastError) {
494-
reject(new Error(chrome.runtime.lastError.message));
495-
return;
496-
}
497-
resolve();
498-
});
499-
});
462+
await chrome.runtime.sendMessage({ type: 'SET_STORAGE_DATA', data: { currentLanguage: language } });
500463

501464
sendDebugLog(`${popupI18n.t('language_settings_saved')} ${language}.`, 'info');
502465
};
@@ -1262,14 +1225,13 @@ document.addEventListener('DOMContentLoaded', async () => {
12621225
* 同步自动切换状态到本地存储
12631226
* @param {boolean} autoSwitchEnabled - 自动切换是否启用
12641227
*/
1265-
const syncAutoSwitchStatusToStorage = (autoSwitchEnabled) => {
1266-
chrome.runtime.sendMessage({ type: 'SET_STORAGE_DATA', data: { autoSwitchEnabled } }, (response) => {
1267-
if (chrome.runtime.lastError) {
1268-
sendDebugLog(popupI18n.t('update_storage_status_failed', { message: chrome.runtime.lastError.message }), 'error');
1269-
} else {
1270-
sendDebugLog(popupI18n.t('synced_auto_switch_status_to_storage', { status: autoSwitchEnabled }), 'info');
1271-
}
1272-
});
1228+
const syncAutoSwitchStatusToStorage = async (autoSwitchEnabled) => {
1229+
try {
1230+
await chrome.runtime.sendMessage({ type: 'SET_STORAGE_DATA', data: { autoSwitchEnabled } });
1231+
sendDebugLog(popupI18n.t('synced_auto_switch_status_to_storage', { status: autoSwitchEnabled }), 'info');
1232+
} catch (error) {
1233+
sendDebugLog(popupI18n.t('update_storage_status_failed', { message: error.message }), 'error');
1234+
}
12731235
};
12741236

12751237
/**

shared/shared-actions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212
const resetAcceptLanguage = async () => {
1313
try {
14-
// 早期返回模式 - 检查 Chrome API 可用性
14+
// 检查 Chrome API 可用性
1515
if (!chrome?.runtime?.sendMessage) {
1616
throw new Error('Chrome runtime API is not available');
1717
}
@@ -27,7 +27,7 @@ const resetAcceptLanguage = async () => {
2727
});
2828
});
2929

30-
// 早期返回模式 - 验证响应状态
30+
// 验证响应状态
3131
if (response?.status === 'success') {
3232
// 记录成功日志
3333
if (typeof sendDebugLog === 'function') {

shared/shared-language-options.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ const generateLanguageOptions = (selectedValue = null) => {
120120
* @param {string|null} selectedValue - 要选中的语言值
121121
*/
122122
const populateLanguageSelect = (selectElement, selectedValue = null) => {
123-
// 早期返回 - 验证必需参数和类型
123+
// 验证必需参数和类型
124124
if (!selectElement || !(selectElement instanceof HTMLElement)) return;
125125

126126
selectElement.innerHTML = generateLanguageOptions(selectedValue);

shared/shared-utils.js

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* @param {string} logType - 日志类型 (info, warning, error, success)
1010
*/
1111
const sendDebugLog = (message, logType = 'info') => {
12-
// 早期返回模式 - 验证输入
12+
// 验证输入
1313
if (!message) return;
1414

1515
try {
@@ -192,6 +192,7 @@ const getFallbackTranslation = (key, params = {}) => {
192192
// 完整的 fallback 翻译
193193
const fallbackTranslations = {
194194
en: {
195+
// Update checker related keys
195196
'check_for_updates': 'Check for updates',
196197
'checking_updates': 'Checking for updates...',
197198
'update_available': 'Update available: v{version}',
@@ -206,6 +207,31 @@ const getFallbackTranslation = (key, params = {}) => {
206207
'invalid_response': 'Invalid response from server',
207208
'update_check_success': 'Update check completed successfully',
208209
'update_notification_title': 'Extension Update Available',
210+
'using_persistent_cached_update_info': 'Using persistent cached update information',
211+
'update_check_completed': 'Update check completed. Update available: {updateAvailable}',
212+
'update_check_cancelled': 'Update check was cancelled',
213+
'update_check_attempt': 'Update check attempt {attempt}/{maxAttempts}',
214+
'update_check_succeeded_on_attempt': 'Update check succeeded on attempt {attempt}',
215+
'version_comparison_failed': 'Version comparison failed: {error}',
216+
'error_details': 'Error details - Type: {type}, Original: {message}, Stack: {stack}',
217+
'update_check_failed_after_attempts': 'Update check failed after {attempt} attempts. Error: {error}',
218+
'update_check_retry_delay': 'Update check attempt {attempt} failed ({error}), retrying in {delay}ms...',
219+
'update_info_cached_persistently': 'Update information cached persistently',
220+
'failed_cache_update_info': 'Failed to cache update info persistently: {error}',
221+
'invalid_persistent_cache_structure': 'Invalid persistent cache structure, clearing',
222+
'persistent_cache_different_version': 'Persistent cache is for different version, clearing',
223+
'persistent_cache_expired': 'Persistent cache expired, clearing',
224+
'failed_load_persistent_cache': 'Failed to load persistent cache: {error}',
225+
'persistent_cache_cleared': 'Persistent cache cleared',
226+
'failed_clear_persistent_cache': 'Failed to clear persistent cache: {error}',
227+
'update_checker_cache_cleared': 'Update checker cache cleared',
228+
'error_getting_cache_status': 'Error getting persistent cache status: {error}',
229+
'expired_memory_cache_cleaned': 'Expired memory cache cleaned up',
230+
'persistent_cache_optimization_completed': 'Persistent cache optimization completed - no cleanup needed',
231+
'cache_optimization_failed': 'Cache optimization failed: {error}',
232+
'cache_preload_failed': 'Cache preload failed: {error}',
233+
'providing_graceful_fallback': 'Providing graceful fallback for update check',
234+
'using_graceful_fallback': 'Using graceful fallback due to {error}',
209235
'update_check_initiated': 'Update check initiated for repository: {repo}',
210236
'update_check_api_request': 'Making API request to GitHub releases endpoint',
211237
'update_check_network_error': 'Network error during update check: {error}',
@@ -282,20 +308,46 @@ const getFallbackTranslation = (key, params = {}) => {
282308
'debug_log_started': 'Debug log started'
283309
},
284310
zh: {
311+
// Update checker related keys
285312
'check_for_updates': '检查更新',
286313
'checking_updates': '正在检查更新...',
287-
'update_available': '发现可用更新: v{version}',
314+
'update_available': '发现新版本: v{version}',
288315
'no_updates_available': '您正在使用最新版本',
289-
'current_version': '当前: v{current}',
290-
'latest_version': '最新: v{latest}',
291-
'view_release': '查看发布',
316+
'current_version': '当前版本: v{current}',
317+
'latest_version': '最新版本: v{latest}',
318+
'view_release': '查看发布页面',
292319
'download_update': '下载更新',
293320
'update_check_failed': '检查更新失败',
294-
'network_error': '发生网络错误',
295-
'rate_limit_exceeded': '请求频率超限,请稍后重试',
321+
'network_error': '网络错误',
322+
'rate_limit_exceeded': '请求频率超限,请稍后再试',
296323
'invalid_response': '服务器响应无效',
297-
'update_check_success': '更新检查成功完成',
324+
'update_check_success': '更新检查完成',
298325
'update_notification_title': '扩展更新可用',
326+
'using_persistent_cached_update_info': '使用持久化缓存的更新信息',
327+
'update_check_completed': '更新检查完成。有可用更新: {updateAvailable}',
328+
'update_check_cancelled': '更新检查已取消',
329+
'update_check_attempt': '更新检查尝试 {attempt}/{maxAttempts}',
330+
'update_check_succeeded_on_attempt': '更新检查在第 {attempt} 次尝试时成功',
331+
'version_comparison_failed': '版本比较失败: {error}',
332+
'error_details': '错误详情 - 类型: {type}, 原始: {message}, 堆栈: {stack}',
333+
'update_check_failed_after_attempts': '更新检查在 {attempt} 次尝试后失败。错误: {error}',
334+
'update_check_retry_delay': '更新检查第 {attempt} 次尝试失败 ({error}),将在 {delay}ms 后重试...',
335+
'update_info_cached_persistently': '更新信息已持久化缓存',
336+
'failed_cache_update_info': '持久化缓存更新信息失败: {error}',
337+
'invalid_persistent_cache_structure': '持久化缓存结构无效,正在清除',
338+
'persistent_cache_different_version': '持久化缓存版本不同,正在清除',
339+
'persistent_cache_expired': '持久化缓存已过期,正在清除',
340+
'failed_load_persistent_cache': '加载持久化缓存失败: {error}',
341+
'persistent_cache_cleared': '持久化缓存已清除',
342+
'failed_clear_persistent_cache': '清除持久化缓存失败: {error}',
343+
'update_checker_cache_cleared': '更新检查器缓存已清除',
344+
'error_getting_cache_status': '获取持久化缓存状态时出错: {error}',
345+
'expired_memory_cache_cleaned': '过期内存缓存已清理',
346+
'persistent_cache_optimization_completed': '持久化缓存优化完成 - 无需清理',
347+
'cache_optimization_failed': '缓存优化失败: {error}',
348+
'cache_preload_failed': '缓存预加载失败: {error}',
349+
'providing_graceful_fallback': '为更新检查提供优雅降级',
350+
'using_graceful_fallback': '由于 {error} 使用优雅降级',
299351
'update_check_initiated': '为仓库启动更新检查: {repo}',
300352
'update_check_api_request': '向 GitHub releases 端点发起 API 请求',
301353
'update_check_network_error': '更新检查时发生网络错误: {error}',

0 commit comments

Comments
 (0)