/** * JRSoft Subway 统一WebSocket协议定义 * 版本: 1.0 * * 功能特性: * 1. 统一消息格式定义 * 2. 支持设备注册、命令执行、心跳等核心功能 * 3. 支持 Edge 代理模式 * * v1.6.0:单一 MessageStatus + CodeMeta + dispatchMessage(详见 code-meta.ts) */ export declare enum MessageType { REGISTER = "REGISTER", REGISTER_ACK = "REGISTER_ACK", UNREGISTER = "UNREGISTER", UNREGISTER_ACK = "UNREGISTER_ACK", HEARTBEAT = "HEARTBEAT", HEARTBEAT_ACK = "HEARTBEAT_ACK", COMMAND = "COMMAND", COMMAND_RESPONSE = "COMMAND_RESPONSE", PROGRAM = "PROGRAM", PROGRAM_RESPONSE = "PROGRAM_RESPONSE", PROGRESS_UPDATE = "PROGRESS_UPDATE", UPDATE_ROUTES = "UPDATE_ROUTES", UPDATE_ROUTES_ACK = "UPDATE_ROUTES_ACK", REGISTER_PENDING = "REGISTER_PENDING", AUTHORIZATION_GRANTED = "AUTHORIZATION_GRANTED", AUTHORIZATION_REJECTED = "AUTHORIZATION_REJECTED", DEVICE_APPROVAL_REQUEST = "DEVICE_APPROVAL_REQUEST", DEVICE_APPROVAL_RESPONSE = "DEVICE_APPROVAL_RESPONSE", ACL_INVALIDATED = "ACL_INVALIDATED", ERROR = "ERROR" } export declare enum ClientType { DEVICE = "DEVICE", BACKEND = "BACKEND", EDGE = "EDGE", GATEWAY = "GATEWAY",// 添加缺失的 GATEWAY 类型 API_CLIENT = "API_CLIENT" } export declare enum OperationType { READ = "READ", WRITE = "WRITE" } export declare enum Priority { LOW = "LOW", NORMAL = "NORMAL", HIGH = "HIGH", CRITICAL = "CRITICAL", EMERGENCY = "EMERGENCY" } export { MessageStatus, type CodeMeta, type CodeSemantic, type CodeMetaContext, resolveCodeMeta, isKnownCode, EXPLICIT_META } from './code-meta'; export interface BaseMessage { type: MessageType; timestamp: string; version: string; } export interface ClientInfo { name?: string; version?: string; platform?: string; capabilities?: string[]; deviceType?: string; description?: string; metadata?: Record; physicalParams?: DevicePhysicalParams; } export interface DevicePhysicalParams { width: number; height: number; direction: ProgramDirection; maxProgramSlots: number; } export interface EdgeInfo { edgeId: string; edgeVersion?: string; connectionTime?: string; } export interface DeviceFingerprint { /** 仅允许 'installPubkey' (L3 strict, 无 L1/L2/L4 fallback); 详见 upgrade-guide §3 */ type: 'installPubkey'; /** "sha256:" — SHA-256 of DER-encoded SubjectPublicKeyInfo (P-256 91 bytes) */ value: string; /** base64 编码的 ECDSA-SHA256 签名 (用私钥签 proofPayload, 证明私钥在手) */ proof: string; /** 签名基串, 推荐 "${clientId}|${nonce}|${timestamp}", Edge 用同款规则重建后 verify */ proofPayload: string; /** PEM-encoded SPKI 公钥, 首次审批时必填 (Edge 持久化用于后续验签); 后续注册可省 */ publicKeyPem?: string; } interface BaseRegisterMessage extends BaseMessage { type: MessageType.REGISTER; clientId: string; clientInfo?: ClientInfo; edgeInfo?: EdgeInfo; licenseToken?: string; } export interface DeviceRegisterMessage extends BaseRegisterMessage { clientType: ClientType.DEVICE; deviceFingerprint: DeviceFingerprint; } export interface NonDeviceRegisterMessage extends BaseRegisterMessage { clientType: Exclude; deviceFingerprint?: never; } export type RegisterMessage = DeviceRegisterMessage | NonDeviceRegisterMessage; export interface RegisterAckMessage extends BaseMessage { type: MessageType.REGISTER_ACK; clientId: string; success: boolean; sessionId?: string; error?: { code: string; message: string; }; serverInfo?: { version: string; capabilities: string[]; currentLoad?: number; maxClients?: number; }; } export interface UnregisterMessage extends BaseMessage { type: MessageType.UNREGISTER; clientId: string; reason?: string; } export interface UnregisterAckMessage extends BaseMessage { type: MessageType.UNREGISTER_ACK; clientId: string; success: boolean; cleanupInfo?: { messagesProcessed: number; pendingMessages: number; connectionDuration: number; }; } export interface RegisterPendingMessage extends BaseMessage { type: MessageType.REGISTER_PENDING; requestId: string; pollInterval: number; expiresIn: number; } export interface AuthorizationGrantedMessage extends BaseMessage { type: MessageType.AUTHORIZATION_GRANTED; requestId: string; licenseToken: string; } export interface AuthorizationRejectedMessage extends BaseMessage { type: MessageType.AUTHORIZATION_REJECTED; requestId: string; reason?: string; } export interface DeviceApprovalRequestMessage extends BaseMessage { type: MessageType.DEVICE_APPROVAL_REQUEST; edgeId: string; requestId: string; deviceId: string; deviceInfo?: ClientInfo; sourceIp?: string; } export interface DeviceApprovalResponseMessage extends BaseMessage { type: MessageType.DEVICE_APPROVAL_RESPONSE; requestId: string; deviceId: string; approved: boolean; deviceAccessKey?: string; reason?: string; action?: 'unblacklist' | 'revoke'; } import type { SpecificCommand as ImportedSpecificCommand, CommandTypeMap as ImportedCommandTypeMap } from './command-types'; export type SpecificCommand = ImportedSpecificCommand; export type CommandTypeMap = ImportedCommandTypeMap; export interface BaseCommand { commandCode: string; parameters?: Record; } export interface SimpleCommand extends BaseCommand { commandType: CommandType.SIMPLE; deviceId: number | string; deviceType: string; operationType: OperationType; } export interface BatchCommand extends BaseCommand { commandType: CommandType.BATCH; deviceId: number[] | string; deviceType: string; operationType: OperationType; } export interface ComplexCommand extends BaseCommand { commandType: CommandType.COMPLEX; deviceId?: number | number[] | string; deviceType?: string; operationType?: OperationType; } export interface GenericCommand extends BaseCommand { commandType?: CommandType; deviceId?: number | number[] | string; deviceType?: string; operationType?: OperationType; } export type Command = SpecificCommand | SimpleCommand | BatchCommand | ComplexCommand | GenericCommand; export declare enum CommandType { SIMPLE = "SIMPLE",// 点对点命令 BATCH = "BATCH",// 多设备命令 COMPLEX = "COMPLEX" } export interface CommandMessage extends BaseMessage { type: MessageType.COMMAND; requestRef: string; targetClientId: string; command: Command; priority: Priority; timeout: number; retryCount?: number; callback: string; metadata?: Record; } export interface CommandResult { deviceType: string; deviceId: number | string; commandCode: string; operationType: OperationType; data: Record; } export interface CommandResponseMessage extends BaseMessage { type: MessageType.COMMAND_RESPONSE; clientId: string; requestRef: string; /** * COMMAND_RESPONSE wire 的 status 字段是**终态语义**, 必须 COMPLETED/FAILED/CANCELLED/TIMEOUT. * v1.8.5 spec invariant (反向约束, 设备端 Round 1 review §4.2 启发): * `IN_PROGRESS` 只属于 PROGRESS_UPDATE message type, 不可出现在 COMMAND_RESPONSE. * Edge v1.8.5 validator 对 status='IN_PROGRESS' 的 COMMAND_RESPONSE → REJECT * (fail code: ERROR_RESPONSE_NON_TERMINAL_STATUS_NOT_ALLOWED). * TypeScript literal type 编译期 catch. */ status: 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'TIMEOUT'; result?: CommandResult; report?: ReportMessage; executionTime?: number; } export interface HeartbeatMessage extends BaseMessage { type: MessageType.HEARTBEAT; clientId: string; sequence: number; clientTime: string; } export interface HeartbeatAckMessage extends BaseMessage { type: MessageType.HEARTBEAT_ACK; clientId: string; sequence: number; clientTime: string; serverTime: string; latency?: number; serverStatus?: { healthy: boolean; activeConnections: number; messageQueueSize: number; cpuUsage?: number; memoryUsage?: number; }; } export interface ErrorMessage extends BaseMessage { type: MessageType.ERROR; code: string; message: string; severity?: string; category?: string; context?: any; retryable?: boolean; } export declare enum ProgramType { DYNAMIC = "DYNAMIC", STATIC = "STATIC" } export declare enum ProgramDirection { LEFT_TO_RIGHT = "LEFT_TO_RIGHT", RIGHT_TO_LEFT = "RIGHT_TO_LEFT" } export interface ImageProcessConfig { gamma?: { k: number; gamma: number; n: number; }; histogram?: boolean; rgbCorrection?: { r: number; g: number; b: number; k: number; }; } export interface ProgramParameters { deviceId: string; taskId: string; programId: string; programName: string; programNo: number; programType: ProgramType; width: number; height: number; direction: ProgramDirection; publishTime?: string; unpublishTime?: string; downloadUrl: string; checksum: string; hashAlgorithm: 'SHA256' | 'MD5'; fileSize?: number; imageProcessConfig?: ImageProcessConfig; } export interface ProgramMessage extends BaseMessage { type: MessageType.PROGRAM; requestRef: string; targetClientId: string; command: { commandCode: 'UPLOAD_PROGRAM'; parameters: ProgramParameters; }; priority: Priority; timeout: number; callback: string; } export interface ProgramResponseMessage extends BaseMessage { type: MessageType.PROGRAM_RESPONSE; clientId: string; requestRef: string; /** * PROGRAM_RESPONSE wire 的 status 字段是**终态语义**, 必须 COMPLETED/FAILED/CANCELLED/TIMEOUT. * v1.8.5 spec invariant (反向约束, 设备端 Round 1 review §4.2 启发): * `IN_PROGRESS` 只属于 PROGRESS_UPDATE, 不可出现在 PROGRAM_RESPONSE. * Edge v1.8.5 validator 对 status='IN_PROGRESS' 的 PROGRAM_RESPONSE → REJECT * (fail code: ERROR_RESPONSE_NON_TERMINAL_STATUS_NOT_ALLOWED). */ status: 'COMPLETED' | 'FAILED' | 'CANCELLED' | 'TIMEOUT'; context?: ProgramContext; report?: ReportMessage; executionTime?: number; } /** * 进度阶段(PROGRESS_UPDATE.phase) * * v1.4.11 重命名整理(不保留 deprecated): * - 节目处理 pipeline 改用 PROGRAM_ 前缀,与 SYNC_DETECT/SWITCH_DETECT 同风格 * - EDGE_CACHE_FETCH/READY 新增(Edge 缓存活动可见性) * - 一键检测的首尾边界 INITIALIZATION/COMPLETE 改名为 DETECT_INIT/DETECT_COMPLETE * - BATCH_EXECUTE 替代旧的 'executing' 字符串(消除与 Backend 内部状态字符串撞名) * - SYNC_EXPORT 替代 EXPORT(与 SYNC_DETECT/SYNC_RECOVER 同主语) * * v1.9.0 命名空间统一(不保留 deprecated): * - 一键检测 7 phase 加 QUICK_DETECTION_ 前缀(DETECT_INIT→QUICK_DETECTION_INIT 等) * - 镜像 PROGRAM_/EDGE_CACHE_/SYNC_/BATCH_ 族风格,闭合 v1.4.11 detection 族无前缀的设计空洞 * - 协议方主动升 minor — 不扩 prefix 打补丁, 治本设计(MEMORY rule #1) * - 详见 claude-docs/discussions/protocol-team-proposal-progressphase-detection-namespace-v1.9.0.md * * 注意:Backend 状态机的内部相位(TASK_ACCEPTED / TASK_RESOLVING_URL 等) * 不通过协议消息流转,**不**列在此 enum 中(属于 Backend 内部 audit 字符串)。 */ export declare enum ProgressPhase { PROGRAM_INIT = "PROGRAM_INIT",// v1.5.0 新增 — 任务初始化(参数校验、资源准备、并发检查) PROGRAM_FETCH = "PROGRAM_FETCH",// 拉取节目源文件(OSS / Edge / 其他) PROGRAM_EXTRACT = "PROGRAM_EXTRACT",// 解压归档(zip/tar/rar) PROGRAM_PREPROCESS = "PROGRAM_PREPROCESS",// 图片预处理(缩放/滤镜等) PROGRAM_COMPILE = "PROGRAM_COMPILE",// 编译为显示帧 PROGRAM_UPLOAD = "PROGRAM_UPLOAD",// 上传到底层显示设备 PROGRAM_STATS = "PROGRAM_STATS",// 上报统计信息 PROGRAM_COMPLETE = "PROGRAM_COMPLETE",// v1.5.0 新增 — 终态边界(决定 ALL_SUCCESS / PARTIAL / FAILED 等) EDGE_CACHE_FETCH = "EDGE_CACHE_FETCH",// Edge 从 OSS 拉文件中 EDGE_CACHE_READY = "EDGE_CACHE_READY",// Edge 缓存就绪 SYNC_EXPORT = "SYNC_EXPORT",// 同步器监播表导出 SYNC_MONITORING_TABLE QUICK_DETECTION_INIT = "QUICK_DETECTION_INIT",// 一键检测流程初始化 (v1.9.0 ← DETECT_INIT) QUICK_DETECTION_SWITCH_DETECT = "QUICK_DETECTION_SWITCH_DETECT",// 检测交换机在线状态 (v1.9.0 ← SWITCH_DETECT) QUICK_DETECTION_SWITCH_CONFIG_READ = "QUICK_DETECTION_SWITCH_CONFIG_READ",// 读取交换机配置信息 (v1.9.0 ← SWITCH_CONFIG_READ) QUICK_DETECTION_SYNC_DETECT = "QUICK_DETECTION_SYNC_DETECT",// 检测同步器状态 (v1.9.0 ← SYNC_DETECT) QUICK_DETECTION_BARGRAPH_DETECT = "QUICK_DETECTION_BARGRAPH_DETECT",// 检测光柱节点在线状态 (v1.9.0 ← BARGRAPH_DETECT) QUICK_DETECTION_SYNC_RECOVER = "QUICK_DETECTION_SYNC_RECOVER",// 恢复同步器原始状态 (v1.9.0 ← SYNC_RECOVER) QUICK_DETECTION_COMPLETE = "QUICK_DETECTION_COMPLETE",// 一键检测全部阶段完成 (v1.9.0 ← DETECT_COMPLETE) BATCH_EXECUTE = "BATCH_EXECUTE" } /** PROGRESS_UPDATE.sourceType 合法值(v1.4.11 新增 EDGE) */ export type ProgressSourceType = 'COMMAND' | 'SYSTEM' | 'EDGE'; export interface DeviceOperationRecord { commandType: CommandType; commandCode: string; deviceType: string; deviceId: number | string; operationType: OperationType; result?: Record; } export interface ProgramContext { taskId: string; programId: string; programName: string; programNo: number; programType: ProgramType; } export declare enum ReportLevel { INFO = "INFO", WARNING = "WARNING", ERROR = "ERROR" } export type ErrorCategory = 'TRANSPORT' | 'TIMEOUT' | 'RESOURCE' | 'BUSINESS' | 'CONFIGURATION' | 'PROTOCOL' | 'AUTHORIZATION'; export type ErrorPhase = 'PROGRAM_INIT' | 'PROGRAM_FETCH' | 'PROGRAM_EXTRACT' | 'PROGRAM_PREPROCESS' | 'PROGRAM_COMPILE' | 'PROGRAM_UPLOAD' | 'PROGRAM_STATS' | 'PROGRAM_COMPLETE' | 'QUICK_DETECTION_INIT' | 'QUICK_DETECTION_SWITCH_DETECT' | 'QUICK_DETECTION_SWITCH_CONFIG_READ' | 'QUICK_DETECTION_SYNC_DETECT' | 'QUICK_DETECTION_BARGRAPH_DETECT' | 'QUICK_DETECTION_SYNC_RECOVER' | 'QUICK_DETECTION_COMPLETE' | 'SYNC_EXPORT' | 'BATCH_EXECUTE' | 'EDGE_PROXY'; export type ErrorStep = 'ValidateParameters' | 'PrepareResources' | 'LoadConfig' | 'CheckConcurrency' | 'Download' | 'VerifyChecksum' | 'ExtractZip' | 'ResizeImage' | 'AdjustColor' | 'GammaCorrect' | 'Histogram' | 'RGBCorrection' | 'CompileFrame' | 'MoveFrame' | 'VerifyFrameCount' | 'DeviceCheck' | 'DataTransfer' | 'ForbiddenTable' | 'StatusRecovery' | 'RetryLimitExceeded' | 'ProgramWrapup' | 'DetectionInit' | 'NetworkScan' | 'SwitchConfigRead' | 'CommBoardInfoRead' | 'SyncDeviceCheck' | 'BargraphNodeCheck' | 'SyncStatusRecover' | 'DetectionWrapup' | 'ValidateCommandFormat' | 'CheckDeviceOnline' | 'DispatchToDevice' | 'AwaitDeviceResponse' | 'SubItemTimeout' | 'SubItemDeviceQuery' | 'ReadDayData' | 'AggregateExport'; export interface ErrorInfo { phase?: ErrorPhase; step?: ErrorStep; category: ErrorCategory; detail: string; } export interface ReportData { error?: ErrorInfo; [key: string]: any; } export interface ReportMessage { level: ReportLevel; message: string; code?: string; data?: ReportData; } export interface ProgressUpdateMessage extends BaseMessage { type: MessageType.PROGRESS_UPDATE; clientId: string; requestRef: string; /** * PROGRESS_UPDATE wire 的 status 字段**永远 'IN_PROGRESS'**. * v1.8.5 spec invariant — TypeScript literal type 编译期 catch 任何手写派生. * * 终态语义 (COMPLETED / FAILED / CANCELLED / TIMEOUT) 只属于 * COMMAND_RESPONSE / PROGRAM_RESPONSE message types. * * progress=100 on PROGRESS_UPDATE 表示"达到 100% 进度", 而非"命令完成". * 命令真正完成由 COMMAND_RESPONSE / PROGRAM_RESPONSE 单独承载. * * Edge v1.8.5 validator 对 status !== 'IN_PROGRESS' 的 PROGRESS_UPDATE → REJECT * (单步 ship, 0 grace mode, fail code: ERROR_PROGRESS_UPDATE_TERMINAL_STATUS_NOT_ALLOWED). */ status: 'IN_PROGRESS'; phase: ProgressPhase | string; progress: number; sourceType: ProgressSourceType; context?: ProgramContext; command?: DeviceOperationRecord; report?: ReportMessage; timestamp: string; version: string; } /** * v1.8.1: Edge → Gateway 内部 forward envelope * * 用途: Edge 收到设备端 wire 消息后, 包一层 envelope 转发到 Gateway, * 把 Edge 校验结果 (metaCompliance / validationFailures) 放外层 annotation, * 不污染 device emit 的原始 payload。 * * 与 v1.8.0 mutate 模式的区别: * v1.8.0: Edge 直接 (message as any).metaCompliance = 'TOLERATED' 改写 payload * v1.8.1: Edge send EdgeForwardEnvelope, payload 字段保留 device emit 原样 * * 协议层使用范围: 仅 Edge↔Gateway WebSocket 内部协议 — 设备端 wire 不涉及。 */ export interface EdgeForwardEnvelope { /** 包装设备端 emit 的原始 wire payload (PROGRESS_UPDATE / COMMAND_RESPONSE / PROGRAM_RESPONSE) */ edgePayload: ProgressUpdateMessage | CommandResponseMessage | ProgramResponseMessage; /** Edge 添加的 metadata, 不污染 edgePayload */ edgeAnnotation: { /** META 校验 outcome — STRICT 通过 / TOLERATED 宽容放行 */ metaCompliance: 'STRICT' | 'TOLERATED'; /** 校验失败的具体原因 (TOLERATED 时 dashboard 展示用; STRICT 时通常空) */ validationFailures?: string[]; /** Edge 收到 wire 的时间 (ISO 8601, 与 device emit timestamp 区分) */ edgeReceivedAt: string; }; /** envelope 标识 — 让 Gateway 解析时能区分 v1.8.0 raw message vs v1.8.1 envelope (forward-compat) */ envelopeVersion: '1.8.1'; } /** * v1.8.1: 类型守卫 — 判断 Gateway 收到的 message 是 v1.8.1 envelope 还是 v1.8.0 raw payload * (向后兼容: 老 Edge 仍可能 send raw message) */ export declare function isEdgeForwardEnvelope(msg: unknown): msg is EdgeForwardEnvelope; export interface UpdateRoutesMessage extends BaseMessage { type: MessageType.UPDATE_ROUTES; clientId: string; devices: string[]; } export interface UpdateRoutesAckMessage extends BaseMessage { type: MessageType.UPDATE_ROUTES_ACK; clientId: string; success: boolean; message?: string; routeCount?: number; } export interface AclInvalidatedMessage extends BaseMessage { type: MessageType.ACL_INVALIDATED; clientId?: string; jti?: string; reason?: string; } export declare function isRegisterMessage(msg: any): msg is RegisterMessage; export declare function isRegisterAckMessage(msg: any): msg is RegisterAckMessage; export declare function isUnregisterMessage(msg: any): msg is UnregisterMessage; export declare function isUnregisterAckMessage(msg: any): msg is UnregisterAckMessage; export declare function isHeartbeatMessage(msg: any): msg is HeartbeatMessage; export declare function isHeartbeatAckMessage(msg: any): msg is HeartbeatAckMessage; export declare function isCommandMessage(msg: any): msg is CommandMessage; export declare function isCommandResponseMessage(msg: any): msg is CommandResponseMessage; export declare function isProgramMessage(msg: any): msg is ProgramMessage; export declare function isProgramResponseMessage(msg: any): msg is ProgramResponseMessage; export declare function isProgressUpdateMessage(msg: any): msg is ProgressUpdateMessage; export declare function isErrorMessage(msg: any): msg is ErrorMessage; export declare function isUpdateRoutesMessage(msg: any): msg is UpdateRoutesMessage; export declare function isUpdateRoutesAckMessage(msg: any): msg is UpdateRoutesAckMessage; export declare function isRegisterPendingMessage(msg: any): msg is RegisterPendingMessage; export declare function isAuthorizationGrantedMessage(msg: any): msg is AuthorizationGrantedMessage; export declare function isAuthorizationRejectedMessage(msg: any): msg is AuthorizationRejectedMessage; export declare function isDeviceApprovalRequestMessage(msg: any): msg is DeviceApprovalRequestMessage; export declare function isDeviceApprovalResponseMessage(msg: any): msg is DeviceApprovalResponseMessage; export declare function isAclInvalidatedMessage(msg: any): msg is AclInvalidatedMessage; export declare const VALID_ERROR_CATEGORIES: readonly ErrorCategory[]; export declare function isValidErrorCategory(value: any): value is ErrorCategory; export declare function normalizeErrorCategory(value: any): ErrorCategory; export declare const ERROR_STEP_BY_PHASE: Record; export declare function isValidErrorStepForPhase(step: any, phase: any): boolean; export declare function isOrchestratorCodedWire(wireCode: any): boolean; export declare class MessageFactory { /** * 创建注册消息 (v1.12.0 discriminated union) * * DEVICE clientType: deviceFingerprint **必填** (runtime Edge 强制, schema 层 C 方案类型挡) * 非 DEVICE clientType: deviceFingerprint **禁带** (类型层 ?: never) */ static createRegisterMessage(clientId: string, clientType: ClientType.DEVICE, options: { deviceFingerprint: DeviceFingerprint; clientInfo?: ClientInfo; edgeInfo?: EdgeInfo; licenseToken?: string; }): DeviceRegisterMessage; static createRegisterMessage(clientId: string, clientType: Exclude, options?: { clientInfo?: ClientInfo; edgeInfo?: EdgeInfo; licenseToken?: string; }): NonDeviceRegisterMessage; /** * 创建命令消息 */ static createCommandMessage(requestRef: string, targetClientId: string, command: Command, callback: string, options?: { priority?: Priority; timeout?: number; retryCount?: number; }): CommandMessage; /** * 创建心跳消息 */ static createHeartbeatMessage(clientId: string, sequence: number): HeartbeatMessage; /** * 创建注销消息 */ static createUnregisterMessage(clientId: string, reason?: string): UnregisterMessage; /** * 创建注册挂起消息(Gateway → Edge/Backend) */ static createRegisterPendingMessage(requestId: string, pollInterval?: number, expiresIn?: number): RegisterPendingMessage; /** * 创建授权通过消息(Gateway → Edge/Backend) */ static createAuthorizationGrantedMessage(requestId: string, licenseToken: string): AuthorizationGrantedMessage; /** * 创建授权拒绝消息(Gateway → Edge/Backend) */ static createAuthorizationRejectedMessage(requestId: string, reason?: string): AuthorizationRejectedMessage; /** * 创建程序上传消息 */ static createProgramMessage(requestRef: string, targetClientId: string, parameters: ProgramParameters, callback: string, options?: { priority?: Priority; timeout?: number; }): ProgramMessage; /** * 创建错误消息 (Gateway & Backend 都需要) */ static createErrorMessage(code: string, message: string, requestRef?: string, options?: { level?: ReportLevel; data?: Record; severity?: string; category?: string; retryable?: boolean; }): ErrorMessage; /** * 创建心跳确认消息 (Gateway 急需) */ static createHeartbeatAckMessage(sequence: number, clientId?: string, clientTime?: string, options?: { latency?: number; heartbeatReceivedTime?: number; }): HeartbeatAckMessage; /** * 创建注册确认消息 (Gateway 需要) */ static createRegisterAckMessage(clientId: string, success: boolean, message?: string, sessionId?: string): RegisterAckMessage; /** * 创建注销确认消息 */ static createUnregisterAckMessage(clientId: string, success: boolean): UnregisterAckMessage; /** * 创建设备审批请求消息(Edge → Gateway) */ static createDeviceApprovalRequestMessage(edgeId: string, requestId: string, deviceId: string, deviceInfo?: ClientInfo, sourceIp?: string): DeviceApprovalRequestMessage; /** * 创建设备审批响应消息(Gateway → Edge) */ static createDeviceApprovalResponseMessage(requestId: string, deviceId: string, approved: boolean, deviceAccessKey?: string, reason?: string, action?: 'unblacklist' | 'revoke'): DeviceApprovalResponseMessage; /** * 创建路由更新消息 */ static createUpdateRoutesMessage(clientId: string, // 改为 clientId,统一命名 devices: string[]): UpdateRoutesMessage; /** * 创建路由更新确认消息 */ static createUpdateRoutesAckMessage(clientId: string, // 改为 clientId,统一命名 success: boolean, message?: string, routeCount?: number): UpdateRoutesAckMessage; /** * v1.6.0: 统一消息派发接口 * * 设备端发送终态消息(COMMAND_RESPONSE / PROGRAM_RESPONSE)或进度消息(PROGRESS_UPDATE)时, * 只需要提供 code 和业务字段,协议层通过 CodeMeta 自动推导 status / level / 消息类型。 * * 替代旧的 createCommandResponseMessage / createProgramResponseMessage / createProgressUpdateMessage。 * * @param params dispatch 参数 * @returns 完整的协议消息(具体类型由 code 派生的 isTerminal 决定) * @throws Error 当 code 要求 data.error 但 params.error 缺失时 */ static dispatchMessage(params: { clientId: string; requestRef: string; code: string; message: string; /** 终态消息:result 块;进度消息:业务平铺字段 */ data?: Record; /** v1.5.0 失败 schema — 当 code 要求时必填 */ error?: { phase: string; step: string; category: string; detail: string; }; /** 仅进度消息:phase 与 progress */ phase?: ProgressPhase | string; progress?: number; /** 进度消息 sourceType(默认 COMMAND)*/ sourceType?: ProgressSourceType; /** 终态消息 result 块(COMMAND_RESPONSE)*/ result?: any; /** 终态消息 context(PROGRAM_RESPONSE)*/ context?: ProgramContext; /** 终态消息 executionTime */ executionTime?: number; /** * v1.10.3: caller 可显式 override level (partial-failure 场景必传) * - 不传时: * - meta.level 是 string → 用 meta.level (向后兼容) * - meta.level 是 array → 用 array[0] 作为默认 (通常 'INFO') * - 传时: 必须命中 meta.level 接受值 (string 严格相等 / array includes) */ level?: ReportLevel; }): CommandResponseMessage | ProgramResponseMessage | ProgressUpdateMessage; } export type AnyMessage = RegisterMessage | RegisterAckMessage | UnregisterMessage | UnregisterAckMessage | CommandMessage | CommandResponseMessage | ProgramMessage | ProgramResponseMessage | HeartbeatMessage | HeartbeatAckMessage | ProgressUpdateMessage | UpdateRoutesMessage | UpdateRoutesAckMessage | RegisterPendingMessage | AuthorizationGrantedMessage | AuthorizationRejectedMessage | DeviceApprovalRequestMessage | DeviceApprovalResponseMessage | AclInvalidatedMessage | ErrorMessage; /** * 协议 wire schema 版本号(与 package.json.version 解耦演进) * * Semantic versioning of the wire protocol schema: * - Major/minor bump: BREAKING wire change(e.g. v1.6.0 删 createCommandResponse) * - Patch bump on schema: 仅当 schema 行为有 backward-compat 增强时 * - package.json.version 可独立 patch(不动 PROTOCOL_VERSION)— 例如 v1.7.3 仅 * publish-time fix 无 wire 变化,PROTOCOL_VERSION 保持 '1.7.2' * * v1.7.3 patch: 修正 v1.7.2 publish-time 漏改(原值 '1.7.1'),同时申明 schema 版本 * 与 package 版本可解耦的设计意图。详见 README.md > Versioning Policy + CHANGELOG v1.7.3。 * * v1.7.4 patch: schema 真有变化(EXPLICIT_META rename + add + OperationType 缩 + messageEn 删) * 所以 schema 版本同步升 '1.7.3',package 版本 1.7.4。 * * v1.7.5 patch: schema BREAKING wire rename — ProgramParameters.programNumber / ProgramContext.programNumber * → programNo(对齐设备端 wire emit + 与 Snowflake programId 区分)。Phase 3.5 Category C escalation 仲裁结果。 * schema 版本 1.7.3 → 1.7.4,package 版本 1.7.4 → 1.7.5。 * * v1.7.6 patch: SUFFIX_RULES 新增 _READ_SUCCESS / _WRITE_SUCCESS 终态规则。 * 修复 v1.7.0–v1.7.5 协议大坑:SIMPLE 命令 (SYNC_FUNCTIONS_SWITCH / SYNC_PROGRAM_CONTROL / * DEVICE_DATETIME_INFORMATION / 等几十个) 的 _READ_SUCCESS / _WRITE_SUCCESS 终态响应被 * 误匹配 _SUCCESS 规则降为 IN_PROGRESS → Edge 协议校验拒收 → 30s 假 timeout。 * v1.7.5 wire 联调 req_1778811285514_oan6qa 实证暴露。 * schema 版本 1.7.4 → 1.7.5,package 版本 1.7.5 → 1.7.6。 * * v1.7.7 patch: SUFFIX_RULES 对称侧补完 — v1.7.6 只修了 SUCCESS 侧,留下 FAILED + BATCH 漏: * - _READ_FAILED / _WRITE_FAILED (SIMPLE 命令失败终态对称) * - _ALL_SUCCESS / _PARTIAL_SUCCESS / _ALL_FAILED (BATCH 三态终态) * 触发:v1.7.6 wire 联调 req_1778824929909_jlvome (BARGRAPH_MISALIGNMENT_READ_FAILED) * schema 版本 1.7.5 → 1.7.6,package 版本 1.7.6 → 1.7.7。 * * v1.7.8 patch: SUFFIX_RULES 第 3 轮对称补完 — v1.7.7 漏 ECAN 广播 WRITE 终态: * - _BROADCAST_SUCCESS / _BROADCAST_FAILED (5 个光柱命令的 WRITE 广播终态) * 触发:v1.7.7 wire 联调 req_1778824943659_4gaxtv (BARGRAPH_MISALIGNMENT_WRITE_BROADCAST_SUCCESS) * 流程改进:本版严守 Principle 5(Round 2 reply → 设备端 Round 5 final ack → Phase 4 implement) * 配套工具卡:scripts/check-consumer-ack.sh + escape-hatch-audit.jsonl 进 prepublishOnly hook * schema 版本 1.7.6 → 1.7.7,package 版本 1.7.7 → 1.7.8。 * * v1.8.2 patch: ERROR_STEP_BY_PHASE map drift 修复 — 补 v1.5.0 残留塌方: * 触发: 设备端 v1.8.1 staging Round 8' audit dashboard ⚠️ TOLERATED * (req_1778991911621_gjqlbi, BARGRAPH_MISALIGNMENT_READ_FAILED * data.error.phase="BATCH_EXECUTE" Edge validator 报"不在白名单内") * 根因: ErrorPhase type (line 506-524) 含 BATCH_EXECUTE + SYNC_EXPORT, * 但 ERROR_STEP_BY_PHASE map (line 770-789) 漏这 2 key * Edge VALID_ERROR_PHASES 派生自 map, 也缺 * 修复 (additive, 0 break): * - ErrorStep type + 4 候选 step (SubItemTimeout/SubItemDeviceQuery/ReadDayData/AggregateExport) * - ERROR_STEP_BY_PHASE map 补 BATCH_EXECUTE + SYNC_EXPORT 2 key * 设备端影响: 0 改动 (设备端已 emit BATCH_EXECUTE/DataTransfer, 修后 Edge STRICT 通过) * 设计协商: Round 9'' reply + Round 10'' ack (transition mode 第 2 次) * schema 版本 1.8.1 → 1.8.2, package 版本 1.8.1 → 1.8.2 * * v1.8.1 patch: envelope 重构 — 删 ProgressUpdateMessage.metaCompliance + 加 EdgeForwardEnvelope: * 触发: 设备端 Round 8 audit P1 finding — Edge mutate device wire payload 注入 metaCompliance, * dashboard 展开 payload 误判 "私自加字段" * 设计纠正: Edge↔Gateway forward 改为 envelope 包装, device payload immutable * - ProgressUpdateMessage.metaCompliance 字段删除 (设备端从不 emit, 0 影响) * - 加 EdgeForwardEnvelope { edgePayload, edgeAnnotation: { metaCompliance, validationFailures?, edgeReceivedAt } } * - 加 isEdgeForwardEnvelope() 类型守卫 (Gateway forward-compat 老 Edge raw message) * 设备端影响: 0 改动 (wire / C# / catalog 全 0 改) — 字段本来设备端就不发 * 第三方影响: 0 grep 验证 (全 repo 仅协议方 own Edge/Gateway 用 metaCompliance) * schema 版本 1.8.0 → 1.8.1, package 版本 1.8.0 → 1.8.1 * 设计协商: Round 9 protocol-team-reply-to-consumer-audit-v1.8.0.md → Round 10 device-team-final-ack-v1.8.0.md * * v1.8.0 minor: resolveCodeMeta(code, ctx?) 升维 — 上下文派生 (向后兼容, ctx=undefined 等同 v1.7.8): * - CodeMetaContext interface: messageType / parentCommandType / phase / sourceType / subCommandType * - applyContextRules() R1-R7 派生规则 (PROGRESS_UPDATE 终态降级 + BATCH/COMPLEX 子项 + EDGE_CACHE invariant + 命名空间合规) * - SUFFIX_RULES +2: _STEP_OK / _STEP_FAIL (BATCH/COMPLEX 子项进度显式后缀, Q9) * - EXPLICIT_META QUICK_DETECTION_ALL_OFFLINE: status COMPLETED → FAILED (Q5 语义打架修) * - ProgressUpdateMessage.metaCompliance?: 'STRICT'|'TOLERATED' (Edge 添加标记) * - CLI tool: npx @thejrsoft/subway-protocol resolve / --batch / --diff (Q6 + 4 项增强) * 触发:v1.7.x cycle 多轮 META 命名空间冲突 + 真实测试环境 17 条拒收数据归因 * 设计协商:upgrade-guide-v1.8.0.md (Round 0) → 12 题 4 轮 (Round 1-4) 全 ack 0 反驳 * schema 版本 1.7.7 → 1.8.0,package 版本 1.7.8 → 1.8.0。 * * 防再犯:本常量被 scripts/check-protocol-version.js 在 prepublishOnly hook 中校验。 */ export declare const PROTOCOL_VERSION = "1.12.0"; export declare const DEFAULT_TIMEOUT = 10000; export declare const DEFAULT_PRIORITY = Priority.NORMAL; export * from './command-types'; export * from './command-factory'; export { MessageValidator, ValidationResult } from './message-validator'; export { ProtocolUtils } from './protocol-utils'; //# sourceMappingURL=index.d.ts.map