@talex-touch/utils 1.0.31 → 1.0.33

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 (116) hide show
  1. package/animation/window-node.ts +15 -12
  2. package/animation/window.ts +19 -15
  3. package/auth/clerk-types.ts +1 -1
  4. package/auth/index.ts +1 -1
  5. package/auth/useAuthState.ts +6 -5
  6. package/auth/useClerkConfig.ts +4 -4
  7. package/auth/useClerkProvider.ts +3 -2
  8. package/channel/index.ts +23 -22
  9. package/common/file-scan-constants.ts +137 -121
  10. package/common/file-scan-utils.ts +48 -27
  11. package/common/index.ts +3 -3
  12. package/common/search/gather.ts +1 -1
  13. package/common/search/index.ts +5 -6
  14. package/common/storage/constants.ts +3 -2
  15. package/common/storage/entity/app-settings.ts +5 -3
  16. package/common/storage/entity/shortcut-settings.ts +10 -10
  17. package/common/storage/shortcut-storage.ts +6 -4
  18. package/common/utils/file.ts +14 -6
  19. package/common/utils/index.ts +62 -52
  20. package/common/utils/polling.ts +88 -84
  21. package/common/utils/task-queue.ts +11 -10
  22. package/common/utils/time.ts +50 -47
  23. package/common/utils/timing.ts +41 -37
  24. package/core-box/builder/index.ts +1 -1
  25. package/core-box/builder/tuff-builder.ts +254 -229
  26. package/core-box/index.ts +4 -6
  27. package/core-box/preview/index.ts +1 -0
  28. package/core-box/preview/types.ts +43 -0
  29. package/core-box/recommendation.ts +77 -0
  30. package/core-box/tuff/index.ts +1 -1
  31. package/core-box/tuff/tuff-dsl.ts +328 -266
  32. package/electron/download-manager.ts +43 -42
  33. package/electron/env-tool.ts +19 -18
  34. package/electron/file-parsers/index.ts +2 -2
  35. package/electron/file-parsers/parsers/text-parser.ts +15 -14
  36. package/electron/file-parsers/registry.ts +9 -7
  37. package/electron/file-parsers/types.ts +4 -4
  38. package/electron/index.ts +2 -2
  39. package/eventbus/index.ts +11 -11
  40. package/index.ts +5 -4
  41. package/intelligence/client.ts +87 -0
  42. package/intelligence/index.ts +1 -0
  43. package/package.json +14 -14
  44. package/permission/index.ts +8 -8
  45. package/plugin/channel.ts +77 -68
  46. package/plugin/index.ts +96 -82
  47. package/plugin/install.ts +8 -8
  48. package/plugin/log/types.ts +5 -5
  49. package/plugin/node/index.ts +1 -1
  50. package/plugin/node/logger-manager.ts +14 -11
  51. package/plugin/node/logger.ts +8 -8
  52. package/plugin/plugin-source.ts +11 -11
  53. package/plugin/preload.ts +1 -1
  54. package/plugin/providers/registry.ts +8 -7
  55. package/plugin/providers/types.ts +6 -6
  56. package/plugin/sdk/README.md +216 -0
  57. package/plugin/sdk/box-sdk.ts +219 -0
  58. package/plugin/sdk/channel.ts +20 -20
  59. package/plugin/sdk/clipboard.ts +8 -6
  60. package/plugin/sdk/common.ts +10 -6
  61. package/plugin/sdk/core-box.ts +2 -3
  62. package/plugin/sdk/division-box.ts +266 -0
  63. package/plugin/sdk/enum/bridge-event.ts +1 -1
  64. package/plugin/sdk/examples/storage-onDidChange-example.js +1 -1
  65. package/plugin/sdk/feature-sdk.ts +235 -0
  66. package/plugin/sdk/features.ts +34 -26
  67. package/plugin/sdk/hooks/bridge.ts +3 -6
  68. package/plugin/sdk/hooks/index.ts +1 -1
  69. package/plugin/sdk/hooks/life-cycle.ts +4 -10
  70. package/plugin/sdk/index.ts +10 -7
  71. package/plugin/sdk/service/index.ts +3 -3
  72. package/plugin/sdk/storage.ts +4 -4
  73. package/plugin/sdk/system.ts +1 -1
  74. package/plugin/sdk/types.ts +165 -146
  75. package/plugin/sdk/window/index.ts +8 -5
  76. package/preload/loading.ts +6 -6
  77. package/preload/renderer.ts +4 -2
  78. package/renderer/hooks/arg-mapper.ts +1 -2
  79. package/renderer/hooks/index.ts +2 -0
  80. package/renderer/hooks/initialize.ts +10 -8
  81. package/renderer/hooks/performance.ts +4 -4
  82. package/renderer/hooks/use-channel.ts +150 -0
  83. package/renderer/hooks/use-intelligence.ts +236 -0
  84. package/renderer/index.ts +6 -2
  85. package/renderer/ref.ts +32 -36
  86. package/renderer/slots.ts +29 -26
  87. package/renderer/storage/app-settings.ts +16 -6
  88. package/renderer/storage/base-storage.ts +222 -114
  89. package/renderer/storage/index.ts +3 -0
  90. package/renderer/storage/intelligence-storage.ts +218 -0
  91. package/renderer/storage/openers.ts +13 -3
  92. package/renderer/touch-sdk/env.ts +41 -41
  93. package/renderer/touch-sdk/index.ts +1 -1
  94. package/renderer/touch-sdk/terminal.ts +5 -5
  95. package/renderer/touch-sdk/utils.ts +4 -3
  96. package/search/levenshtein-utils.ts +11 -11
  97. package/search/types.ts +102 -102
  98. package/service/index.ts +11 -11
  99. package/service/protocol/index.ts +217 -14
  100. package/types/division-box.ts +248 -0
  101. package/types/download.ts +72 -34
  102. package/types/index.ts +3 -1
  103. package/types/intelligence.ts +607 -0
  104. package/types/modules/base.ts +16 -16
  105. package/types/modules/index.ts +1 -1
  106. package/types/modules/module-lifecycle.ts +21 -21
  107. package/types/modules/module-manager.ts +11 -11
  108. package/types/modules/module.ts +16 -16
  109. package/types/storage.ts +0 -1
  110. package/types/touch-app-core.ts +32 -32
  111. package/types/update.ts +91 -21
  112. package/core-box/README.md +0 -218
  113. package/core-box/builder/tuff-builder.example.ts.bak +0 -258
  114. package/core-box/run-tests.sh +0 -7
  115. package/core-box/search.ts +0 -1
  116. package/electron/clipboard-helper.ts +0 -199
@@ -0,0 +1,266 @@
1
+ /**
2
+ * DivisionBox SDK for Plugin Development
3
+ *
4
+ * Provides a simple API for plugins to create and manage DivisionBox instances.
5
+ * DivisionBox is a lightweight floating window container for plugin UIs and tools.
6
+ */
7
+
8
+ import type {
9
+ CloseOptions,
10
+ DivisionBoxConfig,
11
+ DivisionBoxState,
12
+ SessionInfo,
13
+ } from '../../types/division-box'
14
+
15
+ /**
16
+ * State change event handler
17
+ */
18
+ export type StateChangeHandler = (data: {
19
+ sessionId: string
20
+ state: DivisionBoxState
21
+ }) => void
22
+
23
+ /**
24
+ * DivisionBox SDK interface for plugins
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Open a DivisionBox
29
+ * const { sessionId } = await plugin.divisionBox.open({
30
+ * url: 'https://example.com/tool',
31
+ * title: 'My Tool',
32
+ * size: 'medium',
33
+ * keepAlive: true
34
+ * })
35
+ *
36
+ * // Listen for state changes
37
+ * plugin.divisionBox.onStateChange((data) => {
38
+ * console.log(`Session ${data.sessionId} is now ${data.state}`)
39
+ * })
40
+ *
41
+ * // Close the DivisionBox
42
+ * await plugin.divisionBox.close(sessionId)
43
+ * ```
44
+ */
45
+ export interface DivisionBoxSDK {
46
+ /**
47
+ * Opens a new DivisionBox instance
48
+ *
49
+ * @param config - Configuration for the DivisionBox
50
+ * @returns Promise resolving to session information
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const { sessionId } = await plugin.divisionBox.open({
55
+ * url: 'https://example.com',
56
+ * title: 'Web Tool',
57
+ * icon: 'ri:tools-line',
58
+ * size: 'medium',
59
+ * keepAlive: true,
60
+ * header: {
61
+ * show: true,
62
+ * title: 'Custom Title',
63
+ * actions: [
64
+ * { label: 'Refresh', icon: 'ri:refresh-line', onClick: () => {} }
65
+ * ]
66
+ * }
67
+ * })
68
+ * ```
69
+ */
70
+ open(config: DivisionBoxConfig): Promise<SessionInfo>
71
+
72
+ /**
73
+ * Closes a DivisionBox instance
74
+ *
75
+ * @param sessionId - The session ID to close
76
+ * @param options - Optional close options
77
+ * @returns Promise that resolves when closed
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // Simple close
82
+ * await plugin.divisionBox.close(sessionId)
83
+ *
84
+ * // Close with delay and animation
85
+ * await plugin.divisionBox.close(sessionId, {
86
+ * delay: 1000,
87
+ * animation: true
88
+ * })
89
+ *
90
+ * // Force close (ignore keepAlive)
91
+ * await plugin.divisionBox.close(sessionId, {
92
+ * force: true
93
+ * })
94
+ * ```
95
+ */
96
+ close(sessionId: string, options?: CloseOptions): Promise<void>
97
+
98
+ /**
99
+ * Registers a state change listener
100
+ *
101
+ * @param handler - Callback function for state changes
102
+ * @returns Unsubscribe function
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const unsubscribe = plugin.divisionBox.onStateChange((data) => {
107
+ * console.log(`Session ${data.sessionId} changed to ${data.state}`)
108
+ * })
109
+ *
110
+ * // Later, unsubscribe
111
+ * unsubscribe()
112
+ * ```
113
+ */
114
+ onStateChange(handler: StateChangeHandler): () => void
115
+
116
+ /**
117
+ * Updates session state data
118
+ *
119
+ * @param sessionId - The session ID
120
+ * @param key - State key
121
+ * @param value - State value
122
+ * @returns Promise that resolves when updated
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * // Save scroll position
127
+ * await plugin.divisionBox.updateState(sessionId, 'scrollY', 150)
128
+ *
129
+ * // Save draft content
130
+ * await plugin.divisionBox.updateState(sessionId, 'draft', {
131
+ * text: 'Hello world',
132
+ * timestamp: Date.now()
133
+ * })
134
+ * ```
135
+ */
136
+ updateState(sessionId: string, key: string, value: any): Promise<void>
137
+
138
+ /**
139
+ * Gets session state data
140
+ *
141
+ * @param sessionId - The session ID
142
+ * @param key - State key
143
+ * @returns Promise resolving to the state value
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const scrollY = await plugin.divisionBox.getState(sessionId, 'scrollY')
148
+ * const draft = await plugin.divisionBox.getState(sessionId, 'draft')
149
+ * ```
150
+ */
151
+ getState(sessionId: string, key: string): Promise<any>
152
+ }
153
+
154
+ /**
155
+ * Creates a DivisionBox SDK instance for plugin use
156
+ *
157
+ * @param channel - The plugin channel bridge for IPC communication
158
+ * @returns Configured DivisionBox SDK instance
159
+ *
160
+ * @internal
161
+ */
162
+ export function createDivisionBoxSDK(channel: any): DivisionBoxSDK {
163
+ const stateChangeHandlers: Set<StateChangeHandler> = new Set()
164
+
165
+ // Register listener for state change events from main process
166
+ // The channel can be either IPluginChannelBridge (main process) or window.$channel (renderer)
167
+ const registerListener = () => {
168
+ if (channel.onMain) {
169
+ // Main process plugin context
170
+ channel.onMain('division-box:state-changed', (event: any) => {
171
+ stateChangeHandlers.forEach(handler => handler(event.data || event))
172
+ })
173
+ } else if (channel.on) {
174
+ // Renderer process context
175
+ channel.on('division-box:state-changed', (data: any) => {
176
+ stateChangeHandlers.forEach(handler => handler(data))
177
+ })
178
+ }
179
+ }
180
+
181
+ registerListener()
182
+
183
+ return {
184
+ async open(config: DivisionBoxConfig): Promise<SessionInfo> {
185
+ // Send to main process
186
+ const sendFn = channel.sendToMain || channel.send
187
+ const result = await sendFn('division-box:open', config)
188
+
189
+ if (!result.success) {
190
+ throw new Error(result.error?.message || 'Failed to open DivisionBox')
191
+ }
192
+
193
+ return result.data
194
+ },
195
+
196
+ async close(sessionId: string, options?: CloseOptions): Promise<void> {
197
+ const sendFn = channel.sendToMain || channel.send
198
+ const result = await sendFn('division-box:close', { sessionId, options })
199
+
200
+ if (!result.success) {
201
+ throw new Error(result.error?.message || 'Failed to close DivisionBox')
202
+ }
203
+ },
204
+
205
+ onStateChange(handler: StateChangeHandler): () => void {
206
+ stateChangeHandlers.add(handler)
207
+
208
+ return () => {
209
+ stateChangeHandlers.delete(handler)
210
+ }
211
+ },
212
+
213
+ async updateState(sessionId: string, key: string, value: any): Promise<void> {
214
+ const sendFn = channel.sendToMain || channel.send
215
+ const result = await sendFn('division-box:update-state', {
216
+ sessionId,
217
+ key,
218
+ value
219
+ })
220
+
221
+ if (!result.success) {
222
+ throw new Error(result.error?.message || 'Failed to update state')
223
+ }
224
+ },
225
+
226
+ async getState(sessionId: string, key: string): Promise<any> {
227
+ const sendFn = channel.sendToMain || channel.send
228
+ const result = await sendFn('division-box:get-state', {
229
+ sessionId,
230
+ key
231
+ })
232
+
233
+ if (!result.success) {
234
+ throw new Error(result.error?.message || 'Failed to get state')
235
+ }
236
+
237
+ return result.data
238
+ }
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Hook for using DivisionBox SDK in plugin context
244
+ *
245
+ * @returns DivisionBox SDK instance
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * const divisionBox = useDivisionBox()
250
+ *
251
+ * const { sessionId } = await divisionBox.open({
252
+ * url: 'https://example.com',
253
+ * title: 'My Tool'
254
+ * })
255
+ * ```
256
+ */
257
+ export function useDivisionBox(): DivisionBoxSDK {
258
+ // @ts-ignore - window.$channel is injected by the plugin system
259
+ const channel = window.$channel
260
+
261
+ if (!channel) {
262
+ throw new Error('[DivisionBox SDK] Channel not available. Make sure this is called in a plugin context.')
263
+ }
264
+
265
+ return createDivisionBoxSDK(channel)
266
+ }
@@ -1,4 +1,4 @@
1
1
  export enum BridgeEventForCoreBox {
2
2
  CORE_BOX_INPUT_CHANGE = 'core-box:input-change',
3
- CORE_BOX_CLIPBOARD_CHANGE = 'core-box:clipboard-change'
3
+ CORE_BOX_CLIPBOARD_CHANGE = 'core-box:clipboard-change',
4
4
  }
@@ -185,7 +185,7 @@ window.storageOnDidChangeExample = {
185
185
  setupMultipleFileListeners,
186
186
  setupDynamicListener,
187
187
  setupConditionalListener,
188
- setupBatchOperationListener
188
+ setupBatchOperationListener,
189
189
  }
190
190
 
191
191
  // 自动运行示例(可选)
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Feature SDK for Plugin Development
3
+ *
4
+ * Provides a unified API for plugins to manage search result items (TuffItems)
5
+ * in the CoreBox interface. This SDK handles item lifecycle, updates, and
6
+ * input change notifications.
7
+ */
8
+
9
+ import type { TuffItem } from '../../core-box/tuff'
10
+
11
+ /**
12
+ * Input change event handler
13
+ */
14
+ export type InputChangeHandler = (input: string) => void
15
+
16
+ /**
17
+ * Feature SDK interface for plugins
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Push items to CoreBox
22
+ * plugin.feature.pushItems([
23
+ * { id: 'item-1', title: 'Result 1', ... },
24
+ * { id: 'item-2', title: 'Result 2', ... }
25
+ * ])
26
+ *
27
+ * // Update a specific item
28
+ * plugin.feature.updateItem('item-1', { title: 'Updated Title' })
29
+ *
30
+ * // Listen for input changes
31
+ * plugin.feature.onInputChange((input) => {
32
+ * console.log('User typed:', input)
33
+ * })
34
+ * ```
35
+ */
36
+ export interface FeatureSDK {
37
+ /**
38
+ * Pushes multiple items to the CoreBox search results
39
+ *
40
+ * @param items - Array of TuffItem objects to display
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * plugin.feature.pushItems([
45
+ * {
46
+ * id: 'calc-result',
47
+ * title: { text: '42' },
48
+ * subtitle: { text: 'Calculation result' },
49
+ * source: { id: 'calculator', name: 'Calculator' }
50
+ * }
51
+ * ])
52
+ * ```
53
+ */
54
+ pushItems(items: TuffItem[]): void
55
+
56
+ /**
57
+ * Updates a specific item by ID
58
+ *
59
+ * @param id - The unique ID of the item to update
60
+ * @param updates - Partial TuffItem with fields to update
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * // Update title and subtitle
65
+ * plugin.feature.updateItem('item-1', {
66
+ * title: { text: 'New Title' },
67
+ * subtitle: { text: 'Updated subtitle' }
68
+ * })
69
+ * ```
70
+ */
71
+ updateItem(id: string, updates: Partial<TuffItem>): void
72
+
73
+ /**
74
+ * Removes a specific item by ID
75
+ *
76
+ * @param id - The unique ID of the item to remove
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * plugin.feature.removeItem('item-1')
81
+ * ```
82
+ */
83
+ removeItem(id: string): void
84
+
85
+ /**
86
+ * Clears all items pushed by this plugin
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * plugin.feature.clearItems()
91
+ * ```
92
+ */
93
+ clearItems(): void
94
+
95
+ /**
96
+ * Gets all items currently pushed by this plugin
97
+ *
98
+ * @returns Array of TuffItem objects
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const items = plugin.feature.getItems()
103
+ * console.log(`Currently showing ${items.length} items`)
104
+ * ```
105
+ */
106
+ getItems(): TuffItem[]
107
+
108
+ /**
109
+ * Registers a listener for input changes in the CoreBox search field
110
+ *
111
+ * @param handler - Callback function invoked when input changes
112
+ * @returns Unsubscribe function
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * const unsubscribe = plugin.feature.onInputChange((input) => {
117
+ * console.log('User typed:', input)
118
+ * // Perform real-time search
119
+ * performSearch(input)
120
+ * })
121
+ *
122
+ * // Later, unsubscribe
123
+ * unsubscribe()
124
+ * ```
125
+ */
126
+ onInputChange(handler: InputChangeHandler): () => void
127
+ }
128
+
129
+ /**
130
+ * Creates a Feature SDK instance for plugin use
131
+ *
132
+ * @param boxItemsAPI - The boxItems API object from plugin context
133
+ * @param channel - The plugin channel bridge for IPC communication
134
+ * @returns Configured Feature SDK instance
135
+ *
136
+ * @internal
137
+ */
138
+ export function createFeatureSDK(boxItemsAPI: any, channel: any): FeatureSDK {
139
+ const inputChangeHandlers: Set<InputChangeHandler> = new Set()
140
+
141
+ // Register listener for input change events from main process
142
+ const registerListener = () => {
143
+ if (channel.onMain) {
144
+ // Main process plugin context
145
+ channel.onMain('core-box:input-changed', (event: any) => {
146
+ const input = event.data?.input || event.input || ''
147
+ inputChangeHandlers.forEach(handler => handler(input))
148
+ })
149
+ } else if (channel.on) {
150
+ // Renderer process context
151
+ channel.on('core-box:input-changed', (data: any) => {
152
+ const input = data?.input || data || ''
153
+ inputChangeHandlers.forEach(handler => handler(input))
154
+ })
155
+ }
156
+ }
157
+
158
+ registerListener()
159
+
160
+ return {
161
+ pushItems(items: TuffItem[]): void {
162
+ if (!boxItemsAPI || !boxItemsAPI.pushItems) {
163
+ throw new Error('[Feature SDK] boxItems API not available')
164
+ }
165
+ boxItemsAPI.pushItems(items)
166
+ },
167
+
168
+ updateItem(id: string, updates: Partial<TuffItem>): void {
169
+ if (!boxItemsAPI || !boxItemsAPI.update) {
170
+ throw new Error('[Feature SDK] boxItems API not available')
171
+ }
172
+ boxItemsAPI.update(id, updates)
173
+ },
174
+
175
+ removeItem(id: string): void {
176
+ if (!boxItemsAPI || !boxItemsAPI.remove) {
177
+ throw new Error('[Feature SDK] boxItems API not available')
178
+ }
179
+ boxItemsAPI.remove(id)
180
+ },
181
+
182
+ clearItems(): void {
183
+ if (!boxItemsAPI || !boxItemsAPI.clear) {
184
+ throw new Error('[Feature SDK] boxItems API not available')
185
+ }
186
+ boxItemsAPI.clear()
187
+ },
188
+
189
+ getItems(): TuffItem[] {
190
+ if (!boxItemsAPI || !boxItemsAPI.getItems) {
191
+ throw new Error('[Feature SDK] boxItems API not available')
192
+ }
193
+ return boxItemsAPI.getItems()
194
+ },
195
+
196
+ onInputChange(handler: InputChangeHandler): () => void {
197
+ inputChangeHandlers.add(handler)
198
+
199
+ return () => {
200
+ inputChangeHandlers.delete(handler)
201
+ }
202
+ }
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Hook for using Feature SDK in plugin context
208
+ *
209
+ * @returns Feature SDK instance
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * const feature = useFeature()
214
+ *
215
+ * feature.pushItems([
216
+ * { id: '1', title: { text: 'Item 1' }, ... }
217
+ * ])
218
+ * ```
219
+ */
220
+ export function useFeature(): FeatureSDK {
221
+ // @ts-ignore - window.$boxItems and window.$channel are injected by the plugin system
222
+ const boxItemsAPI = window.$boxItems
223
+ // @ts-ignore
224
+ const channel = window.$channel
225
+
226
+ if (!boxItemsAPI) {
227
+ throw new Error('[Feature SDK] boxItems API not available. Make sure this is called in a plugin context.')
228
+ }
229
+
230
+ if (!channel) {
231
+ throw new Error('[Feature SDK] Channel not available. Make sure this is called in a plugin context.')
232
+ }
233
+
234
+ return createFeatureSDK(boxItemsAPI, channel)
235
+ }