chore: bump version to 0.5.25
This commit is contained in:
1 parent
5571d3f1d9
commit
8bd7f30c19
8 files changed
+173
-22
No files matched your search
@@ -1 +1,4 @@
|
||||
legacy-peer-deps=true
|
||||
|
||||
# 发布使用官方 npm registry
|
||||
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
||||
@@ -1,3 +1,26 @@
|
||||
## 0.5.23 (2026-01-20)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- 优化素材库 UI 交互、缩放缓存、Grid 布局及空间效率 ([c64e4a7](https://github.com/ljquan/aitu/commit/c64e4a7))
|
||||
|
||||
### 🔧 Chores
|
||||
|
||||
- bump version to 0.5.22 ([5571d3f](https://github.com/ljquan/aitu/commit/5571d3f))
|
||||
- bump version to 0.5.21 ([55ad29c](https://github.com/ljquan/aitu/commit/55ad29c))
|
||||
- bump version to 0.5.20 ([8bfc191](https://github.com/ljquan/aitu/commit/8bfc191))
|
||||
- bump version to 0.5.19 ([8707a5b](https://github.com/ljquan/aitu/commit/8707a5b))
|
||||
- bump version to 0.5.18 ([88c0dfd](https://github.com/ljquan/aitu/commit/88c0dfd))
|
||||
- bump version to 0.5.17 ([91799c9](https://github.com/ljquan/aitu/commit/91799c9))
|
||||
- bump version to 0.5.17 and update build time in version.json ([51b5f3f](https://github.com/ljquan/aitu/commit/51b5f3f))
|
||||
- bump version to 0.5.17 ([c41c9bd](https://github.com/ljquan/aitu/commit/c41c9bd))
|
||||
- docs(claude): 更新调试日志处理和命令行工具使用说明,添加后台清理任务日志记录示例 ([30cf458](https://github.com/ljquan/aitu/commit/30cf458))
|
||||
- docs(claude): 添加 React 事件委托、筛选逻辑、Grid 布局及 UI 高度统一规则 ([dcabd75](https://github.com/ljquan/aitu/commit/dcabd75))
|
||||
|
||||
### ❤️ Thank You
|
||||
|
||||
- liquidliang <ljquan@qq.com>
|
||||
|
||||
## 0.5.17 (2026-01-20)
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
+4
-1
@@ -61,7 +61,7 @@
|
||||
</script>
|
||||
<!-- base href 由构建工具处理,CDN 模式下使用相对路径 -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||
<meta name="app-version" content="0.5.17" />
|
||||
<meta name="app-version" content="0.5.24" />
|
||||
|
||||
<link rel="icon" type="image/svg+xml" sizes="16x16" href="./icons/favicon-16x16.svg" />
|
||||
<link rel="icon" type="image/svg+xml" sizes="32x32" href="./icons/favicon-32x32.svg" />
|
||||
@@ -88,6 +88,9 @@
|
||||
<meta name="msapplication-square310x310logo" content="./icons/icon-512x512.svg" />
|
||||
|
||||
<link rel="stylesheet" href="./src/styles.scss" />
|
||||
|
||||
<!-- CDN 智能选择器(可选,用于提前检测最佳 CDN) -->
|
||||
<script src="./cdn-config.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
{
|
||||
"version": "0.5.22",
|
||||
"buildTime": "2026-01-20T04:55:16.014Z",
|
||||
"version": "0.5.25",
|
||||
"buildTime": "2026-01-20T05:11:17.776Z",
|
||||
"gitCommit": "unknown",
|
||||
"changelog": [
|
||||
"优化素材库 UI 交互、缩放缓存、Grid 布局及空间效率",
|
||||
"封装函数不应被绕过、页面卸载清理定时器"
|
||||
]
|
||||
"changelog": []
|
||||
}
|
||||
@@ -52,8 +52,10 @@ const CDN_CONFIG = {
|
||||
degradeTimeout: 60 * 1000,
|
||||
// 连续失败次数阈值
|
||||
failThreshold: 3,
|
||||
// 请求超时(毫秒)
|
||||
fetchTimeout: 10000,
|
||||
// 请求超时(毫秒)- 短超时策略:
|
||||
// CDN 缓存命中通常 < 200ms,设置 1.5s 超时
|
||||
// 超时后快速回退到服务器,避免 CDN 回源慢影响用户体验
|
||||
fetchTimeout: 1500,
|
||||
};
|
||||
|
||||
// CDN 源列表(按优先级排序)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/// <reference lib="webworker" />
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
// fix: self redeclaration error and type casting
|
||||
const sw = self as unknown as ServiceWorkerGlobalScope;
|
||||
export { }; // Make this a module
|
||||
|
||||
// Import task queue module
|
||||
import {
|
||||
initTaskQueue,
|
||||
@@ -33,9 +29,17 @@ import {
|
||||
initMessageSender,
|
||||
setDebugMode as setMessageSenderDebugMode,
|
||||
setBroadcastCallback,
|
||||
sendToClient,
|
||||
broadcastToAllClients,
|
||||
} from './task-queue/utils/message-bus';
|
||||
import {
|
||||
fetchFromCDNWithFallback,
|
||||
getCDNStatusReport,
|
||||
resetCDNStatus,
|
||||
performHealthCheck,
|
||||
} from './cdn-fallback';
|
||||
|
||||
// fix: self redeclaration error and type casting
|
||||
const sw = self as unknown as ServiceWorkerGlobalScope;
|
||||
export { }; // Make this a module
|
||||
|
||||
// Initialize task queue (instance used internally by handleTaskQueueMessage)
|
||||
initTaskQueue(sw);
|
||||
@@ -1404,6 +1408,27 @@ sw.addEventListener('message', (event: ExtendableMessageEvent) => {
|
||||
event.source?.postMessage({
|
||||
type: 'SW_DEBUG_LOGS_CLEARED',
|
||||
});
|
||||
} else if (event.data && event.data.type === 'SW_CDN_GET_STATUS') {
|
||||
// 获取 CDN 状态
|
||||
event.source?.postMessage({
|
||||
type: 'SW_CDN_STATUS',
|
||||
status: getCDNStatusReport(),
|
||||
});
|
||||
} else if (event.data && event.data.type === 'SW_CDN_RESET_STATUS') {
|
||||
// 重置 CDN 状态
|
||||
resetCDNStatus();
|
||||
event.source?.postMessage({
|
||||
type: 'SW_CDN_STATUS_RESET',
|
||||
});
|
||||
} else if (event.data && event.data.type === 'SW_CDN_HEALTH_CHECK') {
|
||||
// 执行 CDN 健康检查
|
||||
(async () => {
|
||||
const results = await performHealthCheck(APP_VERSION);
|
||||
event.source?.postMessage({
|
||||
type: 'SW_CDN_HEALTH_CHECK_RESULT',
|
||||
results: Object.fromEntries(results),
|
||||
});
|
||||
})();
|
||||
} else if (event.data && event.data.type === 'SW_DEBUG_GET_CACHE_ENTRIES') {
|
||||
// 获取缓存条目列表
|
||||
const { cacheName, limit = 50, offset = 0 } = event.data;
|
||||
@@ -3086,7 +3111,42 @@ async function handleStaticRequest(request: Request): Promise<Response> {
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
// Cache miss - try network
|
||||
// Cache miss - determine if this is a CDN-cacheable static resource
|
||||
const resourcePath = url.pathname;
|
||||
const isStaticResource = !isDevelopment && (
|
||||
resourcePath.match(/\.(js|css|png|jpg|jpeg|gif|webp|svg|woff|woff2|ttf|eot|json|ico)$/i) ||
|
||||
request.destination === 'script' ||
|
||||
request.destination === 'style' ||
|
||||
request.destination === 'image' ||
|
||||
request.destination === 'font'
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// CDN 优先策略:暂时禁用,等 npm 包发布后再启用
|
||||
// TODO: npm publish aitu-app 后取消注释下面的代码
|
||||
// ============================================
|
||||
// if (isStaticResource) {
|
||||
// try {
|
||||
// console.log(`[SW CDN] Trying CDN first for: ${resourcePath}`);
|
||||
// const cdnResult = await fetchFromCDNWithFallback(
|
||||
// resourcePath,
|
||||
// APP_VERSION,
|
||||
// location.origin
|
||||
// );
|
||||
//
|
||||
// if (cdnResult && cdnResult.response.ok) {
|
||||
// console.log(`[SW CDN] Success from ${cdnResult.source}: ${resourcePath}`);
|
||||
// // 缓存成功的响应
|
||||
// const responseToCache = cdnResult.response.clone();
|
||||
// cache.put(request, responseToCache);
|
||||
// return cdnResult.response;
|
||||
// }
|
||||
// } catch (cdnError) {
|
||||
// console.warn('[SW CDN] CDN sources failed, trying local server:', cdnError);
|
||||
// }
|
||||
// }
|
||||
|
||||
// 回退到本地服务器(开发模式或 CDN 失败)
|
||||
try {
|
||||
const response = await fetchQuick(request);
|
||||
|
||||
@@ -3134,7 +3194,7 @@ async function handleStaticRequest(request: Request): Promise<Response> {
|
||||
|
||||
return response;
|
||||
} catch (networkError) {
|
||||
console.error('Static resource unavailable:', request.url);
|
||||
console.warn('[SW] Network failed, trying old caches:', request.url);
|
||||
|
||||
// Try to find the resource in any cache (including old version caches)
|
||||
const allCacheNames = await caches.keys();
|
||||
@@ -3144,7 +3204,7 @@ async function handleStaticRequest(request: Request): Promise<Response> {
|
||||
const oldCache = await caches.open(cacheName);
|
||||
const oldCachedResponse = await oldCache.match(request);
|
||||
if (oldCachedResponse) {
|
||||
// console.log(`Service Worker: Found resource in ${cacheName} after network failure`);
|
||||
console.log(`[SW] Found resource in ${cacheName} after network failure`);
|
||||
return oldCachedResponse;
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -3153,6 +3213,7 @@ async function handleStaticRequest(request: Request): Promise<Response> {
|
||||
}
|
||||
}
|
||||
|
||||
// 所有来源都失败了
|
||||
return new Response('Resource unavailable offline', {
|
||||
status: 503,
|
||||
statusText: 'Service Unavailable',
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@aitu/source",
|
||||
"version": "0.5.22",
|
||||
"version": "0.5.25",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.21.0",
|
||||
"description": "Aitu - An open-source whiteboard tool with AI-powered image/video creation, mind mapping, flowcharts, and freehand drawing",
|
||||
|
||||
@@ -132,6 +132,7 @@ function waitForIdle(timeout = 50): Promise<void> {
|
||||
async function detectDatabaseVersion(dbName: string): Promise<number> {
|
||||
return new Promise((resolve) => {
|
||||
if (typeof indexedDB === 'undefined') {
|
||||
console.warn('[WorkspaceStorage] IndexedDB not available, using min version');
|
||||
resolve(WORKSPACE_DB_CONFIG.MIN_DATABASE_VERSION);
|
||||
return;
|
||||
}
|
||||
@@ -143,11 +144,22 @@ async function detectDatabaseVersion(dbName: string): Promise<number> {
|
||||
const db = request.result;
|
||||
const version = db.version;
|
||||
db.close();
|
||||
resolve(Math.max(version, WORKSPACE_DB_CONFIG.MIN_DATABASE_VERSION));
|
||||
const targetVersion = Math.max(version, WORKSPACE_DB_CONFIG.MIN_DATABASE_VERSION);
|
||||
console.log(`[WorkspaceStorage] Detected DB version: ${version}, using: ${targetVersion}`);
|
||||
resolve(targetVersion);
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
resolve(WORKSPACE_DB_CONFIG.MIN_DATABASE_VERSION);
|
||||
request.onerror = (event) => {
|
||||
// Try to get version from error event or use a safe high version
|
||||
console.error('[WorkspaceStorage] Error detecting DB version:', event);
|
||||
// Use a higher version to avoid downgrade - version 10 should be safe
|
||||
resolve(10);
|
||||
};
|
||||
|
||||
request.onblocked = () => {
|
||||
// Database is blocked by another connection, use a safe high version
|
||||
console.warn('[WorkspaceStorage] DB blocked, using safe version 10');
|
||||
resolve(10);
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -226,10 +238,60 @@ class WorkspaceStorageService {
|
||||
this.initialized = true;
|
||||
} catch (error) {
|
||||
console.error('[WorkspaceStorage] Failed to initialize:', error);
|
||||
|
||||
// Check if it's a version downgrade error
|
||||
const errorMsg = String(error);
|
||||
if (errorMsg.includes("can't be downgraded") || errorMsg.includes('version')) {
|
||||
console.warn('[WorkspaceStorage] Version conflict detected, attempting recovery...');
|
||||
|
||||
// Try to delete the database and reinitialize
|
||||
try {
|
||||
await this.deleteDatabase();
|
||||
await this.createStores();
|
||||
await Promise.all([
|
||||
this.foldersStore!.ready(),
|
||||
this.boardsStore!.ready(),
|
||||
this.stateStore!.ready(),
|
||||
]);
|
||||
this.initialized = true;
|
||||
console.log('[WorkspaceStorage] Recovery successful, database recreated');
|
||||
return;
|
||||
} catch (recoveryError) {
|
||||
console.error('[WorkspaceStorage] Recovery failed:', recoveryError);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Workspace storage initialization failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the database (for recovery from version conflicts)
|
||||
*/
|
||||
private async deleteDatabase(): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof indexedDB === 'undefined') {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const request = indexedDB.deleteDatabase(WORKSPACE_DB_CONFIG.DATABASE_NAME);
|
||||
request.onsuccess = () => {
|
||||
console.log('[WorkspaceStorage] Database deleted successfully');
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
console.error('[WorkspaceStorage] Failed to delete database');
|
||||
reject(new Error('Failed to delete database'));
|
||||
};
|
||||
request.onblocked = () => {
|
||||
console.warn('[WorkspaceStorage] Database deletion blocked');
|
||||
// Still resolve after a timeout
|
||||
setTimeout(resolve, 1000);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// ========== Private Store Getters (ensure initialized) ==========
|
||||
|
||||
private getFoldersStore(): LocalForage {
|
||||
|
||||
Reference in new issue
Block a user