front-cpu 0.1.1

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 (136) hide show
  1. package/README.md +475 -0
  2. package/README.zh-CN.md +474 -0
  3. package/dist/Pipeline.d.ts +119 -0
  4. package/dist/Pipeline.d.ts.map +1 -0
  5. package/dist/Pipeline.js +373 -0
  6. package/dist/Pipeline.js.map +1 -0
  7. package/dist/debug.d.ts +3 -0
  8. package/dist/debug.d.ts.map +1 -0
  9. package/dist/debug.js +12 -0
  10. package/dist/debug.js.map +1 -0
  11. package/dist/index.d.ts +20 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +19 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/interfaces.d.ts +49 -0
  16. package/dist/interfaces.d.ts.map +1 -0
  17. package/dist/interfaces.js +8 -0
  18. package/dist/interfaces.js.map +1 -0
  19. package/dist/isa/index.d.ts +20 -0
  20. package/dist/isa/index.d.ts.map +1 -0
  21. package/dist/isa/index.js +26 -0
  22. package/dist/isa/index.js.map +1 -0
  23. package/dist/isa/types.d.ts +144 -0
  24. package/dist/isa/types.d.ts.map +1 -0
  25. package/dist/isa/types.js +10 -0
  26. package/dist/isa/types.js.map +1 -0
  27. package/dist/logging/CPUConsole.d.ts +105 -0
  28. package/dist/logging/CPUConsole.d.ts.map +1 -0
  29. package/dist/logging/CPUConsole.js +471 -0
  30. package/dist/logging/CPUConsole.js.map +1 -0
  31. package/dist/logging/CPUDebugger.d.ts +91 -0
  32. package/dist/logging/CPUDebugger.d.ts.map +1 -0
  33. package/dist/logging/CPUDebugger.js +166 -0
  34. package/dist/logging/CPUDebugger.js.map +1 -0
  35. package/dist/logging/CPUEventCollector.d.ts +90 -0
  36. package/dist/logging/CPUEventCollector.d.ts.map +1 -0
  37. package/dist/logging/CPUEventCollector.js +353 -0
  38. package/dist/logging/CPUEventCollector.js.map +1 -0
  39. package/dist/logging/CPULogger.d.ts +150 -0
  40. package/dist/logging/CPULogger.d.ts.map +1 -0
  41. package/dist/logging/CPULogger.js +336 -0
  42. package/dist/logging/CPULogger.js.map +1 -0
  43. package/dist/logging/index.d.ts +10 -0
  44. package/dist/logging/index.d.ts.map +1 -0
  45. package/dist/logging/index.js +16 -0
  46. package/dist/logging/index.js.map +1 -0
  47. package/dist/logging/runtime.d.ts +37 -0
  48. package/dist/logging/runtime.d.ts.map +1 -0
  49. package/dist/logging/runtime.js +42 -0
  50. package/dist/logging/runtime.js.map +1 -0
  51. package/dist/logging/stack-parser.d.ts +22 -0
  52. package/dist/logging/stack-parser.d.ts.map +1 -0
  53. package/dist/logging/stack-parser.js +144 -0
  54. package/dist/logging/stack-parser.js.map +1 -0
  55. package/dist/logging/types.d.ts +73 -0
  56. package/dist/logging/types.d.ts.map +1 -0
  57. package/dist/logging/types.js +47 -0
  58. package/dist/logging/types.js.map +1 -0
  59. package/dist/scheduling/ResourceStrategyRegistry.d.ts +61 -0
  60. package/dist/scheduling/ResourceStrategyRegistry.d.ts.map +1 -0
  61. package/dist/scheduling/ResourceStrategyRegistry.js +109 -0
  62. package/dist/scheduling/ResourceStrategyRegistry.js.map +1 -0
  63. package/dist/scheduling/index.d.ts +6 -0
  64. package/dist/scheduling/index.d.ts.map +1 -0
  65. package/dist/scheduling/index.js +5 -0
  66. package/dist/scheduling/index.js.map +1 -0
  67. package/dist/scheduling/types.d.ts +44 -0
  68. package/dist/scheduling/types.d.ts.map +1 -0
  69. package/dist/scheduling/types.js +5 -0
  70. package/dist/scheduling/types.js.map +1 -0
  71. package/dist/stages/EX.d.ts +17 -0
  72. package/dist/stages/EX.d.ts.map +1 -0
  73. package/dist/stages/EX.js +95 -0
  74. package/dist/stages/EX.js.map +1 -0
  75. package/dist/stages/IF.d.ts +41 -0
  76. package/dist/stages/IF.d.ts.map +1 -0
  77. package/dist/stages/IF.js +83 -0
  78. package/dist/stages/IF.js.map +1 -0
  79. package/dist/stages/RES.d.ts +17 -0
  80. package/dist/stages/RES.d.ts.map +1 -0
  81. package/dist/stages/RES.js +37 -0
  82. package/dist/stages/RES.js.map +1 -0
  83. package/dist/stages/SCH.d.ts +77 -0
  84. package/dist/stages/SCH.d.ts.map +1 -0
  85. package/dist/stages/SCH.js +270 -0
  86. package/dist/stages/SCH.js.map +1 -0
  87. package/dist/stages/WB.d.ts +19 -0
  88. package/dist/stages/WB.d.ts.map +1 -0
  89. package/dist/stages/WB.js +102 -0
  90. package/dist/stages/WB.js.map +1 -0
  91. package/dist/types.d.ts +111 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +26 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/utils/InstructionCancellation.d.ts +31 -0
  96. package/dist/utils/InstructionCancellation.d.ts.map +1 -0
  97. package/dist/utils/InstructionCancellation.js +53 -0
  98. package/dist/utils/InstructionCancellation.js.map +1 -0
  99. package/dist/utils/abortable.d.ts +30 -0
  100. package/dist/utils/abortable.d.ts.map +1 -0
  101. package/dist/utils/abortable.js +76 -0
  102. package/dist/utils/abortable.js.map +1 -0
  103. package/dist/utils/request.d.ts +27 -0
  104. package/dist/utils/request.d.ts.map +1 -0
  105. package/dist/utils/request.js +96 -0
  106. package/dist/utils/request.js.map +1 -0
  107. package/package.json +74 -0
  108. package/src/Pipeline.ts +475 -0
  109. package/src/debug.ts +15 -0
  110. package/src/index.ts +67 -0
  111. package/src/interfaces.ts +53 -0
  112. package/src/isa/index.ts +34 -0
  113. package/src/isa/types.ts +178 -0
  114. package/src/logging/CPUConsole.md +843 -0
  115. package/src/logging/CPUConsole.ts +631 -0
  116. package/src/logging/CPUDebugger.ts +235 -0
  117. package/src/logging/CPUEventCollector.ts +418 -0
  118. package/src/logging/CPULogger.ts +435 -0
  119. package/src/logging/CPU_LOGGING_DESIGN.md +1319 -0
  120. package/src/logging/USAGE_GUIDE.md +505 -0
  121. package/src/logging/index.ts +21 -0
  122. package/src/logging/runtime.ts +96 -0
  123. package/src/logging/stack-parser.ts +168 -0
  124. package/src/logging/types.ts +101 -0
  125. package/src/scheduling/ResourceStrategyRegistry.ts +124 -0
  126. package/src/scheduling/index.ts +13 -0
  127. package/src/scheduling/types.ts +47 -0
  128. package/src/stages/EX.ts +121 -0
  129. package/src/stages/IF.ts +103 -0
  130. package/src/stages/RES.ts +46 -0
  131. package/src/stages/SCH.ts +331 -0
  132. package/src/stages/WB.ts +127 -0
  133. package/src/types.ts +118 -0
  134. package/src/utils/InstructionCancellation.ts +73 -0
  135. package/src/utils/abortable.ts +89 -0
  136. package/src/utils/request.ts +125 -0
@@ -0,0 +1,631 @@
1
+ /**
2
+ * CPU 控制台打印系统
3
+ *
4
+ * 职责:
5
+ * 1. 实时打印指令执行过程
6
+ * 2. 美观的彩色输出
7
+ * 3. 分级别控制详细程度
8
+ * 4. 可折叠的详细信息
9
+ */
10
+
11
+ import type { QueuedInstruction } from '../types'
12
+ import { ConsoleLevel } from './types'
13
+ import { formatCallSourceShort } from './stack-parser'
14
+
15
+ export class CPUConsole {
16
+ private enabled: boolean = true
17
+ private level: ConsoleLevel = ConsoleLevel.NORMAL
18
+ private filter: Set<string> = new Set() // 指令类型过滤
19
+
20
+ constructor() {
21
+ this.loadSettings()
22
+ }
23
+
24
+ /**
25
+ * 加载设置
26
+ */
27
+ private loadSettings(): void {
28
+ const savedLevel = localStorage.getItem('cpu-console-level')
29
+ if (savedLevel) {
30
+ this.level = parseInt(savedLevel) as ConsoleLevel
31
+ }
32
+
33
+ const savedFilter = localStorage.getItem('cpu-console-filter')
34
+ if (savedFilter) {
35
+ try {
36
+ const types = JSON.parse(savedFilter)
37
+ this.filter = new Set(types)
38
+ } catch (e) {
39
+ // 忽略解析错误
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * 配置方法
46
+ */
47
+ setLevel(level: ConsoleLevel): void {
48
+ this.level = level
49
+ localStorage.setItem('cpu-console-level', level.toString())
50
+ }
51
+
52
+ setFilter(types: string[]): void {
53
+ this.filter = new Set(types)
54
+ localStorage.setItem('cpu-console-filter', JSON.stringify(types))
55
+ }
56
+
57
+ enable(): void {
58
+ this.enabled = true
59
+ }
60
+
61
+ disable(): void {
62
+ this.enabled = false
63
+ }
64
+
65
+ getLevel(): ConsoleLevel {
66
+ return this.level
67
+ }
68
+
69
+ // ==================== 打印方法 ====================
70
+
71
+ /**
72
+ * 指令创建
73
+ */
74
+ onInstructionCreated(instruction: QueuedInstruction): void {
75
+ if (!this.shouldPrint(instruction.type)) return
76
+
77
+ if (this.level >= ConsoleLevel.NORMAL) {
78
+ // 🔍 格式化调用源信息
79
+ const callSourceInfo = instruction.context.callSource
80
+ ? ` %c📍 ${formatCallSourceShort(instruction.context.callSource)}`
81
+ : ''
82
+
83
+ // 🎯 使用与指令成功一致的分组格式
84
+ console.groupCollapsed(
85
+ `%c[指令创建] %c${this.formatTime()} %c${instruction.type}%c${callSourceInfo}`,
86
+ 'color: #3b82f6; font-weight: bold',
87
+ 'color: #666; font-size: 11px',
88
+ 'color: #3b82f6; font-weight: bold; background: #3b82f615; padding: 2px 6px; border-radius: 3px',
89
+ 'color: #3b82f6',
90
+ ...(callSourceInfo ? ['color: #8b5cf6; font-weight: bold'] : [])
91
+ )
92
+
93
+ // 🔥 显示指令基本信息
94
+ console.log('%c📋 指令信息:', 'color: #3b82f6; font-weight: bold')
95
+ console.table({
96
+ 'Instruction ID': instruction.id,
97
+ 'Correlation ID': instruction.context.correlationId,
98
+ 'Type': instruction.type,
99
+ 'Status': instruction.status,
100
+ 'Source': instruction.context.source,
101
+ 'Retry Count': instruction.context.retryCount,
102
+ })
103
+
104
+ // 🔥 显示指令参数
105
+ if (this.level >= ConsoleLevel.DEBUG) {
106
+ console.log('%c📝 指令参数 (Payload):', 'color: #3b82f6; font-weight: bold')
107
+ console.log(instruction.payload)
108
+ } else {
109
+ console.log('%c📝 指令参数: (use level=DEBUG to see payload)', 'color: #666; font-style: italic')
110
+ }
111
+
112
+ // 🔥 显示调用源详情
113
+ if (instruction.context.callSource && this.level >= ConsoleLevel.VERBOSE) {
114
+ console.log('%c📍 调用源详情:', 'color: #8b5cf6; font-weight: bold')
115
+ console.table({
116
+ 'File': instruction.context.callSource.file,
117
+ 'Line': instruction.context.callSource.line,
118
+ 'Column': instruction.context.callSource.column,
119
+ 'Function': instruction.context.callSource.function || 'N/A',
120
+ })
121
+ }
122
+
123
+ console.groupEnd()
124
+ }
125
+ }
126
+
127
+ /**
128
+ * 指令成功
129
+ */
130
+ onInstructionSuccess(instruction: QueuedInstruction, duration: number): void {
131
+ if (!this.shouldPrint(instruction.type)) return
132
+
133
+ // 🔍 格式化调用源信息
134
+ const callSourceInfo = instruction.context.callSource
135
+ ? ` %c📍 ${formatCallSourceShort(instruction.context.callSource)}`
136
+ : ''
137
+
138
+ // 🎯 核心:折叠分组,方便查看
139
+ console.groupCollapsed(
140
+ `%c[指令成功] %c${this.formatTime()} %c${instruction.type}%c %c${duration}ms${callSourceInfo}`,
141
+ 'color: #10b981; font-weight: bold',
142
+ 'color: #666; font-size: 11px',
143
+ 'color: #10b981; font-weight: bold; background: #10b98115; padding: 2px 6px; border-radius: 3px',
144
+ 'color: #10b981',
145
+ 'color: #10b981; font-weight: bold',
146
+ ...(callSourceInfo ? ['color: #8b5cf6; font-weight: bold'] : [])
147
+ )
148
+
149
+ // 🔥 显示指令输入参数
150
+ if (this.level >= ConsoleLevel.NORMAL) {
151
+ console.log('%c📝 指令参数 (Payload):', 'color: #3b82f6; font-weight: bold')
152
+ console.log(instruction.payload)
153
+ }
154
+
155
+ // 🔥 显示后端返回结果
156
+ if (instruction.result && this.level >= ConsoleLevel.NORMAL) {
157
+ console.log('%c📥 后端返回 (Result):', 'color: #10b981; font-weight: bold')
158
+ console.log(instruction.result)
159
+ }
160
+
161
+ // 🔥 显示WB阶段真实执行内容
162
+ if (this.level >= ConsoleLevel.VERBOSE && instruction.writeBackExecution) {
163
+ const wbExec = instruction.writeBackExecution
164
+ console.log('%c💾 WB阶段执行记录:', 'color: #8b5cf6; font-weight: bold')
165
+
166
+ if (wbExec.hasCommit) {
167
+ if (wbExec.commitSuccess === true) {
168
+ console.log(' ✅ commit() 函数执行成功')
169
+ console.log(' 📝 commit 调用参数:', wbExec.commitArgs)
170
+ } else if (wbExec.commitSuccess === false) {
171
+ console.log(' ❌ commit() 函数执行失败')
172
+ console.log(' 📝 commit 调用参数:', wbExec.commitArgs)
173
+ console.log(' 🚨 commit 错误:', wbExec.commitError)
174
+ } else {
175
+ console.log(' ⚠️ commit() 状态未知')
176
+ }
177
+ } else {
178
+ console.log(' ⏭️ 无 commit() 函数')
179
+ }
180
+
181
+ if (wbExec.rollbackExecuted) {
182
+ console.log(' 🔄 执行了乐观更新回滚')
183
+ console.log(' 📋 回滚快照:', wbExec.rollbackSnapshot)
184
+ if (wbExec.rollbackError) {
185
+ console.log(' 🚨 回滚错误:', wbExec.rollbackError)
186
+ }
187
+ }
188
+
189
+ // 显示中断处理器注册(成功时)
190
+ if (instruction.status === 'committed') {
191
+ console.log(' 🎯 已注册到中断处理器 (SSE去重)')
192
+ }
193
+ }
194
+
195
+ // 显示流水线阶段
196
+ if (this.level >= ConsoleLevel.VERBOSE) {
197
+ this.printPipelineStages(instruction)
198
+ }
199
+
200
+ // 显示详细信息
201
+ if (this.level >= ConsoleLevel.DEBUG) {
202
+ this.printInstructionDetails(instruction)
203
+ }
204
+
205
+ console.groupEnd()
206
+ }
207
+
208
+ /**
209
+ * 指令被取消
210
+ */
211
+ onInstructionCancelled(instruction: QueuedInstruction, duration: number): void {
212
+ if (!this.shouldPrint(instruction.type)) return
213
+
214
+ // 🔍 格式化调用源信息
215
+ const callSourceInfo = instruction.context.callSource
216
+ ? ` %c📍 ${formatCallSourceShort(instruction.context.callSource)}`
217
+ : ''
218
+
219
+ // 使用橙色表示取消(不同于红色的失败)
220
+ console.groupCollapsed(
221
+ `%c[指令取消] %c${this.formatTime()} %c${instruction.type}%c %c${duration}ms${callSourceInfo}`,
222
+ 'color: #f59e0b; font-weight: bold',
223
+ 'color: #666; font-size: 11px',
224
+ 'color: #f59e0b; font-weight: bold; background: #f59e0b15; padding: 2px 6px; border-radius: 3px',
225
+ 'color: #f59e0b',
226
+ 'color: #f59e0b; font-weight: bold',
227
+ ...(callSourceInfo ? ['color: #8b5cf6; font-weight: bold'] : [])
228
+ )
229
+
230
+ // 显示取消原因
231
+ console.warn(
232
+ `%c原因: ${instruction.cancelReason || '未知原因'}`,
233
+ 'color: #f59e0b; font-weight: bold'
234
+ )
235
+
236
+ // 显示取消阶段
237
+ if (instruction.cancelledAt) {
238
+ console.log(
239
+ `%c🔸 取消阶段: ${instruction.cancelledAt}`,
240
+ 'color: #f59e0b'
241
+ )
242
+ }
243
+
244
+ // 🔥 显示指令输入参数
245
+ if (this.level >= ConsoleLevel.NORMAL) {
246
+ console.log('%c📝 指令参数 (Payload):', 'color: #3b82f6; font-weight: bold')
247
+ console.log(instruction.payload)
248
+ }
249
+
250
+ // 显示流水线阶段
251
+ if (this.level >= ConsoleLevel.VERBOSE) {
252
+ this.printPipelineStages(instruction)
253
+ }
254
+
255
+ console.groupEnd()
256
+ }
257
+
258
+ /**
259
+ * 指令失败
260
+ */
261
+ onInstructionFailure(instruction: QueuedInstruction, error: Error, duration: number): void {
262
+ if (!this.shouldPrint(instruction.type)) return
263
+
264
+ // 🔍 格式化调用源信息
265
+ const callSourceInfo = instruction.context.callSource
266
+ ? ` %c📍 ${formatCallSourceShort(instruction.context.callSource)}`
267
+ : ''
268
+
269
+ // 🔥 失败时自动展开,方便排查
270
+ console.group(
271
+ `%c[指令失败] %c${this.formatTime()} %c${instruction.type}%c %c${duration}ms${callSourceInfo}`,
272
+ 'color: #ef4444; font-weight: bold',
273
+ 'color: #666; font-size: 11px',
274
+ 'color: #ef4444; font-weight: bold; background: #ef444415; padding: 2px 6px; border-radius: 3px',
275
+ 'color: #ef4444',
276
+ 'color: #ef4444; font-weight: bold',
277
+ ...(callSourceInfo ? ['color: #8b5cf6; font-weight: bold'] : [])
278
+ )
279
+
280
+ // 显示错误信息
281
+ console.error(`%c原因: ${error.message}`, 'color: #ef4444; font-weight: bold')
282
+
283
+ // 🔥 显示指令输入参数
284
+ if (this.level >= ConsoleLevel.NORMAL) {
285
+ console.log('%c📝 指令参数 (Payload):', 'color: #3b82f6; font-weight: bold')
286
+ console.log(instruction.payload)
287
+ }
288
+
289
+ // 显示是否回滚
290
+ if (instruction.optimisticSnapshot) {
291
+ console.log('%c🔄 已回滚乐观更新', 'color: #f59e0b; font-weight: bold')
292
+ }
293
+
294
+ // 显示流水线阶段
295
+ if (this.level >= ConsoleLevel.VERBOSE) {
296
+ this.printPipelineStages(instruction)
297
+ }
298
+
299
+ // 显示详细信息
300
+ if (this.level >= ConsoleLevel.VERBOSE) {
301
+ this.printInstructionDetails(instruction)
302
+ console.error('Error Stack:', error.stack)
303
+ }
304
+
305
+ // 🔥 智能建议
306
+ this.printSuggestions(instruction, error)
307
+
308
+ console.groupEnd()
309
+ }
310
+
311
+ /**
312
+ * 乐观更新应用
313
+ */
314
+ onOptimisticApplied(instruction: QueuedInstruction): void {
315
+ if (!this.shouldPrint(instruction.type)) return
316
+
317
+ if (this.level >= ConsoleLevel.VERBOSE) {
318
+ // 🔍 格式化调用源信息
319
+ const callSourceInfo = instruction.context.callSource
320
+ ? ` %c📍 ${formatCallSourceShort(instruction.context.callSource)}`
321
+ : ''
322
+
323
+ console.groupCollapsed(
324
+ `%c[乐观更新] %c${this.formatTime()} %c${instruction.type}%c${callSourceInfo}`,
325
+ 'color: #8b5cf6; font-weight: bold',
326
+ 'color: #666; font-size: 11px',
327
+ 'color: #8b5cf6; font-weight: bold; background: #8b5cf615; padding: 2px 6px; border-radius: 3px',
328
+ 'color: #8b5cf6',
329
+ ...(callSourceInfo ? ['color: #8b5cf6; font-weight: bold'] : [])
330
+ )
331
+
332
+ // 显示乐观更新的 payload
333
+ if (this.level >= ConsoleLevel.DEBUG) {
334
+ console.log('%c📝 更新内容:', 'color: #8b5cf6; font-weight: bold')
335
+ console.log(instruction.payload)
336
+ }
337
+
338
+ // 显示快照信息
339
+ if (instruction.optimisticSnapshot) {
340
+ console.log('%c💾 已保存快照(用于回滚)', 'color: #10b981; font-size: 11px')
341
+ }
342
+
343
+ console.groupEnd()
344
+ }
345
+ }
346
+
347
+ /**
348
+ * 乐观更新回滚
349
+ */
350
+ onOptimisticRolledBack(instruction: QueuedInstruction, reason: string): void {
351
+ if (!this.shouldPrint(instruction.type)) return
352
+
353
+ // 回滚是重要事件,总是显示
354
+ if (this.level >= ConsoleLevel.MINIMAL) {
355
+ // 🔍 格式化调用源信息
356
+ const callSourceInfo = instruction.context.callSource
357
+ ? ` %c📍 ${formatCallSourceShort(instruction.context.callSource)}`
358
+ : ''
359
+
360
+ // 🔥 回滚重要,使用展开分组便于立即查看
361
+ console.group(
362
+ `%c[乐观回滚] %c${this.formatTime()} %c${instruction.type}%c${callSourceInfo}`,
363
+ 'color: #f59e0b; font-weight: bold',
364
+ 'color: #666; font-size: 11px',
365
+ 'color: #f59e0b; font-weight: bold; background: #f59e0b15; padding: 2px 6px; border-radius: 3px',
366
+ 'color: #f59e0b',
367
+ ...(callSourceInfo ? ['color: #8b5cf6; font-weight: bold'] : [])
368
+ )
369
+
370
+ // 显示回滚原因
371
+ console.log('%c⚠️ 回滚原因:', 'color: #f59e0b; font-weight: bold')
372
+ console.log(reason)
373
+
374
+ // 显示指令信息
375
+ console.log('%c📋 指令信息:', 'color: #f59e0b; font-weight: bold')
376
+ console.table({
377
+ 'Instruction ID': instruction.id,
378
+ 'Correlation ID': instruction.context.correlationId,
379
+ 'Type': instruction.type,
380
+ })
381
+
382
+ console.groupEnd()
383
+ }
384
+ }
385
+
386
+ /**
387
+ * 资源冲突
388
+ */
389
+ onSchedulerConflict(
390
+ instruction: QueuedInstruction,
391
+ conflictingWith: string[],
392
+ waitTime: number
393
+ ): void {
394
+ if (!this.shouldPrint(instruction.type)) return
395
+
396
+ if (this.level >= ConsoleLevel.VERBOSE) {
397
+ console.log(`%c ⏳ ${this.formatTime()} 资源冲突,等待 ${waitTime}ms`, 'color: #f59e0b', {
398
+ instructionId: instruction.id,
399
+ conflictingWith,
400
+ })
401
+ }
402
+ }
403
+
404
+ /**
405
+ * 网络请求
406
+ */
407
+ onNetworkRequest(instruction: QueuedInstruction, method: string, url: string): void {
408
+ if (!this.shouldPrint(instruction.type)) return
409
+
410
+ if (this.level >= ConsoleLevel.DEBUG) {
411
+ console.log(`%c 🌐 ${this.formatTime()} ${method} ${url}`, 'color: #06b6d4', {
412
+ instructionId: instruction.id,
413
+ correlationId: instruction.context.correlationId,
414
+ })
415
+ }
416
+ }
417
+
418
+ /**
419
+ * 网络响应
420
+ */
421
+ onNetworkResponse(instruction: QueuedInstruction, status: number, latency: number): void {
422
+ if (!this.shouldPrint(instruction.type)) return
423
+
424
+ if (this.level >= ConsoleLevel.DEBUG) {
425
+ const statusColor = status >= 200 && status < 300 ? '#10b981' : '#ef4444'
426
+ console.log(
427
+ `%c ← ${this.formatTime()} HTTP ${status} (${latency}ms)`,
428
+ `color: ${statusColor}`,
429
+ {
430
+ instructionId: instruction.id,
431
+ }
432
+ )
433
+ }
434
+ }
435
+
436
+ // ==================== 辅助方法 ====================
437
+
438
+ /**
439
+ * 打印流水线阶段
440
+ */
441
+ private printPipelineStages(instruction: QueuedInstruction): void {
442
+ const timestamps = instruction.timestamps
443
+
444
+ console.log('%c流水线阶段:', 'color: #666; font-weight: bold')
445
+
446
+ // 打印各阶段之间的耗时
447
+ const transitions = []
448
+
449
+ if (timestamps.IF && timestamps.SCH) {
450
+ transitions.push({ label: 'IF→SCH', duration: timestamps.SCH - timestamps.IF })
451
+ }
452
+ if (timestamps.SCH && timestamps.EX) {
453
+ transitions.push({ label: 'SCH→EX', duration: timestamps.EX - timestamps.SCH })
454
+ }
455
+ if (timestamps.EX && timestamps.WB) {
456
+ transitions.push({ label: 'EX→WB', duration: timestamps.WB - timestamps.EX })
457
+ }
458
+
459
+ for (const transition of transitions) {
460
+ const bar = this.createDurationBar(transition.duration)
461
+ console.log(
462
+ ` %c${transition.label}%c ${bar} %c${transition.duration}ms`,
463
+ 'color: #3b82f6; font-weight: bold',
464
+ 'color: #666',
465
+ 'color: #666; font-weight: bold'
466
+ )
467
+ }
468
+
469
+ // 打印总耗时
470
+ if (timestamps.IF && timestamps.WB) {
471
+ const total = timestamps.WB - timestamps.IF
472
+ console.log(
473
+ ` %c总耗时: %c${total}ms`,
474
+ 'color: #666; font-weight: bold',
475
+ 'color: #10b981; font-weight: bold; font-size: 14px'
476
+ )
477
+ }
478
+
479
+ // 特殊标记
480
+ if (instruction.optimisticSnapshot) {
481
+ console.log(' %c✓ 乐观更新', 'color: #8b5cf6')
482
+ }
483
+ }
484
+
485
+ /**
486
+ * 打印指令详情
487
+ */
488
+ private printInstructionDetails(instruction: QueuedInstruction): void {
489
+ console.log('%c详细信息:', 'color: #666; font-weight: bold')
490
+ console.table({
491
+ 'Instruction ID': instruction.id,
492
+ 'Correlation ID': instruction.context.correlationId,
493
+ Type: instruction.type,
494
+ Status: instruction.status,
495
+ 'Created At': instruction.timestamps.IF
496
+ ? new Date(instruction.timestamps.IF).toISOString()
497
+ : 'N/A',
498
+ })
499
+
500
+ if (this.level >= ConsoleLevel.DEBUG) {
501
+ console.log('%cPayload:', 'color: #666; font-weight: bold', instruction.payload)
502
+
503
+ if (instruction.result) {
504
+ console.log('%cResult:', 'color: #666; font-weight: bold', instruction.result)
505
+ }
506
+ }
507
+ }
508
+
509
+ /**
510
+ * 打印智能建议
511
+ */
512
+ private printSuggestions(instruction: QueuedInstruction, error: Error): void {
513
+ const suggestions: string[] = []
514
+
515
+ // 根据错误类型给出建议
516
+ if (error.message.includes('database is locked')) {
517
+ suggestions.push('后端数据库锁定,检查写入许可是否正确获取')
518
+ }
519
+
520
+ if (error.message.includes('Network')) {
521
+ suggestions.push('网络错误,检查后端服务是否运行')
522
+ }
523
+
524
+ if (error.message.includes('timeout')) {
525
+ suggestions.push('请求超时,考虑增加超时时间或优化后端性能')
526
+ }
527
+
528
+ // 根据指令类型给出建议
529
+ const duration =
530
+ instruction.timestamps.WB && instruction.timestamps.IF
531
+ ? instruction.timestamps.WB - instruction.timestamps.IF
532
+ : 0
533
+
534
+ if (duration > 1000) {
535
+ suggestions.push(`执行耗时 ${duration}ms,超过 1 秒,检查是否存在性能问题`)
536
+ }
537
+
538
+ if (suggestions.length > 0) {
539
+ console.log('%c💡 建议:', 'color: #f59e0b; font-weight: bold')
540
+ suggestions.forEach((s) => {
541
+ console.log(` • ${s}`)
542
+ })
543
+ }
544
+ }
545
+
546
+ /**
547
+ * 创建耗时条形图
548
+ */
549
+ private createDurationBar(duration: number): string {
550
+ const maxWidth = 20
551
+ const width = Math.min(Math.round(duration / 50), maxWidth)
552
+ const bar = '█'.repeat(width)
553
+
554
+ return bar
555
+ }
556
+
557
+ /**
558
+ * 格式化时间
559
+ */
560
+ private formatTime(): string {
561
+ const now = new Date()
562
+ return now.toLocaleTimeString('zh-CN', {
563
+ hour12: false,
564
+ hour: '2-digit',
565
+ minute: '2-digit',
566
+ second: '2-digit',
567
+ fractionalSecondDigits: 3,
568
+ } as any)
569
+ }
570
+
571
+ /**
572
+ * 判断是否应该打印
573
+ */
574
+ private shouldPrint(instructionType: string): boolean {
575
+ if (!this.enabled) return false
576
+ if (this.level === ConsoleLevel.SILENT) return false
577
+ if (this.filter.size > 0 && !this.filter.has(instructionType)) return false
578
+ return true
579
+ }
580
+
581
+ // ==================== 便捷方法 ====================
582
+
583
+ /**
584
+ * 打印分隔线
585
+ */
586
+ printSeparator(title?: string): void {
587
+ if (!this.enabled) return
588
+
589
+ if (title) {
590
+ console.log(
591
+ `%c━━━━━━━━━━━━━━━━━━━━━━━━━━ ${title} ━━━━━━━━━━━━━━━━━━━━━━━━━━`,
592
+ 'color: #666; font-weight: bold'
593
+ )
594
+ } else {
595
+ console.log('%c━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', 'color: #666')
596
+ }
597
+ }
598
+
599
+ /**
600
+ * 打印统计信息
601
+ */
602
+ printStats(stats: { total: number; success: number; failed: number; avgLatency: number }): void {
603
+ if (!this.enabled) return
604
+
605
+ console.group('%c📊 流水线统计', 'color: #3b82f6; font-weight: bold; font-size: 14px')
606
+
607
+ console.log(` 总指令数: %c${stats.total}`, 'color: #3b82f6; font-weight: bold')
608
+
609
+ console.log(
610
+ ` 成功: %c${stats.success} %c(${((stats.success / stats.total) * 100).toFixed(1)}%)`,
611
+ 'color: #10b981; font-weight: bold',
612
+ 'color: #666'
613
+ )
614
+
615
+ console.log(
616
+ ` 失败: %c${stats.failed} %c(${((stats.failed / stats.total) * 100).toFixed(1)}%)`,
617
+ 'color: #ef4444; font-weight: bold',
618
+ 'color: #666'
619
+ )
620
+
621
+ console.log(` 平均延迟: %c${stats.avgLatency.toFixed(0)}ms`, 'color: #666; font-weight: bold')
622
+
623
+ console.groupEnd()
624
+ }
625
+ }
626
+
627
+ // 导出全局单例
628
+ export const cpuConsole = new CPUConsole()
629
+
630
+ // 导出枚举
631
+ export { ConsoleLevel }