@talex-touch/utils 1.0.40 → 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 (235) 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 +97 -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 +21 -3
  72. package/market/index.ts +1 -1
  73. package/market/types.ts +20 -5
  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 +82 -8
  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 -0
  87. package/plugin/providers/market-client.ts +218 -0
  88. package/plugin/providers/npm-provider.ts +228 -0
  89. package/plugin/providers/tpex-provider.ts +297 -0
  90. package/plugin/providers/tpex-types.ts +34 -0
  91. package/plugin/sdk/box-items.ts +14 -0
  92. package/plugin/sdk/box-sdk.ts +64 -0
  93. package/plugin/sdk/channel.ts +119 -4
  94. package/plugin/sdk/clipboard.ts +26 -12
  95. package/plugin/sdk/cloud-sync.ts +113 -0
  96. package/plugin/sdk/common.ts +19 -11
  97. package/plugin/sdk/core-box.ts +6 -15
  98. package/plugin/sdk/division-box.ts +160 -65
  99. package/plugin/sdk/examples/storage-onDidChange-example.js +5 -2
  100. package/plugin/sdk/feature-sdk.ts +111 -76
  101. package/plugin/sdk/flow.ts +146 -45
  102. package/plugin/sdk/hooks/bridge.ts +113 -49
  103. package/plugin/sdk/hooks/life-cycle.ts +35 -16
  104. package/plugin/sdk/index.ts +14 -3
  105. package/plugin/sdk/intelligence.ts +87 -0
  106. package/plugin/sdk/meta/README.md +179 -0
  107. package/plugin/sdk/meta-sdk.ts +244 -0
  108. package/plugin/sdk/notification.ts +9 -0
  109. package/plugin/sdk/performance.ts +1 -16
  110. package/plugin/sdk/plugin-info.ts +64 -0
  111. package/plugin/sdk/power.ts +155 -0
  112. package/plugin/sdk/recommend.ts +21 -0
  113. package/plugin/sdk/service/index.ts +12 -8
  114. package/plugin/sdk/sqlite.ts +141 -0
  115. package/plugin/sdk/storage.ts +2 -6
  116. package/plugin/sdk/system.ts +2 -9
  117. package/plugin/sdk/temp-files.ts +41 -0
  118. package/plugin/sdk/touch-sdk.ts +18 -0
  119. package/plugin/sdk/types.ts +44 -4
  120. package/plugin/sdk/window/index.ts +12 -9
  121. package/plugin/sdk-version.ts +231 -0
  122. package/preload/renderer.ts +3 -2
  123. package/renderer/hooks/arg-mapper.ts +34 -6
  124. package/renderer/hooks/index.ts +13 -0
  125. package/renderer/hooks/initialize.ts +2 -1
  126. package/renderer/hooks/use-agent-market-sdk.ts +7 -0
  127. package/renderer/hooks/use-agent-market.ts +106 -0
  128. package/renderer/hooks/use-agents-sdk.ts +7 -0
  129. package/renderer/hooks/use-app-sdk.ts +7 -0
  130. package/renderer/hooks/use-channel.ts +33 -4
  131. package/renderer/hooks/use-download-sdk.ts +21 -0
  132. package/renderer/hooks/use-intelligence-sdk.ts +7 -0
  133. package/renderer/hooks/use-intelligence-stats.ts +290 -0
  134. package/renderer/hooks/use-intelligence.ts +202 -104
  135. package/renderer/hooks/use-market-sdk.ts +16 -0
  136. package/renderer/hooks/use-notification-sdk.ts +7 -0
  137. package/renderer/hooks/use-permission-sdk.ts +7 -0
  138. package/renderer/hooks/use-permission.ts +325 -0
  139. package/renderer/hooks/use-platform-sdk.ts +7 -0
  140. package/renderer/hooks/use-plugin-sdk.ts +16 -0
  141. package/renderer/hooks/use-settings-sdk.ts +7 -0
  142. package/renderer/hooks/use-update-sdk.ts +21 -0
  143. package/renderer/index.ts +1 -0
  144. package/renderer/ref.ts +19 -10
  145. package/renderer/shared/components/SharedPluginDetailContent.vue +84 -0
  146. package/renderer/shared/components/SharedPluginDetailHeader.vue +116 -0
  147. package/renderer/shared/components/SharedPluginDetailMetaList.vue +39 -0
  148. package/renderer/shared/components/SharedPluginDetailReadme.vue +45 -0
  149. package/renderer/shared/components/SharedPluginDetailVersions.vue +98 -0
  150. package/renderer/shared/components/index.ts +5 -0
  151. package/renderer/shared/components/shims-vue.d.ts +5 -0
  152. package/renderer/shared/index.ts +2 -0
  153. package/renderer/shared/plugin-detail.ts +62 -0
  154. package/renderer/storage/app-settings.ts +3 -1
  155. package/renderer/storage/base-storage.ts +508 -82
  156. package/renderer/storage/intelligence-storage.ts +37 -46
  157. package/renderer/storage/openers.ts +3 -1
  158. package/renderer/storage/storage-subscription.ts +126 -42
  159. package/renderer/touch-sdk/env.ts +10 -10
  160. package/renderer/touch-sdk/index.ts +114 -18
  161. package/renderer/touch-sdk/terminal.ts +24 -13
  162. package/search/feature-matcher.ts +279 -0
  163. package/search/fuzzy-match.ts +64 -34
  164. package/search/index.ts +10 -0
  165. package/search/levenshtein-utils.ts +17 -11
  166. package/transport/errors.ts +310 -0
  167. package/transport/event/builder.ts +378 -0
  168. package/transport/event/index.ts +7 -0
  169. package/transport/event/types.ts +292 -0
  170. package/transport/events/index.ts +2670 -0
  171. package/transport/events/meta-overlay.ts +79 -0
  172. package/transport/events/types/agents.ts +177 -0
  173. package/transport/events/types/app-index.ts +9 -0
  174. package/transport/events/types/app.ts +475 -0
  175. package/transport/events/types/box-item.ts +222 -0
  176. package/transport/events/types/clipboard.ts +80 -0
  177. package/transport/events/types/core-box.ts +534 -0
  178. package/transport/events/types/device-idle.ts +7 -0
  179. package/transport/events/types/division-box.ts +99 -0
  180. package/transport/events/types/download.ts +115 -0
  181. package/transport/events/types/file-index.ts +73 -0
  182. package/transport/events/types/flow.ts +149 -0
  183. package/transport/events/types/index.ts +70 -0
  184. package/transport/events/types/market.ts +39 -0
  185. package/transport/events/types/meta-overlay.ts +184 -0
  186. package/transport/events/types/notification.ts +140 -0
  187. package/transport/events/types/permission.ts +90 -0
  188. package/transport/events/types/platform.ts +8 -0
  189. package/transport/events/types/plugin.ts +620 -0
  190. package/transport/events/types/sentry.ts +20 -0
  191. package/transport/events/types/storage.ts +208 -0
  192. package/transport/events/types/transport.ts +60 -0
  193. package/transport/events/types/tray.ts +16 -0
  194. package/transport/events/types/update.ts +78 -0
  195. package/transport/index.ts +139 -0
  196. package/transport/main.ts +2 -0
  197. package/transport/sdk/constants.ts +29 -0
  198. package/transport/sdk/domains/agents-market.ts +47 -0
  199. package/transport/sdk/domains/agents.ts +62 -0
  200. package/transport/sdk/domains/app.ts +48 -0
  201. package/transport/sdk/domains/disposable.ts +35 -0
  202. package/transport/sdk/domains/download.ts +139 -0
  203. package/transport/sdk/domains/index.ts +13 -0
  204. package/transport/sdk/domains/intelligence.ts +616 -0
  205. package/transport/sdk/domains/market.ts +35 -0
  206. package/transport/sdk/domains/notification.ts +62 -0
  207. package/transport/sdk/domains/permission.ts +85 -0
  208. package/transport/sdk/domains/platform.ts +19 -0
  209. package/transport/sdk/domains/plugin.ts +144 -0
  210. package/transport/sdk/domains/settings.ts +92 -0
  211. package/transport/sdk/domains/update.ts +64 -0
  212. package/transport/sdk/index.ts +60 -0
  213. package/transport/sdk/main-transport.ts +710 -0
  214. package/transport/sdk/main.ts +9 -0
  215. package/transport/sdk/plugin-transport.ts +654 -0
  216. package/transport/sdk/port-policy.ts +38 -0
  217. package/transport/sdk/renderer-transport.ts +1165 -0
  218. package/transport/types.ts +605 -0
  219. package/types/agent.ts +399 -0
  220. package/types/cloud-sync.ts +157 -0
  221. package/types/division-box.ts +47 -27
  222. package/types/download.ts +1 -0
  223. package/types/flow.ts +63 -12
  224. package/types/icon.ts +2 -1
  225. package/types/index.ts +5 -0
  226. package/types/intelligence.ts +1492 -81
  227. package/types/modules/base.ts +2 -0
  228. package/types/path-browserify.d.ts +5 -0
  229. package/types/platform.ts +12 -0
  230. package/types/startup-info.ts +32 -0
  231. package/types/touch-app-core.ts +8 -8
  232. package/types/update.ts +94 -1
  233. package/vitest.config.ts +25 -0
  234. package/auth/useClerkConfig.ts +0 -40
  235. package/auth/useClerkProvider.ts +0 -52
@@ -0,0 +1,378 @@
1
+ /**
2
+ * @fileoverview TuffEvent Builder - Type-safe event definition system
3
+ * @module @talex-touch/utils/transport/event/builder
4
+ */
5
+
6
+ import type { EventOptions, TuffEvent } from './types'
7
+
8
+ // ============================================================================
9
+ // Builder Classes
10
+ // ============================================================================
11
+
12
+ /**
13
+ * Namespace builder - Entry point for event definition.
14
+ *
15
+ * @typeParam TNamespace - The namespace string type
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const builder = TuffEventBuilder.namespace('core-box')
20
+ * // or use the shorthand:
21
+ * const builder = defineEvent('core-box')
22
+ * ```
23
+ */
24
+ export class TuffEventBuilder<TNamespace extends string> {
25
+ private readonly _namespace: TNamespace
26
+
27
+ private constructor(namespace: TNamespace) {
28
+ this._namespace = namespace
29
+ }
30
+
31
+ /**
32
+ * Creates a new event builder with the specified namespace.
33
+ *
34
+ * @param ns - The namespace string (e.g., 'core-box', 'storage')
35
+ * @returns A new TuffEventBuilder instance
36
+ * @throws {Error} If namespace is empty or not a string
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const builder = TuffEventBuilder.namespace('my-plugin')
41
+ * ```
42
+ */
43
+ static namespace<T extends string>(ns: T): TuffEventBuilder<T> {
44
+ if (!ns || typeof ns !== 'string') {
45
+ throw new Error('[TuffEvent] Namespace must be a non-empty string')
46
+ }
47
+ return new TuffEventBuilder(ns)
48
+ }
49
+
50
+ /**
51
+ * Defines the module for this event.
52
+ *
53
+ * @param module - The module string (e.g., 'search', 'ui')
54
+ * @returns A TuffModuleBuilder instance
55
+ * @throws {Error} If module is empty or not a string
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * defineEvent('core-box').module('search')
60
+ * ```
61
+ */
62
+ module<TModule extends string>(module: TModule): TuffModuleBuilder<TNamespace, TModule> {
63
+ if (!module || typeof module !== 'string') {
64
+ throw new Error('[TuffEvent] Module must be a non-empty string')
65
+ }
66
+ return new TuffModuleBuilder(this._namespace, module)
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Module builder - Second stage of event definition.
72
+ *
73
+ * @typeParam TNamespace - The namespace string type
74
+ * @typeParam TModule - The module string type
75
+ */
76
+ export class TuffModuleBuilder<
77
+ TNamespace extends string,
78
+ TModule extends string,
79
+ > {
80
+ /**
81
+ * @internal
82
+ */
83
+ constructor(
84
+ private readonly _namespace: TNamespace,
85
+ private readonly _module: TModule,
86
+ ) {}
87
+
88
+ /**
89
+ * Defines the action for this event.
90
+ *
91
+ * @param action - The action string (e.g., 'query', 'hide')
92
+ * @returns A TuffActionBuilder instance
93
+ * @throws {Error} If action is empty or not a string
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * defineEvent('core-box').module('search').event('query')
98
+ * ```
99
+ */
100
+ event<TAction extends string>(action: TAction): TuffActionBuilder<TNamespace, TModule, TAction> {
101
+ if (!action || typeof action !== 'string') {
102
+ throw new Error('[TuffEvent] Action must be a non-empty string')
103
+ }
104
+ return new TuffActionBuilder(this._namespace, this._module, action)
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Action builder - Final stage of event definition.
110
+ *
111
+ * @typeParam TNamespace - The namespace string type
112
+ * @typeParam TModule - The module string type
113
+ * @typeParam TAction - The action string type
114
+ */
115
+ export class TuffActionBuilder<
116
+ TNamespace extends string,
117
+ TModule extends string,
118
+ TAction extends string,
119
+ > {
120
+ /**
121
+ * @internal
122
+ */
123
+ constructor(
124
+ private readonly _namespace: TNamespace,
125
+ private readonly _module: TModule,
126
+ private readonly _action: TAction,
127
+ ) {}
128
+
129
+ /**
130
+ * Finalizes the event definition with request/response types.
131
+ *
132
+ * @typeParam TRequest - Type of the request payload (default: void)
133
+ * @typeParam TResponse - Type of the response payload (default: void)
134
+ * @param options - Optional batch/stream configuration
135
+ * @returns An immutable TuffEvent instance
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // Simple event with no payload
140
+ * const hideEvent = defineEvent('core-box')
141
+ * .module('ui')
142
+ * .event('hide')
143
+ * .define()
144
+ *
145
+ * // Event with typed request/response
146
+ * const queryEvent = defineEvent('core-box')
147
+ * .module('search')
148
+ * .event('query')
149
+ * .define<{ text: string }, SearchResult[]>()
150
+ *
151
+ * // Event with batch configuration
152
+ * const getEvent = defineEvent('storage')
153
+ * .module('app')
154
+ * .event('get')
155
+ * .define<{ key: string }, unknown>({
156
+ * batch: { enabled: true, windowMs: 50 }
157
+ * })
158
+ *
159
+ * // Stream event
160
+ * const streamEvent = defineEvent('core-box')
161
+ * .module('search')
162
+ * .event('stream')
163
+ * .define<{ text: string }, AsyncIterable<SearchResult>>({
164
+ * stream: { enabled: true }
165
+ * })
166
+ * ```
167
+ */
168
+ define<TRequest = void, TResponse = void>(
169
+ options?: EventOptions,
170
+ ): TuffEvent<TRequest, TResponse, TNamespace, TModule, TAction> {
171
+ const namespace = this._namespace
172
+ const module = this._module
173
+ const action = this._action
174
+ const eventName = `${namespace}:${module}:${action}`
175
+
176
+ // Create immutable event object
177
+ const event: TuffEvent<TRequest, TResponse, TNamespace, TModule, TAction> = Object.freeze({
178
+ __brand: 'TuffEvent' as const,
179
+ namespace,
180
+ module,
181
+ action,
182
+ _batch: options?.batch,
183
+ _stream: options?.stream,
184
+ _request: undefined as unknown as TRequest,
185
+ _response: undefined as unknown as TResponse,
186
+
187
+ toString(): string {
188
+ return eventName
189
+ },
190
+
191
+ toEventName(): string {
192
+ return eventName
193
+ },
194
+ })
195
+
196
+ return event
197
+ }
198
+ }
199
+
200
+ // ============================================================================
201
+ // Shorthand Functions
202
+ // ============================================================================
203
+
204
+ /**
205
+ * Creates a new event definition builder.
206
+ *
207
+ * @remarks
208
+ * This is the primary entry point for defining TuffEvents.
209
+ * All events MUST be created using this builder to ensure type safety.
210
+ *
211
+ * @param namespace - The event namespace (e.g., 'core-box', 'storage', 'plugin')
212
+ * @returns A TuffEventBuilder instance
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * // Define a simple event
217
+ * const hideEvent = defineEvent('core-box')
218
+ * .module('ui')
219
+ * .event('hide')
220
+ * .define()
221
+ *
222
+ * // Define an event with typed payloads
223
+ * const queryEvent = defineEvent('core-box')
224
+ * .module('search')
225
+ * .event('query')
226
+ * .define<QueryRequest, QueryResponse>()
227
+ *
228
+ * // Define a batch-enabled event
229
+ * const getEvent = defineEvent('storage')
230
+ * .module('app')
231
+ * .event('get')
232
+ * .define<{ key: string }, unknown>({
233
+ * batch: { enabled: true, windowMs: 50, maxSize: 20 }
234
+ * })
235
+ * ```
236
+ */
237
+ export const defineEvent = TuffEventBuilder.namespace
238
+
239
+ /**
240
+ * Defines a TuffEvent using a raw event name string.
241
+ *
242
+ * @remarks
243
+ * This is intended for incremental migrations from legacy IPC event names that
244
+ * don't follow the `namespace:module:action` convention yet.
245
+ *
246
+ * Prefer `defineEvent(namespace).module(module).event(action)` for new code.
247
+ */
248
+ export function defineRawEvent<TRequest = void, TResponse = void>(
249
+ eventName: string,
250
+ options?: EventOptions,
251
+ ): TuffEvent<TRequest, TResponse, string, string, string> {
252
+ if (!eventName || typeof eventName !== 'string') {
253
+ throw new Error('[TuffEvent] Raw event name must be a non-empty string')
254
+ }
255
+
256
+ const parts = eventName.split(':')
257
+ const namespace = parts[0] || 'raw'
258
+ const module = parts.length >= 2 ? (parts[1] || 'raw') : 'raw'
259
+ const action = parts.length >= 3 ? (parts.slice(2).join(':') || 'raw') : 'raw'
260
+
261
+ const event: TuffEvent<TRequest, TResponse, string, string, string> = Object.freeze({
262
+ __brand: 'TuffEvent' as const,
263
+ namespace,
264
+ module,
265
+ action,
266
+ _batch: options?.batch,
267
+ _stream: options?.stream,
268
+ _request: undefined as unknown as TRequest,
269
+ _response: undefined as unknown as TResponse,
270
+
271
+ toString(): string {
272
+ return eventName
273
+ },
274
+
275
+ toEventName(): string {
276
+ return eventName
277
+ },
278
+ })
279
+
280
+ return event
281
+ }
282
+
283
+ // ============================================================================
284
+ // Type Guards and Assertions
285
+ // ============================================================================
286
+
287
+ /**
288
+ * Runtime type guard to check if a value is a valid TuffEvent.
289
+ *
290
+ * @param value - The value to check
291
+ * @returns `true` if the value is a TuffEvent, `false` otherwise
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * if (isTuffEvent(maybeEvent)) {
296
+ * // TypeScript now knows maybeEvent is a TuffEvent
297
+ * console.log(maybeEvent.toString())
298
+ * }
299
+ * ```
300
+ */
301
+ export function isTuffEvent(value: unknown): value is TuffEvent {
302
+ return (
303
+ typeof value === 'object'
304
+ && value !== null
305
+ && (value as Record<string, unknown>).__brand === 'TuffEvent'
306
+ && typeof (value as Record<string, unknown>).toString === 'function'
307
+ && typeof (value as Record<string, unknown>).namespace === 'string'
308
+ && typeof (value as Record<string, unknown>).module === 'string'
309
+ && typeof (value as Record<string, unknown>).action === 'string'
310
+ )
311
+ }
312
+
313
+ /**
314
+ * Asserts that a value is a valid TuffEvent, throwing if not.
315
+ *
316
+ * @param value - The value to assert
317
+ * @param context - Optional context string for error messages
318
+ * @throws {TypeError} If the value is not a TuffEvent
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * function sendEvent(event: unknown, payload: unknown) {
323
+ * assertTuffEvent(event, 'sendEvent')
324
+ * // TypeScript now knows event is a TuffEvent
325
+ * console.log(`Sending: ${event.toString()}`)
326
+ * }
327
+ * ```
328
+ */
329
+ export function assertTuffEvent(
330
+ value: unknown,
331
+ context?: string,
332
+ ): asserts value is TuffEvent {
333
+ if (!isTuffEvent(value)) {
334
+ const prefix = context ? `[${context}] ` : ''
335
+ throw new TypeError(
336
+ `${prefix}Invalid event. Expected TuffEvent created via defineEvent(), `
337
+ + `got ${value === null ? 'null' : typeof value}. `
338
+ + `String event names are not allowed - use the event builder.`,
339
+ )
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Extracts the event name string from a TuffEvent.
345
+ *
346
+ * @param event - The TuffEvent to extract from
347
+ * @returns The event name string
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * const name = getEventName(CoreBoxEvents.ui.hide)
352
+ * // name = 'core-box:ui:hide'
353
+ * ```
354
+ */
355
+ export function getEventName(event: TuffEvent): string {
356
+ assertTuffEvent(event, 'getEventName')
357
+ return event.toString()
358
+ }
359
+
360
+ /**
361
+ * Checks if an event has batch configuration enabled.
362
+ *
363
+ * @param event - The TuffEvent to check
364
+ * @returns `true` if batch is enabled
365
+ */
366
+ export function isBatchEnabled(event: TuffEvent): boolean {
367
+ return event._batch?.enabled === true
368
+ }
369
+
370
+ /**
371
+ * Checks if an event has stream configuration enabled.
372
+ *
373
+ * @param event - The TuffEvent to check
374
+ * @returns `true` if stream is enabled
375
+ */
376
+ export function isStreamEnabled(event: TuffEvent): boolean {
377
+ return event._stream?.enabled === true
378
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Event module exports
3
+ * @module @talex-touch/utils/transport/event
4
+ */
5
+
6
+ export * from './builder'
7
+ export * from './types'
@@ -0,0 +1,292 @@
1
+ /**
2
+ * @fileoverview Core type definitions for TuffEvent system
3
+ * @module @talex-touch/utils/transport/event/types
4
+ */
5
+
6
+ // ============================================================================
7
+ // Brand Symbol for Type Safety
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Unique symbol used for branding TuffEvent instances.
12
+ * This ensures type-level distinction from plain objects.
13
+ * @internal
14
+ */
15
+ declare const _TuffEventBrand: unique symbol
16
+
17
+ // ============================================================================
18
+ // Configuration Types
19
+ // ============================================================================
20
+
21
+ /**
22
+ * Merge strategy for batch requests.
23
+ *
24
+ * @remarks
25
+ * - `queue` - All requests are queued in order
26
+ * - `dedupe` - Duplicate payloads share a single request/response
27
+ * - `latest` - Only the latest request for a given key is kept
28
+ */
29
+ export type BatchMergeStrategy = 'queue' | 'dedupe' | 'latest'
30
+
31
+ /**
32
+ * Backpressure strategy for stream processing.
33
+ *
34
+ * @remarks
35
+ * - `drop` - Drop new data when buffer is full
36
+ * - `buffer` - Buffer data (may cause memory growth)
37
+ * - `error` - Throw error when buffer is full
38
+ */
39
+ export type StreamBackpressure = 'drop' | 'buffer' | 'error'
40
+
41
+ /**
42
+ * Configuration for batch request merging.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const config: BatchConfig = {
47
+ * enabled: true,
48
+ * windowMs: 50,
49
+ * maxSize: 20,
50
+ * mergeStrategy: 'dedupe'
51
+ * }
52
+ * ```
53
+ */
54
+ export interface BatchConfig {
55
+ /**
56
+ * Whether batch mode is enabled for this event.
57
+ * @defaultValue false
58
+ */
59
+ enabled: boolean
60
+
61
+ /**
62
+ * Time window in milliseconds to collect requests before flushing.
63
+ * @defaultValue 50
64
+ */
65
+ windowMs?: number
66
+
67
+ /**
68
+ * Maximum number of requests to batch before forcing a flush.
69
+ * @defaultValue 50
70
+ */
71
+ maxSize?: number
72
+
73
+ /**
74
+ * Strategy for merging duplicate requests.
75
+ * @defaultValue 'queue'
76
+ */
77
+ mergeStrategy?: BatchMergeStrategy
78
+ }
79
+
80
+ /**
81
+ * Configuration for stream-based communication.
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const config: StreamConfig = {
86
+ * enabled: true,
87
+ * bufferSize: 100,
88
+ * backpressure: 'buffer'
89
+ * }
90
+ * ```
91
+ */
92
+ export interface StreamConfig {
93
+ /**
94
+ * Whether stream mode is enabled for this event.
95
+ * @defaultValue false
96
+ */
97
+ enabled: boolean
98
+
99
+ /**
100
+ * Maximum number of items to buffer.
101
+ * @defaultValue 100
102
+ */
103
+ bufferSize?: number
104
+
105
+ /**
106
+ * Strategy for handling backpressure.
107
+ * @defaultValue 'buffer'
108
+ */
109
+ backpressure?: StreamBackpressure
110
+ }
111
+
112
+ /**
113
+ * Options for event definition.
114
+ */
115
+ export interface EventOptions {
116
+ /**
117
+ * Batch configuration for this event.
118
+ */
119
+ batch?: BatchConfig
120
+
121
+ /**
122
+ * Stream configuration for this event.
123
+ */
124
+ stream?: StreamConfig
125
+ }
126
+
127
+ // ============================================================================
128
+ // TuffEvent Core Interface
129
+ // ============================================================================
130
+
131
+ /**
132
+ * Type-safe event definition for TuffTransport.
133
+ *
134
+ * @remarks
135
+ * TuffEvent instances are immutable and created via the event builder.
136
+ * They encode request/response types at the type level for compile-time safety.
137
+ *
138
+ * @typeParam TRequest - Type of the request payload
139
+ * @typeParam TResponse - Type of the response payload
140
+ * @typeParam TNamespace - Event namespace (e.g., 'core-box')
141
+ * @typeParam TModule - Event module (e.g., 'search')
142
+ * @typeParam TAction - Event action (e.g., 'query')
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const event: TuffEvent<{ text: string }, SearchResult[]> = defineEvent('core-box')
147
+ * .module('search')
148
+ * .event('query')
149
+ * .define()
150
+ *
151
+ * // event.toString() returns 'core-box:search:query'
152
+ * ```
153
+ */
154
+ export interface TuffEvent<
155
+ TRequest = void,
156
+ TResponse = void,
157
+ TNamespace extends string = string,
158
+ TModule extends string = string,
159
+ TAction extends string = string,
160
+ > {
161
+ /**
162
+ * Brand identifier for runtime type checking.
163
+ * @internal
164
+ */
165
+ readonly __brand: 'TuffEvent'
166
+
167
+ /**
168
+ * Event namespace (first segment of event name).
169
+ * @example 'core-box', 'storage', 'plugin'
170
+ */
171
+ readonly namespace: TNamespace
172
+
173
+ /**
174
+ * Event module (second segment of event name).
175
+ * @example 'search', 'ui', 'lifecycle'
176
+ */
177
+ readonly module: TModule
178
+
179
+ /**
180
+ * Event action (third segment of event name).
181
+ * @example 'query', 'hide', 'load'
182
+ */
183
+ readonly action: TAction
184
+
185
+ /**
186
+ * Batch configuration for this event.
187
+ * @internal
188
+ */
189
+ readonly _batch?: BatchConfig
190
+
191
+ /**
192
+ * Stream configuration for this event.
193
+ * @internal
194
+ */
195
+ readonly _stream?: StreamConfig
196
+
197
+ /**
198
+ * Type marker for request payload (compile-time only).
199
+ * @internal
200
+ */
201
+ readonly _request: TRequest
202
+
203
+ /**
204
+ * Type marker for response payload (compile-time only).
205
+ * @internal
206
+ */
207
+ readonly _response: TResponse
208
+
209
+ /**
210
+ * Converts event to its string representation.
211
+ * @returns Event name in format 'namespace:module:action'
212
+ */
213
+ toString: () => string
214
+
215
+ /**
216
+ * Gets the full event name.
217
+ * @returns Event name in format 'namespace:module:action'
218
+ */
219
+ toEventName: () => string
220
+ }
221
+
222
+ // ============================================================================
223
+ // Type Utilities
224
+ // ============================================================================
225
+
226
+ /**
227
+ * Extracts the request type from a TuffEvent.
228
+ *
229
+ * @typeParam E - The TuffEvent type
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * type Req = EventRequest<typeof CoreBoxEvents.search.query>
234
+ * // Req = { text: string }
235
+ * ```
236
+ */
237
+ export type EventRequest<E> = E extends TuffEvent<infer R, any, any, any, any> ? R : never
238
+
239
+ /**
240
+ * Extracts the response type from a TuffEvent.
241
+ *
242
+ * @typeParam E - The TuffEvent type
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * type Res = EventResponse<typeof CoreBoxEvents.search.query>
247
+ * // Res = TuffSearchResult
248
+ * ```
249
+ */
250
+ export type EventResponse<E> = E extends TuffEvent<any, infer R, any, any, any> ? R : never
251
+
252
+ /**
253
+ * Checks if an event is a stream event (response is AsyncIterable).
254
+ *
255
+ * @typeParam E - The TuffEvent type
256
+ */
257
+ export type IsStreamEvent<E> = E extends TuffEvent<any, AsyncIterable<any>, any, any, any>
258
+ ? true
259
+ : false
260
+
261
+ /**
262
+ * Extracts the chunk type from a stream event.
263
+ *
264
+ * @typeParam E - The TuffEvent type (must be a stream event)
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * type Chunk = StreamChunk<typeof CoreBoxEvents.search.stream>
269
+ * // Chunk = SearchResult
270
+ * ```
271
+ */
272
+ export type StreamChunk<E> = E extends TuffEvent<any, AsyncIterable<infer C>, any, any, any>
273
+ ? C
274
+ : never
275
+
276
+ /**
277
+ * Extracts the namespace from a TuffEvent.
278
+ * @internal
279
+ */
280
+ export type EventNamespace<E> = E extends TuffEvent<any, any, infer N, any, any> ? N : never
281
+
282
+ /**
283
+ * Extracts the module from a TuffEvent.
284
+ * @internal
285
+ */
286
+ export type EventModule<E> = E extends TuffEvent<any, any, any, infer M, any> ? M : never
287
+
288
+ /**
289
+ * Extracts the action from a TuffEvent.
290
+ * @internal
291
+ */
292
+ export type EventAction<E> = E extends TuffEvent<any, any, any, any, infer A> ? A : never