@talex-touch/utils 1.0.30 → 1.0.32
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 +205 -0
- package/animation/window.ts +19 -15
- package/auth/clerk-types.ts +1 -1
- package/auth/index.ts +1 -1
- package/auth/useAuthState.ts +6 -5
- package/auth/useClerkConfig.ts +6 -6
- package/auth/useClerkProvider.ts +3 -2
- package/channel/index.ts +28 -21
- package/common/file-scan-constants.ts +137 -121
- package/common/file-scan-utils.ts +49 -25
- package/common/index.ts +3 -3
- package/common/search/gather.ts +1 -1
- package/common/search/index.ts +5 -6
- package/common/storage/constants.ts +3 -2
- package/common/storage/entity/app-settings.ts +19 -3
- package/common/storage/entity/shortcut-settings.ts +10 -10
- package/common/storage/shortcut-storage.ts +6 -4
- package/common/utils/file.ts +15 -4
- package/common/utils/index.ts +62 -52
- package/common/utils/polling.ts +114 -63
- package/common/utils/task-queue.ts +11 -10
- package/common/utils/time.ts +50 -47
- package/common/utils/timing.ts +41 -37
- package/core-box/builder/index.ts +1 -1
- package/core-box/builder/tuff-builder.ts +255 -230
- package/core-box/index.ts +3 -6
- package/core-box/preview/index.ts +1 -0
- package/core-box/preview/types.ts +43 -0
- package/core-box/tuff/index.ts +1 -1
- package/core-box/tuff/tuff-dsl.ts +419 -253
- package/electron/clipboard-helper.ts +20 -12
- package/electron/download-manager.ts +43 -42
- package/electron/env-tool.ts +19 -18
- package/electron/file-parsers/index.ts +2 -2
- package/electron/file-parsers/parsers/text-parser.ts +15 -14
- package/electron/file-parsers/registry.ts +9 -7
- package/electron/file-parsers/types.ts +4 -4
- package/electron/index.ts +1 -1
- package/eventbus/index.ts +11 -11
- package/index.ts +6 -5
- package/intelligence/client.ts +87 -0
- package/intelligence/index.ts +1 -0
- package/package.json +14 -14
- package/permission/index.ts +8 -8
- package/plugin/channel.ts +77 -68
- package/plugin/index.ts +113 -84
- package/plugin/install.ts +8 -8
- package/plugin/log/types.ts +5 -5
- package/plugin/node/index.ts +1 -1
- package/plugin/node/logger-manager.ts +14 -11
- package/plugin/node/logger.ts +8 -8
- package/plugin/plugin-source.ts +11 -11
- package/plugin/preload.ts +6 -3
- package/plugin/providers/registry.ts +8 -7
- package/plugin/providers/types.ts +6 -6
- package/plugin/sdk/channel.ts +20 -20
- package/plugin/sdk/clipboard.ts +8 -6
- package/plugin/sdk/common.ts +10 -6
- package/plugin/sdk/core-box.ts +2 -3
- package/plugin/sdk/division-box.ts +266 -0
- package/plugin/sdk/enum/bridge-event.ts +1 -1
- package/plugin/sdk/examples/storage-onDidChange-example.js +1 -1
- package/plugin/sdk/features.ts +34 -26
- package/plugin/sdk/hooks/bridge.ts +3 -6
- package/plugin/sdk/hooks/index.ts +1 -1
- package/plugin/sdk/hooks/life-cycle.ts +4 -10
- package/plugin/sdk/index.ts +9 -13
- package/plugin/sdk/service/index.ts +3 -3
- package/plugin/sdk/storage.ts +4 -4
- package/plugin/sdk/system.ts +1 -1
- package/plugin/sdk/types.ts +169 -143
- package/plugin/sdk/window/index.ts +8 -5
- package/preload/loading.ts +6 -6
- package/preload/renderer.ts +4 -2
- package/renderer/hooks/arg-mapper.ts +1 -2
- package/renderer/hooks/index.ts +2 -0
- package/renderer/hooks/initialize.ts +10 -8
- package/renderer/hooks/performance.ts +4 -4
- package/renderer/hooks/use-channel.ts +150 -0
- package/renderer/hooks/use-intelligence.ts +236 -0
- package/renderer/index.ts +6 -1
- package/renderer/ref.ts +32 -36
- package/renderer/slots.ts +29 -26
- package/renderer/storage/app-settings.ts +16 -6
- package/renderer/storage/base-storage.ts +236 -88
- package/renderer/storage/index.ts +3 -0
- package/renderer/storage/intelligence-storage.ts +215 -0
- package/renderer/storage/openers.ts +13 -3
- package/renderer/touch-sdk/env.ts +41 -41
- package/renderer/touch-sdk/index.ts +1 -1
- package/renderer/touch-sdk/terminal.ts +5 -5
- package/renderer/touch-sdk/utils.ts +4 -3
- package/search/levenshtein-utils.ts +11 -11
- package/search/types.ts +102 -103
- package/service/index.ts +11 -11
- package/service/protocol/index.ts +217 -14
- package/types/division-box.ts +248 -0
- package/types/download.ts +72 -34
- package/types/icon.ts +2 -1
- package/types/index.ts +3 -1
- package/types/intelligence.ts +413 -0
- package/types/modules/base.ts +16 -16
- package/types/modules/index.ts +1 -1
- package/types/modules/module-lifecycle.ts +21 -21
- package/types/modules/module-manager.ts +11 -11
- package/types/modules/module.ts +16 -16
- package/types/storage.ts +0 -1
- package/types/touch-app-core.ts +32 -32
- package/types/update.ts +79 -21
- package/core-box/README.md +0 -218
- package/core-box/builder/tuff-builder.example.ts.bak +0 -258
- package/core-box/run-tests.sh +0 -7
- package/core-box/search.ts +0 -1
|
@@ -47,7 +47,8 @@ export class ClipboardHelper {
|
|
|
47
47
|
for (i = 0; i < length; i++) {
|
|
48
48
|
uuid[i] = chars[0 | (Math.random() * radix)]
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
51
52
|
let r: number
|
|
52
53
|
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
|
|
53
54
|
uuid[14] = '4'
|
|
@@ -75,7 +76,8 @@ export class ClipboardHelper {
|
|
|
75
76
|
// Handle multiple files
|
|
76
77
|
const tagContent = clipboard.read('NSFilenamesPboardType').match(/<string>.*<\/string>/g)
|
|
77
78
|
filePath = tagContent ? tagContent.map(item => item.replace(/<string>|<\/string>/g, '')) : []
|
|
78
|
-
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
79
81
|
// Handle single file
|
|
80
82
|
const clipboardImage = clipboard.readImage('clipboard')
|
|
81
83
|
if (!clipboardImage.isEmpty()) {
|
|
@@ -84,10 +86,11 @@ export class ClipboardHelper {
|
|
|
84
86
|
const fileInfo: ClipboardFileInfo = {
|
|
85
87
|
buffer: png,
|
|
86
88
|
mimetype: 'image/png',
|
|
87
|
-
originalname: this.generateUuid(8, 16)
|
|
89
|
+
originalname: `${this.generateUuid(8, 16)}.png`,
|
|
88
90
|
}
|
|
89
91
|
filePath = [fileInfo]
|
|
90
|
-
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
91
94
|
// Handle single file path
|
|
92
95
|
const fileUrl = clipboard.read('public.file-url')
|
|
93
96
|
if (fileUrl) {
|
|
@@ -115,7 +118,7 @@ export class ClipboardHelper {
|
|
|
115
118
|
.join('')
|
|
116
119
|
.replace(/\\/g, '\\\\')
|
|
117
120
|
|
|
118
|
-
const drivePrefix = formatFilePathStr.match(/[a-
|
|
121
|
+
const drivePrefix = formatFilePathStr.match(/[a-z]:\\/i)
|
|
119
122
|
|
|
120
123
|
if (drivePrefix) {
|
|
121
124
|
const drivePrefixIndex = formatFilePathStr.indexOf(drivePrefix[0])
|
|
@@ -127,7 +130,8 @@ export class ClipboardHelper {
|
|
|
127
130
|
.filter(item => item)
|
|
128
131
|
.map(item => drivePrefix[0] + item)
|
|
129
132
|
}
|
|
130
|
-
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
131
135
|
// Handle single file
|
|
132
136
|
const clipboardImage = clipboard.readImage('clipboard')
|
|
133
137
|
if (!clipboardImage.isEmpty()) {
|
|
@@ -136,17 +140,19 @@ export class ClipboardHelper {
|
|
|
136
140
|
const fileInfo: ClipboardFileInfo = {
|
|
137
141
|
buffer: png,
|
|
138
142
|
mimetype: 'image/png',
|
|
139
|
-
originalname: this.generateUuid(8, 16)
|
|
143
|
+
originalname: `${this.generateUuid(8, 16)}.png`,
|
|
140
144
|
}
|
|
141
145
|
filePath = [fileInfo]
|
|
142
|
-
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
143
148
|
// Handle single file path
|
|
144
149
|
try {
|
|
145
|
-
const fileName = clipboard.readBuffer('FileNameW').toString('ucs2').replace(RegExp(String.fromCharCode(0), 'g'), '')
|
|
150
|
+
const fileName = clipboard.readBuffer('FileNameW').toString('ucs2').replace(new RegExp(String.fromCharCode(0), 'g'), '')
|
|
146
151
|
if (fileName) {
|
|
147
152
|
filePath = [fileName]
|
|
148
153
|
}
|
|
149
|
-
}
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
150
156
|
// Ignore read errors for non-file clipboard content
|
|
151
157
|
}
|
|
152
158
|
}
|
|
@@ -183,10 +189,12 @@ export class ClipboardHelper {
|
|
|
183
189
|
try {
|
|
184
190
|
if (this.isMac) {
|
|
185
191
|
return this.getClipboardFilesMac()
|
|
186
|
-
}
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
187
194
|
return this.getClipboardFilesWindows()
|
|
188
195
|
}
|
|
189
|
-
}
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
190
198
|
console.error('Failed to read clipboard files:', error)
|
|
191
199
|
return []
|
|
192
200
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
1
2
|
import { net } from 'electron'
|
|
2
3
|
import fse from 'fs-extra'
|
|
3
|
-
import path from 'path'
|
|
4
4
|
|
|
5
5
|
interface DownloadItem {
|
|
6
|
-
url: string
|
|
7
|
-
filename: string
|
|
8
|
-
apply?: (filePath: string) => void
|
|
6
|
+
url: string
|
|
7
|
+
filename: string
|
|
8
|
+
apply?: (filePath: string) => void
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export class DownloadManager {
|
|
12
|
-
private basePath: string
|
|
13
|
-
private downloadQueue: DownloadItem[] = []
|
|
14
|
-
private isDownloading = false
|
|
12
|
+
private basePath: string
|
|
13
|
+
private downloadQueue: DownloadItem[] = []
|
|
14
|
+
private isDownloading = false
|
|
15
15
|
|
|
16
16
|
constructor(basePath: string = '') {
|
|
17
|
-
this.basePath = basePath
|
|
17
|
+
this.basePath = basePath
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -22,9 +22,9 @@ export class DownloadManager {
|
|
|
22
22
|
* @param item The download item object
|
|
23
23
|
*/
|
|
24
24
|
addDownload(item: DownloadItem): void {
|
|
25
|
-
this.downloadQueue.push(item)
|
|
25
|
+
this.downloadQueue.push(item)
|
|
26
26
|
if (!this.isDownloading) {
|
|
27
|
-
this.processQueue()
|
|
27
|
+
this.processQueue()
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -33,9 +33,9 @@ export class DownloadManager {
|
|
|
33
33
|
* @param items Array of download items
|
|
34
34
|
*/
|
|
35
35
|
addDownloads(items: DownloadItem[]): void {
|
|
36
|
-
this.downloadQueue.push(...items)
|
|
36
|
+
this.downloadQueue.push(...items)
|
|
37
37
|
if (!this.isDownloading) {
|
|
38
|
-
this.processQueue()
|
|
38
|
+
this.processQueue()
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -44,26 +44,27 @@ export class DownloadManager {
|
|
|
44
44
|
*/
|
|
45
45
|
private async processQueue(): Promise<void> {
|
|
46
46
|
if (this.downloadQueue.length === 0) {
|
|
47
|
-
this.isDownloading = false
|
|
48
|
-
return
|
|
47
|
+
this.isDownloading = false
|
|
48
|
+
return
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
this.isDownloading = true
|
|
52
|
-
const item = this.downloadQueue.shift()
|
|
51
|
+
this.isDownloading = true
|
|
52
|
+
const item = this.downloadQueue.shift()!
|
|
53
53
|
|
|
54
54
|
try {
|
|
55
|
-
console.log(`[DownloadManager] Starting to download ${item.filename} from ${item.url}`)
|
|
56
|
-
const filePath = await this.downloadFile(item.url, item.filename)
|
|
57
|
-
console.log(`[DownloadManager] Download ${item.filename} completed`)
|
|
55
|
+
console.log(`[DownloadManager] Starting to download ${item.filename} from ${item.url}`)
|
|
56
|
+
const filePath = await this.downloadFile(item.url, item.filename)
|
|
57
|
+
console.log(`[DownloadManager] Download ${item.filename} completed`)
|
|
58
58
|
|
|
59
59
|
if (item.apply) {
|
|
60
|
-
item.apply(filePath)
|
|
60
|
+
item.apply(filePath)
|
|
61
61
|
}
|
|
62
|
-
}
|
|
63
|
-
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error(`[DownloadManager] Download ${item.filename} failed:`, error)
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
this.processQueue()
|
|
67
|
+
this.processQueue()
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
/**
|
|
@@ -74,45 +75,45 @@ export class DownloadManager {
|
|
|
74
75
|
*/
|
|
75
76
|
private downloadFile(url: string, filename: string): Promise<string> {
|
|
76
77
|
return new Promise((resolve, reject) => {
|
|
77
|
-
const request = net.request(url)
|
|
78
|
-
const filePath = this.basePath ? path.join(this.basePath, filename) : filename
|
|
78
|
+
const request = net.request(url)
|
|
79
|
+
const filePath = this.basePath ? path.join(this.basePath, filename) : filename
|
|
79
80
|
|
|
80
|
-
console.log(`[DownloadManager] File download request sent for ${filename}.`)
|
|
81
|
+
console.log(`[DownloadManager] File download request sent for ${filename}.`)
|
|
81
82
|
|
|
82
83
|
request.addListener('error', (error) => {
|
|
83
|
-
console.error(`[DownloadManager] Download request error for ${filename}:`, error)
|
|
84
|
-
reject(error)
|
|
85
|
-
})
|
|
84
|
+
console.error(`[DownloadManager] Download request error for ${filename}:`, error)
|
|
85
|
+
reject(error)
|
|
86
|
+
})
|
|
86
87
|
|
|
87
88
|
request.addListener('response', (response) => {
|
|
88
|
-
fse.createFileSync(filePath)
|
|
89
|
+
fse.createFileSync(filePath)
|
|
89
90
|
|
|
90
91
|
response.addListener('data', (chunk: any) => {
|
|
91
|
-
console.log(`[DownloadManager] Downloading ${filename}...`)
|
|
92
|
-
fse.appendFile(filePath, chunk, 'utf8')
|
|
93
|
-
})
|
|
92
|
+
console.log(`[DownloadManager] Downloading ${filename}...`)
|
|
93
|
+
fse.appendFile(filePath, chunk, 'utf8')
|
|
94
|
+
})
|
|
94
95
|
|
|
95
96
|
response.addListener('end', () => {
|
|
96
|
-
console.log(`[DownloadManager] Download ${filename} finished.`)
|
|
97
|
-
resolve(filePath)
|
|
98
|
-
})
|
|
99
|
-
})
|
|
97
|
+
console.log(`[DownloadManager] Download ${filename} finished.`)
|
|
98
|
+
resolve(filePath)
|
|
99
|
+
})
|
|
100
|
+
})
|
|
100
101
|
|
|
101
|
-
request.end()
|
|
102
|
-
})
|
|
102
|
+
request.end()
|
|
103
|
+
})
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
/**
|
|
106
107
|
* Clear the download queue
|
|
107
108
|
*/
|
|
108
109
|
clearQueue(): void {
|
|
109
|
-
this.downloadQueue = []
|
|
110
|
+
this.downloadQueue = []
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
/**
|
|
113
114
|
* Get the number of items in the download queue
|
|
114
115
|
*/
|
|
115
116
|
getQueueLength(): number {
|
|
116
|
-
return this.downloadQueue.length
|
|
117
|
+
return this.downloadQueue.length
|
|
117
118
|
}
|
|
118
|
-
}
|
|
119
|
+
}
|
package/electron/env-tool.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { ExecException } from 'node:child_process'
|
|
2
|
+
import { exec } from 'node:child_process'
|
|
3
|
+
import { platform } from 'node:process'
|
|
3
4
|
|
|
4
5
|
export interface IGlobalPkgResult {
|
|
5
6
|
exist: boolean
|
|
@@ -14,35 +15,34 @@ export function checkGlobalPackageExist(packageName: string): Promise<IGlobalPkg
|
|
|
14
15
|
if (error) {
|
|
15
16
|
reject({
|
|
16
17
|
exits: false,
|
|
17
|
-
error
|
|
18
|
-
})
|
|
19
|
-
return
|
|
18
|
+
error,
|
|
19
|
+
})
|
|
20
|
+
return
|
|
20
21
|
}
|
|
21
22
|
if (stderr) {
|
|
22
23
|
reject({
|
|
23
24
|
exits: false,
|
|
24
|
-
error: stderr
|
|
25
|
-
})
|
|
26
|
-
return
|
|
25
|
+
error: stderr,
|
|
26
|
+
})
|
|
27
|
+
return
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
const lines = stdout.split('\n')
|
|
30
|
-
const lastLine = lines[lines.length - 3]
|
|
31
|
-
const match = lastLine.match(/(\S+)@(\S+)/)
|
|
30
|
+
const lines = stdout.split('\n')
|
|
31
|
+
const lastLine = lines[lines.length - 3]
|
|
32
|
+
const match = lastLine.match(/(\S+)@(\S+)/)
|
|
32
33
|
if (match) {
|
|
33
34
|
resolve({
|
|
34
35
|
exist: true,
|
|
35
36
|
name: match[1],
|
|
36
|
-
version: match[2]
|
|
37
|
-
} as IGlobalPkgResult)
|
|
38
|
-
return
|
|
37
|
+
version: match[2],
|
|
38
|
+
} as IGlobalPkgResult)
|
|
39
|
+
return
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
resolve({
|
|
42
|
-
exist: false
|
|
43
|
+
exist: false,
|
|
43
44
|
} as IGlobalPkgResult)
|
|
44
|
-
|
|
45
|
-
});
|
|
45
|
+
})
|
|
46
46
|
})
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -50,7 +50,8 @@ export function checkGlobalPackageExist(packageName: string): Promise<IGlobalPkg
|
|
|
50
50
|
export function getNpmVersion(): Promise<string | null> {
|
|
51
51
|
return new Promise((resolve) => {
|
|
52
52
|
exec(`npm --version`, (error, stdout, stderr) => {
|
|
53
|
-
if (error || stderr)
|
|
53
|
+
if (error || stderr)
|
|
54
|
+
resolve(null)
|
|
54
55
|
|
|
55
56
|
resolve(stdout.trim())
|
|
56
57
|
})
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { fileParserRegistry } from './registry'
|
|
2
1
|
import { textFileParser } from './parsers/text-parser'
|
|
2
|
+
import { fileParserRegistry } from './registry'
|
|
3
3
|
|
|
4
4
|
fileParserRegistry.register(textFileParser)
|
|
5
5
|
|
|
6
|
-
export * from './types'
|
|
7
6
|
export * from './registry'
|
|
7
|
+
export * from './types'
|
|
8
8
|
export { textFileParser }
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import {
|
|
1
|
+
import type {
|
|
4
2
|
FileParser,
|
|
5
3
|
FileParserContext,
|
|
6
4
|
FileParserProgress,
|
|
7
|
-
FileParserResult
|
|
5
|
+
FileParserResult,
|
|
8
6
|
} from '../types'
|
|
7
|
+
import fs from 'node:fs/promises'
|
|
8
|
+
import path from 'node:path'
|
|
9
9
|
|
|
10
10
|
const TEXTUAL_EXTENSIONS = new Set(
|
|
11
11
|
[
|
|
@@ -48,8 +48,8 @@ const TEXTUAL_EXTENSIONS = new Set(
|
|
|
48
48
|
'.fish',
|
|
49
49
|
'.bat',
|
|
50
50
|
'.ps1',
|
|
51
|
-
'.sql'
|
|
52
|
-
].map(
|
|
51
|
+
'.sql',
|
|
52
|
+
].map(ext => ext.toLowerCase()),
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
export class TextFileParser implements FileParser {
|
|
@@ -59,7 +59,7 @@ export class TextFileParser implements FileParser {
|
|
|
59
59
|
|
|
60
60
|
async parse(
|
|
61
61
|
context: FileParserContext,
|
|
62
|
-
onProgress?: (progress: FileParserProgress) => void
|
|
62
|
+
onProgress?: (progress: FileParserProgress) => void,
|
|
63
63
|
): Promise<FileParserResult> {
|
|
64
64
|
const { filePath, extension, size, maxBytes } = context
|
|
65
65
|
if (maxBytes && size > maxBytes) {
|
|
@@ -69,15 +69,15 @@ export class TextFileParser implements FileParser {
|
|
|
69
69
|
totalBytes: size,
|
|
70
70
|
processedBytes: 0,
|
|
71
71
|
warnings: [
|
|
72
|
-
`File size ${(size / (1024 * 1024)).toFixed(2)}MB exceeds limit ${(maxBytes / (1024 * 1024)).toFixed(2)}MB
|
|
73
|
-
]
|
|
72
|
+
`File size ${(size / (1024 * 1024)).toFixed(2)}MB exceeds limit ${(maxBytes / (1024 * 1024)).toFixed(2)}MB`,
|
|
73
|
+
],
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
if (!TEXTUAL_EXTENSIONS.has(extension)) {
|
|
78
78
|
return {
|
|
79
79
|
status: 'skipped',
|
|
80
|
-
reason: 'unsupported-extension'
|
|
80
|
+
reason: 'unsupported-extension',
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -92,15 +92,16 @@ export class TextFileParser implements FileParser {
|
|
|
92
92
|
content,
|
|
93
93
|
metadata: {
|
|
94
94
|
length: content.length,
|
|
95
|
-
basename: path.basename(filePath)
|
|
95
|
+
basename: path.basename(filePath),
|
|
96
96
|
},
|
|
97
97
|
processedBytes: size,
|
|
98
|
-
totalBytes: size
|
|
98
|
+
totalBytes: size,
|
|
99
99
|
}
|
|
100
|
-
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
101
102
|
return {
|
|
102
103
|
status: 'failed',
|
|
103
|
-
reason: error instanceof Error ? error.message : 'unknown-error'
|
|
104
|
+
reason: error instanceof Error ? error.message : 'unknown-error',
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
2
|
FileParser,
|
|
3
3
|
FileParserContext,
|
|
4
4
|
FileParserProgress,
|
|
5
5
|
FileParserResult,
|
|
6
|
-
FileParserSelectionOptions
|
|
6
|
+
FileParserSelectionOptions,
|
|
7
7
|
} from './types'
|
|
8
8
|
|
|
9
9
|
interface RegisteredParser {
|
|
@@ -17,7 +17,7 @@ export class FileParserRegistry {
|
|
|
17
17
|
|
|
18
18
|
register(parser: FileParser): void {
|
|
19
19
|
const extensions = new Set(
|
|
20
|
-
Array.from(parser.supportedExtensions).map(
|
|
20
|
+
Array.from(parser.supportedExtensions).map(ext => ext.trim().toLowerCase()),
|
|
21
21
|
)
|
|
22
22
|
if (extensions.size === 0) {
|
|
23
23
|
throw new Error(`[FileParserRegistry] Parser ${parser.id} registered without extensions`)
|
|
@@ -35,7 +35,8 @@ export class FileParserRegistry {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
getParsersForExtension(extension: string): FileParser[] {
|
|
38
|
-
if (!extension)
|
|
38
|
+
if (!extension)
|
|
39
|
+
return []
|
|
39
40
|
const normalized = extension.toLowerCase()
|
|
40
41
|
return this.parsers
|
|
41
42
|
.filter(({ extensions }) => extensions.has(normalized))
|
|
@@ -54,7 +55,7 @@ export class FileParserRegistry {
|
|
|
54
55
|
|
|
55
56
|
async parseWithBestParser(
|
|
56
57
|
context: FileParserContext,
|
|
57
|
-
onProgress?: (progress: FileParserProgress) => void
|
|
58
|
+
onProgress?: (progress: FileParserProgress) => void,
|
|
58
59
|
): Promise<FileParserResult | null> {
|
|
59
60
|
const candidates = this.getParsersForExtension(context.extension)
|
|
60
61
|
const allParsers = context.extension !== '*' ? candidates : []
|
|
@@ -76,11 +77,12 @@ export class FileParserRegistry {
|
|
|
76
77
|
if (result.status !== 'skipped') {
|
|
77
78
|
return result
|
|
78
79
|
}
|
|
79
|
-
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
80
82
|
console.error(`[FileParserRegistry] Parser ${parser.id} failed:`, error)
|
|
81
83
|
return {
|
|
82
84
|
status: 'failed',
|
|
83
|
-
reason: error instanceof Error ? error.message : 'unknown-error'
|
|
85
|
+
reason: error instanceof Error ? error.message : 'unknown-error',
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
}
|
|
@@ -41,11 +41,11 @@ export interface FileParser {
|
|
|
41
41
|
/** Higher priority parsers win when multiple support the same extension */
|
|
42
42
|
readonly priority?: number
|
|
43
43
|
readonly supportedExtensions: string[] | Set<string>
|
|
44
|
-
canParse
|
|
45
|
-
parse(
|
|
44
|
+
canParse?: (context: FileParserContext) => boolean | Promise<boolean>
|
|
45
|
+
parse: (
|
|
46
46
|
context: FileParserContext,
|
|
47
|
-
onProgress?: (progress: FileParserProgress) => void
|
|
48
|
-
)
|
|
47
|
+
onProgress?: (progress: FileParserProgress) => void,
|
|
48
|
+
) => Promise<FileParserResult>
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export interface FileParserSelectionOptions {
|
package/electron/index.ts
CHANGED
package/eventbus/index.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
export type EventHandler = (event: ITouchEvent) => void
|
|
1
|
+
export type EventHandler = (event: ITouchEvent) => void
|
|
2
2
|
|
|
3
3
|
export interface EventHandlerWrapper {
|
|
4
4
|
/**
|
|
5
5
|
* Event handler
|
|
6
6
|
*/
|
|
7
|
-
handler: EventHandler
|
|
7
|
+
handler: EventHandler
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Event type
|
|
11
11
|
* @see EventType
|
|
12
12
|
* @default EventType.PERSIST (must be, if implements)
|
|
13
13
|
*/
|
|
14
|
-
type?: EventType
|
|
14
|
+
type?: EventType
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export enum EventType {
|
|
@@ -23,16 +23,16 @@ export interface ITouchEvent<E = any> {
|
|
|
23
23
|
/**
|
|
24
24
|
* Event name
|
|
25
25
|
*/
|
|
26
|
-
name: E
|
|
26
|
+
name: E
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Event data
|
|
30
30
|
*/
|
|
31
|
-
data?: any
|
|
31
|
+
data?: any
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export interface ITouchEventBus<E> {
|
|
35
|
-
map: Map<E, Set<EventHandlerWrapper
|
|
35
|
+
map: Map<E, Set<EventHandlerWrapper>>
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Subscribe touch-app events (any kind of events extends from TouchEvent)
|
|
@@ -40,7 +40,7 @@ export interface ITouchEventBus<E> {
|
|
|
40
40
|
* @param handler Event handler (extends from EventHandler)
|
|
41
41
|
* @returns true if the event was added, otherwise false
|
|
42
42
|
*/
|
|
43
|
-
on(event: E, handler: EventHandler)
|
|
43
|
+
on: (event: E, handler: EventHandler) => boolean | void
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Subscribe touch-app events (any kind of events extends from TouchEvent)
|
|
@@ -48,7 +48,7 @@ export interface ITouchEventBus<E> {
|
|
|
48
48
|
* @param handler Event handler (extends from EventHandler)
|
|
49
49
|
* @returns true if the event was added, otherwise false
|
|
50
50
|
*/
|
|
51
|
-
once(event: E, handler: EventHandler)
|
|
51
|
+
once: (event: E, handler: EventHandler) => boolean | void
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* UnSubscribe touch-app events (any kind of events extends from TouchEvent)
|
|
@@ -61,19 +61,19 @@ export interface ITouchEventBus<E> {
|
|
|
61
61
|
* console.log(event)
|
|
62
62
|
* }
|
|
63
63
|
*/
|
|
64
|
-
off(event: E, handler: EventHandler)
|
|
64
|
+
off: (event: E, handler: EventHandler) => boolean
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* UnSubscribe touch-app events all matched (any kind of events extends from TouchEvent)
|
|
68
68
|
* @param event EventName (extends from TouchEvent)
|
|
69
69
|
* @returns true if the event was added, otherwise false
|
|
70
70
|
*/
|
|
71
|
-
offAll(event: E)
|
|
71
|
+
offAll: (event: E) => boolean
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Emit touch-app events (any kind of events extends from TouchEvent)
|
|
75
75
|
* @param event EventName (extends from TouchEvent)
|
|
76
76
|
* @param data Event data (extends from TouchEvent)
|
|
77
77
|
*/
|
|
78
|
-
emit<T extends ITouchEvent<E>>(event: E, data: T)
|
|
78
|
+
emit: <T extends ITouchEvent<E>>(event: E, data: T) => void
|
|
79
79
|
}
|
package/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export * from './auth'
|
|
1
|
+
// export * from './auth' // Renderer-only, use @talex-touch/utils/renderer instead
|
|
2
2
|
export * from './base'
|
|
3
|
+
export * from './channel'
|
|
3
4
|
export * from './common'
|
|
4
|
-
export * from './plugin'
|
|
5
5
|
export * from './core-box'
|
|
6
|
-
export * from './channel'
|
|
7
|
-
export * from './types'
|
|
8
|
-
export * from './types/icon'
|
|
9
6
|
export * from './eventbus'
|
|
7
|
+
export * from './intelligence'
|
|
8
|
+
export * from './plugin'
|
|
10
9
|
export * from './preload'
|
|
10
|
+
export * from './types'
|
|
11
11
|
export * from './types/download'
|
|
12
|
+
export * from './types/icon'
|
|
12
13
|
export * from './types/update'
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { AiInvokeOptions, AiInvokeResult, AiProviderConfig } from '../types/intelligence'
|
|
2
|
+
|
|
3
|
+
export interface IntelligenceClientChannel {
|
|
4
|
+
send: (eventName: string, payload: unknown) => Promise<any>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type IntelligenceChannelResolver = () => IntelligenceClientChannel | null | undefined
|
|
8
|
+
|
|
9
|
+
const defaultResolvers: IntelligenceChannelResolver[] = [
|
|
10
|
+
() => {
|
|
11
|
+
if (typeof globalThis === 'undefined')
|
|
12
|
+
return null
|
|
13
|
+
const maybe
|
|
14
|
+
= (globalThis as any).touchChannel
|
|
15
|
+
|| (globalThis as any).$touchChannel
|
|
16
|
+
|| (globalThis as any).channel
|
|
17
|
+
|| (globalThis as any).window?.touchChannel
|
|
18
|
+
|| (globalThis as any).window?.$touchChannel
|
|
19
|
+
return maybe ?? null
|
|
20
|
+
},
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
export function resolveIntelligenceChannel(resolvers: IntelligenceChannelResolver[] = defaultResolvers): IntelligenceClientChannel | null {
|
|
24
|
+
for (const resolver of resolvers) {
|
|
25
|
+
try {
|
|
26
|
+
const channel = resolver()
|
|
27
|
+
if (channel) {
|
|
28
|
+
return channel
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.warn('[Intelligence Client] Channel resolver failed:', error)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface ChannelResponse<T> {
|
|
39
|
+
ok: boolean
|
|
40
|
+
result?: T
|
|
41
|
+
error?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function assertResponse<T>(promise: Promise<ChannelResponse<T>>): Promise<T> {
|
|
45
|
+
const response = await promise
|
|
46
|
+
if (!response?.ok) {
|
|
47
|
+
throw new Error(response?.error || 'Intelligence channel request failed')
|
|
48
|
+
}
|
|
49
|
+
return response.result as T
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface IntelligenceClient {
|
|
53
|
+
invoke: <T = any>(capabilityId: string, payload: any, options?: AiInvokeOptions) => Promise<AiInvokeResult<T>>
|
|
54
|
+
testProvider: (config: AiProviderConfig) => Promise<unknown>
|
|
55
|
+
testCapability: (params: Record<string, any>) => Promise<unknown>
|
|
56
|
+
fetchModels: (config: AiProviderConfig) => Promise<{ success: boolean, models?: string[], message?: string }>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function createIntelligenceClient(channel?: IntelligenceClientChannel, resolvers?: IntelligenceChannelResolver[]): IntelligenceClient {
|
|
60
|
+
const resolvedChannel = channel ?? resolveIntelligenceChannel(resolvers)
|
|
61
|
+
if (!resolvedChannel) {
|
|
62
|
+
throw new Error('[Intelligence Client] Unable to resolve channel. Pass a channel instance or register a resolver.')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
invoke<T = any>(capabilityId: string, payload: any, options?: AiInvokeOptions) {
|
|
67
|
+
return assertResponse<AiInvokeResult<T>>(
|
|
68
|
+
resolvedChannel.send('intelligence:invoke', { capabilityId, payload, options }),
|
|
69
|
+
)
|
|
70
|
+
},
|
|
71
|
+
testProvider(config: AiProviderConfig) {
|
|
72
|
+
return assertResponse(
|
|
73
|
+
resolvedChannel.send('intelligence:test-provider', { provider: config }),
|
|
74
|
+
)
|
|
75
|
+
},
|
|
76
|
+
testCapability(params: Record<string, any>) {
|
|
77
|
+
return assertResponse(
|
|
78
|
+
resolvedChannel.send('intelligence:test-capability', params),
|
|
79
|
+
)
|
|
80
|
+
},
|
|
81
|
+
fetchModels(config: AiProviderConfig) {
|
|
82
|
+
return assertResponse<{ success: boolean, models?: string[], message?: string }>(
|
|
83
|
+
resolvedChannel.send('intelligence:fetch-models', { provider: config }),
|
|
84
|
+
)
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './client'
|