@thejrsoft/subway-protocol 1.4.14 → 1.6.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,217 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.0] - 2026-05-13
4
+
5
+ ### ⚠️ BREAKING CHANGES — 硬切,零兼容(系统未上线)
6
+
7
+ #### 1. CodeMeta 单一信息源 — status / level 由 report.code 派生
8
+
9
+ 新设计:所有协议消息的 `status` 和 `level` 字段由 `report.code` 通过 `CodeMeta` 表自动派生。
10
+ 集成方收到消息后调用 `resolveCodeMeta(code)` 查表得到 `semantic` / `requiresErrorBlock` 等元数据。
11
+
12
+ ```typescript
13
+ import { resolveCodeMeta } from '@thejrsoft/subway-protocol';
14
+
15
+ const meta = resolveCodeMeta(msg.report.code);
16
+ // meta: { isTerminal, status, level, semantic, requiresErrorBlock }
17
+ switch (meta.semantic) {
18
+ case 'success': /* ALL_SUCCESS / ALL_ONLINE 等 */ break;
19
+ case 'partial': /* PARTIAL_SUCCESS / PARTIAL_ONLINE */ break;
20
+ case 'failure': /* ALL_FAILED / UPLOAD_FAILED */ break;
21
+ case 'busy': /* BUSY 并发拒绝 */ break;
22
+ case 'cancel': /* CANCELLED */ break;
23
+ case 'no-op': /* NO_PROGRAMS */ break;
24
+ // 进度语义: phase_start / phase_end / phase_failed / step_success ...
25
+ }
26
+ ```
27
+
28
+ #### 2. MessageStatus 单一 enum 取代 CommandStatus / ProgressStatus
29
+
30
+ ```typescript
31
+ // v1.5.0 (已删)
32
+ enum CommandStatus { COMPLETED, FAILED, TIMEOUT, CANCELLED, IN_PROGRESS } ← 删
33
+ enum ProgressStatus { PENDING, IN_PROGRESS, PAUSED, COMPLETED, FAILED, CANCELLED } ← 删
34
+
35
+ // v1.6.0 (新)
36
+ enum MessageStatus { IN_PROGRESS, COMPLETED, FAILED, CANCELLED }
37
+ ```
38
+
39
+ **删除的死代码值**:
40
+ - `ProgressStatus.PENDING` / `PAUSED`(v1.5.0 内 0 引用)
41
+ - `CommandStatus.TIMEOUT` 语义迁移到 `status=FAILED + data.error.category='TIMEOUT'`
42
+
43
+ #### 3. dispatchMessage 统一发消息接口
44
+
45
+ 替代旧 `MessageFactory.createCommandResponseMessage` / `createProgramResponseMessage` /
46
+ `createProgressUpdateMessage`:
47
+
48
+ ```typescript
49
+ MessageFactory.dispatchMessage({
50
+ clientId, requestRef,
51
+ code: 'PROGRAM_COMPLETED', // 单一信息源
52
+ message: 'Program upload completed',
53
+ data: { totalPrograms: 5, successCount: 5 },
54
+ // status / level / 消息类型由 CodeMeta 自动推导
55
+ });
56
+ ```
57
+
58
+ 设备端只填 `code` 和业务字段,违反 META 决策矩阵的风险归零。
59
+
60
+ #### 4. 拆分歧义 code — 一码一义原则
61
+
62
+ `PROGRAM_UPLOAD_FAILED` v1.5.0 既表 FAILED 又表 BUSY → v1.6.0 拆分:
63
+ - `PROGRAM_UPLOAD_FAILED`:仅表异常中断(status=FAILED + level=ERROR)
64
+ - `PROGRAM_UPLOAD_BUSY`:独立 code,表并发拒绝(status=FAILED + level=WARNING)
65
+
66
+ ### 新增
67
+
68
+ - `MessageStatus` enum(4 值)
69
+ - `CodeMeta` interface(5 字段)
70
+ - `CodeSemantic` 联合类型(15 值,覆盖终态 + 进度)
71
+ - `EXPLICIT_META` 终态显式表(~14 entries)
72
+ - `SUFFIX_RULES` 进度后缀规则(9 条)
73
+ - `resolveCodeMeta(code)` / `isKnownCode(code)` 工具函数
74
+ - `MessageFactory.dispatchMessage(params)` 统一发消息接口
75
+
76
+ ### 删除
77
+
78
+ - ✂️ `enum CommandStatus`(v1.5.0 5 值)
79
+ - ✂️ `enum ProgressStatus`(v1.5.0 6 值)
80
+ - ✂️ `CommandStatus.TIMEOUT`(合并到 data.error.category)
81
+ - ✂️ `ProgressStatus.PENDING` / `PAUSED`(0 引用死代码)
82
+
83
+ ### Migration
84
+
85
+ ```typescript
86
+ // v1.5.0
87
+ import { CommandStatus, ProgressStatus, MessageFactory } from '@thejrsoft/subway-protocol';
88
+ const msg = MessageFactory.createCommandResponseMessage(
89
+ clientId, requestRef, CommandStatus.COMPLETED, result, message,
90
+ );
91
+
92
+ // v1.6.0
93
+ import { MessageStatus, MessageFactory } from '@thejrsoft/subway-protocol';
94
+ const msg = MessageFactory.dispatchMessage({
95
+ clientId, requestRef,
96
+ code: 'SYNC_FUNCTIONS_SWITCH_WRITE_SUCCESS', // 单一信息源
97
+ message: 'Switch set to On',
98
+ result,
99
+ });
100
+ // status (COMPLETED) + level (INFO) 自动从 code 派生
101
+ ```
102
+
103
+ ### 协议设计依据
104
+
105
+ 完整设计原则、决策回放(CodeMeta 设计奇点、status 合并理由、为什么 semantic 不进消息等)
106
+ 见 `claude-docs/protocol-upgrade-proposal-v1.6.0.md`。
107
+
108
+ ---
109
+
110
+ ## [1.5.0] - 2026-05-12
111
+
112
+ ### ⚠️ BREAKING CHANGES — 无兼容、无 fallback(系统未上线)
113
+
114
+ #### 1. 统一失败信号 schema(`data.error` 嵌套对象)
115
+
116
+ 所有失败上报(`level=ERROR` / `status=FAILED`)必须使用新 schema:
117
+
118
+ ```json
119
+ {
120
+ "report": {
121
+ "code": "PROGRAM_UPLOAD_FAILED",
122
+ "level": "ERROR",
123
+ "message": "Program download timed out",
124
+ "messageEn": "Program download timed out",
125
+ "data": {
126
+ "error": {
127
+ "phase": "PROGRAM_FETCH",
128
+ "step": "Download",
129
+ "category": "TIMEOUT",
130
+ "detail": "HTTP 504 from CDN after 30s, 3/3 attempts"
131
+ }
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
137
+ #### 2. 新增 / 移除字段
138
+
139
+ **新增**:
140
+ - `ReportMessage.messageEn?: string` — 英文文本(与 message 同义,便于 i18n 兼容)
141
+ - `ReportData` 接口(含 `error?: ErrorInfo` + 业务字段 index signature)
142
+ - `ErrorInfo` 接口(`phase` / `step` / `category` / `detail` 4 字段全必填)
143
+ - `ErrorPhase` 类型(15 个值,与 ProgressPhase 对齐)
144
+ - `ErrorStep` 类型(21 个值的 closed enum)
145
+ - `ErrorCategory` 类型(**7 类**:在 v1.4.14 的 4 类基础上加 `CONFIGURATION` / `PROTOCOL` / `AUTHORIZATION`)
146
+ - `ERROR_STEP_BY_PHASE` 映射常量(强校验 step ↔ phase 归属)
147
+ - 工具函数:`VALID_ERROR_CATEGORIES` / `isValidErrorCategory()` / `normalizeErrorCategory()` / `isValidErrorStepForPhase()`
148
+ - `ProgressPhase` 枚举新增 2 个值:`PROGRAM_INIT`(任务初始化)/ `PROGRAM_COMPLETE`(终态边界)
149
+
150
+ **删除**:
151
+ - `ReportMessage.category` 顶层字段(下沉到 `data.error.category`)
152
+ - `ReportCategory` 类型(重命名为 `ErrorCategory`,并扩到 7 类)
153
+ - `VALID_REPORT_CATEGORIES` / `isValidReportCategory()` / `normalizeReportCategory()`(重命名为 `VALID_ERROR_CATEGORIES` 等)
154
+ - `data.failedPhase` / `data.failedSubStage` / `data.failedReason` 平铺字段(合并到 `data.error.*`)
155
+ - PROGRAM 命令 6 个独立失败 code(统一为 `PROGRAM_UPLOAD_FAILED` + `data.error.*`):
156
+ - `PROGRAM_DOWNLOAD_FAILED`
157
+ - `PROGRAM_CHECKSUM_MISMATCH`
158
+ - `PROGRAM_COMPILE_FAILED`
159
+ - `PROGRAM_COMPILE_ERROR`
160
+ - `PROGRAM_DEPLOY_NOT_INITIALIZED`
161
+ - `PROGRAM_DEPLOY_ERROR`
162
+ - `failedReason` 6 值枚举(合并到 `category` + `step` + `detail`)
163
+
164
+ #### 3. COMPLEX 命令统一生命周期
165
+
166
+ 所有 COMPLEX 命令统一为 `{CMD}_INIT (progress=0%) → 业务 phase → {CMD}_COMPLETE (progress=100%)`:
167
+
168
+ - PROGRAM 命令新增 `PROGRAM_INIT` / `PROGRAM_COMPLETE` phase(8 phase 序列)
169
+ - 终态决策矩阵在 `PROGRAM_COMPLETE` 触发(唯一收尾点)
170
+ - BUSY 并发拒绝场景从"特例"变成 `PROGRAM_INIT.CheckConcurrency` 阶段正常失败
171
+
172
+ #### 4. PROGRAM phase 序列重排(6 → 8)
173
+
174
+ | 序号 | phase | progress |
175
+ |---|---|---|
176
+ | 0 | `PROGRAM_INIT` | 0% |
177
+ | 1 | `PROGRAM_FETCH` | 1~15% |
178
+ | 2 | `PROGRAM_EXTRACT` | 16~25% |
179
+ | 3 | `PROGRAM_PREPROCESS` | 26~50% |
180
+ | 4 | `PROGRAM_COMPILE` | 51~70% |
181
+ | 5 | `PROGRAM_UPLOAD` | 71~95% |
182
+ | 6 | `PROGRAM_STATS` | 96~99% |
183
+ | 7 | `PROGRAM_COMPLETE` | 100% |
184
+
185
+ ### Migration
186
+
187
+ 设备端 (C#):
188
+ 1. 新增 `ErrorPhase` / `ErrorStep` / `ErrorCategory` 强类型 enum
189
+ 2. `ReportMessage` 移除 `Category` 顶层,新增 `ReportData.Error`
190
+ 3. 新建 `ErrorClassifier` 集中归类异常 → (phase, step, category) 三元组
191
+ 4. PROGRAM 编排器 6 处独立失败 code 调用改用 `ErrorClassifier.Classify(...)` 生成 `ErrorInfo`
192
+ 5. 新增 `PROGRAM_INIT` / `PROGRAM_COMPLETE` phase 上报
193
+
194
+ 第三方 (TypeScript/JS):
195
+ ```javascript
196
+ function parseFailureMessage(msg) {
197
+ if (msg.report.level !== 'ERROR' && msg.status !== 'FAILED') return null;
198
+ const err = msg.report.data?.error;
199
+ if (!err) return null;
200
+ return {
201
+ category: err.category, // 粗分类(告警/聚合)
202
+ location: `${err.phase}.${err.step}`, // 细位置(诊断/UI)
203
+ i18nKey: `${err.phase}.${err.step}.${err.category}`, // i18n key
204
+ diagnostic: err.detail, // 日志/调试
205
+ };
206
+ }
207
+ ```
208
+
209
+ ### 协议设计依据
210
+
211
+ 完整设计原则、决策回放(11 个关键技术选择记录)、归类决策树、错误映射表见 `claude-docs/protocol-upgrade-proposal-v1.5.0.md`。
212
+
213
+ ---
214
+
3
215
  ## [1.4.14] - 2026-05-11
4
216
 
5
217
  ### Added (零破坏 / minor bump)
@@ -15,7 +15,7 @@ function generateAsyncApiEnums() {
15
15
  ClientType: Object.values(index_1.ClientType),
16
16
  OperationType: Object.values(index_1.OperationType),
17
17
  Priority: Object.values(index_1.Priority),
18
- CommandStatus: Object.values(index_1.CommandStatus)
18
+ MessageStatus: Object.values(index_1.MessageStatus)
19
19
  };
20
20
  return `
21
21
  # AsyncAPI Enum Definitions
@@ -39,9 +39,9 @@ components:
39
39
  type: string
40
40
  enum: ${JSON.stringify(enums.Priority)}
41
41
 
42
- CommandStatus:
42
+ MessageStatus:
43
43
  type: string
44
- enum: ${JSON.stringify(enums.CommandStatus)}
44
+ enum: ${JSON.stringify(enums.MessageStatus)}
45
45
  `;
46
46
  }
47
47
  /**
@@ -0,0 +1,57 @@
1
+ /**
2
+ * CodeMeta — v1.6.0 协议核心
3
+ *
4
+ * report.code 是业务命运的单一信息源;status / level / semantic 全部由此派生。
5
+ *
6
+ * 设备端调用 dispatchMessage(code, data) 时,协议层自动按 code 推导 status / level,
7
+ * 集成方接收消息后调用 resolveCodeMeta(code) 查表得到 semantic / requiresErrorBlock 等。
8
+ *
9
+ * 设计依据:claude-docs/protocol-upgrade-proposal-v1.6.0.md
10
+ */
11
+ import type { ReportLevel } from './index';
12
+ /** v1.6.0:单一 status enum,合并 v1.5.0 的 CommandStatus + ProgressStatus */
13
+ export declare enum MessageStatus {
14
+ IN_PROGRESS = "IN_PROGRESS",
15
+ COMPLETED = "COMPLETED",
16
+ FAILED = "FAILED",
17
+ CANCELLED = "CANCELLED"
18
+ }
19
+ /** 业务语义分类——终态语义 + 进度语义 */
20
+ export type CodeSemantic = 'success' | 'partial' | 'failure' | 'no-op' | 'cancel' | 'busy' | 'phase_start' | 'phase_end' | 'phase_failed' | 'step_success' | 'step_skipped' | 'step_progress' | 'retry' | 'retry_pending' | 'warning';
21
+ /**
22
+ * 单一 code 的元数据描述符
23
+ *
24
+ * 派生字段(status / level)会序列化进消息;
25
+ * 客户端字段(semantic / requiresErrorBlock / isTerminal)仅供查表,不进消息。
26
+ */
27
+ export interface CodeMeta {
28
+ isTerminal: boolean;
29
+ status: MessageStatus;
30
+ level: ReportLevel;
31
+ semantic: CodeSemantic;
32
+ requiresErrorBlock: boolean;
33
+ }
34
+ /**
35
+ * 终态 code 显式 META 表
36
+ *
37
+ * 这些 code 是业务命运决断点,每个语义都是独特的,**不能用后缀规则推导**。
38
+ * 设备端发送终态消息时,dispatchMessage 在此表查询,自动填充消息字段。
39
+ */
40
+ export declare const EXPLICIT_META: Record<string, CodeMeta>;
41
+ /**
42
+ * 单一 code 解析入口
43
+ *
44
+ * 解析顺序:
45
+ * 1. 终态显式表(EXPLICIT_META) — 30 个 closed enum
46
+ * 2. 后缀规则(SUFFIX_RULES) — 9 条规则覆盖数百个进度 code
47
+ * 3. 兜底(FALLBACK_META) — 未知 code 降级
48
+ *
49
+ * @param code report.code 字符串
50
+ * @returns CodeMeta — status / level / semantic / requiresErrorBlock / isTerminal
51
+ */
52
+ export declare function resolveCodeMeta(code: string): CodeMeta;
53
+ /**
54
+ * 判断 code 是否已知(命中显式表或后缀规则,不走兜底)
55
+ */
56
+ export declare function isKnownCode(code: string): boolean;
57
+ //# sourceMappingURL=code-meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-meta.d.ts","sourceRoot":"","sources":["../src/code-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,uEAAuE;AACvE,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,SAAS,cAAc;IACvB,MAAM,WAAW;IACjB,SAAS,cAAc;CACxB;AAED,0BAA0B;AAC1B,MAAM,MAAM,YAAY,GAEpB,SAAS,GACT,SAAS,GACT,SAAS,GACT,OAAO,GACP,QAAQ,GACR,MAAM,GAEN,aAAa,GACb,WAAW,GACX,cAAc,GACd,cAAc,GACd,cAAc,GACd,eAAe,GACf,OAAO,GACP,eAAe,GACf,SAAS,CAAC;AAEd;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAwGlD,CAAC;AAoHF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAatD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOjD"}
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ /**
3
+ * CodeMeta — v1.6.0 协议核心
4
+ *
5
+ * report.code 是业务命运的单一信息源;status / level / semantic 全部由此派生。
6
+ *
7
+ * 设备端调用 dispatchMessage(code, data) 时,协议层自动按 code 推导 status / level,
8
+ * 集成方接收消息后调用 resolveCodeMeta(code) 查表得到 semantic / requiresErrorBlock 等。
9
+ *
10
+ * 设计依据:claude-docs/protocol-upgrade-proposal-v1.6.0.md
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.EXPLICIT_META = exports.MessageStatus = void 0;
14
+ exports.resolveCodeMeta = resolveCodeMeta;
15
+ exports.isKnownCode = isKnownCode;
16
+ /** v1.6.0:单一 status enum,合并 v1.5.0 的 CommandStatus + ProgressStatus */
17
+ var MessageStatus;
18
+ (function (MessageStatus) {
19
+ MessageStatus["IN_PROGRESS"] = "IN_PROGRESS";
20
+ MessageStatus["COMPLETED"] = "COMPLETED";
21
+ MessageStatus["FAILED"] = "FAILED";
22
+ MessageStatus["CANCELLED"] = "CANCELLED";
23
+ })(MessageStatus || (exports.MessageStatus = MessageStatus = {}));
24
+ /**
25
+ * 终态 code 显式 META 表
26
+ *
27
+ * 这些 code 是业务命运决断点,每个语义都是独特的,**不能用后缀规则推导**。
28
+ * 设备端发送终态消息时,dispatchMessage 在此表查询,自动填充消息字段。
29
+ */
30
+ exports.EXPLICIT_META = {
31
+ // ═══════════ PROGRAM 节目部署 ═══════════
32
+ PROGRAM_COMPLETED: {
33
+ isTerminal: true,
34
+ status: MessageStatus.COMPLETED,
35
+ level: 'INFO',
36
+ semantic: 'success',
37
+ requiresErrorBlock: false,
38
+ },
39
+ PROGRAM_PARTIALLY_SUCCEEDED: {
40
+ isTerminal: true,
41
+ status: MessageStatus.COMPLETED,
42
+ level: 'WARNING',
43
+ semantic: 'partial',
44
+ requiresErrorBlock: false,
45
+ },
46
+ PROGRAM_ALL_FAILED: {
47
+ isTerminal: true,
48
+ status: MessageStatus.FAILED,
49
+ level: 'ERROR',
50
+ semantic: 'failure',
51
+ requiresErrorBlock: true,
52
+ },
53
+ PROGRAM_NO_PROGRAMS: {
54
+ isTerminal: true,
55
+ status: MessageStatus.COMPLETED,
56
+ level: 'INFO',
57
+ semantic: 'no-op',
58
+ requiresErrorBlock: false,
59
+ },
60
+ PROGRAM_UPLOAD_FAILED: {
61
+ isTerminal: true,
62
+ status: MessageStatus.FAILED,
63
+ level: 'ERROR',
64
+ semantic: 'failure',
65
+ requiresErrorBlock: true,
66
+ },
67
+ PROGRAM_UPLOAD_BUSY: {
68
+ isTerminal: true,
69
+ status: MessageStatus.FAILED,
70
+ level: 'WARNING',
71
+ semantic: 'busy',
72
+ requiresErrorBlock: true,
73
+ },
74
+ PROGRAM_UPLOAD_CANCELLED: {
75
+ isTerminal: true,
76
+ status: MessageStatus.CANCELLED,
77
+ level: 'WARNING',
78
+ semantic: 'cancel',
79
+ requiresErrorBlock: true,
80
+ },
81
+ // ═══════════ QUICKLY_DETECTION 一键检测 ═══════════
82
+ QUICK_DETECTION_ALL_ONLINE: {
83
+ isTerminal: true,
84
+ status: MessageStatus.COMPLETED,
85
+ level: 'INFO',
86
+ semantic: 'success',
87
+ requiresErrorBlock: false,
88
+ },
89
+ QUICK_DETECTION_PARTIAL_ONLINE: {
90
+ isTerminal: true,
91
+ status: MessageStatus.COMPLETED,
92
+ level: 'WARNING',
93
+ semantic: 'partial',
94
+ requiresErrorBlock: false,
95
+ },
96
+ QUICK_DETECTION_ALL_OFFLINE: {
97
+ isTerminal: true,
98
+ status: MessageStatus.COMPLETED,
99
+ level: 'ERROR',
100
+ semantic: 'failure',
101
+ requiresErrorBlock: true,
102
+ },
103
+ QUICK_DETECTION_FAILED: {
104
+ isTerminal: true,
105
+ status: MessageStatus.FAILED,
106
+ level: 'ERROR',
107
+ semantic: 'failure',
108
+ requiresErrorBlock: true,
109
+ },
110
+ QUICK_DETECTION_BUSY: {
111
+ isTerminal: true,
112
+ status: MessageStatus.FAILED,
113
+ level: 'WARNING',
114
+ semantic: 'busy',
115
+ requiresErrorBlock: true,
116
+ },
117
+ // ═══════════ SYNC_MONITORING_TABLE 监播导出 ═══════════
118
+ SYNC_MONITORING_TABLE_READ_SUCCESS: {
119
+ isTerminal: true,
120
+ status: MessageStatus.COMPLETED,
121
+ level: 'INFO',
122
+ semantic: 'success',
123
+ requiresErrorBlock: false,
124
+ },
125
+ SYNC_MONITORING_TABLE_READ_FAILED: {
126
+ isTerminal: true,
127
+ status: MessageStatus.FAILED,
128
+ level: 'ERROR',
129
+ semantic: 'failure',
130
+ requiresErrorBlock: true,
131
+ },
132
+ };
133
+ const SUFFIX_RULES = [
134
+ {
135
+ suffix: '_FAILED',
136
+ meta: {
137
+ status: MessageStatus.IN_PROGRESS,
138
+ level: 'ERROR',
139
+ semantic: 'phase_failed',
140
+ requiresErrorBlock: true,
141
+ },
142
+ },
143
+ {
144
+ suffix: '_RETRY_PENDING',
145
+ meta: {
146
+ status: MessageStatus.IN_PROGRESS,
147
+ level: 'WARNING',
148
+ semantic: 'retry_pending',
149
+ requiresErrorBlock: false,
150
+ },
151
+ },
152
+ {
153
+ suffix: '_RETRY',
154
+ meta: {
155
+ status: MessageStatus.IN_PROGRESS,
156
+ level: 'WARNING',
157
+ semantic: 'retry',
158
+ requiresErrorBlock: false,
159
+ },
160
+ },
161
+ {
162
+ // 后缀或中缀都命中:例 PROGRAM_UPLOAD_WARN_CAN_BUS_ALARM
163
+ infix: '_WARN',
164
+ meta: {
165
+ status: MessageStatus.IN_PROGRESS,
166
+ level: 'WARNING',
167
+ semantic: 'warning',
168
+ requiresErrorBlock: false,
169
+ },
170
+ },
171
+ {
172
+ suffix: '_SKIPPED',
173
+ meta: {
174
+ status: MessageStatus.IN_PROGRESS,
175
+ level: 'INFO',
176
+ semantic: 'step_skipped',
177
+ requiresErrorBlock: false,
178
+ },
179
+ },
180
+ {
181
+ suffix: '_COMPLETED',
182
+ meta: {
183
+ status: MessageStatus.IN_PROGRESS,
184
+ level: 'INFO',
185
+ semantic: 'phase_end',
186
+ requiresErrorBlock: false,
187
+ },
188
+ },
189
+ {
190
+ suffix: '_START',
191
+ meta: {
192
+ status: MessageStatus.IN_PROGRESS,
193
+ level: 'INFO',
194
+ semantic: 'phase_start',
195
+ requiresErrorBlock: false,
196
+ },
197
+ },
198
+ {
199
+ suffix: '_PROGRESS',
200
+ meta: {
201
+ status: MessageStatus.IN_PROGRESS,
202
+ level: 'INFO',
203
+ semantic: 'step_progress',
204
+ requiresErrorBlock: false,
205
+ },
206
+ },
207
+ {
208
+ suffix: '_SUCCESS',
209
+ meta: {
210
+ status: MessageStatus.IN_PROGRESS,
211
+ level: 'INFO',
212
+ semantic: 'step_success',
213
+ requiresErrorBlock: false,
214
+ },
215
+ },
216
+ ];
217
+ /**
218
+ * 兜底 META(未知 code 时返回)
219
+ *
220
+ * 接收方收到未知 code 时降级到 step_progress,避免阻塞协议处理。
221
+ */
222
+ const FALLBACK_META = {
223
+ isTerminal: false,
224
+ status: MessageStatus.IN_PROGRESS,
225
+ level: 'INFO',
226
+ semantic: 'step_progress',
227
+ requiresErrorBlock: false,
228
+ };
229
+ /**
230
+ * 单一 code 解析入口
231
+ *
232
+ * 解析顺序:
233
+ * 1. 终态显式表(EXPLICIT_META) — 30 个 closed enum
234
+ * 2. 后缀规则(SUFFIX_RULES) — 9 条规则覆盖数百个进度 code
235
+ * 3. 兜底(FALLBACK_META) — 未知 code 降级
236
+ *
237
+ * @param code report.code 字符串
238
+ * @returns CodeMeta — status / level / semantic / requiresErrorBlock / isTerminal
239
+ */
240
+ function resolveCodeMeta(code) {
241
+ if (exports.EXPLICIT_META[code]) {
242
+ return exports.EXPLICIT_META[code];
243
+ }
244
+ for (const rule of SUFFIX_RULES) {
245
+ if (rule.suffix && code.endsWith(rule.suffix)) {
246
+ return { isTerminal: false, ...rule.meta };
247
+ }
248
+ if (rule.infix && code.includes(rule.infix)) {
249
+ return { isTerminal: false, ...rule.meta };
250
+ }
251
+ }
252
+ return FALLBACK_META;
253
+ }
254
+ /**
255
+ * 判断 code 是否已知(命中显式表或后缀规则,不走兜底)
256
+ */
257
+ function isKnownCode(code) {
258
+ if (exports.EXPLICIT_META[code])
259
+ return true;
260
+ for (const rule of SUFFIX_RULES) {
261
+ if (rule.suffix && code.endsWith(rule.suffix))
262
+ return true;
263
+ if (rule.infix && code.includes(rule.infix))
264
+ return true;
265
+ }
266
+ return false;
267
+ }
268
+ //# sourceMappingURL=code-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-meta.js","sourceRoot":"","sources":["../src/code-meta.ts"],"names":[],"mappings":"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"}