@talex-touch/utils 1.0.30 → 1.0.32

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 (113) hide show
  1. package/animation/window-node.ts +205 -0
  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 +6 -6
  7. package/auth/useClerkProvider.ts +3 -2
  8. package/channel/index.ts +28 -21
  9. package/common/file-scan-constants.ts +137 -121
  10. package/common/file-scan-utils.ts +49 -25
  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 +19 -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 +15 -4
  19. package/common/utils/index.ts +62 -52
  20. package/common/utils/polling.ts +114 -63
  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 +255 -230
  26. package/core-box/index.ts +3 -6
  27. package/core-box/preview/index.ts +1 -0
  28. package/core-box/preview/types.ts +43 -0
  29. package/core-box/tuff/index.ts +1 -1
  30. package/core-box/tuff/tuff-dsl.ts +419 -253
  31. package/electron/clipboard-helper.ts +20 -12
  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 +1 -1
  39. package/eventbus/index.ts +11 -11
  40. package/index.ts +6 -5
  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 +113 -84
  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 +6 -3
  54. package/plugin/providers/registry.ts +8 -7
  55. package/plugin/providers/types.ts +6 -6
  56. package/plugin/sdk/channel.ts +20 -20
  57. package/plugin/sdk/clipboard.ts +8 -6
  58. package/plugin/sdk/common.ts +10 -6
  59. package/plugin/sdk/core-box.ts +2 -3
  60. package/plugin/sdk/division-box.ts +266 -0
  61. package/plugin/sdk/enum/bridge-event.ts +1 -1
  62. package/plugin/sdk/examples/storage-onDidChange-example.js +1 -1
  63. package/plugin/sdk/features.ts +34 -26
  64. package/plugin/sdk/hooks/bridge.ts +3 -6
  65. package/plugin/sdk/hooks/index.ts +1 -1
  66. package/plugin/sdk/hooks/life-cycle.ts +4 -10
  67. package/plugin/sdk/index.ts +9 -13
  68. package/plugin/sdk/service/index.ts +3 -3
  69. package/plugin/sdk/storage.ts +4 -4
  70. package/plugin/sdk/system.ts +1 -1
  71. package/plugin/sdk/types.ts +169 -143
  72. package/plugin/sdk/window/index.ts +8 -5
  73. package/preload/loading.ts +6 -6
  74. package/preload/renderer.ts +4 -2
  75. package/renderer/hooks/arg-mapper.ts +1 -2
  76. package/renderer/hooks/index.ts +2 -0
  77. package/renderer/hooks/initialize.ts +10 -8
  78. package/renderer/hooks/performance.ts +4 -4
  79. package/renderer/hooks/use-channel.ts +150 -0
  80. package/renderer/hooks/use-intelligence.ts +236 -0
  81. package/renderer/index.ts +6 -1
  82. package/renderer/ref.ts +32 -36
  83. package/renderer/slots.ts +29 -26
  84. package/renderer/storage/app-settings.ts +16 -6
  85. package/renderer/storage/base-storage.ts +236 -88
  86. package/renderer/storage/index.ts +3 -0
  87. package/renderer/storage/intelligence-storage.ts +215 -0
  88. package/renderer/storage/openers.ts +13 -3
  89. package/renderer/touch-sdk/env.ts +41 -41
  90. package/renderer/touch-sdk/index.ts +1 -1
  91. package/renderer/touch-sdk/terminal.ts +5 -5
  92. package/renderer/touch-sdk/utils.ts +4 -3
  93. package/search/levenshtein-utils.ts +11 -11
  94. package/search/types.ts +102 -103
  95. package/service/index.ts +11 -11
  96. package/service/protocol/index.ts +217 -14
  97. package/types/division-box.ts +248 -0
  98. package/types/download.ts +72 -34
  99. package/types/icon.ts +2 -1
  100. package/types/index.ts +3 -1
  101. package/types/intelligence.ts +413 -0
  102. package/types/modules/base.ts +16 -16
  103. package/types/modules/index.ts +1 -1
  104. package/types/modules/module-lifecycle.ts +21 -21
  105. package/types/modules/module-manager.ts +11 -11
  106. package/types/modules/module.ts +16 -16
  107. package/types/storage.ts +0 -1
  108. package/types/touch-app-core.ts +32 -32
  109. package/types/update.ts +79 -21
  110. package/core-box/README.md +0 -218
  111. package/core-box/builder/tuff-builder.example.ts.bak +0 -258
  112. package/core-box/run-tests.sh +0 -7
  113. package/core-box/search.ts +0 -1
@@ -36,8 +36,9 @@ export interface AdaptiveTaskQueueOptions {
36
36
  const DEFAULT_YIELD_INTERVAL_MS = 17
37
37
 
38
38
  async function delay(ms: number): Promise<void> {
39
- if (ms <= 0) return
40
- await new Promise<void>((resolve) => setTimeout(resolve, ms))
39
+ if (ms <= 0)
40
+ return
41
+ await new Promise<void>(resolve => setTimeout(resolve, ms))
41
42
  }
42
43
 
43
44
  /**
@@ -50,10 +51,11 @@ async function delay(ms: number): Promise<void> {
50
51
  export async function runAdaptiveTaskQueue<T>(
51
52
  items: readonly T[],
52
53
  handler: (item: T, index: number) => Promise<void> | void,
53
- options: AdaptiveTaskQueueOptions = {}
54
+ options: AdaptiveTaskQueueOptions = {},
54
55
  ): Promise<void> {
55
56
  const total = items.length
56
- if (total === 0) return
57
+ if (total === 0)
58
+ return
57
59
 
58
60
  const {
59
61
  estimatedTaskTimeMs = 1,
@@ -61,7 +63,7 @@ export async function runAdaptiveTaskQueue<T>(
61
63
  maxBatchSize,
62
64
  logger = console,
63
65
  label = 'AdaptiveTaskQueue',
64
- onYield
66
+ onYield,
65
67
  } = options
66
68
 
67
69
  const safeTaskMs = Math.max(estimatedTaskTimeMs, 0.1)
@@ -71,11 +73,10 @@ export async function runAdaptiveTaskQueue<T>(
71
73
  const currentPerformance = typeof globalThis !== 'undefined' ? (globalThis as any)?.performance : undefined
72
74
  const now = () => (currentPerformance ? currentPerformance.now() : Date.now())
73
75
 
74
-
75
76
  const startTime = now()
76
77
 
77
78
  logger.debug?.(
78
- `[${label}] Starting queue for ${total} item(s). batchSize=${batchSize}, estimated=${safeTaskMs.toFixed(2)}ms`
79
+ `[${label}] Starting queue for ${total} item(s). batchSize=${batchSize}, estimated=${safeTaskMs.toFixed(2)}ms`,
79
80
  )
80
81
 
81
82
  for (let index = 0; index < total; index++) {
@@ -90,19 +91,19 @@ export async function runAdaptiveTaskQueue<T>(
90
91
  logger.debug?.(
91
92
  `[${label}] Yielded after ${processed}/${total} item(s); wait ${(
92
93
  afterYield - beforeYield
93
- ).toFixed(1)}ms`
94
+ ).toFixed(1)}ms`,
94
95
  )
95
96
  onYield?.({
96
97
  processed,
97
98
  total,
98
99
  batchSize,
99
- elapsedMs
100
+ elapsedMs,
100
101
  })
101
102
  }
102
103
  }
103
104
 
104
105
  const endTime = now()
105
106
  logger.debug?.(
106
- `[${label}] Completed ${total} item(s) in ${((endTime - startTime) / 1000).toFixed(2)}s`
107
+ `[${label}] Completed ${total} item(s) in ${((endTime - startTime) / 1000).toFixed(2)}s`,
107
108
  )
108
109
  }
@@ -19,11 +19,11 @@ export class TimeoutError extends Error {
19
19
  * @param message - An optional message describing the timeout error. Defaults to 'Operation timed out'.
20
20
  */
21
21
  constructor(message: string = 'Operation timed out') {
22
- super(message);
23
- this.name = 'TimeoutError';
22
+ super(message)
23
+ this.name = 'TimeoutError'
24
24
  // Maintain proper stack trace for the error.
25
25
  if (Error.captureStackTrace) {
26
- Error.captureStackTrace(this, TimeoutError);
26
+ Error.captureStackTrace(this, TimeoutError)
27
27
  }
28
28
  }
29
29
  }
@@ -62,19 +62,19 @@ export class TimeoutError extends Error {
62
62
  export function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
63
63
  if (ms <= 0) {
64
64
  // If timeout is 0 or negative, return the original Promise without a timeout mechanism.
65
- return promise;
65
+ return promise
66
66
  }
67
67
 
68
68
  // Create a promise that rejects in <ms> milliseconds
69
69
  const timeout = new Promise<never>((_, reject) => {
70
70
  const id = setTimeout(() => {
71
- clearTimeout(id);
72
- reject(new TimeoutError(`Promise timed out after ${ms} ms`));
73
- }, ms);
74
- });
71
+ clearTimeout(id)
72
+ reject(new TimeoutError(`Promise timed out after ${ms} ms`))
73
+ }, ms)
74
+ })
75
75
 
76
76
  // Race the input promise against the timeout promise
77
- return Promise.race([promise, timeout]);
77
+ return Promise.race([promise, timeout])
78
78
  }
79
79
 
80
80
  /**
@@ -82,13 +82,13 @@ export function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
82
82
  * computes `T` based on the current attempt number.
83
83
  * @template T The type of the value.
84
84
  */
85
- type DynamicValue<T> = T | ((attempt: number) => T);
85
+ type DynamicValue<T> = T | ((attempt: number) => T)
86
86
 
87
87
  /**
88
88
  * Defines a generic asynchronous function type that returns a Promise.
89
89
  * @template T The type of the Promise's resolution value.
90
90
  */
91
- type AsyncFunction<T> = (...args: any[]) => Promise<T>;
91
+ type AsyncFunction<T> = (...args: any[]) => Promise<T>
92
92
 
93
93
  /**
94
94
  * Defines the options for configuring the retrier behavior.
@@ -100,45 +100,45 @@ export interface RetrierOptions {
100
100
  * - If a `function`, it dynamically calculates the maximum retries based on the current attempt number (starting from 1).
101
101
  * @defaultValue 2 (meaning 1 initial attempt + 2 retries, total 3 attempts)
102
102
  */
103
- maxRetries?: DynamicValue<number>;
103
+ maxRetries?: DynamicValue<number>
104
104
  /**
105
105
  * The timeout duration for each individual attempt in milliseconds.
106
106
  * - If a `number`, it represents a fixed timeout for each attempt.
107
107
  * - If a `function`, it dynamically calculates the timeout based on the current attempt number.
108
108
  * @defaultValue 5000 (5 seconds)
109
109
  */
110
- timeoutMs?: DynamicValue<number>;
110
+ timeoutMs?: DynamicValue<number>
111
111
  /**
112
112
  * Callback invoked at the beginning of each attempt.
113
113
  * @param attempt - The current attempt number (starts from 1).
114
114
  * @param error - The error from the previous attempt, if any (undefined for the first attempt).
115
115
  */
116
- onAttempt?: (attempt: number, error?: Error) => void;
116
+ onAttempt?: (attempt: number, error?: Error) => void
117
117
  /**
118
118
  * Callback invoked upon successful completion of the operation.
119
119
  * @template T The type of the successful result.
120
120
  * @param result - The successful result of the operation.
121
121
  * @param attempt - The attempt number on which the operation succeeded.
122
122
  */
123
- onSuccess?: <T>(result: T, attempt: number) => void;
123
+ onSuccess?: <T>(result: T, attempt: number) => void
124
124
  /**
125
125
  * Callback invoked when all retries have been exhausted and the operation ultimately fails.
126
126
  * @param error - The final error that caused the operation to fail.
127
127
  * @param attempt - The total number of attempts made before final failure.
128
128
  */
129
- onFailure?: (error: Error, attempt: number) => void;
129
+ onFailure?: (error: Error, attempt: number) => void
130
130
  /**
131
131
  * Callback invoked before initiating a retry, indicating that a retry will occur.
132
132
  * @param attempt - The attempt number that just failed and will lead to the next retry.
133
133
  * @param error - The error that caused the current attempt to fail.
134
134
  */
135
- onRetry?: (attempt: number, error: Error) => void;
135
+ onRetry?: (attempt: number, error: Error) => void
136
136
  /**
137
137
  * Callback invoked when a single attempt times out. Note that this is a specific type of failure that leads to a retry.
138
138
  * @param attempt - The attempt number that timed out.
139
139
  * @param ms - The timeout duration (in milliseconds) that was set for this specific attempt.
140
140
  */
141
- onTimeout?: (attempt: number, ms: number) => void;
141
+ onTimeout?: (attempt: number, ms: number) => void
142
142
  /**
143
143
  * A predicate function that determines whether a given error should trigger a retry.
144
144
  * If this function returns `false`, the retrier will immediately stop and throw the error.
@@ -147,7 +147,7 @@ export interface RetrierOptions {
147
147
  * @param attempt - The current attempt number.
148
148
  * @returns `true` if a retry should occur, `false` otherwise.
149
149
  */
150
- shouldRetry?: (error: Error, attempt: number) => boolean;
150
+ shouldRetry?: (error: Error, attempt: number) => boolean
151
151
  }
152
152
 
153
153
  /**
@@ -218,7 +218,7 @@ export function createRetrier(options: RetrierOptions = {}) {
218
218
  onRetry,
219
219
  onTimeout,
220
220
  shouldRetry = () => true, // Default: retry on all errors
221
- } = options;
221
+ } = options
222
222
 
223
223
  /**
224
224
  * Resolves a DynamicValue to its concrete value for the given attempt.
@@ -228,8 +228,8 @@ export function createRetrier(options: RetrierOptions = {}) {
228
228
  * @returns The concrete value.
229
229
  */
230
230
  const resolveDynamicValue = <T_Val>(value: DynamicValue<T_Val>, attempt: number): T_Val => {
231
- return typeof value === 'function' ? (value as (attempt: number) => T_Val)(attempt) : value;
232
- };
231
+ return typeof value === 'function' ? (value as (attempt: number) => T_Val)(attempt) : value
232
+ }
233
233
 
234
234
  /**
235
235
  * A higher-order function that takes an asynchronous function and returns a new function
@@ -243,53 +243,55 @@ export function createRetrier(options: RetrierOptions = {}) {
243
243
  */
244
244
  return function <T, Func extends AsyncFunction<T>>(func: Func): ((...args: Parameters<Func>) => Promise<T>) {
245
245
  return async function (this: ThisParameterType<Func>, ...args: Parameters<Func>): Promise<T> {
246
- let currentAttempt = 0;
247
- let lastError: Error | undefined;
246
+ let currentAttempt = 0
247
+ let lastError: Error | undefined
248
248
 
249
249
  // Resolve maxRetries once or dynamically per attempt based on DynamicValue type
250
- const calculatedMaxRetries = resolveDynamicValue(maxRetries, 1); // Calculate for the first attempt as starting point
250
+ const calculatedMaxRetries = resolveDynamicValue(maxRetries, 1) // Calculate for the first attempt as starting point
251
251
 
252
252
  // Loop through attempts up to the maximum allowed retries
253
253
  while (currentAttempt <= calculatedMaxRetries) {
254
- currentAttempt++;
255
- onAttempt?.(currentAttempt, lastError); // Notify about current attempt, including previous error if any
254
+ currentAttempt++
255
+ onAttempt?.(currentAttempt, lastError) // Notify about current attempt, including previous error if any
256
256
 
257
257
  // Resolve timeoutMs dynamically for the current attempt
258
- const currentTimeoutMs = resolveDynamicValue(timeoutMs, currentAttempt);
258
+ const currentTimeoutMs = resolveDynamicValue(timeoutMs, currentAttempt)
259
259
 
260
260
  try {
261
261
  // Execute the original function with its original `this` context and arguments,
262
262
  // wrapped by the `withTimeout` utility.
263
- const result = await withTimeout(func.apply(this, args), currentTimeoutMs);
264
- onSuccess?.(result, currentAttempt); // Notify success
265
- return result; // Return the successful result
266
- } catch (error: any) {
267
- lastError = error; // Store the error for the next attempt's `onAttempt` callback
263
+ const result = await withTimeout(func.apply(this, args), currentTimeoutMs)
264
+ onSuccess?.(result, currentAttempt) // Notify success
265
+ return result // Return the successful result
266
+ }
267
+ catch (error: any) {
268
+ lastError = error // Store the error for the next attempt's `onAttempt` callback
268
269
 
269
270
  // Notify if the specific error was a timeout
270
271
  if (error instanceof TimeoutError) {
271
- onTimeout?.(currentAttempt, currentTimeoutMs);
272
- } else {
272
+ onTimeout?.(currentAttempt, currentTimeoutMs)
273
+ }
274
+ else {
273
275
  // console.warn(`Attempt ${currentAttempt} failed with error:`, error.message); // Example internal logging
274
276
  }
275
277
 
276
278
  // Determine if a retry should proceed based on the `shouldRetry` predicate and max attempts
277
- const shouldProceedRetry = shouldRetry(error, currentAttempt);
279
+ const shouldProceedRetry = shouldRetry(error, currentAttempt)
278
280
 
279
281
  if (!shouldProceedRetry || currentAttempt > calculatedMaxRetries) {
280
- onFailure?.(error, currentAttempt); // Notify final failure
281
- throw error; // Throw the error if no more retries or `shouldRetry` returns false
282
+ onFailure?.(error, currentAttempt) // Notify final failure
283
+ throw error // Throw the error if no more retries or `shouldRetry` returns false
282
284
  }
283
285
 
284
- onRetry?.(currentAttempt, error); // Notify that a retry will occur
286
+ onRetry?.(currentAttempt, error) // Notify that a retry will occur
285
287
  // Optional: Add a delay here for exponential backoff or other retry strategies.
286
288
  // e.g., `await new Promise(resolve => setTimeout(resolve, Math.pow(2, currentAttempt) * 100));`
287
289
  }
288
290
  }
289
291
  // This line should ideally not be reached if the loop's conditions are correct and errors are always thrown.
290
- throw new Error('Retrier exhausted all attempts without success. This is an unexpected state.');
291
- };
292
- };
292
+ throw new Error('Retrier exhausted all attempts without success. This is an unexpected state.')
293
+ }
294
+ }
293
295
  }
294
296
 
295
297
  /**
@@ -359,16 +361,17 @@ export function useRetrier<T, Func extends AsyncFunction<T>>(func: Func): ((...a
359
361
  timeoutMs: 5000, // Default: 5 seconds timeout
360
362
  onAttempt: (attempt, error) => {
361
363
  if (attempt > 1) {
362
- console.log(`[UseRetrier Default] Attempt ${attempt} (after previous error: ${error?.message || 'None'})...`);
363
- } else {
364
- console.log(`[UseRetrier Default] Starting initial attempt ${attempt}...`);
364
+ console.log(`[UseRetrier Default] Attempt ${attempt} (after previous error: ${error?.message || 'None'})...`)
365
+ }
366
+ else {
367
+ console.log(`[UseRetrier Default] Starting initial attempt ${attempt}...`)
365
368
  }
366
369
  },
367
370
  onSuccess: (result, attempt) => console.log(`[UseRetrier Default] ✅ Succeeded on attempt ${attempt}. Result:`, result),
368
371
  onFailure: (error, attempt) => console.error(`[UseRetrier Default] ❌ Failed after ${attempt} attempts. Final Error:`, error.message),
369
372
  onRetry: (attempt, error) => console.warn(`[UseRetrier Default] 🔄 Will retry. Attempt ${attempt} failed with: ${error.message}`),
370
373
  onTimeout: (attempt, ms) => console.warn(`[UseRetrier Default] ⏰ Attempt ${attempt} timed out after ${ms}ms.`),
371
- });
374
+ })
372
375
  // Use the created default retrier to wrap the provided function.
373
- return defaultRetrier(func);
376
+ return defaultRetrier(func)
374
377
  }
@@ -24,7 +24,7 @@ const DEFAULT_HISTORY_LIMIT = 50
24
24
  export const DEFAULT_TIMING_LOG_THRESHOLDS: Readonly<ResolvedTimingLogThresholds> = Object.freeze({
25
25
  none: 16.7,
26
26
  info: 200,
27
- warn: 500
27
+ warn: 500,
28
28
  })
29
29
 
30
30
  export const DEFAULT_TIMING_OPTIONS: Readonly<Required<Pick<TimingOptions, 'autoLog' | 'storeHistory'>> & {
@@ -32,7 +32,7 @@ export const DEFAULT_TIMING_OPTIONS: Readonly<Required<Pick<TimingOptions, 'auto
32
32
  }> = Object.freeze({
33
33
  autoLog: DEFAULT_AUTO_LOG,
34
34
  storeHistory: DEFAULT_STORE_HISTORY,
35
- logThresholds: DEFAULT_TIMING_LOG_THRESHOLDS
35
+ logThresholds: DEFAULT_TIMING_LOG_THRESHOLDS,
36
36
  })
37
37
 
38
38
  export const DEFAULT_TIMING_MANAGER_CONFIG: Readonly<
@@ -43,7 +43,7 @@ export const DEFAULT_TIMING_MANAGER_CONFIG: Readonly<
43
43
  autoLog: DEFAULT_AUTO_LOG,
44
44
  storeHistory: DEFAULT_STORE_HISTORY,
45
45
  historyLimit: DEFAULT_HISTORY_LIMIT,
46
- logThresholds: DEFAULT_TIMING_LOG_THRESHOLDS
46
+ logThresholds: DEFAULT_TIMING_LOG_THRESHOLDS,
47
47
  })
48
48
 
49
49
  export interface TimingStats {
@@ -83,7 +83,7 @@ export interface TimingOptions {
83
83
  logThresholds?: TimingLogThresholdOverrides
84
84
  }
85
85
 
86
- type ResolvedTimingOptions = {
86
+ interface ResolvedTimingOptions {
87
87
  autoLog: boolean
88
88
  storeHistory: boolean
89
89
  historyLimit: number
@@ -101,13 +101,13 @@ export class TimingManager {
101
101
  constructor(config: TimingManagerConfig = {}) {
102
102
  const mergedThresholds: ResolvedTimingLogThresholds = {
103
103
  ...DEFAULT_TIMING_LOG_THRESHOLDS,
104
- ...(config.logThresholds ?? {})
104
+ ...(config.logThresholds ?? {}),
105
105
  }
106
106
 
107
107
  this.config = {
108
108
  ...DEFAULT_TIMING_MANAGER_CONFIG,
109
109
  ...config,
110
- logThresholds: mergedThresholds
110
+ logThresholds: mergedThresholds,
111
111
  }
112
112
  }
113
113
 
@@ -142,12 +142,13 @@ export class TimingManager {
142
142
 
143
143
  getStats(label: string): TimingStats | undefined {
144
144
  const stats = this.stats.get(label)
145
- if (!stats) return undefined
145
+ if (!stats)
146
+ return undefined
146
147
  return { ...stats }
147
148
  }
148
149
 
149
150
  getAllStats(): TimingStats[] {
150
- return Array.from(this.stats.values()).map((s) => ({ ...s }))
151
+ return Array.from(this.stats.values()).map(s => ({ ...s }))
151
152
  }
152
153
 
153
154
  getHistory(label: string): TimingRecord[] {
@@ -159,7 +160,7 @@ export class TimingManager {
159
160
  const stats = this.moduleStats.get(moduleKey)
160
161
  return stats ? { ...stats } : undefined
161
162
  }
162
- return Array.from(this.moduleStats.values()).map((s) => ({ ...s }))
163
+ return Array.from(this.moduleStats.values()).map(s => ({ ...s }))
163
164
  }
164
165
 
165
166
  reset(label?: string): void {
@@ -183,7 +184,7 @@ export class TimingManager {
183
184
  maxMs: Number.NEGATIVE_INFINITY,
184
185
  minMs: Number.POSITIVE_INFINITY,
185
186
  lastMs: 0,
186
- errorCount: 0
187
+ errorCount: 0,
187
188
  }
188
189
 
189
190
  next.count += 1
@@ -214,7 +215,7 @@ export class TimingManager {
214
215
  const logThresholds: ResolvedTimingLogThresholds = {
215
216
  ...DEFAULT_TIMING_LOG_THRESHOLDS,
216
217
  ...(this.config.logThresholds ?? {}),
217
- ...(options.logThresholds ?? {})
218
+ ...(options.logThresholds ?? {}),
218
219
  }
219
220
 
220
221
  return {
@@ -223,7 +224,7 @@ export class TimingManager {
223
224
  historyLimit: options.historyLimit ?? this.config.historyLimit ?? DEFAULT_HISTORY_LIMIT,
224
225
  logThresholds,
225
226
  formatter: options.formatter ?? this.config.formatter ?? defaultFormatter,
226
- logger: options.logger ?? this.config.logger ?? defaultLogger
227
+ logger: options.logger ?? this.config.logger ?? defaultLogger,
227
228
  }
228
229
  }
229
230
  }
@@ -232,7 +233,7 @@ export class TimingScope {
232
233
  constructor(
233
234
  private readonly manager: TimingManager,
234
235
  private readonly label: string,
235
- private readonly options: TimingOptions
236
+ private readonly options: TimingOptions,
236
237
  ) {}
237
238
 
238
239
  async cost<T>(fn: () => Promise<T> | T, meta: TimingMeta = {}, overrides: TimingOptions = {}): Promise<T> {
@@ -241,7 +242,8 @@ export class TimingScope {
241
242
  const result = await fn()
242
243
  this.finish(startedAt, meta, undefined, overrides)
243
244
  return result
244
- } catch (error) {
245
+ }
246
+ catch (error) {
245
247
  this.finish(startedAt, meta, error, overrides)
246
248
  throw error
247
249
  }
@@ -256,7 +258,8 @@ export class TimingScope {
256
258
  const value = await fn(index)
257
259
  this.finish(startedAt, { ...iterationMeta, iteration: index }, undefined, overrides)
258
260
  results.push(value)
259
- } catch (error) {
261
+ }
262
+ catch (error) {
260
263
  this.finish(startedAt, { ...iterationMeta, iteration: index }, error, overrides)
261
264
  throw error
262
265
  }
@@ -274,9 +277,9 @@ export class TimingScope {
274
277
  durationMs,
275
278
  startedAt,
276
279
  endedAt,
277
- meta
280
+ meta,
278
281
  },
279
- { ...this.options, ...overrides }
282
+ { ...this.options, ...overrides },
280
283
  )
281
284
  }
282
285
 
@@ -296,7 +299,7 @@ export class TimingScope {
296
299
  startedAt,
297
300
  endedAt,
298
301
  meta,
299
- error
302
+ error,
300
303
  }
301
304
 
302
305
  this.manager.record(this.label, record, { ...this.options, ...overrides })
@@ -305,10 +308,10 @@ export class TimingScope {
305
308
 
306
309
  function defaultFormatter(record: TimingRecord, stats: TimingStats): string {
307
310
  const duration = record.durationMs.toFixed(2)
308
- const levelTag =
309
- record.logLevel && record.logLevel !== 'info' ? ` [${record.logLevel.toUpperCase()}]` : ''
311
+ const levelTag
312
+ = record.logLevel && record.logLevel !== 'info' ? ` [${record.logLevel.toUpperCase()}]` : ''
310
313
  return `⏱ [${record.label}] ${duration} ms${levelTag} (avg: ${stats.avgMs.toFixed(
311
- 2
314
+ 2,
312
315
  )} ms, max: ${stats.maxMs.toFixed(2)} ms, count: ${stats.count})`
313
316
  }
314
317
 
@@ -370,7 +373,7 @@ export function completeTiming(
370
373
  label: string,
371
374
  startedAt: number,
372
375
  meta: TimingMeta = {},
373
- options: TimingOptions = {}
376
+ options: TimingOptions = {},
374
377
  ): number {
375
378
  const endedAt = now()
376
379
  const durationMs = endedAt - startedAt
@@ -381,9 +384,9 @@ export function completeTiming(
381
384
  durationMs,
382
385
  startedAt,
383
386
  endedAt,
384
- meta
387
+ meta,
385
388
  },
386
- options
389
+ options,
387
390
  )
388
391
  return durationMs
389
392
  }
@@ -392,7 +395,7 @@ export function logTiming(
392
395
  label: string,
393
396
  durationMs: number,
394
397
  meta: TimingMeta = {},
395
- options: TimingOptions = {}
398
+ options: TimingOptions = {},
396
399
  ): void {
397
400
  const endedAt = now()
398
401
  const startedAt = endedAt - durationMs
@@ -403,9 +406,9 @@ export function logTiming(
403
406
  durationMs,
404
407
  startedAt,
405
408
  endedAt,
406
- meta
409
+ meta,
407
410
  },
408
- options
411
+ options,
409
412
  )
410
413
  }
411
414
 
@@ -422,14 +425,14 @@ export const timingLogger = {
422
425
  label,
423
426
  startedAt: startTiming(),
424
427
  meta,
425
- options
428
+ options,
426
429
  }
427
430
  },
428
431
 
429
432
  finish(
430
433
  token: TimingLoggerToken,
431
434
  meta: TimingMeta = {},
432
- overrides: TimingOptions = {}
435
+ overrides: TimingOptions = {},
433
436
  ): number {
434
437
  const mergedMeta = { ...token.meta, ...meta }
435
438
  const mergedOptions = mergeTimingOptions(token.options, overrides)
@@ -440,7 +443,7 @@ export const timingLogger = {
440
443
  label: string,
441
444
  durationMs: number,
442
445
  meta: TimingMeta = {},
443
- options: TimingOptions = {}
446
+ options: TimingOptions = {},
444
447
  ): number {
445
448
  logTiming(label, durationMs, meta, options)
446
449
  return durationMs
@@ -450,7 +453,7 @@ export const timingLogger = {
450
453
  label: string,
451
454
  fn: () => Promise<T> | T,
452
455
  meta: TimingMeta = {},
453
- options: TimingOptions = {}
456
+ options: TimingOptions = {},
454
457
  ): Promise<T> {
455
458
  const scope = createTiming(label, options)
456
459
  return scope.cost(fn, meta)
@@ -460,11 +463,11 @@ export const timingLogger = {
460
463
  label: string,
461
464
  durationMs: number,
462
465
  meta: TimingMeta = {},
463
- options: TimingOptions = {}
466
+ options: TimingOptions = {},
464
467
  ): number {
465
468
  logTiming(label, durationMs, meta, options)
466
469
  return durationMs
467
- }
470
+ },
468
471
  }
469
472
 
470
473
  export function createTiming(label: string, options: TimingOptions = {}): TimingScope {
@@ -473,9 +476,10 @@ export function createTiming(label: string, options: TimingOptions = {}): Timing
473
476
 
474
477
  function mergeTimingOptions(
475
478
  base: TimingOptions = {},
476
- override: TimingOptions = {}
479
+ override: TimingOptions = {},
477
480
  ): TimingOptions {
478
- if (!base && !override) return {}
481
+ if (!base && !override)
482
+ return {}
479
483
  if (!override || Object.keys(override).length === 0) {
480
484
  return { ...base }
481
485
  }
@@ -488,7 +492,7 @@ function mergeTimingOptions(
488
492
  ...override,
489
493
  logThresholds: {
490
494
  ...(base.logThresholds ?? {}),
491
- ...(override.logThresholds ?? {})
492
- }
495
+ ...(override.logThresholds ?? {}),
496
+ },
493
497
  }
494
498
  }
@@ -3,4 +3,4 @@
3
3
  * 提供 TuffItem 构建工具和实用函数
4
4
  */
5
5
 
6
- export * from './tuff-builder';
6
+ export * from './tuff-builder'