@talex-touch/utils 1.0.42 → 1.0.44

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 (233) hide show
  1. package/.eslintcache +1 -0
  2. package/__tests__/cloud-sync-sdk.test.ts +442 -0
  3. package/__tests__/icons/icons.test.ts +84 -0
  4. package/__tests__/plugin-sdk-lifecycle.test.ts +130 -0
  5. package/__tests__/power-sdk.test.ts +143 -0
  6. package/__tests__/preset-export-types.test.ts +108 -0
  7. package/__tests__/search/fuzzy-match.test.ts +137 -0
  8. package/__tests__/transport/port-policy.test.ts +44 -0
  9. package/__tests__/transport-domain-sdks.test.ts +152 -0
  10. package/__tests__/types/update.test.ts +67 -0
  11. package/account/account-sdk.ts +915 -0
  12. package/account/index.ts +2 -0
  13. package/account/types.ts +321 -0
  14. package/analytics/client.ts +136 -0
  15. package/analytics/index.ts +2 -0
  16. package/analytics/types.ts +156 -0
  17. package/animation/auto-resize.ts +322 -0
  18. package/animation/window-node.ts +26 -19
  19. package/auth/clerk-types.ts +12 -30
  20. package/auth/index.ts +0 -2
  21. package/auth/useAuthState.ts +6 -14
  22. package/base/index.ts +2 -0
  23. package/base/log-level.ts +105 -0
  24. package/channel/index.ts +170 -69
  25. package/cloud-sync/cloud-sync-sdk.ts +450 -0
  26. package/cloud-sync/index.ts +1 -0
  27. package/common/file-scan-utils.ts +17 -9
  28. package/common/index.ts +4 -0
  29. package/common/logger/index.ts +46 -0
  30. package/common/logger/logger-manager.ts +303 -0
  31. package/common/logger/module-logger.ts +270 -0
  32. package/common/logger/transport-logger.ts +234 -0
  33. package/common/logger/types.ts +93 -0
  34. package/common/search/gather.ts +48 -6
  35. package/common/search/index.ts +8 -0
  36. package/common/storage/constants.ts +13 -0
  37. package/common/storage/entity/app-settings.ts +245 -0
  38. package/common/storage/entity/index.ts +3 -0
  39. package/common/storage/entity/layout-atom-types.ts +147 -0
  40. package/common/storage/entity/openers.ts +1 -0
  41. package/common/storage/entity/preset-cloud-api.ts +132 -0
  42. package/common/storage/entity/preset-export-types.ts +256 -0
  43. package/common/storage/entity/shortcut-settings.ts +1 -0
  44. package/common/storage/shortcut-storage.ts +11 -0
  45. package/common/utils/clone-diagnostics.ts +105 -0
  46. package/common/utils/file.ts +16 -8
  47. package/common/utils/index.ts +6 -2
  48. package/common/utils/payload-preview.ts +173 -0
  49. package/common/utils/polling.ts +167 -13
  50. package/common/utils/safe-path.ts +103 -0
  51. package/common/utils/safe-shell.ts +115 -0
  52. package/common/utils/task-queue.ts +4 -1
  53. package/core-box/builder/tuff-builder.ts +0 -1
  54. package/core-box/index.ts +1 -1
  55. package/core-box/recommendation.ts +38 -1
  56. package/core-box/tuff/tuff-dsl.ts +32 -0
  57. package/electron/download-manager.ts +10 -7
  58. package/electron/env-tool.ts +42 -40
  59. package/electron/index.ts +0 -1
  60. package/env/index.ts +156 -0
  61. package/eslint.config.js +55 -0
  62. package/i18n/index.ts +62 -0
  63. package/i18n/locales/en.json +226 -0
  64. package/i18n/locales/zh.json +226 -0
  65. package/i18n/message-keys.ts +236 -0
  66. package/i18n/resolver.ts +181 -0
  67. package/icons/index.ts +257 -0
  68. package/icons/svg.ts +69 -0
  69. package/index.ts +9 -1
  70. package/intelligence/client.ts +72 -42
  71. package/market/constants.ts +9 -5
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +19 -4
  74. package/package.json +15 -5
  75. package/permission/index.ts +143 -46
  76. package/permission/legacy.ts +26 -0
  77. package/permission/registry.ts +304 -0
  78. package/permission/types.ts +164 -0
  79. package/plugin/channel.ts +68 -39
  80. package/plugin/index.ts +80 -7
  81. package/plugin/install.ts +3 -0
  82. package/plugin/log/types.ts +22 -5
  83. package/plugin/node/logger-manager.ts +11 -3
  84. package/plugin/node/logger.ts +24 -17
  85. package/plugin/preload.ts +25 -2
  86. package/plugin/providers/index.ts +4 -4
  87. package/plugin/providers/market-client.ts +6 -3
  88. package/plugin/providers/npm-provider.ts +22 -7
  89. package/plugin/providers/tpex-provider.ts +22 -8
  90. package/plugin/sdk/box-items.ts +14 -0
  91. package/plugin/sdk/box-sdk.ts +64 -0
  92. package/plugin/sdk/channel.ts +119 -4
  93. package/plugin/sdk/clipboard.ts +26 -12
  94. package/plugin/sdk/cloud-sync.ts +113 -0
  95. package/plugin/sdk/common.ts +19 -11
  96. package/plugin/sdk/core-box.ts +6 -15
  97. package/plugin/sdk/division-box.ts +160 -65
  98. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  99. package/plugin/sdk/feature-sdk.ts +111 -76
  100. package/plugin/sdk/flow.ts +146 -45
  101. package/plugin/sdk/hooks/bridge.ts +13 -6
  102. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  103. package/plugin/sdk/index.ts +14 -3
  104. package/plugin/sdk/intelligence.ts +87 -0
  105. package/plugin/sdk/meta/README.md +179 -0
  106. package/plugin/sdk/meta-sdk.ts +244 -0
  107. package/plugin/sdk/notification.ts +9 -0
  108. package/plugin/sdk/plugin-info.ts +64 -0
  109. package/plugin/sdk/power.ts +155 -0
  110. package/plugin/sdk/recommend.ts +21 -0
  111. package/plugin/sdk/service/index.ts +12 -8
  112. package/plugin/sdk/sqlite.ts +141 -0
  113. package/plugin/sdk/storage.ts +2 -6
  114. package/plugin/sdk/system.ts +2 -9
  115. package/plugin/sdk/temp-files.ts +41 -0
  116. package/plugin/sdk/touch-sdk.ts +18 -0
  117. package/plugin/sdk/types.ts +44 -4
  118. package/plugin/sdk/window/index.ts +12 -9
  119. package/plugin/sdk-version.ts +231 -0
  120. package/preload/renderer.ts +3 -2
  121. package/renderer/hooks/arg-mapper.ts +16 -2
  122. package/renderer/hooks/index.ts +13 -0
  123. package/renderer/hooks/initialize.ts +2 -1
  124. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  125. package/renderer/hooks/use-agent-market.ts +106 -0
  126. package/renderer/hooks/use-agents-sdk.ts +7 -0
  127. package/renderer/hooks/use-app-sdk.ts +7 -0
  128. package/renderer/hooks/use-channel.ts +33 -4
  129. package/renderer/hooks/use-download-sdk.ts +21 -0
  130. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  131. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  132. package/renderer/hooks/use-intelligence.ts +55 -214
  133. package/renderer/hooks/use-market-sdk.ts +16 -0
  134. package/renderer/hooks/use-notification-sdk.ts +7 -0
  135. package/renderer/hooks/use-permission-sdk.ts +7 -0
  136. package/renderer/hooks/use-permission.ts +325 -0
  137. package/renderer/hooks/use-platform-sdk.ts +7 -0
  138. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  139. package/renderer/hooks/use-settings-sdk.ts +7 -0
  140. package/renderer/hooks/use-update-sdk.ts +21 -0
  141. package/renderer/index.ts +1 -0
  142. package/renderer/ref.ts +19 -10
  143. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  144. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  145. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  146. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  147. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  148. package/renderer/shared/components/index.ts +5 -0
  149. package/renderer/shared/components/shims-vue.d.ts +5 -0
  150. package/renderer/shared/index.ts +2 -0
  151. package/renderer/shared/plugin-detail.ts +62 -0
  152. package/renderer/storage/app-settings.ts +3 -1
  153. package/renderer/storage/base-storage.ts +508 -82
  154. package/renderer/storage/intelligence-storage.ts +31 -40
  155. package/renderer/storage/openers.ts +3 -1
  156. package/renderer/storage/storage-subscription.ts +126 -42
  157. package/renderer/touch-sdk/env.ts +10 -10
  158. package/renderer/touch-sdk/index.ts +114 -18
  159. package/renderer/touch-sdk/terminal.ts +24 -13
  160. package/search/feature-matcher.ts +279 -0
  161. package/search/fuzzy-match.ts +64 -34
  162. package/search/index.ts +10 -0
  163. package/search/levenshtein-utils.ts +17 -11
  164. package/transport/errors.ts +310 -0
  165. package/transport/event/builder.ts +378 -0
  166. package/transport/event/index.ts +7 -0
  167. package/transport/event/types.ts +292 -0
  168. package/transport/events/index.ts +2670 -0
  169. package/transport/events/meta-overlay.ts +79 -0
  170. package/transport/events/types/agents.ts +177 -0
  171. package/transport/events/types/app-index.ts +9 -0
  172. package/transport/events/types/app.ts +475 -0
  173. package/transport/events/types/box-item.ts +222 -0
  174. package/transport/events/types/clipboard.ts +80 -0
  175. package/transport/events/types/core-box.ts +534 -0
  176. package/transport/events/types/device-idle.ts +7 -0
  177. package/transport/events/types/division-box.ts +99 -0
  178. package/transport/events/types/download.ts +115 -0
  179. package/transport/events/types/file-index.ts +73 -0
  180. package/transport/events/types/flow.ts +149 -0
  181. package/transport/events/types/index.ts +70 -0
  182. package/transport/events/types/market.ts +39 -0
  183. package/transport/events/types/meta-overlay.ts +184 -0
  184. package/transport/events/types/notification.ts +140 -0
  185. package/transport/events/types/permission.ts +90 -0
  186. package/transport/events/types/platform.ts +8 -0
  187. package/transport/events/types/plugin.ts +620 -0
  188. package/transport/events/types/sentry.ts +20 -0
  189. package/transport/events/types/storage.ts +208 -0
  190. package/transport/events/types/transport.ts +60 -0
  191. package/transport/events/types/tray.ts +16 -0
  192. package/transport/events/types/update.ts +78 -0
  193. package/transport/index.ts +139 -0
  194. package/transport/main.ts +2 -0
  195. package/transport/sdk/constants.ts +29 -0
  196. package/transport/sdk/domains/agents-market.ts +47 -0
  197. package/transport/sdk/domains/agents.ts +62 -0
  198. package/transport/sdk/domains/app.ts +48 -0
  199. package/transport/sdk/domains/disposable.ts +35 -0
  200. package/transport/sdk/domains/download.ts +139 -0
  201. package/transport/sdk/domains/index.ts +13 -0
  202. package/transport/sdk/domains/intelligence.ts +616 -0
  203. package/transport/sdk/domains/market.ts +35 -0
  204. package/transport/sdk/domains/notification.ts +62 -0
  205. package/transport/sdk/domains/permission.ts +85 -0
  206. package/transport/sdk/domains/platform.ts +19 -0
  207. package/transport/sdk/domains/plugin.ts +144 -0
  208. package/transport/sdk/domains/settings.ts +92 -0
  209. package/transport/sdk/domains/update.ts +64 -0
  210. package/transport/sdk/index.ts +60 -0
  211. package/transport/sdk/main-transport.ts +710 -0
  212. package/transport/sdk/main.ts +9 -0
  213. package/transport/sdk/plugin-transport.ts +654 -0
  214. package/transport/sdk/port-policy.ts +38 -0
  215. package/transport/sdk/renderer-transport.ts +1165 -0
  216. package/transport/types.ts +605 -0
  217. package/types/agent.ts +399 -0
  218. package/types/cloud-sync.ts +157 -0
  219. package/types/division-box.ts +31 -31
  220. package/types/download.ts +1 -0
  221. package/types/flow.ts +63 -12
  222. package/types/icon.ts +2 -1
  223. package/types/index.ts +5 -0
  224. package/types/intelligence.ts +166 -173
  225. package/types/modules/base.ts +2 -0
  226. package/types/path-browserify.d.ts +5 -0
  227. package/types/platform.ts +12 -0
  228. package/types/startup-info.ts +32 -0
  229. package/types/touch-app-core.ts +8 -8
  230. package/types/update.ts +94 -1
  231. package/vitest.config.ts +25 -0
  232. package/auth/useClerkConfig.ts +0 -40
  233. package/auth/useClerkProvider.ts +0 -52
@@ -1,20 +1,11 @@
1
- import type { IPluginRendererChannel } from './types'
1
+ import { useChannel } from './channel'
2
+ import { usePluginName } from './plugin-info'
2
3
 
3
- function ensurePluginContext(): { channel: IPluginRendererChannel, pluginName: string } {
4
- const plugin = (window as any)?.$plugin
5
- if (!plugin?.name) {
6
- throw new Error('[TouchSDK] Unable to resolve plugin name inside renderer context.')
7
- }
4
+ function ensurePluginContext(): { channel: ReturnType<typeof useChannel>, pluginName: string } {
5
+ const pluginName = usePluginName('[TouchSDK] Unable to resolve plugin name inside renderer context.')
6
+ const channel = useChannel('[TouchSDK] Channel bridge is not available for the current plugin renderer.')
8
7
 
9
- const channel = (window as any)?.$channel as IPluginRendererChannel | undefined
10
- if (!channel) {
11
- throw new Error('[TouchSDK] Channel bridge is not available for the current plugin renderer.')
12
- }
13
-
14
- return {
15
- channel,
16
- pluginName: plugin.name as string,
17
- }
8
+ return { channel, pluginName }
18
9
  }
19
10
 
20
11
  /**
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * DivisionBox SDK for Plugin Development
3
- *
3
+ *
4
4
  * Provides a simple API for plugins to create and manage DivisionBox instances.
5
5
  * DivisionBox is a lightweight floating window container for plugin UIs and tools.
6
6
  */
@@ -10,8 +10,17 @@ import type {
10
10
  DivisionBoxConfig,
11
11
  DivisionBoxState,
12
12
  SessionInfo,
13
+ StateChangeEvent,
13
14
  } from '../../types/division-box'
15
+ import { createPluginTuffTransport } from '../../transport'
16
+ import { createDisposableBag } from '../../transport/sdk'
17
+ import { DivisionBoxEvents } from '../../transport/events'
14
18
  import { ensureRendererChannel } from './channel'
19
+ import { tryGetPluginSdkApi } from './plugin-info'
20
+
21
+ function resolveSdkApi(): number | undefined {
22
+ return tryGetPluginSdkApi()
23
+ }
15
24
 
16
25
  /**
17
26
  * State change event handler
@@ -21,9 +30,11 @@ export type StateChangeHandler = (data: {
21
30
  state: DivisionBoxState
22
31
  }) => void
23
32
 
33
+ export type LifecycleChangeHandler = (event: StateChangeEvent) => void
34
+
24
35
  /**
25
36
  * DivisionBox SDK interface for plugins
26
- *
37
+ *
27
38
  * @example
28
39
  * ```typescript
29
40
  * // Open a DivisionBox
@@ -33,12 +44,12 @@ export type StateChangeHandler = (data: {
33
44
  * size: 'medium',
34
45
  * keepAlive: true
35
46
  * })
36
- *
47
+ *
37
48
  * // Listen for state changes
38
49
  * plugin.divisionBox.onStateChange((data) => {
39
50
  * console.log(`Session ${data.sessionId} is now ${data.state}`)
40
51
  * })
41
- *
52
+ *
42
53
  * // Close the DivisionBox
43
54
  * await plugin.divisionBox.close(sessionId)
44
55
  * ```
@@ -46,10 +57,10 @@ export type StateChangeHandler = (data: {
46
57
  export interface DivisionBoxSDK {
47
58
  /**
48
59
  * Opens a new DivisionBox instance
49
- *
60
+ *
50
61
  * @param config - Configuration for the DivisionBox
51
62
  * @returns Promise resolving to session information
52
- *
63
+ *
53
64
  * @example
54
65
  * ```typescript
55
66
  * const { sessionId } = await plugin.divisionBox.open({
@@ -68,65 +79,67 @@ export interface DivisionBoxSDK {
68
79
  * })
69
80
  * ```
70
81
  */
71
- open(config: DivisionBoxConfig): Promise<SessionInfo>
82
+ open: (config: DivisionBoxConfig) => Promise<SessionInfo>
72
83
 
73
84
  /**
74
85
  * Closes a DivisionBox instance
75
- *
86
+ *
76
87
  * @param sessionId - The session ID to close
77
88
  * @param options - Optional close options
78
89
  * @returns Promise that resolves when closed
79
- *
90
+ *
80
91
  * @example
81
92
  * ```typescript
82
93
  * // Simple close
83
94
  * await plugin.divisionBox.close(sessionId)
84
- *
95
+ *
85
96
  * // Close with delay and animation
86
97
  * await plugin.divisionBox.close(sessionId, {
87
98
  * delay: 1000,
88
99
  * animation: true
89
100
  * })
90
- *
101
+ *
91
102
  * // Force close (ignore keepAlive)
92
103
  * await plugin.divisionBox.close(sessionId, {
93
104
  * force: true
94
105
  * })
95
106
  * ```
96
107
  */
97
- close(sessionId: string, options?: CloseOptions): Promise<void>
108
+ close: (sessionId: string, options?: CloseOptions) => Promise<void>
98
109
 
99
110
  /**
100
111
  * Registers a state change listener
101
- *
112
+ *
102
113
  * @param handler - Callback function for state changes
103
114
  * @returns Unsubscribe function
104
- *
115
+ *
105
116
  * @example
106
117
  * ```typescript
107
118
  * const unsubscribe = plugin.divisionBox.onStateChange((data) => {
108
119
  * console.log(`Session ${data.sessionId} changed to ${data.state}`)
109
120
  * })
110
- *
121
+ *
111
122
  * // Later, unsubscribe
112
123
  * unsubscribe()
113
124
  * ```
114
125
  */
115
- onStateChange(handler: StateChangeHandler): () => void
126
+ onStateChange: (handler: StateChangeHandler) => () => void
127
+
128
+ onLifecycleChange: (handler: LifecycleChangeHandler) => () => void
116
129
 
117
130
  /**
118
131
  * Updates session state data
119
- *
132
+ *
120
133
  * @param sessionId - The session ID
121
134
  * @param key - State key
122
135
  * @param value - State value
123
136
  * @returns Promise that resolves when updated
124
- *
137
+ *
125
138
  * @example
126
139
  * ```typescript
127
140
  * // Save scroll position
128
141
  * await plugin.divisionBox.updateState(sessionId, 'scrollY', 150)
129
- *
142
+ *
130
143
  * // Save draft content
131
144
  * await plugin.divisionBox.updateState(sessionId, 'draft', {
132
145
  * text: 'Hello world',
@@ -134,126 +147,208 @@ export interface DivisionBoxSDK {
134
147
  * })
135
148
  * ```
136
149
  */
137
- updateState(sessionId: string, key: string, value: any): Promise<void>
150
+ updateState: (sessionId: string, key: string, value: any) => Promise<void>
138
151
 
139
152
  /**
140
153
  * Gets session state data
141
- *
154
+ *
142
155
  * @param sessionId - The session ID
143
156
  * @param key - State key
144
157
  * @returns Promise resolving to the state value
145
- *
158
+ *
146
159
  * @example
147
160
  * ```typescript
148
161
  * const scrollY = await plugin.divisionBox.getState(sessionId, 'scrollY')
149
162
  * const draft = await plugin.divisionBox.getState(sessionId, 'draft')
150
163
  * ```
151
164
  */
152
- getState(sessionId: string, key: string): Promise<any>
165
+ getState: (sessionId: string, key: string) => Promise<any>
166
+
167
+ /**
168
+ * 释放 SDK 内部注册的监听器
169
+ */
170
+ dispose: () => void
153
171
  }
154
172
 
155
173
  /**
156
174
  * Creates a DivisionBox SDK instance for plugin use
157
- *
175
+ *
158
176
  * @param channel - The plugin channel bridge for IPC communication
159
177
  * @returns Configured DivisionBox SDK instance
160
- *
178
+ *
161
179
  * @internal
162
180
  */
163
181
  export function createDivisionBoxSDK(channel: any): DivisionBoxSDK {
164
182
  const stateChangeHandlers: Set<StateChangeHandler> = new Set()
183
+ const lifecycleChangeHandlers: Set<LifecycleChangeHandler> = new Set()
184
+ const transport = createPluginTuffTransport(channel)
185
+ const disposables = createDisposableBag()
186
+ let disposed = false
165
187
 
166
- // Register listener for state change events from main process
167
- // The channel can be either IPluginChannelBridge (main process) or window.$channel (renderer)
168
- const registerListener = () => {
169
- if (channel.onMain) {
170
- // Main process plugin context
171
- channel.onMain('division-box:state-changed', (event: any) => {
172
- stateChangeHandlers.forEach(handler => handler(event.data || event))
173
- })
174
- } else if (channel.on) {
175
- // Renderer process context
176
- channel.on('division-box:state-changed', (data: any) => {
177
- stateChangeHandlers.forEach(handler => handler(data))
178
- })
188
+ const emitStateChange = (payload: StateChangeEvent) => {
189
+ for (const handler of lifecycleChangeHandlers) {
190
+ try {
191
+ handler(payload)
192
+ }
193
+ catch (error) {
194
+ console.error('[DivisionBox SDK] onLifecycleChange handler error:', error)
195
+ }
179
196
  }
197
+
198
+ for (const handler of stateChangeHandlers) {
199
+ try {
200
+ handler({ sessionId: payload.sessionId, state: payload.newState })
201
+ }
202
+ catch (error) {
203
+ console.error('[DivisionBox SDK] onStateChange handler error:', error)
204
+ }
205
+ }
206
+ }
207
+
208
+ const dispose = () => {
209
+ if (disposed) {
210
+ return
211
+ }
212
+
213
+ disposed = true
214
+ stateChangeHandlers.clear()
215
+ lifecycleChangeHandlers.clear()
216
+ disposables.dispose()
217
+ transport.destroy()
180
218
  }
181
219
 
182
- registerListener()
220
+ const ensureActive = (method: string) => {
221
+ if (disposed) {
222
+ throw new Error(`[DivisionBox SDK] Cannot call ${method} after dispose`)
223
+ }
224
+ }
225
+
226
+ try {
227
+ disposables.add(
228
+ transport.on(DivisionBoxEvents.stateChanged, (payload: StateChangeEvent) => {
229
+ emitStateChange(payload)
230
+ }),
231
+ )
232
+ }
233
+ catch {
234
+ const registerFallback =
235
+ typeof channel?.onMain === 'function'
236
+ ? channel.onMain.bind(channel)
237
+ : typeof channel?.on === 'function'
238
+ ? channel.on.bind(channel)
239
+ : null
240
+
241
+ if (registerFallback) {
242
+ const fallbackDispose = registerFallback('division-box:state-changed', (raw: any) => {
243
+ const payload = (raw?.data || raw) as StateChangeEvent
244
+ if (payload?.sessionId) {
245
+ emitStateChange(payload)
246
+ }
247
+ })
248
+ if (typeof fallbackDispose === 'function') {
249
+ disposables.add(fallbackDispose)
250
+ }
251
+ }
252
+ }
183
253
 
184
- const send: (eventName: string, payload?: any) => Promise<any> =
185
- typeof channel?.sendToMain === 'function'
186
- ? channel.sendToMain.bind(channel)
187
- : typeof channel?.send === 'function'
188
- ? channel.send.bind(channel)
189
- : (() => {
190
- throw new Error('[DivisionBox SDK] Channel send function not available')
191
- })()
254
+ if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
255
+ const onBeforeUnload = () => dispose()
256
+ window.addEventListener('beforeunload', onBeforeUnload, { once: true })
257
+ disposables.add(() => window.removeEventListener('beforeunload', onBeforeUnload))
258
+ }
192
259
 
193
260
  return {
194
261
  async open(config: DivisionBoxConfig): Promise<SessionInfo> {
195
- // Send to main process
196
- const result = await send('division-box:open', config)
197
-
262
+ ensureActive('open')
263
+ const result = await transport.send(DivisionBoxEvents.open, {
264
+ ...(config as any),
265
+ _sdkapi: resolveSdkApi(),
266
+ })
267
+
198
268
  if (!result.success) {
199
269
  throw new Error(result.error?.message || 'Failed to open DivisionBox')
200
270
  }
201
-
271
+
272
+ if (!result.data) {
273
+ throw new Error('Failed to open DivisionBox')
274
+ }
275
+
202
276
  return result.data
203
277
  },
204
278
 
205
279
  async close(sessionId: string, options?: CloseOptions): Promise<void> {
206
- const result = await send('division-box:close', { sessionId, options })
207
-
280
+ ensureActive('close')
281
+ const result = await transport.send(DivisionBoxEvents.close, {
282
+ sessionId,
283
+ options,
284
+ _sdkapi: resolveSdkApi(),
285
+ })
286
+
208
287
  if (!result.success) {
209
288
  throw new Error(result.error?.message || 'Failed to close DivisionBox')
210
289
  }
211
290
  },
212
291
 
213
292
  onStateChange(handler: StateChangeHandler): () => void {
293
+ ensureActive('onStateChange')
214
294
  stateChangeHandlers.add(handler)
215
-
295
+
216
296
  return () => {
217
297
  stateChangeHandlers.delete(handler)
218
298
  }
219
299
  },
220
300
 
301
+ onLifecycleChange(handler: LifecycleChangeHandler): () => void {
302
+ ensureActive('onLifecycleChange')
303
+ lifecycleChangeHandlers.add(handler)
304
+
305
+ return () => {
306
+ lifecycleChangeHandlers.delete(handler)
307
+ }
308
+ },
309
+
221
310
  async updateState(sessionId: string, key: string, value: any): Promise<void> {
222
- const result = await send('division-box:update-state', {
311
+ ensureActive('updateState')
312
+ const result = await transport.send(DivisionBoxEvents.updateState, {
223
313
  sessionId,
224
314
  key,
225
- value
315
+ value,
316
+ _sdkapi: resolveSdkApi(),
226
317
  })
227
-
318
+
228
319
  if (!result.success) {
229
320
  throw new Error(result.error?.message || 'Failed to update state')
230
321
  }
231
322
  },
232
323
 
233
324
  async getState(sessionId: string, key: string): Promise<any> {
234
- const result = await send('division-box:get-state', {
325
+ ensureActive('getState')
326
+ const result = await transport.send(DivisionBoxEvents.getState, {
235
327
  sessionId,
236
- key
328
+ key,
329
+ _sdkapi: resolveSdkApi(),
237
330
  })
238
-
331
+
239
332
  if (!result.success) {
240
333
  throw new Error(result.error?.message || 'Failed to get state')
241
334
  }
242
-
335
+
243
336
  return result.data
244
- }
337
+ },
338
+
339
+ dispose,
245
340
  }
246
341
  }
247
342
 
248
343
  /**
249
344
  * Hook for using DivisionBox SDK in plugin context
250
- *
345
+ *
251
346
  * @returns DivisionBox SDK instance
252
- *
347
+ *
253
348
  * @example
254
349
  * ```typescript
255
350
  * const divisionBox = useDivisionBox()
256
- *
351
+ *
257
352
  * const { sessionId } = await divisionBox.open({
258
353
  * url: 'https://example.com',
259
354
  * title: 'My Tool'
@@ -1,3 +1,6 @@
1
+ import { hasWindow } from '@talex-touch/utils/env'
2
+ import { useTouchSDK } from '@talex-touch/utils/plugin/sdk'
3
+
1
4
  /**
2
5
  * Storage onDidChange 示例
3
6
  * 展示如何使用 storage.onDidChange 监听存储文件变化
@@ -5,7 +8,7 @@
5
8
  */
6
9
 
7
10
  // 获取SDK实例
8
- const sdk = window.$touchSDK
11
+ const sdk = useTouchSDK()
9
12
 
10
13
  // 示例1: 监听特定配置文件的变化
11
14
  function setupConfigListener() {
@@ -189,7 +192,7 @@ window.storageOnDidChangeExample = {
189
192
  }
190
193
 
191
194
  // 自动运行示例(可选)
192
- if (typeof window !== 'undefined' && window.location.hostname === 'localhost') {
195
+ if (hasWindow() && window.location.hostname === 'localhost') {
193
196
  console.log('[Auto] Setting up storage listeners...')
194
197
 
195
198
  // 设置配置监听