@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
@@ -1,18 +1,18 @@
1
- import { defaultRiskPromptHandler } from '../risk'
2
1
  import type { PluginInstallRequest, PluginInstallResult, PluginProvider, PluginProviderContext } from './types'
2
+ import { defaultRiskPromptHandler } from '../risk'
3
3
 
4
4
  class ProviderRegistry {
5
5
  private providers: PluginProvider[] = []
6
6
 
7
7
  register(provider: PluginProvider): void {
8
- if (this.providers.some((item) => item.type === provider.type)) {
8
+ if (this.providers.some(item => item.type === provider.type)) {
9
9
  throw new Error(`Plugin provider '${provider.type}' already registered`)
10
10
  }
11
11
  this.providers.push(provider)
12
12
  }
13
13
 
14
14
  unregister(type: PluginProvider['type']): void {
15
- this.providers = this.providers.filter((item) => item.type !== type)
15
+ this.providers = this.providers.filter(item => item.type !== type)
16
16
  }
17
17
 
18
18
  clear(): void {
@@ -20,19 +20,20 @@ class ProviderRegistry {
20
20
  }
21
21
 
22
22
  resolve(request: PluginInstallRequest): PluginProvider | undefined {
23
- return this.providers.find((provider) => provider.canHandle(request))
23
+ return this.providers.find(provider => provider.canHandle(request))
24
24
  }
25
25
 
26
26
  async install(
27
27
  request: PluginInstallRequest,
28
- context: PluginProviderContext = {}
28
+ context: PluginProviderContext = {},
29
29
  ): Promise<PluginInstallResult | undefined> {
30
30
  const provider = this.resolve(request)
31
- if (!provider) return undefined
31
+ if (!provider)
32
+ return undefined
32
33
 
33
34
  const composedContext: PluginProviderContext = {
34
35
  riskPrompt: defaultRiskPromptHandler,
35
- ...context
36
+ ...context,
36
37
  }
37
38
 
38
39
  if (!composedContext.riskPrompt) {
@@ -1,5 +1,5 @@
1
- import type { IDownloadOptions, IDownloadResult } from '../plugin-source'
2
1
  import type { IManifest } from '..'
2
+ import type { IDownloadOptions, IDownloadResult } from '../plugin-source'
3
3
  import type { RiskPromptHandler } from '../risk'
4
4
 
5
5
  export enum PluginProviderType {
@@ -7,7 +7,7 @@ export enum PluginProviderType {
7
7
  NPM = 'npm',
8
8
  TPEX = 'tpex',
9
9
  FILE = 'file',
10
- DEV = 'dev'
10
+ DEV = 'dev',
11
11
  }
12
12
 
13
13
  export interface PluginInstallRequest {
@@ -43,11 +43,11 @@ export interface PluginInstallResult extends IDownloadResult {
43
43
 
44
44
  export interface PluginProvider {
45
45
  readonly type: PluginProviderType
46
- canHandle(request: PluginInstallRequest): boolean
47
- install(
46
+ canHandle: (request: PluginInstallRequest) => boolean
47
+ install: (
48
48
  request: PluginInstallRequest,
49
- context?: PluginProviderContext
50
- ): Promise<PluginInstallResult>
49
+ context?: PluginProviderContext,
50
+ ) => Promise<PluginInstallResult>
51
51
  }
52
52
 
53
53
  export interface PluginInstallSummary {
@@ -0,0 +1,216 @@
1
+ # Plugin SDK 重构说明
2
+
3
+ ## 概述
4
+
5
+ Plugin SDK 已重构为统一的工厂函数模式,参考 `DivisionBoxSDK` 的设计。旧版本 API 已废弃,调用时会抛出错误。
6
+
7
+ ## 新的 SDK 结构
8
+
9
+ ### 1. BoxSDK - CoreBox 窗口控制
10
+
11
+ 控制 CoreBox 窗口的显示、大小和输入框状态。
12
+
13
+ ```typescript
14
+ // 隐藏/显示 CoreBox
15
+ plugin.box.hide()
16
+ plugin.box.show()
17
+
18
+ // 扩展窗口(显示更多结果)
19
+ plugin.box.expand({ length: 10 })
20
+ plugin.box.expand({ forceMax: true })
21
+
22
+ // 收缩窗口
23
+ plugin.box.shrink()
24
+
25
+ // 控制输入框
26
+ plugin.box.hideInput()
27
+ plugin.box.showInput()
28
+
29
+ // 获取当前输入
30
+ const input = await plugin.box.getInput()
31
+ ```
32
+
33
+ ### 2. FeatureSDK - 搜索结果管理
34
+
35
+ 管理插件推送的搜索结果项(TuffItems)。
36
+
37
+ ```typescript
38
+ // 推送多个结果
39
+ plugin.feature.pushItems([
40
+ { id: 'item-1', title: { text: 'Result 1' }, ... },
41
+ { id: 'item-2', title: { text: 'Result 2' }, ... }
42
+ ])
43
+
44
+ // 更新单个结果
45
+ plugin.feature.updateItem('item-1', {
46
+ title: { text: 'Updated Title' }
47
+ })
48
+
49
+ // 删除单个结果
50
+ plugin.feature.removeItem('item-1')
51
+
52
+ // 清空所有结果
53
+ plugin.feature.clearItems()
54
+
55
+ // 获取所有结果
56
+ const items = plugin.feature.getItems()
57
+
58
+ // 监听输入变化(实时搜索)
59
+ const unsubscribe = plugin.feature.onInputChange((input) => {
60
+ console.log('User typed:', input)
61
+ // 执行实时搜索
62
+ performSearch(input)
63
+ })
64
+
65
+ // 取消监听
66
+ unsubscribe()
67
+ ```
68
+
69
+ ## 废弃的 API
70
+
71
+ 以下 API 已废弃,调用时会抛出错误:
72
+
73
+ ### 旧的 Box API
74
+ ```typescript
75
+ // ❌ 废弃
76
+ plugin.$box.hide()
77
+ plugin.$box.show()
78
+
79
+ // ✅ 使用新 API
80
+ plugin.box.hide()
81
+ plugin.box.show()
82
+ ```
83
+
84
+ ### 旧的 Feature API
85
+ ```typescript
86
+ // ❌ 废弃
87
+ plugin.pushItems(items)
88
+ plugin.clearItems()
89
+ plugin.getItems()
90
+
91
+ // ✅ 使用新 API
92
+ plugin.feature.pushItems(items)
93
+ plugin.feature.clearItems()
94
+ plugin.feature.getItems()
95
+ ```
96
+
97
+ ## 迁移指南
98
+
99
+ ### 1. 更新 Box 控制代码
100
+
101
+ **旧代码:**
102
+ ```typescript
103
+ plugin.$box.hide()
104
+ plugin.$box.show()
105
+ ```
106
+
107
+ **新代码:**
108
+ ```typescript
109
+ plugin.box.hide()
110
+ plugin.box.show()
111
+ plugin.box.expand({ length: 10 })
112
+ plugin.box.shrink()
113
+ ```
114
+
115
+ ### 2. 更新搜索结果管理
116
+
117
+ **旧代码:**
118
+ ```typescript
119
+ plugin.pushItems([...])
120
+ plugin.clearItems()
121
+ const items = plugin.getItems()
122
+ ```
123
+
124
+ **新代码:**
125
+ ```typescript
126
+ plugin.feature.pushItems([...])
127
+ plugin.feature.updateItem('id', { ... })
128
+ plugin.feature.removeItem('id')
129
+ plugin.feature.clearItems()
130
+ const items = plugin.feature.getItems()
131
+ ```
132
+
133
+ ### 3. 添加实时搜索支持
134
+
135
+ **新功能:**
136
+ ```typescript
137
+ // 在插件初始化时注册监听器
138
+ onInit(context) {
139
+ context.utils.feature.onInputChange((input) => {
140
+ // 用户输入变化时触发
141
+ this.performRealTimeSearch(input)
142
+ })
143
+ }
144
+ ```
145
+
146
+ ## 完整示例
147
+
148
+ ```typescript
149
+ export default {
150
+ onInit(context) {
151
+ const { feature, box } = context.utils
152
+
153
+ // 监听输入变化
154
+ feature.onInputChange((input) => {
155
+ if (input.length > 2) {
156
+ // 执行搜索
157
+ const results = performSearch(input)
158
+ feature.pushItems(results)
159
+ } else {
160
+ feature.clearItems()
161
+ }
162
+ })
163
+ },
164
+
165
+ onFeatureTriggered(featureId, query, feature) {
166
+ const { feature: featureSDK, box } = this.context.utils
167
+
168
+ // 推送结果
169
+ featureSDK.pushItems([
170
+ {
171
+ id: 'result-1',
172
+ title: { text: 'Search Result' },
173
+ subtitle: { text: 'Description' },
174
+ source: { id: this.pluginName, name: this.pluginName }
175
+ }
176
+ ])
177
+
178
+ // 扩展窗口显示结果
179
+ box.expand({ length: 5 })
180
+
181
+ // 3秒后隐藏
182
+ setTimeout(() => {
183
+ box.hide()
184
+ }, 3000)
185
+ }
186
+ }
187
+ ```
188
+
189
+ ## 技术细节
190
+
191
+ ### SDK 工厂函数
192
+
193
+ 所有 SDK 都通过工厂函数创建:
194
+
195
+ - `createBoxSDK(channel)` - 创建 Box SDK 实例
196
+ - `createFeatureSDK(boxItems, channel)` - 创建 Feature SDK 实例
197
+ - `createDivisionBoxSDK(channel)` - 创建 DivisionBox SDK 实例
198
+
199
+ ### IPC 通道
200
+
201
+ 新增的 IPC 通道:
202
+
203
+ - `core-box:hide-input` - 隐藏输入框
204
+ - `core-box:show-input` - 显示输入框
205
+ - `core-box:get-input` - 获取当前输入值
206
+ - `core-box:input-changed` - 输入变化广播(主进程 → 插件)
207
+ - `core-box:set-input-visibility` - 设置输入框可见性(主进程 → 渲染进程)
208
+ - `core-box:request-input-value` - 请求输入值(主进程 → 渲染进程)
209
+
210
+ ### 架构优势
211
+
212
+ 1. **统一的 API 风格** - 所有 SDK 使用相同的工厂函数模式
213
+ 2. **更好的类型安全** - TypeScript 类型定义完整
214
+ 3. **功能分离** - Box 控制和 Feature 管理职责清晰
215
+ 4. **扩展性强** - 易于添加新功能
216
+ 5. **向后不兼容** - 强制迁移到新 API,避免技术债务
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Box SDK for Plugin Development
3
+ *
4
+ * Provides a unified API for plugins to control the CoreBox window behavior,
5
+ * including visibility, size, input field control, and input value access.
6
+ */
7
+
8
+ /**
9
+ * Expand options for CoreBox window
10
+ */
11
+ export interface BoxExpandOptions {
12
+ /** Number of items to show (affects window height) */
13
+ length?: number
14
+ /** Force maximum expansion */
15
+ forceMax?: boolean
16
+ }
17
+
18
+ /**
19
+ * Box SDK interface for plugins
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Hide CoreBox
24
+ * plugin.box.hide()
25
+ *
26
+ * // Show CoreBox
27
+ * plugin.box.show()
28
+ *
29
+ * // Expand to show 10 items
30
+ * plugin.box.expand({ length: 10 })
31
+ *
32
+ * // Get current input
33
+ * const input = plugin.box.getInput()
34
+ * ```
35
+ */
36
+ export interface BoxSDK {
37
+ /**
38
+ * Hides the CoreBox window
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * plugin.box.hide()
43
+ * ```
44
+ */
45
+ hide(): void
46
+
47
+ /**
48
+ * Shows the CoreBox window
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * plugin.box.show()
53
+ * ```
54
+ */
55
+ show(): void
56
+
57
+ /**
58
+ * Expands the CoreBox window
59
+ *
60
+ * @param options - Optional expansion configuration
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * // Expand to show 10 items
65
+ * plugin.box.expand({ length: 10 })
66
+ *
67
+ * // Force maximum expansion
68
+ * plugin.box.expand({ forceMax: true })
69
+ *
70
+ * // Default expansion
71
+ * plugin.box.expand()
72
+ * ```
73
+ */
74
+ expand(options?: BoxExpandOptions): Promise<void>
75
+
76
+ /**
77
+ * Shrinks the CoreBox window to compact size
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * plugin.box.shrink()
82
+ * ```
83
+ */
84
+ shrink(): Promise<void>
85
+
86
+ /**
87
+ * Hides the input field in CoreBox
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * plugin.box.hideInput()
92
+ * ```
93
+ */
94
+ hideInput(): Promise<void>
95
+
96
+ /**
97
+ * Shows the input field in CoreBox
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * plugin.box.showInput()
102
+ * ```
103
+ */
104
+ showInput(): Promise<void>
105
+
106
+ /**
107
+ * Gets the current input value from CoreBox search field
108
+ *
109
+ * @returns Promise resolving to the current input string
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const input = await plugin.box.getInput()
114
+ * console.log('Current input:', input)
115
+ * ```
116
+ */
117
+ getInput(): Promise<string>
118
+ }
119
+
120
+ /**
121
+ * Creates a Box SDK instance for plugin use
122
+ *
123
+ * @param channel - The plugin channel bridge for IPC communication
124
+ * @returns Configured Box SDK instance
125
+ *
126
+ * @internal
127
+ */
128
+ export function createBoxSDK(channel: any): BoxSDK {
129
+ const sendFn = channel.sendToMain || channel.send
130
+
131
+ if (!sendFn) {
132
+ throw new Error('[Box SDK] Channel send function not available')
133
+ }
134
+
135
+ return {
136
+ hide(): void {
137
+ sendFn('core-box:hide').catch((error: any) => {
138
+ console.error('[Box SDK] Failed to hide CoreBox:', error)
139
+ })
140
+ },
141
+
142
+ show(): void {
143
+ sendFn('core-box:show').catch((error: any) => {
144
+ console.error('[Box SDK] Failed to show CoreBox:', error)
145
+ })
146
+ },
147
+
148
+ async expand(options?: BoxExpandOptions): Promise<void> {
149
+ try {
150
+ await sendFn('core-box:expand', options || {})
151
+ } catch (error) {
152
+ console.error('[Box SDK] Failed to expand CoreBox:', error)
153
+ throw error
154
+ }
155
+ },
156
+
157
+ async shrink(): Promise<void> {
158
+ try {
159
+ await sendFn('core-box:expand', { mode: 'collapse' })
160
+ } catch (error) {
161
+ console.error('[Box SDK] Failed to shrink CoreBox:', error)
162
+ throw error
163
+ }
164
+ },
165
+
166
+ async hideInput(): Promise<void> {
167
+ try {
168
+ await sendFn('core-box:hide-input')
169
+ } catch (error) {
170
+ console.error('[Box SDK] Failed to hide input:', error)
171
+ throw error
172
+ }
173
+ },
174
+
175
+ async showInput(): Promise<void> {
176
+ try {
177
+ await sendFn('core-box:show-input')
178
+ } catch (error) {
179
+ console.error('[Box SDK] Failed to show input:', error)
180
+ throw error
181
+ }
182
+ },
183
+
184
+ async getInput(): Promise<string> {
185
+ try {
186
+ const result = await sendFn('core-box:get-input')
187
+ return result?.data?.input || result?.input || ''
188
+ } catch (error) {
189
+ console.error('[Box SDK] Failed to get input:', error)
190
+ throw error
191
+ }
192
+ }
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Hook for using Box SDK in plugin context
198
+ *
199
+ * @returns Box SDK instance
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * const box = useBox()
204
+ *
205
+ * box.hide()
206
+ * box.expand({ length: 10 })
207
+ * const input = await box.getInput()
208
+ * ```
209
+ */
210
+ export function useBox(): BoxSDK {
211
+ // @ts-ignore - window.$channel is injected by the plugin system
212
+ const channel = window.$channel
213
+
214
+ if (!channel) {
215
+ throw new Error('[Box SDK] Channel not available. Make sure this is called in a plugin context.')
216
+ }
217
+
218
+ return createBoxSDK(channel)
219
+ }
@@ -1,48 +1,48 @@
1
- import type { ITouchClientChannel } from '@talex-touch/utils/channel';
2
- import { genChannel } from '../channel';
3
- import type { IPluginRendererChannel, PluginChannelHandler } from './types';
1
+ import type { ITouchClientChannel } from '@talex-touch/utils/channel'
2
+ import type { IPluginRendererChannel, PluginChannelHandler } from './types'
3
+ import { genChannel } from '../channel'
4
4
 
5
- const ensureClientChannel = (): ITouchClientChannel => genChannel();
5
+ const ensureClientChannel = (): ITouchClientChannel => genChannel()
6
6
 
7
7
  export function createPluginRendererChannel(): IPluginRendererChannel {
8
- const client = ensureClientChannel();
8
+ const client = ensureClientChannel()
9
9
 
10
10
  return {
11
11
  send(eventName, payload) {
12
- return client.send(eventName, payload);
12
+ return client.send(eventName, payload)
13
13
  },
14
14
 
15
15
  sendSync(eventName, payload) {
16
- return client.sendSync(eventName, payload);
16
+ return client.sendSync(eventName, payload)
17
17
  },
18
18
 
19
19
  on(eventName, handler) {
20
- return client.regChannel(eventName, handler);
20
+ return client.regChannel(eventName, handler)
21
21
  },
22
22
 
23
23
  once(eventName, handler) {
24
- let dispose: () => void = () => void 0;
24
+ let dispose: () => void = () => void 0
25
25
  const wrapped: PluginChannelHandler = (event) => {
26
- dispose();
27
- handler(event);
28
- };
26
+ dispose()
27
+ handler(event)
28
+ }
29
29
 
30
- dispose = client.regChannel(eventName, wrapped);
31
- return dispose;
30
+ dispose = client.regChannel(eventName, wrapped)
31
+ return dispose
32
32
  },
33
33
 
34
34
  get raw() {
35
- return client;
36
- }
37
- };
35
+ return client
36
+ },
37
+ }
38
38
  }
39
39
 
40
- let cachedRendererChannel: IPluginRendererChannel | null = null;
40
+ let cachedRendererChannel: IPluginRendererChannel | null = null
41
41
 
42
42
  export function usePluginRendererChannel(): IPluginRendererChannel {
43
43
  if (!cachedRendererChannel) {
44
- cachedRendererChannel = createPluginRendererChannel();
44
+ cachedRendererChannel = createPluginRendererChannel()
45
45
  }
46
46
 
47
- return cachedRendererChannel;
47
+ return cachedRendererChannel
48
48
  }
@@ -1,6 +1,6 @@
1
1
  import type { PluginClipboardHistoryResponse, PluginClipboardItem } from './types'
2
2
 
3
- const ensurePluginChannel = () => {
3
+ function ensurePluginChannel() {
4
4
  const channel = (window as any)?.$channel
5
5
  if (!channel) {
6
6
  throw new Error('[Plugin SDK] Clipboard channel requires plugin renderer context with $channel available.')
@@ -8,13 +8,15 @@ const ensurePluginChannel = () => {
8
8
  return channel
9
9
  }
10
10
 
11
- const normalizeItem = (item: PluginClipboardItem | null): PluginClipboardItem | null => {
12
- if (!item) return item
11
+ function normalizeItem(item: PluginClipboardItem | null): PluginClipboardItem | null {
12
+ if (!item)
13
+ return item
13
14
  if (!item.meta && typeof item.metadata === 'string') {
14
15
  try {
15
16
  const parsed = JSON.parse(item.metadata)
16
17
  return { ...item, meta: parsed }
17
- } catch {
18
+ }
19
+ catch {
18
20
  return { ...item, meta: null }
19
21
  }
20
22
  }
@@ -61,7 +63,7 @@ export function useClipboardHistory() {
61
63
  : []
62
64
  return {
63
65
  ...response,
64
- history
66
+ history,
65
67
  }
66
68
  },
67
69
 
@@ -94,6 +96,6 @@ export function useClipboardHistory() {
94
96
  return Boolean((response as any).success)
95
97
  }
96
98
  return true
97
- }
99
+ },
98
100
  }
99
101
  }
@@ -17,8 +17,10 @@ export function regShortcut(key: string, func: Function): boolean {
17
17
  const channel = genChannel()
18
18
 
19
19
  const res = channel.sendSync('shortcon:reg', { key })
20
- if (res instanceof String) throw new Error(String(res))
21
- if (res === false) return false
20
+ if (res instanceof String)
21
+ throw new Error(String(res))
22
+ if (res === false)
23
+ return false
22
24
 
23
25
  channel.regChannel('shortcon:trigger', ({ data }) => key === data.key && func())
24
26
 
@@ -33,16 +35,17 @@ export function regShortcut(key: string, func: Function): boolean {
33
35
  */
34
36
  export async function communicateWithPlugin(
35
37
  key: string,
36
- info: any = {}
38
+ info: any = {},
37
39
  ): Promise<any> {
38
40
  const channel = genChannel()
39
41
 
40
42
  try {
41
43
  return await channel.send('index:communicate', {
42
44
  key,
43
- info
45
+ info,
44
46
  })
45
- } catch (error) {
47
+ }
48
+ catch (error) {
46
49
  console.error(`[Plugin SDK] Failed to communicate`, error)
47
50
  throw error
48
51
  }
@@ -59,7 +62,8 @@ export async function sendMessage(message: string, data: any = {}): Promise<any>
59
62
 
60
63
  try {
61
64
  return await channel.send(`plugin:${message}`, data)
62
- } catch (error) {
65
+ }
66
+ catch (error) {
63
67
  console.error(`[Plugin SDK] Failed to send message: ${message}`, error)
64
68
  throw error
65
69
  }
@@ -1,6 +1,6 @@
1
1
  import type { IPluginRendererChannel } from './types'
2
2
 
3
- const ensurePluginContext = (): { channel: IPluginRendererChannel; pluginName: string } => {
3
+ function ensurePluginContext(): { channel: IPluginRendererChannel, pluginName: string } {
4
4
  const plugin = (window as any)?.$plugin
5
5
  if (!plugin?.name) {
6
6
  throw new Error('[TouchSDK] Unable to resolve plugin name inside renderer context.')
@@ -13,7 +13,7 @@ const ensurePluginContext = (): { channel: IPluginRendererChannel; pluginName: s
13
13
 
14
14
  return {
15
15
  channel,
16
- pluginName: plugin.name as string
16
+ pluginName: plugin.name as string,
17
17
  }
18
18
  }
19
19
 
@@ -24,4 +24,3 @@ export async function clearCoreBoxItems(): Promise<void> {
24
24
  const { channel, pluginName } = ensurePluginContext()
25
25
  await channel.send('core-box:clear-items', { pluginName })
26
26
  }
27
-