@talex-touch/utils 1.0.29 → 1.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/animation/window-node.ts +202 -0
- package/auth/clerk-types.ts +56 -0
- package/auth/index.ts +4 -0
- package/auth/useAuth.ts +0 -0
- package/auth/useAuthState.ts +44 -0
- package/auth/useClerkConfig.ts +40 -0
- package/auth/useClerkProvider.ts +51 -0
- package/channel/index.ts +6 -0
- package/common/file-scan-utils.ts +4 -1
- package/common/storage/entity/app-settings.ts +15 -1
- package/common/utils/file.ts +4 -1
- package/common/utils/polling.ts +51 -3
- package/core-box/README.md +1 -1
- package/core-box/builder/tuff-builder.ts +1 -1
- package/core-box/tuff/tuff-dsl.ts +112 -48
- package/index.ts +4 -0
- package/package.json +1 -1
- package/plugin/index.ts +35 -12
- package/plugin/preload.ts +5 -2
- package/plugin/sdk/features.ts +1 -1
- package/plugin/sdk/index.ts +2 -7
- package/plugin/sdk/storage.ts +64 -0
- package/plugin/sdk/types.ts +96 -1
- package/preload/renderer.ts +1 -1
- package/renderer/hooks/index.ts +1 -0
- package/renderer/hooks/initialize.ts +5 -0
- package/renderer/hooks/performance.ts +87 -0
- package/renderer/index.ts +1 -0
- package/renderer/storage/app-settings.ts +0 -2
- package/renderer/storage/base-storage.ts +52 -13
- package/search/types.ts +7 -7
- package/types/download.ts +162 -0
- package/types/icon.ts +45 -0
- package/types/index.ts +1 -0
- package/types/modules/module-lifecycle.ts +1 -1
- package/types/storage.ts +56 -0
- package/types/update.ts +99 -0
package/renderer/index.ts
CHANGED
|
@@ -29,8 +29,14 @@ export interface IStorageChannel extends ITouchClientChannel {
|
|
|
29
29
|
|
|
30
30
|
let channel: IStorageChannel | null = null;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Queue of initialization callbacks waiting for channel initialization
|
|
34
|
+
*/
|
|
35
|
+
const pendingInitializations: Array<() => void> = [];
|
|
36
|
+
|
|
32
37
|
/**
|
|
33
38
|
* Initializes the global channel for communication.
|
|
39
|
+
* Processes all pending storage initializations after initialization.
|
|
34
40
|
*
|
|
35
41
|
* @example
|
|
36
42
|
* ```ts
|
|
@@ -45,6 +51,14 @@ let channel: IStorageChannel | null = null;
|
|
|
45
51
|
*/
|
|
46
52
|
export function initStorageChannel(c: IStorageChannel): void {
|
|
47
53
|
channel = c;
|
|
54
|
+
|
|
55
|
+
// Process all pending storage initializations
|
|
56
|
+
for (const initFn of pendingInitializations) {
|
|
57
|
+
initFn();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Clear the queue
|
|
61
|
+
pendingInitializations.length = 0;
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
/**
|
|
@@ -64,6 +78,7 @@ export class TouchStorage<T extends object> {
|
|
|
64
78
|
#assigning = false;
|
|
65
79
|
readonly originalData: T;
|
|
66
80
|
private readonly _onUpdate: Array<() => void> = [];
|
|
81
|
+
#channelInitialized = false;
|
|
67
82
|
|
|
68
83
|
/**
|
|
69
84
|
* The reactive data exposed to users.
|
|
@@ -72,6 +87,7 @@ export class TouchStorage<T extends object> {
|
|
|
72
87
|
|
|
73
88
|
/**
|
|
74
89
|
* Creates a new reactive storage instance.
|
|
90
|
+
* If channel is not initialized, the instance will be queued for initialization.
|
|
75
91
|
*
|
|
76
92
|
* @param qName Globally unique name for the instance
|
|
77
93
|
* @param initData Initial data to populate the storage
|
|
@@ -86,30 +102,52 @@ export class TouchStorage<T extends object> {
|
|
|
86
102
|
if (storages.has(qName)) {
|
|
87
103
|
throw new Error(`Storage "${qName}" already exists`);
|
|
88
104
|
}
|
|
105
|
+
|
|
106
|
+
this.#qualifiedName = qName;
|
|
107
|
+
this.originalData = initData;
|
|
108
|
+
this.data = reactive({ ...initData }) as UnwrapNestedRefs<T>;
|
|
109
|
+
|
|
110
|
+
if (onUpdate) this._onUpdate.push(onUpdate);
|
|
111
|
+
|
|
112
|
+
// Register to storages map immediately
|
|
113
|
+
storages.set(qName, this);
|
|
114
|
+
|
|
115
|
+
// Initialize channel-dependent operations
|
|
116
|
+
if (channel) {
|
|
117
|
+
this.#initializeChannel();
|
|
118
|
+
} else {
|
|
119
|
+
// Queue initialization callback for later
|
|
120
|
+
pendingInitializations.push(() => this.#initializeChannel());
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Initialize channel-dependent operations
|
|
126
|
+
*/
|
|
127
|
+
#initializeChannel(): void {
|
|
128
|
+
if (this.#channelInitialized) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
89
132
|
if (!channel) {
|
|
90
133
|
throw new Error(
|
|
91
134
|
'TouchStorage: channel is not initialized. Please call initStorageChannel(...) before using.'
|
|
92
135
|
);
|
|
93
136
|
}
|
|
94
137
|
|
|
95
|
-
this.#
|
|
96
|
-
this.originalData = initData;
|
|
97
|
-
|
|
98
|
-
// const stored = (channel.sendSync('storage:get', qName) as Partial<T>) || {};
|
|
99
|
-
this.data = reactive({ ...initData }) as UnwrapNestedRefs<T>;
|
|
100
|
-
this.loadFromRemote()
|
|
138
|
+
this.#channelInitialized = true;
|
|
101
139
|
|
|
102
|
-
|
|
140
|
+
// Load data from remote
|
|
141
|
+
this.loadFromRemote();
|
|
103
142
|
|
|
143
|
+
// Register update listener
|
|
104
144
|
channel.regChannel('storage:update', ({ data }) => {
|
|
105
145
|
const { name } = data!
|
|
106
146
|
|
|
107
|
-
if (name ===
|
|
147
|
+
if (name === this.#qualifiedName) {
|
|
108
148
|
this.loadFromRemote()
|
|
109
149
|
}
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
storages.set(qName, this);
|
|
150
|
+
});
|
|
113
151
|
}
|
|
114
152
|
|
|
115
153
|
/**
|
|
@@ -313,6 +351,7 @@ export class TouchStorage<T extends object> {
|
|
|
313
351
|
}
|
|
314
352
|
/**
|
|
315
353
|
* Loads data from remote storage and applies it.
|
|
354
|
+
* If channel is not initialized yet, this method will do nothing.
|
|
316
355
|
*
|
|
317
356
|
* @returns The current instance
|
|
318
357
|
*
|
|
@@ -323,11 +362,11 @@ export class TouchStorage<T extends object> {
|
|
|
323
362
|
*/
|
|
324
363
|
loadFromRemote(): this {
|
|
325
364
|
if (!channel) {
|
|
326
|
-
|
|
365
|
+
// Channel not initialized yet, data will be loaded when channel is ready
|
|
366
|
+
return this;
|
|
327
367
|
}
|
|
328
368
|
|
|
329
369
|
const result = channel.sendSync('storage:get', this.#qualifiedName)
|
|
330
|
-
console.log("result", result)
|
|
331
370
|
const parsed = result ? (result as Partial<T>) : {};
|
|
332
371
|
this.assignData(parsed, true);
|
|
333
372
|
|
package/search/types.ts
CHANGED
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* @version 1.0.0
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import type {
|
|
19
|
+
import type { IFeatureCommand } from '../plugin';
|
|
20
|
+
import type { ITuffIcon, TuffIconType } from '../types/icon';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Search Result Item Interface
|
|
@@ -59,9 +60,9 @@ export interface ISearchItem {
|
|
|
59
60
|
* Defines how the item's icon should be displayed in the UI.
|
|
60
61
|
* Supports various icon types including files, remix icons, and data URLs.
|
|
61
62
|
*
|
|
62
|
-
* @see {@link
|
|
63
|
+
* @see {@link ITuffIcon} for icon configuration options
|
|
63
64
|
*/
|
|
64
|
-
icon:
|
|
65
|
+
icon: ITuffIcon;
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* Whether this item supports push mode functionality
|
|
@@ -590,9 +591,8 @@ export function createDataItem(options: {
|
|
|
590
591
|
name,
|
|
591
592
|
desc,
|
|
592
593
|
icon: {
|
|
593
|
-
type: iconType,
|
|
594
|
-
value: iconValue
|
|
595
|
-
init: async () => {} // Required by IPluginIcon interface
|
|
594
|
+
type: (iconType === 'remix' || iconType === 'base64' ? 'url' : (iconType === 'file' || iconType === 'emoji' ? iconType : 'emoji')) as TuffIconType,
|
|
595
|
+
value: iconValue
|
|
596
596
|
},
|
|
597
597
|
push: false, // Data items don't support push mode
|
|
598
598
|
names: [name], // Include name in searchable names
|
|
@@ -675,7 +675,7 @@ export function createSearchItem(options: {
|
|
|
675
675
|
/** Description or subtitle text */
|
|
676
676
|
desc: string;
|
|
677
677
|
/** Icon configuration object */
|
|
678
|
-
icon:
|
|
678
|
+
icon: ITuffIcon;
|
|
679
679
|
/** Name of the plugin creating this item */
|
|
680
680
|
pluginName: string;
|
|
681
681
|
/** Plugin type (defaults to "feature") */
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// 下载优先级枚举
|
|
2
|
+
export enum DownloadPriority {
|
|
3
|
+
CRITICAL = 100, // 用户手动触发
|
|
4
|
+
HIGH = 80, // 插件安装
|
|
5
|
+
NORMAL = 50, // 应用更新
|
|
6
|
+
LOW = 20, // 资源文件
|
|
7
|
+
BACKGROUND = 10 // 后台预加载
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// 下载模块枚举
|
|
11
|
+
export enum DownloadModule {
|
|
12
|
+
APP_UPDATE = 'app_update',
|
|
13
|
+
PLUGIN_INSTALL = 'plugin_install',
|
|
14
|
+
RESOURCE_DOWNLOAD = 'resource_download',
|
|
15
|
+
USER_MANUAL = 'user_manual'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 下载状态枚举
|
|
19
|
+
export enum DownloadStatus {
|
|
20
|
+
PENDING = 'pending', // 等待中
|
|
21
|
+
DOWNLOADING = 'downloading', // 下载中
|
|
22
|
+
PAUSED = 'paused', // 已暂停
|
|
23
|
+
COMPLETED = 'completed', // 已完成
|
|
24
|
+
FAILED = 'failed', // 失败
|
|
25
|
+
CANCELLED = 'cancelled' // 已取消
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 切片状态枚举
|
|
29
|
+
export enum ChunkStatus {
|
|
30
|
+
PENDING = 'pending',
|
|
31
|
+
DOWNLOADING = 'downloading',
|
|
32
|
+
COMPLETED = 'completed',
|
|
33
|
+
FAILED = 'failed'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 下载任务请求接口
|
|
37
|
+
export interface DownloadRequest {
|
|
38
|
+
id?: string
|
|
39
|
+
url: string
|
|
40
|
+
destination: string
|
|
41
|
+
filename?: string
|
|
42
|
+
priority: DownloadPriority
|
|
43
|
+
module: DownloadModule
|
|
44
|
+
metadata?: Record<string, any>
|
|
45
|
+
checksum?: string
|
|
46
|
+
headers?: Record<string, string>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 下载任务实体
|
|
50
|
+
export interface DownloadTask {
|
|
51
|
+
id: string
|
|
52
|
+
url: string
|
|
53
|
+
destination: string
|
|
54
|
+
filename: string
|
|
55
|
+
priority: DownloadPriority
|
|
56
|
+
module: DownloadModule
|
|
57
|
+
status: DownloadStatus
|
|
58
|
+
progress: DownloadProgress
|
|
59
|
+
chunks: ChunkInfo[]
|
|
60
|
+
metadata: Record<string, any>
|
|
61
|
+
createdAt: Date
|
|
62
|
+
updatedAt: Date
|
|
63
|
+
error?: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 下载进度接口
|
|
67
|
+
export interface DownloadProgress {
|
|
68
|
+
totalSize?: number
|
|
69
|
+
downloadedSize: number
|
|
70
|
+
speed: number // bytes/s
|
|
71
|
+
remainingTime?: number // seconds
|
|
72
|
+
percentage: number // 0-100
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 切片信息接口
|
|
76
|
+
export interface ChunkInfo {
|
|
77
|
+
index: number
|
|
78
|
+
start: number
|
|
79
|
+
end: number
|
|
80
|
+
size: number
|
|
81
|
+
downloaded: number
|
|
82
|
+
status: ChunkStatus
|
|
83
|
+
filePath: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 下载配置接口
|
|
87
|
+
export interface DownloadConfig {
|
|
88
|
+
concurrency: {
|
|
89
|
+
maxConcurrent: number // 最大并发数 (1-10)
|
|
90
|
+
autoAdjust: boolean // 自动调整
|
|
91
|
+
networkAware: boolean // 网络感知
|
|
92
|
+
priorityBased: boolean // 基于优先级
|
|
93
|
+
}
|
|
94
|
+
chunk: {
|
|
95
|
+
size: number // 切片大小
|
|
96
|
+
resume: boolean // 断点续传
|
|
97
|
+
autoRetry: boolean // 自动重试
|
|
98
|
+
maxRetries: number // 最大重试次数
|
|
99
|
+
}
|
|
100
|
+
storage: {
|
|
101
|
+
tempDir: string // 临时目录
|
|
102
|
+
historyRetention: number // 历史保留天数
|
|
103
|
+
autoCleanup: boolean // 自动清理
|
|
104
|
+
}
|
|
105
|
+
network: {
|
|
106
|
+
timeout: number // 超时时间
|
|
107
|
+
retryDelay: number // 重试延迟
|
|
108
|
+
maxRetries: number // 最大重试次数
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 网络状态接口
|
|
113
|
+
export interface NetworkStatus {
|
|
114
|
+
speed: number // bytes/s
|
|
115
|
+
latency: number // ms
|
|
116
|
+
stability: number // 0-1
|
|
117
|
+
recommendedConcurrency: number
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 队列状态接口
|
|
121
|
+
export interface QueueStatus {
|
|
122
|
+
totalTasks: number
|
|
123
|
+
pendingTasks: number
|
|
124
|
+
activeTasks: number
|
|
125
|
+
completedTasks: number
|
|
126
|
+
failedTasks: number
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 下载统计接口
|
|
130
|
+
export interface DownloadStats {
|
|
131
|
+
totalTasks: number
|
|
132
|
+
completedTasks: number
|
|
133
|
+
failedTasks: number
|
|
134
|
+
totalDownloaded: number
|
|
135
|
+
averageSpeed: number
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 默认下载配置
|
|
139
|
+
export const defaultDownloadConfig: DownloadConfig = {
|
|
140
|
+
concurrency: {
|
|
141
|
+
maxConcurrent: 3,
|
|
142
|
+
autoAdjust: true,
|
|
143
|
+
networkAware: true,
|
|
144
|
+
priorityBased: true
|
|
145
|
+
},
|
|
146
|
+
chunk: {
|
|
147
|
+
size: 1024 * 1024, // 1MB
|
|
148
|
+
resume: true,
|
|
149
|
+
autoRetry: true,
|
|
150
|
+
maxRetries: 3
|
|
151
|
+
},
|
|
152
|
+
storage: {
|
|
153
|
+
tempDir: '', // 将在运行时设置
|
|
154
|
+
historyRetention: 30,
|
|
155
|
+
autoCleanup: true
|
|
156
|
+
},
|
|
157
|
+
network: {
|
|
158
|
+
timeout: 30000,
|
|
159
|
+
retryDelay: 5000,
|
|
160
|
+
maxRetries: 3
|
|
161
|
+
}
|
|
162
|
+
}
|
package/types/icon.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon type definitions
|
|
3
|
+
*
|
|
4
|
+
* @description
|
|
5
|
+
* Defines common icon interfaces and types, supporting emoji, url, and file types
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Icon type enumeration
|
|
10
|
+
* @description
|
|
11
|
+
* - emoji: Emoji characters (e.g., "🚀")
|
|
12
|
+
* - url: Remote URL (http/https) or Data URL (data:image/...)
|
|
13
|
+
* - file: Local file path (relative to plugin root directory)
|
|
14
|
+
* - class: Class name (e.g., "i-ri-rocket-line")
|
|
15
|
+
*/
|
|
16
|
+
export type TuffIconType = 'emoji' | 'url' | 'file' | 'class'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Icon status enumeration
|
|
20
|
+
* @description
|
|
21
|
+
* - normal: Normal state
|
|
22
|
+
* - loading: Loading state
|
|
23
|
+
* - error: Error state
|
|
24
|
+
*/
|
|
25
|
+
export type TuffIconStatus = 'normal' | 'loading' | 'error'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Common icon interface
|
|
29
|
+
*
|
|
30
|
+
* @description
|
|
31
|
+
* Unified icon data structure supporting three icon types and status management
|
|
32
|
+
*/
|
|
33
|
+
export interface ITuffIcon {
|
|
34
|
+
/** Icon type */
|
|
35
|
+
type: TuffIconType
|
|
36
|
+
|
|
37
|
+
/** Icon value */
|
|
38
|
+
value: string
|
|
39
|
+
|
|
40
|
+
/** Icon status (optional) */
|
|
41
|
+
status?: TuffIconStatus
|
|
42
|
+
|
|
43
|
+
/** Error message (when status is error) */
|
|
44
|
+
error?: string
|
|
45
|
+
}
|
package/types/index.ts
CHANGED
package/types/storage.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin storage statistics
|
|
3
|
+
*/
|
|
4
|
+
export interface StorageStats {
|
|
5
|
+
/** Total size in bytes */
|
|
6
|
+
totalSize: number
|
|
7
|
+
/** Number of files (excluding directories) */
|
|
8
|
+
fileCount: number
|
|
9
|
+
/** Number of directories */
|
|
10
|
+
dirCount: number
|
|
11
|
+
/** Maximum size limit in bytes (10MB) */
|
|
12
|
+
maxSize: number
|
|
13
|
+
/** Usage percentage (0-100) */
|
|
14
|
+
usagePercent: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Storage tree node representing a file or directory
|
|
19
|
+
*/
|
|
20
|
+
export interface StorageTreeNode {
|
|
21
|
+
/** File or directory name */
|
|
22
|
+
name: string
|
|
23
|
+
/** Relative path from storage root */
|
|
24
|
+
path: string
|
|
25
|
+
/** Node type */
|
|
26
|
+
type: 'file' | 'directory'
|
|
27
|
+
/** Size in bytes (for directories, this is the total size of all contained files) */
|
|
28
|
+
size: number
|
|
29
|
+
/** Last modified timestamp */
|
|
30
|
+
modified: number
|
|
31
|
+
/** Child nodes (only for directories) */
|
|
32
|
+
children?: StorageTreeNode[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Detailed information about a specific file
|
|
37
|
+
*/
|
|
38
|
+
export interface FileDetails {
|
|
39
|
+
/** File name */
|
|
40
|
+
name: string
|
|
41
|
+
/** Relative path from storage root */
|
|
42
|
+
path: string
|
|
43
|
+
/** File size in bytes */
|
|
44
|
+
size: number
|
|
45
|
+
/** Creation timestamp */
|
|
46
|
+
created: number
|
|
47
|
+
/** Last modified timestamp */
|
|
48
|
+
modified: number
|
|
49
|
+
/** File type (extension or detected type) */
|
|
50
|
+
type: string
|
|
51
|
+
/** File content (if available and size permits) */
|
|
52
|
+
content?: any
|
|
53
|
+
/** Whether content was truncated due to size */
|
|
54
|
+
truncated?: boolean
|
|
55
|
+
}
|
|
56
|
+
|
package/types/update.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// 更新源类型枚举
|
|
2
|
+
export enum UpdateProviderType {
|
|
3
|
+
GITHUB = 'github',
|
|
4
|
+
OFFICIAL = 'official',
|
|
5
|
+
CUSTOM = 'custom'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// 更新源配置接口
|
|
9
|
+
export interface UpdateSourceConfig {
|
|
10
|
+
type: UpdateProviderType
|
|
11
|
+
name: string
|
|
12
|
+
url?: string
|
|
13
|
+
enabled: boolean
|
|
14
|
+
priority: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 下载资源接口
|
|
18
|
+
export interface DownloadAsset {
|
|
19
|
+
name: string
|
|
20
|
+
url: string
|
|
21
|
+
size: number
|
|
22
|
+
platform: 'win32' | 'darwin' | 'linux'
|
|
23
|
+
arch: 'x64' | 'arm64'
|
|
24
|
+
checksum?: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// GitHub Release接口(兼容GitHub API格式)
|
|
28
|
+
export interface GitHubRelease {
|
|
29
|
+
tag_name: string
|
|
30
|
+
name: string
|
|
31
|
+
published_at: string
|
|
32
|
+
body: string
|
|
33
|
+
assets: DownloadAsset[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 更新检查结果接口
|
|
37
|
+
export interface UpdateCheckResult {
|
|
38
|
+
hasUpdate: boolean
|
|
39
|
+
release?: GitHubRelease
|
|
40
|
+
error?: string
|
|
41
|
+
source: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 自定义更新源配置
|
|
45
|
+
export interface CustomUpdateConfig {
|
|
46
|
+
name: string
|
|
47
|
+
url: string
|
|
48
|
+
apiFormat: 'github' | 'custom'
|
|
49
|
+
headers?: Record<string, string>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 应用预览渠道枚举
|
|
53
|
+
export enum AppPreviewChannel {
|
|
54
|
+
MASTER = 'master',
|
|
55
|
+
SNAPSHOT = 'snapshot'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 更新设置配置
|
|
59
|
+
export interface UpdateSettings {
|
|
60
|
+
enabled: boolean
|
|
61
|
+
frequency: 'startup' | 'daily' | 'weekly' | 'manual'
|
|
62
|
+
source: UpdateSourceConfig
|
|
63
|
+
crossChannel: boolean
|
|
64
|
+
ignoredVersions: string[]
|
|
65
|
+
customSources: CustomUpdateConfig[]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 默认更新设置
|
|
69
|
+
export const defaultUpdateSettings: UpdateSettings = {
|
|
70
|
+
enabled: true,
|
|
71
|
+
frequency: 'startup',
|
|
72
|
+
source: {
|
|
73
|
+
type: UpdateProviderType.GITHUB,
|
|
74
|
+
name: 'GitHub Releases',
|
|
75
|
+
url: 'https://api.github.com/repos/talex-touch/tuff/releases',
|
|
76
|
+
enabled: true,
|
|
77
|
+
priority: 1
|
|
78
|
+
},
|
|
79
|
+
crossChannel: false,
|
|
80
|
+
ignoredVersions: [],
|
|
81
|
+
customSources: []
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 更新错误类型
|
|
85
|
+
export enum UpdateErrorType {
|
|
86
|
+
NETWORK_ERROR = 'network_error',
|
|
87
|
+
TIMEOUT_ERROR = 'timeout_error',
|
|
88
|
+
API_ERROR = 'api_error',
|
|
89
|
+
PARSE_ERROR = 'parse_error',
|
|
90
|
+
VERSION_ERROR = 'version_error',
|
|
91
|
+
UNKNOWN_ERROR = 'unknown_error'
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 更新错误接口
|
|
95
|
+
export interface UpdateError extends Error {
|
|
96
|
+
type: UpdateErrorType
|
|
97
|
+
code?: string
|
|
98
|
+
statusCode?: number
|
|
99
|
+
}
|