@talex-touch/utils 1.0.14 → 1.0.15

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.
Files changed (41) hide show
  1. package/base/index.ts +181 -181
  2. package/channel/index.ts +108 -99
  3. package/common/index.ts +2 -39
  4. package/common/storage/constants.ts +3 -0
  5. package/common/storage/entity/app-settings.ts +47 -0
  6. package/common/storage/entity/index.ts +1 -0
  7. package/common/storage/index.ts +3 -0
  8. package/common/utils.ts +160 -0
  9. package/core-box/README.md +218 -0
  10. package/core-box/index.ts +7 -0
  11. package/core-box/search.ts +536 -0
  12. package/core-box/types.ts +384 -0
  13. package/electron/download-manager.ts +118 -0
  14. package/{common → electron}/env-tool.ts +56 -56
  15. package/electron/touch-core.ts +167 -0
  16. package/electron/window.ts +71 -0
  17. package/eventbus/index.ts +86 -87
  18. package/index.ts +5 -0
  19. package/package.json +55 -30
  20. package/permission/index.ts +48 -48
  21. package/plugin/channel.ts +203 -193
  22. package/plugin/index.ts +216 -121
  23. package/plugin/log/logger-manager.ts +60 -0
  24. package/plugin/log/logger.ts +75 -0
  25. package/plugin/log/types.ts +27 -0
  26. package/plugin/preload.ts +39 -39
  27. package/plugin/sdk/common.ts +27 -27
  28. package/plugin/sdk/hooks/life-cycle.ts +95 -95
  29. package/plugin/sdk/index.ts +18 -13
  30. package/plugin/sdk/service/index.ts +29 -29
  31. package/plugin/sdk/types.ts +578 -0
  32. package/plugin/sdk/window/index.ts +40 -40
  33. package/renderer/index.ts +2 -0
  34. package/renderer/ref.ts +54 -54
  35. package/renderer/slots.ts +124 -0
  36. package/renderer/storage/app-settings.ts +34 -0
  37. package/renderer/storage/base-storage.ts +335 -0
  38. package/renderer/storage/index.ts +1 -0
  39. package/search/types.ts +726 -0
  40. package/service/index.ts +67 -67
  41. package/service/protocol/index.ts +77 -77
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Core Box Type Definitions
3
+ * Universal types extracted from various parts of the project for reuse across the entire codebase
4
+ */
5
+
6
+ import type { IPluginIcon, IFeatureCommand } from '@talex-touch/utils/plugin';
7
+
8
+ /**
9
+ * Render mode enumeration for search result items
10
+ * Defines different ways to render search result content
11
+ */
12
+ export enum RenderMode {
13
+ /** Standard text-based rendering */
14
+ STANDARD = 'standard',
15
+ /** URL-based rendering - loads and displays remote URL content */
16
+ URL = 'url',
17
+ /** HTML content rendering */
18
+ HTML = 'html',
19
+ /** JavaScript code rendering with syntax highlighting */
20
+ JAVASCRIPT = 'javascript',
21
+ /** JSX component rendering */
22
+ JSX = 'jsx',
23
+ /** Vue Single File Component rendering */
24
+ VUE_SFC = 'vue-sfc'
25
+ }
26
+
27
+ /**
28
+ * Render configuration for search result items
29
+ * Specifies how the search result should be displayed in the UI
30
+ */
31
+ export interface IRenderConfig {
32
+ /** The rendering mode to use */
33
+ mode: RenderMode;
34
+
35
+ /**
36
+ * Content to render
37
+ * - For URL mode: The remote URL to load and display
38
+ * - For HTML mode: HTML content string
39
+ * - For code modes: Source code string
40
+ */
41
+ content?: string;
42
+
43
+ /** Additional render options */
44
+ options?: {
45
+ /** Whether to enable syntax highlighting for code */
46
+ syntaxHighlight?: boolean;
47
+ /** Theme for code highlighting */
48
+ theme?: string;
49
+ /** Whether to show line numbers */
50
+ showLineNumbers?: boolean;
51
+ /** Custom CSS classes */
52
+ className?: string;
53
+ /** Inline styles */
54
+ style?: Record<string, string>;
55
+ /** Whether content is trusted (for HTML rendering) */
56
+ trusted?: boolean;
57
+ };
58
+
59
+ /**
60
+ * Preview configuration - provides metadata for URL previews
61
+ * Used to show rich preview information before loading the actual URL content
62
+ */
63
+ preview?: {
64
+ /** Whether to show URL preview */
65
+ enabled?: boolean;
66
+ /** Preview image URL */
67
+ image?: string;
68
+ /** Preview title */
69
+ title?: string;
70
+ /** Preview description */
71
+ description?: string;
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Search result item interface - unified data structure
77
+ * Compatible with SearchItem in app/core/src/views/box/search-box.ts
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const searchItem: ISearchItem = {
82
+ * name: "Example Result",
83
+ * desc: "This is an example search result",
84
+ * icon: { type: 'remix', value: 'search', init: async () => {} },
85
+ * push: false,
86
+ * names: ["Example Result"],
87
+ * keyWords: ["example", "result"],
88
+ * pluginType: "feature",
89
+ * type: "plugin",
90
+ * value: "example-plugin",
91
+ * render: {
92
+ * mode: RenderMode.STANDARD
93
+ * }
94
+ * };
95
+ * ```
96
+ */
97
+ export interface ISearchItem {
98
+ /** Display name of the search result */
99
+ name: string;
100
+
101
+ /** Description or subtitle of the search result */
102
+ desc: string;
103
+
104
+ /** Icon configuration for visual representation */
105
+ icon: IPluginIcon;
106
+
107
+ /** Whether this item supports push mode functionality */
108
+ push: boolean;
109
+
110
+ /** List of feature commands associated with this item */
111
+ commands?: IFeatureCommand[];
112
+
113
+ /** Array of searchable names for this item */
114
+ names: string[];
115
+
116
+ /** Array of keywords for search matching */
117
+ keyWords: string[];
118
+
119
+ /** Type of plugin this item belongs to */
120
+ pluginType: string;
121
+
122
+ /** General type classification of the item */
123
+ type: string;
124
+
125
+ /** Associated value, typically the plugin name */
126
+ value: string;
127
+
128
+ /** Usage frequency counter for ranking */
129
+ amo?: number;
130
+
131
+ /** Matching information from search algorithms */
132
+ matched?: any;
133
+
134
+ /** Whether this item was matched by name */
135
+ matchedByName?: boolean;
136
+
137
+ /** Whether this item was matched by description */
138
+ descMatched?: boolean;
139
+
140
+ /** Whether this item was matched by abbreviation */
141
+ abridgeMatched?: boolean;
142
+
143
+ /** Unique identifier for this search item */
144
+ id?: string;
145
+
146
+ /** Action to execute when this item is selected */
147
+ action?: string;
148
+
149
+ /** Reference to original feature object for command matching */
150
+ originFeature?: ISearchItem;
151
+
152
+ /** Render configuration for custom display */
153
+ render?: IRenderConfig;
154
+
155
+ /** Additional properties for extensibility */
156
+ [key: string]: any;
157
+ }
158
+
159
+ /**
160
+ * Search mode enumeration
161
+ * Defines different modes of operation for the search box
162
+ */
163
+ export enum BoxMode {
164
+ /** Standard input mode for text search */
165
+ INPUT = 0,
166
+ /** Command mode for executing specific commands */
167
+ COMMAND = 1,
168
+ /** Image mode for image-based search */
169
+ IMAGE = 2,
170
+ /** File mode for file-based operations */
171
+ FILE = 3,
172
+ /** Feature mode for plugin feature activation */
173
+ FEATURE = 4
174
+ }
175
+
176
+ /**
177
+ * Search options configuration
178
+ * Configures how search operations should be performed
179
+ */
180
+ export interface ISearchOptions {
181
+ /** The search mode to use */
182
+ mode: BoxMode;
183
+
184
+ /** Maximum number of results to return */
185
+ maxResults?: number;
186
+
187
+ /** Whether to enable fuzzy matching algorithms */
188
+ fuzzyMatch?: boolean;
189
+
190
+ /** Search timeout in milliseconds */
191
+ timeout?: number;
192
+
193
+ /** Whether to include cached results */
194
+ includeCached?: boolean;
195
+
196
+ /** Minimum confidence score for results */
197
+ minConfidence?: number;
198
+ }
199
+
200
+ /**
201
+ * Plugin search result push interface
202
+ * Used when plugins push search results to the core box
203
+ */
204
+ export interface IPluginSearchResult {
205
+ /** Name of the plugin pushing the results */
206
+ pluginName: string;
207
+
208
+ /** Array of search result items */
209
+ items: ISearchItem[];
210
+
211
+ /** Timestamp when results were generated */
212
+ timestamp: number;
213
+
214
+ /** Original query that generated these results */
215
+ query: string;
216
+
217
+ /** Total number of results available */
218
+ total: number;
219
+
220
+ /** Whether more results are available */
221
+ hasMore?: boolean;
222
+
223
+ /** Metadata about the search operation */
224
+ metadata?: {
225
+ /** Time taken to generate results in milliseconds */
226
+ processingTime?: number;
227
+ /** Source of the results */
228
+ source?: string;
229
+ /** Confidence score of the overall result set */
230
+ confidence?: number;
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Search result manager interface
236
+ * Manages search results within the core box
237
+ */
238
+ export interface ISearchResultManager {
239
+ /** Push new search results to the manager */
240
+ pushItems(items: ISearchItem[]): void;
241
+
242
+ /** Clear all current search results */
243
+ clearItems(): void;
244
+
245
+ /** Get all current search results */
246
+ getItems(): ISearchItem[];
247
+
248
+ /** Update a specific search result item */
249
+ updateItem(id: string, item: Partial<ISearchItem>): boolean;
250
+
251
+ /** Remove a specific search result item */
252
+ removeItem(id: string): boolean;
253
+
254
+ /** Get the total count of search results */
255
+ getCount(): number;
256
+
257
+ /** Filter results based on criteria */
258
+ filterItems(predicate: (item: ISearchItem) => boolean): ISearchItem[];
259
+
260
+ /** Sort results using a comparison function */
261
+ sortItems(compareFn: (a: ISearchItem, b: ISearchItem) => number): void;
262
+ }
263
+
264
+ /**
265
+ * Generic data item interface
266
+ * Extended search item for various types of data processing results
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * const dataItem: IDataItem = {
271
+ * name: "Translation Result",
272
+ * desc: "English to Chinese translation",
273
+ * // ... other ISearchItem properties
274
+ * source: "google-translate",
275
+ * dataType: "translation",
276
+ * originalData: "Hello World",
277
+ * processedData: "你好世界",
278
+ * confidence: 95
279
+ * };
280
+ * ```
281
+ */
282
+ export interface IDataItem extends ISearchItem {
283
+ /** Source service or system that generated this data */
284
+ source?: string;
285
+
286
+ /** Type of data processing performed */
287
+ dataType?: string;
288
+
289
+ /** Original input data before processing */
290
+ originalData?: any;
291
+
292
+ /** Processed output data */
293
+ processedData?: any;
294
+
295
+ /** Quality score of the processing result (0-100) */
296
+ quality?: number;
297
+
298
+ /** Whether this result was retrieved from cache */
299
+ cached?: boolean;
300
+
301
+ /** Processing time in milliseconds */
302
+ duration?: number;
303
+
304
+ /** Confidence level of the result (0-100) */
305
+ confidence?: number;
306
+
307
+ /** Additional metadata about the processing */
308
+ metadata?: Record<string, any>;
309
+ }
310
+
311
+ /**
312
+ * Application item interface
313
+ * Represents an application in search results
314
+ */
315
+ export interface IAppItem extends ISearchItem {
316
+ /** File system path to the application */
317
+ path?: string;
318
+
319
+ /** Version string of the application */
320
+ version?: string;
321
+
322
+ /** File size in bytes */
323
+ size?: number;
324
+
325
+ /** Timestamp of last usage */
326
+ lastUsed?: number;
327
+
328
+ /** Application category */
329
+ category?: string;
330
+
331
+ /** Whether the application is currently running */
332
+ isRunning?: boolean;
333
+ }
334
+
335
+ /**
336
+ * File item interface
337
+ * Represents a file in search results
338
+ */
339
+ export interface IFileItem extends ISearchItem {
340
+ /** Full file system path */
341
+ filePath: string;
342
+
343
+ /** File size in bytes */
344
+ fileSize?: number;
345
+
346
+ /** MIME type of the file */
347
+ fileType?: string;
348
+
349
+ /** File extension */
350
+ extension?: string;
351
+
352
+ /** Last modified timestamp */
353
+ modifiedTime?: number;
354
+
355
+ /** Creation timestamp */
356
+ createdTime?: number;
357
+
358
+ /** Whether the file is currently accessible */
359
+ accessible?: boolean;
360
+ }
361
+
362
+ /**
363
+ * Feature item interface
364
+ * Represents a plugin feature in search results
365
+ */
366
+ export interface IFeatureItem extends ISearchItem {
367
+ /** Unique identifier for the feature */
368
+ featureId: string;
369
+
370
+ /** Name of the plugin that owns this feature */
371
+ pluginName: string;
372
+
373
+ /** Detailed description of the feature */
374
+ featureDesc?: string;
375
+
376
+ /** Parameters required by the feature */
377
+ parameters?: Record<string, any>;
378
+
379
+ /** Whether the feature is currently enabled */
380
+ enabled?: boolean;
381
+
382
+ /** Feature category or group */
383
+ category?: string;
384
+ }
@@ -0,0 +1,118 @@
1
+ import { net } from 'electron'
2
+ import fse from 'fs-extra'
3
+ import path from 'path'
4
+
5
+ interface DownloadItem {
6
+ url: string;
7
+ filename: string;
8
+ apply?: (filePath: string) => void;
9
+ }
10
+
11
+ export class DownloadManager {
12
+ private basePath: string;
13
+ private downloadQueue: DownloadItem[] = [];
14
+ private isDownloading = false;
15
+
16
+ constructor(basePath: string = '') {
17
+ this.basePath = basePath;
18
+ }
19
+
20
+ /**
21
+ * Add a download item to the queue
22
+ * @param item The download item object
23
+ */
24
+ addDownload(item: DownloadItem): void {
25
+ this.downloadQueue.push(item);
26
+ if (!this.isDownloading) {
27
+ this.processQueue();
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Add multiple download items to the queue
33
+ * @param items Array of download items
34
+ */
35
+ addDownloads(items: DownloadItem[]): void {
36
+ this.downloadQueue.push(...items);
37
+ if (!this.isDownloading) {
38
+ this.processQueue();
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Process the download queue
44
+ */
45
+ private async processQueue(): Promise<void> {
46
+ if (this.downloadQueue.length === 0) {
47
+ this.isDownloading = false;
48
+ return;
49
+ }
50
+
51
+ this.isDownloading = true;
52
+ const item = this.downloadQueue.shift()!;
53
+
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`);
58
+
59
+ if (item.apply) {
60
+ item.apply(filePath);
61
+ }
62
+ } catch (error) {
63
+ console.error(`[DownloadManager] Download ${item.filename} failed:`, error);
64
+ }
65
+
66
+ this.processQueue();
67
+ }
68
+
69
+ /**
70
+ * Download a single file
71
+ * @param url The download URL
72
+ * @param filename The filename to save as
73
+ * @returns The file path where the file is saved
74
+ */
75
+ private downloadFile(url: string, filename: string): Promise<string> {
76
+ return new Promise((resolve, reject) => {
77
+ const request = net.request(url);
78
+ const filePath = this.basePath ? path.join(this.basePath, filename) : filename;
79
+
80
+ console.log(`[DownloadManager] File download request sent for ${filename}.`);
81
+
82
+ request.addListener('error', (error) => {
83
+ console.error(`[DownloadManager] Download request error for ${filename}:`, error);
84
+ reject(error);
85
+ });
86
+
87
+ request.addListener('response', (response) => {
88
+ fse.createFileSync(filePath);
89
+
90
+ response.addListener('data', (chunk: any) => {
91
+ console.log(`[DownloadManager] Downloading ${filename}...`);
92
+ fse.appendFile(filePath, chunk, 'utf8');
93
+ });
94
+
95
+ response.addListener('end', () => {
96
+ console.log(`[DownloadManager] Download ${filename} finished.`);
97
+ resolve(filePath);
98
+ });
99
+ });
100
+
101
+ request.end();
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Clear the download queue
107
+ */
108
+ clearQueue(): void {
109
+ this.downloadQueue = [];
110
+ }
111
+
112
+ /**
113
+ * Get the number of items in the download queue
114
+ */
115
+ getQueueLength(): number {
116
+ return this.downloadQueue.length;
117
+ }
118
+ }
@@ -1,57 +1,57 @@
1
- import { exec, ExecException } from 'child_process';
2
-
3
- export interface IGlobalPkgResult {
4
- exist: boolean
5
- error?: ExecException
6
- name?: string
7
- version?: string
8
- }
9
-
10
- export function checkGlobalPackageExist(packageName: string): Promise<IGlobalPkgResult> {
11
- return new Promise((resolve, reject) => {
12
- exec(`npm list -g ${packageName}`, (error, stdout, stderr) => {
13
- if (error) {
14
- reject({
15
- exits: false,
16
- error: error
17
- });
18
- return;
19
- }
20
- if (stderr) {
21
- reject({
22
- exits: false,
23
- error: stderr
24
- });
25
- return;
26
- }
27
-
28
- const lines = stdout.split('\n');
29
- const lastLine = lines[lines.length - 3];
30
- const match = lastLine.match(/(\S+)@(\S+)/);
31
- if (match) {
32
- resolve({
33
- exist: true,
34
- name: match[1],
35
- version: match[2]
36
- } as IGlobalPkgResult);
37
- return;
38
- }
39
-
40
- resolve({
41
- exist: false
42
- } as IGlobalPkgResult)
43
-
44
- });
45
- })
46
- }
47
-
48
- // Check npm version
49
- export function getNpmVersion(): Promise<string | null> {
50
- return new Promise((resolve) => {
51
- exec(`npm --version`, (error, stdout, stderr) => {
52
- if (error || stderr) resolve(null)
53
-
54
- resolve(stdout.trim())
55
- })
56
- })
1
+ import { exec, ExecException } from 'child_process';
2
+
3
+ export interface IGlobalPkgResult {
4
+ exist: boolean
5
+ error?: ExecException
6
+ name?: string
7
+ version?: string
8
+ }
9
+
10
+ export function checkGlobalPackageExist(packageName: string): Promise<IGlobalPkgResult> {
11
+ return new Promise((resolve, reject) => {
12
+ exec(`npm list -g ${packageName}`, (error, stdout, stderr) => {
13
+ if (error) {
14
+ reject({
15
+ exits: false,
16
+ error: error
17
+ });
18
+ return;
19
+ }
20
+ if (stderr) {
21
+ reject({
22
+ exits: false,
23
+ error: stderr
24
+ });
25
+ return;
26
+ }
27
+
28
+ const lines = stdout.split('\n');
29
+ const lastLine = lines[lines.length - 3];
30
+ const match = lastLine.match(/(\S+)@(\S+)/);
31
+ if (match) {
32
+ resolve({
33
+ exist: true,
34
+ name: match[1],
35
+ version: match[2]
36
+ } as IGlobalPkgResult);
37
+ return;
38
+ }
39
+
40
+ resolve({
41
+ exist: false
42
+ } as IGlobalPkgResult)
43
+
44
+ });
45
+ })
46
+ }
47
+
48
+ // Check npm version
49
+ export function getNpmVersion(): Promise<string | null> {
50
+ return new Promise((resolve) => {
51
+ exec(`npm --version`, (error, stdout, stderr) => {
52
+ if (error || stderr) resolve(null)
53
+
54
+ resolve(stdout.trim())
55
+ })
56
+ })
57
57
  }