@talex-touch/utils 1.0.14 → 1.0.16

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,160 @@
1
+ /**
2
+ * Delays execution for a given amount of milliseconds.
3
+ *
4
+ * @param time - Time to sleep in milliseconds.
5
+ * @returns A promise that resolves with the same time value after the delay.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * await sleep(1000); // Waits for 1 second
10
+ * ```
11
+ */
12
+ export async function sleep(time: number): Promise<number> {
13
+ return new Promise(resolve => setTimeout(() => resolve(time), time))
14
+ }
15
+
16
+ /**
17
+ * Encodes any string into a `bigint` by converting each character's char code
18
+ * into a relative offset based on the minimum char code in the string.
19
+ *
20
+ * Format: `{minCharCode}000{paddedOffsetPairs}`
21
+ *
22
+ * @param str - Any input string to encode.
23
+ * @returns A BigInt representation of the input string.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const encoded = anyStr2Num("abc"); // e.g., 970000000102
28
+ * ```
29
+ */
30
+ export function anyStr2Num(str: string): bigint {
31
+ const codes = Array.from(str).map(ch => ch.charCodeAt(0))
32
+ const minCode = Math.min(...codes)
33
+
34
+ const encoded = codes
35
+ .map(code => (code - minCode).toString().padStart(2, '0'))
36
+ .join('')
37
+
38
+ return BigInt(`${minCode}000${encoded}`)
39
+ }
40
+
41
+ /**
42
+ * Decodes a BigInt back into the original string.
43
+ * Assumes the format produced by `anyStr2Num`.
44
+ *
45
+ * @param num - The BigInt to decode.
46
+ * @returns The original decoded string.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const decoded = num2anyStr(970000000102n); // returns "abc"
51
+ * ```
52
+ */
53
+ export function num2anyStr(num: bigint): string {
54
+ const [baseStr, encoded] = num.toString().split('000')
55
+ const base = Number(baseStr)
56
+
57
+ let result = ''
58
+ for (let i = 0; i < encoded.length; i += 2) {
59
+ const offset = Number(encoded.slice(i, i + 2))
60
+ result += String.fromCharCode(base + offset)
61
+ }
62
+
63
+ return result
64
+ }
65
+
66
+ const LOCALHOST_KEYS = ['localhost', '127.0.0.1']
67
+
68
+ /**
69
+ * Determines whether a given URL string points to localhost.
70
+ *
71
+ * @param urlStr - The full URL string to check.
72
+ * @returns `true` if the URL hostname is `localhost` or `127.0.0.1`, otherwise `false`.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * isLocalhostUrl("http://localhost:3000"); // true
77
+ * isLocalhostUrl("https://example.com"); // false
78
+ * ```
79
+ */
80
+ export function isLocalhostUrl(urlStr: string): boolean {
81
+ return LOCALHOST_KEYS.includes(new URL(urlStr).hostname)
82
+ }
83
+
84
+ /**
85
+ * Serializes a value to JSON, throwing a detailed error on the first unsupported value (like a function, DOM node, symbol, etc.).
86
+ * Reports the exact path to the error.
87
+ *
88
+ * @param value - Any JS value.
89
+ * @returns The JSON string if serialization succeeds.
90
+ * @throws Error if an unsupported value is found (reports path and type).
91
+ */
92
+ export function structuredStrictStringify(value: unknown): string {
93
+ const seen = new WeakMap<object, string>();
94
+ const badTypes = [
95
+ 'symbol'
96
+ ];
97
+ // Support Map/Set, but not Error, DOM, Proxy, WeakMap, WeakSet
98
+ function getType(val: any): string {
99
+ if (val === null) return 'null';
100
+ if (Array.isArray(val)) return 'Array';
101
+ if (typeof Document !== 'undefined') {
102
+ if (val instanceof Node) return 'DOMNode';
103
+ }
104
+ if (val instanceof Error) return 'Error';
105
+ if (val instanceof WeakMap) return 'WeakMap';
106
+ if (val instanceof WeakSet) return 'WeakSet';
107
+ if (typeof val === 'object' && val !== null && val.constructor?.name === 'Proxy') return 'Proxy';
108
+ if (typeof val === 'bigint') return 'BigInt';
109
+ return typeof val;
110
+ }
111
+
112
+ function serialize(val: any, path: string): any {
113
+ const type = getType(val);
114
+ // Block disallowed/unsafe types and edge cases for structured-clone
115
+ if (badTypes.includes(typeof val) || type === 'DOMNode' || type === 'Error' || type === 'Proxy' || type === 'WeakMap' || type === 'WeakSet' || type === 'BigInt') {
116
+ throw new Error(`Cannot serialize property at path "${path}": type "${type}"`);
117
+ }
118
+ // JSON doesn't support undefined, skip it for values in objects, preserve in arrays as null
119
+ if (typeof val === 'undefined') return null;
120
+ // Simple value
121
+ if (
122
+ val === null ||
123
+ typeof val === 'number' ||
124
+ typeof val === 'boolean' ||
125
+ typeof val === 'string'
126
+ ) return val;
127
+ // Cycle check
128
+ if (typeof val === 'object') {
129
+ if (seen.has(val)) {
130
+ return `[Circular ~${seen.get(val)}]`; // You could just throw if you dislike this fallback!
131
+ }
132
+ seen.set(val, path);
133
+ if (Array.isArray(val)) {
134
+ return val.map((item, idx) => serialize(item, `${path}[${idx}]`));
135
+ }
136
+ if (val instanceof Date) {
137
+ return val.toISOString();
138
+ }
139
+ if (val instanceof Map) {
140
+ const obj: Record<string, any> = {};
141
+ for (const [k, v] of val.entries()) {
142
+ obj[typeof k === 'string' ? k : JSON.stringify(k)] = serialize(v, `${path}[Map(${typeof k === 'string' ? k : JSON.stringify(k)})]`);
143
+ }
144
+ return obj;
145
+ }
146
+ if (val instanceof Set) {
147
+ return Array.from(val).map((item, idx) => serialize(item, `${path}[SetEntry${idx}]`));
148
+ }
149
+ // General object
150
+ const res: any = {};
151
+ for (const key of Object.keys(val)) {
152
+ res[key] = serialize(val[key], `${path}.${key}`);
153
+ }
154
+ return res;
155
+ }
156
+ throw new Error(`Cannot serialize property at path "${path}": unknown type`);
157
+ }
158
+
159
+ return JSON.stringify(serialize(value, 'root'));
160
+ }
@@ -0,0 +1,218 @@
1
+ # Core Box Package
2
+
3
+ The Core Box package provides unified type definitions and utility functions for the Talex Touch search box system. This package contains the foundational types and tools used across the entire project for search result management and plugin integration.
4
+
5
+ ## Features
6
+
7
+ ### 🎯 Unified Type System
8
+ - **ISearchItem**: Universal search result item interface
9
+ - **IRenderConfig**: Flexible rendering configuration with multiple modes
10
+ - **IDataItem**: Extended interface for data processing results
11
+ - **IAppItem**: Specialized interface for application results
12
+ - **IFileItem**: Specialized interface for file results
13
+ - **IFeatureItem**: Specialized interface for plugin feature results
14
+
15
+ ### 🎨 Render Modes
16
+ The package supports multiple rendering modes for search results:
17
+
18
+ - **STANDARD**: Default text-based rendering
19
+ - **URL**: URL rendering - loads and displays remote URL content
20
+ - **HTML**: Rich HTML content rendering
21
+ - **JAVASCRIPT**: JavaScript code with syntax highlighting
22
+ - **JSX**: React JSX component rendering
23
+ - **VUE_SFC**: Vue Single File Component rendering
24
+
25
+ ### 🛠️ Utility Functions
26
+ Comprehensive set of utility functions for creating and managing search results:
27
+
28
+ - `SearchUtils.createSearchItem()`: Create basic search items
29
+ - `SearchUtils.createDataItem()`: Create data processing results
30
+ - `SearchUtils.createAppItem()`: Create application results
31
+ - `SearchUtils.createFileItem()`: Create file results
32
+ - `SearchUtils.createFeatureItem()`: Create plugin feature results
33
+ - `SearchUtils.createErrorItem()`: Create error state items
34
+ - `SearchUtils.sortByPriority()`: Sort results by relevance
35
+ - `SearchUtils.removeDuplicates()`: Remove duplicate results
36
+ - `SearchUtils.filterByConfidence()`: Filter by confidence score
37
+ - `SearchUtils.groupByPluginType()`: Group results by type
38
+
39
+ ## Usage Examples
40
+
41
+ ### Basic Search Item
42
+ ```typescript
43
+ import { SearchUtils, RenderMode } from '@talex-touch/utils';
44
+
45
+ const basicItem = SearchUtils.createSearchItem({
46
+ name: "My Feature",
47
+ desc: "A useful plugin feature",
48
+ pluginName: "my-plugin",
49
+ keyWords: ["feature", "utility"],
50
+ render: {
51
+ mode: RenderMode.STANDARD
52
+ }
53
+ });
54
+ ```
55
+
56
+ ### Data Processing Result
57
+ ```typescript
58
+ const dataItem = SearchUtils.createDataItem({
59
+ name: "Translation Result",
60
+ desc: "English to Chinese translation",
61
+ pluginName: "translator",
62
+ source: "google-translate",
63
+ dataType: "translation",
64
+ originalData: "Hello World",
65
+ processedData: "你好世界",
66
+ confidence: 95,
67
+ duration: 120,
68
+ render: {
69
+ mode: RenderMode.STANDARD
70
+ }
71
+ });
72
+ ```
73
+
74
+ ### HTML Rendering
75
+ ```typescript
76
+ const htmlItem = SearchUtils.createSearchItem({
77
+ name: "Rich Content",
78
+ desc: "HTML formatted result",
79
+ pluginName: "content-plugin",
80
+ render: {
81
+ mode: RenderMode.HTML,
82
+ content: "<div><h3>Title</h3><p>Content</p></div>",
83
+ options: {
84
+ trusted: true,
85
+ className: "custom-content"
86
+ }
87
+ }
88
+ });
89
+ ```
90
+
91
+ ### Code Rendering
92
+ ```typescript
93
+ const codeItem = SearchUtils.createDataItem({
94
+ name: "JavaScript Function",
95
+ desc: "Generated code snippet",
96
+ pluginName: "code-generator",
97
+ dataType: "javascript",
98
+ processedData: "function hello() { return 'world'; }",
99
+ render: {
100
+ mode: RenderMode.JAVASCRIPT,
101
+ content: "function hello() { return 'world'; }",
102
+ options: {
103
+ syntaxHighlight: true,
104
+ showLineNumbers: true,
105
+ theme: "dark"
106
+ }
107
+ }
108
+ });
109
+ ```
110
+
111
+ ### URL Rendering with Preview
112
+ ```typescript
113
+ const urlItem = SearchUtils.createSearchItem({
114
+ name: "GitHub Repository",
115
+ desc: "Talex Touch project",
116
+ pluginName: "web-search",
117
+ render: {
118
+ mode: RenderMode.URL,
119
+ content: "https://github.com/talex-touch/talex-touch", // The actual URL to load
120
+ preview: {
121
+ enabled: true,
122
+ title: "Talex Touch", // Preview metadata
123
+ description: "Modern desktop application framework", // Preview description
124
+ image: "https://github.com/talex-touch.png" // Preview image
125
+ }
126
+ }
127
+ });
128
+ ```
129
+
130
+ **Note**:
131
+ - `content`: The remote URL that will be loaded and displayed
132
+ - `preview`: Metadata shown before/alongside the loaded URL content
133
+
134
+ ## Type Definitions
135
+
136
+ ### ISearchItem
137
+ The core interface for all search results:
138
+
139
+ ```typescript
140
+ interface ISearchItem {
141
+ name: string; // Display name
142
+ desc: string; // Description
143
+ icon: IPluginIcon; // Icon configuration
144
+ push: boolean; // Push mode support
145
+ names: string[]; // Searchable names
146
+ keyWords: string[]; // Search keywords
147
+ pluginType: string; // Plugin type
148
+ type: string; // General type
149
+ value: string; // Associated value
150
+ render?: IRenderConfig; // Render configuration
151
+ // ... additional properties
152
+ }
153
+ ```
154
+
155
+ ### IRenderConfig
156
+ Configuration for custom rendering:
157
+
158
+ ```typescript
159
+ interface IRenderConfig {
160
+ mode: RenderMode; // Rendering mode
161
+ content?: string; // Content to render
162
+ options?: { // Render options
163
+ syntaxHighlight?: boolean;
164
+ theme?: string;
165
+ showLineNumbers?: boolean;
166
+ className?: string;
167
+ style?: Record<string, string>;
168
+ trusted?: boolean;
169
+ };
170
+ preview?: { // URL preview config
171
+ enabled?: boolean;
172
+ image?: string;
173
+ title?: string;
174
+ description?: string;
175
+ };
176
+ }
177
+ ```
178
+
179
+ ## Integration
180
+
181
+ This package is automatically exported from `@talex-touch/utils`:
182
+
183
+ ```typescript
184
+ import {
185
+ ISearchItem,
186
+ IDataItem,
187
+ SearchUtils,
188
+ RenderMode
189
+ } from '@talex-touch/utils';
190
+ ```
191
+
192
+ ## Best Practices
193
+
194
+ 1. **Always specify render mode**: Even for standard rendering, explicitly set the render mode
195
+ 2. **Use appropriate specialized interfaces**: Use IDataItem for data processing, IAppItem for applications, etc.
196
+ 3. **Include confidence scores**: For data processing results, always include confidence levels
197
+ 4. **Sanitize HTML content**: When using HTML render mode, ensure content is safe
198
+ 5. **Provide meaningful keywords**: Include relevant search terms in the keyWords array
199
+ 6. **Use consistent naming**: Follow established naming conventions for plugin types
200
+
201
+ ## Migration Guide
202
+
203
+ If you're migrating from the old type system:
204
+
205
+ 1. Replace `ITranslationItem` with `IDataItem`
206
+ 2. Update render configurations to use the new `IRenderConfig` interface
207
+ 3. Use `SearchUtils` functions instead of manual object creation
208
+ 4. Update import paths to use `@talex-touch/utils`
209
+
210
+ ## Contributing
211
+
212
+ When adding new types or utilities:
213
+
214
+ 1. Add comprehensive TSDoc comments in English
215
+ 2. Include usage examples in documentation
216
+ 3. Follow the established naming conventions
217
+ 4. Add appropriate unit tests
218
+ 5. Update this README with new features
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Core Box Package
3
+ * Search box core functionality package
4
+ */
5
+
6
+ export * from './search';
7
+ export * from './types';