@ray-js/robot-data-stream 0.0.14 → 0.0.15-beta.2

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 (156) hide show
  1. package/lib/mqtt/createCommonOptions.d.ts +4 -2
  2. package/lib/mqtt/createCommonOptions.js +10 -5
  3. package/lib/mqtt/hooks/useStructuredMessage.d.ts +14 -0
  4. package/lib/mqtt/hooks/useStructuredMessage.js +131 -0
  5. package/lib/mqtt/mqttProvider.d.ts +19 -1
  6. package/lib/mqtt/mqttProvider.js +69 -8
  7. package/lib/mqtt/promise.d.ts +57 -4
  8. package/lib/mqtt/promise.js +115 -36
  9. package/lib/mqtt/type/fun.d.ts +49 -0
  10. package/lib/mqtt/type/fun.js +145 -0
  11. package/lib/mqtt/type/index.d.ts +0 -7
  12. package/lib/mqtt/type/index.js +0 -1
  13. package/lib/mqtt/type/protocols/base.d.ts +5 -0
  14. package/lib/mqtt/type/protocols/base.js +32 -0
  15. package/lib/mqtt/type/protocols/carpetCleanProtocol.d.ts +8 -0
  16. package/lib/mqtt/type/protocols/carpetCleanProtocol.js +16 -0
  17. package/lib/mqtt/type/protocols/carpetProtocol.d.ts +41 -0
  18. package/lib/mqtt/type/protocols/carpetProtocol.js +202 -0
  19. package/lib/mqtt/type/protocols/devInfoProtocol.d.ts +5 -0
  20. package/lib/mqtt/type/protocols/devInfoProtocol.js +12 -0
  21. package/lib/mqtt/type/protocols/deviceModelProtocol.d.ts +8 -0
  22. package/lib/mqtt/type/protocols/deviceModelProtocol.js +34 -0
  23. package/lib/mqtt/type/protocols/furnitureModelProtocol.d.ts +10 -0
  24. package/lib/mqtt/type/protocols/furnitureModelProtocol.js +35 -0
  25. package/lib/mqtt/type/protocols/historyMapProtocol.d.ts +17 -0
  26. package/lib/mqtt/type/protocols/historyMapProtocol.js +37 -0
  27. package/lib/mqtt/type/protocols/index.d.ts +20 -0
  28. package/lib/mqtt/type/protocols/index.js +20 -0
  29. package/lib/mqtt/type/protocols/partDivisionProtocol.d.ts +8 -0
  30. package/lib/mqtt/type/protocols/partDivisionProtocol.js +12 -0
  31. package/lib/mqtt/type/protocols/partMergeProtocol.d.ts +7 -0
  32. package/lib/mqtt/type/protocols/partMergeProtocol.js +12 -0
  33. package/lib/mqtt/type/protocols/passwordProtocol.d.ts +11 -0
  34. package/lib/mqtt/type/protocols/passwordProtocol.js +25 -0
  35. package/lib/mqtt/type/protocols/quietHoursProtocol.d.ts +8 -0
  36. package/lib/mqtt/type/protocols/quietHoursProtocol.js +35 -0
  37. package/lib/mqtt/type/protocols/resetMapProtocol.d.ts +4 -0
  38. package/lib/mqtt/type/protocols/resetMapProtocol.js +1 -0
  39. package/lib/mqtt/type/protocols/roomPropertyProtocol.d.ts +14 -0
  40. package/lib/mqtt/type/protocols/roomPropertyProtocol.js +113 -0
  41. package/lib/mqtt/type/protocols/scheduleProtocol.d.ts +18 -0
  42. package/lib/mqtt/type/protocols/scheduleProtocol.js +100 -0
  43. package/lib/mqtt/type/protocols/selectRoomCleanProtocol.d.ts +8 -0
  44. package/lib/mqtt/type/protocols/selectRoomCleanProtocol.js +40 -0
  45. package/lib/mqtt/type/protocols/spotCleanProtocol.d.ts +9 -0
  46. package/lib/mqtt/type/protocols/spotCleanProtocol.js +72 -0
  47. package/lib/mqtt/type/protocols/virtualAreaProtocol.d.ts +8 -0
  48. package/lib/mqtt/type/protocols/virtualAreaProtocol.js +36 -0
  49. package/lib/mqtt/type/protocols/virtualWallProtocol.d.ts +8 -0
  50. package/lib/mqtt/type/protocols/virtualWallProtocol.js +25 -0
  51. package/lib/mqtt/type/protocols/voiceProtocol.d.ts +8 -0
  52. package/lib/mqtt/type/protocols/voiceProtocol.js +23 -0
  53. package/lib/mqtt/type/protocols/wifiMapProtocol.d.ts +8 -0
  54. package/lib/mqtt/type/protocols/wifiMapProtocol.js +14 -0
  55. package/lib/mqtt/type/protocols/zoneCleanProtocol.d.ts +8 -0
  56. package/lib/mqtt/type/protocols/zoneCleanProtocol.js +49 -0
  57. package/lib/mqtt/useCarpet.d.ts +7 -67
  58. package/lib/mqtt/useCarpet.js +101 -181
  59. package/lib/mqtt/useCarpetClean.d.ts +2 -11
  60. package/lib/mqtt/useCarpetClean.js +24 -51
  61. package/lib/mqtt/useDevInfo.d.ts +8 -6
  62. package/lib/mqtt/useDevInfo.js +44 -36
  63. package/lib/mqtt/useDeviceModel.d.ts +6 -19
  64. package/lib/mqtt/useDeviceModel.js +29 -42
  65. package/lib/mqtt/useFurnitureModel.d.ts +6 -18
  66. package/lib/mqtt/useFurnitureModel.js +29 -43
  67. package/lib/mqtt/useHistoryMap.d.ts +2 -18
  68. package/lib/mqtt/useHistoryMap.js +102 -119
  69. package/lib/mqtt/usePartDivision.d.ts +2 -9
  70. package/lib/mqtt/usePartDivision.js +48 -57
  71. package/lib/mqtt/usePartMerge.d.ts +2 -8
  72. package/lib/mqtt/usePartMerge.js +34 -49
  73. package/lib/mqtt/usePassword.d.ts +6 -13
  74. package/lib/mqtt/usePassword.js +84 -74
  75. package/lib/mqtt/useQuiteHours.d.ts +4 -37
  76. package/lib/mqtt/useQuiteHours.js +66 -100
  77. package/lib/mqtt/useResetMap.d.ts +2 -8
  78. package/lib/mqtt/useResetMap.js +27 -34
  79. package/lib/mqtt/useRoomProperty.d.ts +8 -9
  80. package/lib/mqtt/useRoomProperty.js +67 -65
  81. package/lib/mqtt/useSchedule.d.ts +3 -23
  82. package/lib/mqtt/useSchedule.js +72 -101
  83. package/lib/mqtt/useSelectRoomClean.d.ts +3 -24
  84. package/lib/mqtt/useSelectRoomClean.js +107 -133
  85. package/lib/mqtt/useSpotClean.d.ts +5 -15
  86. package/lib/mqtt/useSpotClean.js +68 -121
  87. package/lib/mqtt/useVirtualArea.d.ts +6 -17
  88. package/lib/mqtt/useVirtualArea.js +109 -119
  89. package/lib/mqtt/useVirtualWall.d.ts +2 -18
  90. package/lib/mqtt/useVirtualWall.js +69 -90
  91. package/lib/mqtt/useVoice.d.ts +2 -16
  92. package/lib/mqtt/useVoice.js +48 -68
  93. package/lib/mqtt/useWifiMap.d.ts +6 -5
  94. package/lib/mqtt/useWifiMap.js +43 -42
  95. package/lib/mqtt/useZoneClean.d.ts +2 -21
  96. package/lib/mqtt/useZoneClean.js +125 -137
  97. package/lib/myLib/zod/mini/index.d.cts +1 -0
  98. package/lib/myLib/zod/mini/index.d.ts +1 -0
  99. package/lib/myLib/zod/mini/index.js +1 -0
  100. package/lib/myLib/zod/mini/package.json +6 -0
  101. package/lib/myLib/zod/src/mini/index.d.ts +1 -0
  102. package/lib/myLib/zod/src/mini/index.js +1 -0
  103. package/lib/myLib/zod/src/v4/core/api.d.ts +306 -0
  104. package/lib/myLib/zod/src/v4/core/api.js +1256 -0
  105. package/lib/myLib/zod/src/v4/core/checks.d.ts +278 -0
  106. package/lib/myLib/zod/src/v4/core/checks.js +816 -0
  107. package/lib/myLib/zod/src/v4/core/config.d.ts +9 -0
  108. package/lib/myLib/zod/src/v4/core/config.js +5 -0
  109. package/lib/myLib/zod/src/v4/core/core.d.ts +70 -0
  110. package/lib/myLib/zod/src/v4/core/core.js +95 -0
  111. package/lib/myLib/zod/src/v4/core/doc.d.ts +14 -0
  112. package/lib/myLib/zod/src/v4/core/doc.js +42 -0
  113. package/lib/myLib/zod/src/v4/core/errors.d.ts +220 -0
  114. package/lib/myLib/zod/src/v4/core/errors.js +232 -0
  115. package/lib/myLib/zod/src/v4/core/index.d.ts +15 -0
  116. package/lib/myLib/zod/src/v4/core/index.js +15 -0
  117. package/lib/myLib/zod/src/v4/core/json-schema-generator.d.ts +65 -0
  118. package/lib/myLib/zod/src/v4/core/json-schema-generator.js +120 -0
  119. package/lib/myLib/zod/src/v4/core/json-schema-processors.d.ts +49 -0
  120. package/lib/myLib/zod/src/v4/core/json-schema-processors.js +593 -0
  121. package/lib/myLib/zod/src/v4/core/json-schema.d.ts +88 -0
  122. package/lib/myLib/zod/src/v4/core/json-schema.js +1 -0
  123. package/lib/myLib/zod/src/v4/core/parse.d.ts +49 -0
  124. package/lib/myLib/zod/src/v4/core/parse.js +147 -0
  125. package/lib/myLib/zod/src/v4/core/regexes.d.ts +78 -0
  126. package/lib/myLib/zod/src/v4/core/regexes.js +146 -0
  127. package/lib/myLib/zod/src/v4/core/registries.d.ts +35 -0
  128. package/lib/myLib/zod/src/v4/core/registries.js +51 -0
  129. package/lib/myLib/zod/src/v4/core/schemas.d.ts +1136 -0
  130. package/lib/myLib/zod/src/v4/core/schemas.js +2745 -0
  131. package/lib/myLib/zod/src/v4/core/standard-schema.d.ts +126 -0
  132. package/lib/myLib/zod/src/v4/core/standard-schema.js +1 -0
  133. package/lib/myLib/zod/src/v4/core/to-json-schema.d.ts +114 -0
  134. package/lib/myLib/zod/src/v4/core/to-json-schema.js +488 -0
  135. package/lib/myLib/zod/src/v4/core/util.d.ts +199 -0
  136. package/lib/myLib/zod/src/v4/core/util.js +656 -0
  137. package/lib/myLib/zod/src/v4/core/versions.d.ts +5 -0
  138. package/lib/myLib/zod/src/v4/core/versions.js +5 -0
  139. package/lib/myLib/zod/src/v4/core/zsf.d.ts +91 -0
  140. package/lib/myLib/zod/src/v4/core/zsf.js +1 -0
  141. package/lib/myLib/zod/src/v4/mini/checks.d.ts +1 -0
  142. package/lib/myLib/zod/src/v4/mini/checks.js +1 -0
  143. package/lib/myLib/zod/src/v4/mini/coerce.d.ts +7 -0
  144. package/lib/myLib/zod/src/v4/mini/coerce.js +27 -0
  145. package/lib/myLib/zod/src/v4/mini/external.d.ts +11 -0
  146. package/lib/myLib/zod/src/v4/mini/external.js +16 -0
  147. package/lib/myLib/zod/src/v4/mini/index.d.ts +530 -0
  148. package/lib/myLib/zod/src/v4/mini/index.js +30 -0
  149. package/lib/myLib/zod/src/v4/mini/iso.d.ts +22 -0
  150. package/lib/myLib/zod/src/v4/mini/iso.js +46 -0
  151. package/lib/myLib/zod/src/v4/mini/parse.d.ts +1 -0
  152. package/lib/myLib/zod/src/v4/mini/parse.js +1 -0
  153. package/lib/myLib/zod/src/v4/mini/schemas.js +1244 -0
  154. package/lib/utils/index.d.ts +1 -0
  155. package/lib/utils/index.js +2 -1
  156. package/package.json +5 -3
@@ -22,6 +22,8 @@ export interface CreateSetCommonParamsInput {
22
22
  deviceId: string;
23
23
  /** 请求类型 */
24
24
  reqType: string;
25
+ /** 是否是局域网 */
26
+ isLocalOnLine: boolean;
25
27
  /** 消息体(可选) */
26
28
  message?: Partial<MqttMessage>;
27
29
  /** 版本号(可选,默认为 1.0.0) */
@@ -36,7 +38,7 @@ export interface CreateSetCommonParamsOutput {
36
38
  /** 设备ID */
37
39
  deviceId: string;
38
40
  /** 消息体 */
39
- message: MqttMessage;
41
+ message: MqttMessage | string;
40
42
  /** 选项 */
41
43
  options: MqttOptions;
42
44
  /** 协议号 */
@@ -62,4 +64,4 @@ export interface CreateSetCommonParamsOutput {
62
64
  * });
63
65
  * ```
64
66
  */
65
- export declare const createSetCommonParams: ({ deviceId, reqType, message, version, options, }: CreateSetCommonParamsInput) => CreateSetCommonParamsOutput;
67
+ export declare const createSetCommonParams: ({ deviceId, reqType, isLocalOnLine, message, version, options, }: CreateSetCommonParamsInput) => CreateSetCommonParamsOutput;
@@ -46,18 +46,23 @@ export const createSetCommonParams = _ref => {
46
46
  let {
47
47
  deviceId,
48
48
  reqType,
49
+ isLocalOnLine,
49
50
  message = {},
50
51
  version = DEFAULT_VERSION,
51
52
  options = {}
52
53
  } = _ref;
53
54
  const taskId = Date.now();
55
+ const messageData = _objectSpread({
56
+ reqType,
57
+ version,
58
+ taskId: `${taskId}`
59
+ }, message);
54
60
  return {
55
61
  deviceId,
56
- message: _objectSpread({
57
- reqType,
58
- version,
59
- taskId: `${taskId}`
60
- }, message),
62
+ message: !isLocalOnLine ? messageData : JSON.stringify({
63
+ data: messageData,
64
+ reqType
65
+ }),
61
66
  options,
62
67
  protocol: ProtocolEnum.appToRobot
63
68
  };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 统一的 MQTT 消息发送 Hook
3
+ * 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
4
+ */
5
+ export declare const useStructuredMessage: () => {
6
+ sendStructuredMessage: <T extends z.infer<any>>(reqType: string, message: Record<string, any> | undefined, resolve: (value: T) => void, reject: (reason?: any) => void, responseType?: string) => void;
7
+ };
8
+ /**
9
+ * 错误处理工具函数
10
+ * @param error 错误对象
11
+ * @param defaultMessage 默认错误消息
12
+ * @returns Error 对象
13
+ */
14
+ export declare const handleMqttError: (error: unknown, defaultMessage: string) => Error;
@@ -0,0 +1,131 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import { getDeviceOnlineType, onDeviceOnlineStatusUpdate } from '@ray-js/ray';
3
+ import { isFunction } from 'lodash-es';
4
+ import { useCallback, useEffect, useRef } from 'react';
5
+ import { getBitValue, logger } from '../../utils';
6
+ import { createSetCommonParams } from '../createCommonOptions';
7
+ import { useMqtt } from '../mqttProvider';
8
+ import { normalResolve } from '../promise';
9
+ /**
10
+ * 统一的 MQTT 消息发送 Hook
11
+ * 提供统一的 sendMqttMessage 方法,自动从 Context 获取 devId 和配置
12
+ */
13
+ export const useStructuredMessage = () => {
14
+ const context = useMqtt();
15
+ const {
16
+ devId
17
+ } = context.devices.common.getDevInfo();
18
+ const isLocalOnLineRef = useRef(false);
19
+ const isWifiOnLineRef = useRef(true);
20
+ const _onDeviceOnlineStatusChange = useCallback(_ref => {
21
+ let {
22
+ onlineType
23
+ } = _ref;
24
+ // bit 0: WiFi在线
25
+ const wifiOnline = !!getBitValue(onlineType, 0);
26
+ // bit 1: 局域网在线
27
+ const localOnline = !!getBitValue(onlineType, 1);
28
+ logger('info', {
29
+ msg: `onDeviceOnlineStatusChange00000: onlineType ==>${onlineType}===>wifiOnline:${wifiOnline}===>localOnline:${localOnline}`
30
+ });
31
+ isLocalOnLineRef.current = localOnline;
32
+ isWifiOnLineRef.current = wifiOnline;
33
+ }, []);
34
+ useEffect(() => {
35
+ if (!devId) return;
36
+ getDeviceOnlineType({
37
+ deviceId: devId,
38
+ success: _onDeviceOnlineStatusChange
39
+ });
40
+ onDeviceOnlineStatusUpdate(_onDeviceOnlineStatusChange);
41
+ }, [_onDeviceOnlineStatusChange, devId]);
42
+
43
+ /**
44
+ * 发送 MQTT 消息
45
+ * @param reqType 请求类型
46
+ * @param message 消息体(可选)
47
+ * @param responseType 响应类型(可选,如果不提供则使用 reqType)
48
+ * @param resolve Promise 的 resolve 回调
49
+ * @param reject Promise 的 reject 回调
50
+ */
51
+ const sendStructuredMessage = useCallback((reqType, message, resolve, reject, responseType) => {
52
+ if (!devId) {
53
+ reject(new Error('devId is required'));
54
+ return;
55
+ }
56
+ // 检查是否使用 MQTT 模式
57
+ if (!context.useMqtt) {
58
+ reject(new Error(`Operation ${reqType} requires MQTT mode. Please enable useMqtt in MqttProvider.`));
59
+ return;
60
+ }
61
+ try {
62
+ var _ty, _ty2;
63
+ const params = createSetCommonParams({
64
+ deviceId: devId,
65
+ reqType,
66
+ message,
67
+ isLocalOnLine: isLocalOnLineRef.current
68
+ });
69
+
70
+ // 优先使用局域网通信(LAN)
71
+ if (isLocalOnLineRef.current && (_ty = ty) !== null && _ty !== void 0 && _ty.device && isFunction(ty.device.publishLanMessage)) {
72
+ // @ts-ignore - publishLanMessage 可能不存在于类型定义中
73
+ ty.device.publishLanMessage(_objectSpread(_objectSpread({}, params), {}, {
74
+ success: () => {
75
+ logger('info', {
76
+ msg: `${reqType} LAN message publish success: ${JSON.stringify(params)}`
77
+ });
78
+ // 局域网通信成功回调
79
+ },
80
+ fail: e => {
81
+ logger('error', {
82
+ msg: `${reqType} LAN message publish failed: ${JSON.stringify(e)}`
83
+ });
84
+ }
85
+ }));
86
+ }
87
+ // 如果局域网不可用,使用 WiFi MQTT 通信
88
+ else if (isWifiOnLineRef.current && (_ty2 = ty) !== null && _ty2 !== void 0 && _ty2.device && isFunction(ty.device.sendMqttMessage)) {
89
+ ty.device.sendMqttMessage(_objectSpread(_objectSpread({}, params), {}, {
90
+ success: () => {
91
+ // WiFi MQTT 通信成功回调
92
+ logger('info', {
93
+ msg: `${reqType} WiFi MQTT message send success: ${JSON.stringify(params)}`
94
+ });
95
+ },
96
+ fail: e => {
97
+ logger('error', {
98
+ msg: `${reqType} MQTT message send failed: ${JSON.stringify(e)}`
99
+ });
100
+ }
101
+ }));
102
+ }
103
+ // 如果两种通信方式都不可用,抛出错误
104
+ else {
105
+ reject(new Error(`No available communication method. LAN online: ${isLocalOnLineRef.current}, WiFi online: ${isWifiOnLineRef.current}`));
106
+ return;
107
+ }
108
+ // 如果指定了响应类型,使用响应类型;否则使用请求类型
109
+
110
+ normalResolve(responseType || reqType, resolve, reject);
111
+ } catch (error) {
112
+ reject(error);
113
+ }
114
+ }, [devId, context.useMqtt]);
115
+ return {
116
+ sendStructuredMessage
117
+ };
118
+ };
119
+
120
+ /**
121
+ * 错误处理工具函数
122
+ * @param error 错误对象
123
+ * @param defaultMessage 默认错误消息
124
+ * @returns Error 对象
125
+ */
126
+ export const handleMqttError = (error, defaultMessage) => {
127
+ if (error instanceof Error) {
128
+ return error;
129
+ }
130
+ return new Error(defaultMessage);
131
+ };
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { MqttError } from './promise';
2
3
  export interface MqttContextValue {
3
4
  useMqtt: boolean;
4
5
  commandVersion: '0' | '1';
@@ -19,15 +20,32 @@ export interface MqttContextValue {
19
20
  };
20
21
  }
21
22
  export declare const SingletonContext: React.Context<MqttContextValue | null>;
23
+ export type MqttErrorHandler = (error: MqttError) => void;
22
24
  export interface MqttProviderProps {
23
25
  children: React.ReactNode;
24
26
  useMqtt: boolean;
25
27
  commandVersion: '0' | '1';
26
28
  devices: MqttContextValue['devices'];
27
29
  onMqttReady?: () => void;
30
+ /**
31
+ * 可选的错误处理回调
32
+ * 当 MQTT 请求发生未捕获的错误时(如超时、请求失败等),会调用此回调
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * <MqttProvider
37
+ * onError={(error) => {
38
+ * console.error('MQTT Error:', error);
39
+ * // 可以发送到错误监控服务
40
+ * }}
41
+ * ...
42
+ * />
43
+ * ```
44
+ */
45
+ onError?: MqttErrorHandler;
28
46
  }
29
47
  export declare function useMqtt(): MqttContextValue;
30
- export declare function MqttProvider({ children, useMqtt, commandVersion, devices, onMqttReady, }: MqttProviderProps): React.JSX.Element;
48
+ export declare function MqttProvider({ children, useMqtt, commandVersion, devices, onError, onMqttReady, }: MqttProviderProps): React.JSX.Element;
31
49
  export declare namespace MqttProvider {
32
50
  var defaultProps: {
33
51
  onMqttReady: undefined;
@@ -1,14 +1,19 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import { get, isNil } from 'lodash-es';
2
+ import { registerMQTTProtocolListener } from '@ray-js/ray';
3
+ import { get, isFunction, isNil } from 'lodash-es';
3
4
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
4
5
  import { emitter } from '../utils';
6
+ import { setUnhandledRejectionHandler } from './promise';
5
7
  import { ProtocolEnum } from './type';
8
+ import log4js from '@ray-js/log4js';
6
9
 
7
10
  // Context 类型定义
8
11
 
9
12
  // 创建一个Context
10
13
  export const SingletonContext = /*#__PURE__*/createContext(null);
11
14
 
15
+ // MQTT 错误处理函数类型
16
+
12
17
  // MqttProvider Props 类型定义
13
18
 
14
19
  // MQTT 消息数据类型
@@ -27,13 +32,19 @@ export function MqttProvider(_ref) {
27
32
  useMqtt,
28
33
  commandVersion,
29
34
  devices,
35
+ onError,
30
36
  onMqttReady
31
37
  } = _ref;
38
+ // const [isLocalOnLine, setIsLocalOnLine] = useState(false);
39
+ // const [isWifiOnLine, setIsWifiOnLine] = useState(true);
40
+
32
41
  // 使用 useMemo 创建实例,确保只在依赖项变化时重新创建
33
42
  const instance = useMemo(() => ({
34
43
  useMqtt,
35
44
  commandVersion,
36
45
  devices
46
+ // isLocalOnLine,
47
+ // isWifiOnLine,
37
48
  }), [useMqtt, commandVersion, devices]);
38
49
 
39
50
  // 使用 ref 存储设备 ID 和初始化状态,避免重复初始化
@@ -67,9 +78,46 @@ export function MqttProvider(_ref) {
67
78
  });
68
79
  emitter.emit(reqType, responseData);
69
80
  }, []);
81
+ const onSocketMessageReceived = useCallback(event => {
82
+ const {
83
+ message
84
+ } = event || {};
85
+ log4js.info('onSocketMessageReceived======>', {
86
+ msg: JSON.stringify(message)
87
+ });
88
+ if (message !== null && message !== void 0 && message.data && message !== null && message !== void 0 && message.reqType) {
89
+ emitter.emit(message.reqType, message.data);
90
+ }
91
+ }, []);
92
+
93
+ // 设置全局错误处理器(不依赖 window,适用于小程序环境)
94
+ useEffect(() => {
95
+ if (onError) {
96
+ // 设置全局错误处理器
97
+ setUnhandledRejectionHandler(error => {
98
+ try {
99
+ onError(error);
100
+ } catch (handlerError) {
101
+ // 避免错误处理器本身抛出错误导致无限循环
102
+ console.error('Error in MQTT error handler:', handlerError);
103
+ }
104
+ });
105
+ } else {
106
+ // 如果没有提供错误处理器,设置默认处理器(记录警告)
107
+ setUnhandledRejectionHandler(error => {
108
+ console.warn(`[MQTT] Unhandled rejection for ${error.reqType}:`, error.message);
109
+ });
110
+ }
111
+
112
+ // 清理函数:组件卸载时移除全局处理器
113
+ return () => {
114
+ setUnhandledRejectionHandler(null);
115
+ };
116
+ }, [onError]);
70
117
 
71
118
  // 初始化 MQTT 监听器(只执行一次)
72
119
  useEffect(() => {
120
+ var _ty;
73
121
  // 防止重复初始化
74
122
  if (isInitializedRef.current) return;
75
123
 
@@ -88,10 +136,11 @@ export function MqttProvider(_ref) {
88
136
  }
89
137
 
90
138
  // 注册 MQTT 协议监听器
91
- ty.device.registerMQTTProtocolListener({
139
+ registerMQTTProtocolListener({
92
140
  protocol: ProtocolEnum.robotToApp,
93
141
  success: () => {
94
142
  console.log('注册mqtt成功');
143
+ onMqttReady === null || onMqttReady === void 0 || onMqttReady();
95
144
  },
96
145
  fail: error => {
97
146
  console.error('注册mqtt失败:', error);
@@ -105,14 +154,26 @@ export function MqttProvider(_ref) {
105
154
  }
106
155
  });
107
156
 
157
+ // 注册设备服务监听器(如果方法存在)
158
+ // @ts-ignore - registerDeviceServiceListener 可能不存在于类型定义中
159
+ if ((_ty = ty) !== null && _ty !== void 0 && _ty.device && isFunction(ty.device.registerDeviceServiceListener)) {
160
+ var _ty2;
161
+ // @ts-ignore
162
+ ty.device.registerDeviceServiceListener({
163
+ success: event => {
164
+ console.log(event, '++++++++++2222++++++');
165
+ },
166
+ fail: e => {
167
+ console.log(e);
168
+ }
169
+ });
170
+ // 注册 Socket 消息接收监听器
171
+ (_ty2 = ty) === null || _ty2 === void 0 || (_ty2 = _ty2.device) === null || _ty2 === void 0 || _ty2.onSocketMessageReceived(onSocketMessageReceived);
172
+ }
173
+
108
174
  // 标记为已初始化
109
175
  isInitializedRef.current = true;
110
-
111
- // 调用 onMqttReady 回调,通知业务侧 MQTT 监听器已准备就绪
112
- if (onMqttReadyRef.current) {
113
- onMqttReadyRef.current();
114
- }
115
- }, [devices, onMqttMessageReceived]);
176
+ }, [devices, onMqttMessageReceived, onMqttReady]);
116
177
 
117
178
  // 将实例作为 value 传递给消费组件
118
179
  return /*#__PURE__*/React.createElement(SingletonContext.Provider, {
@@ -1,4 +1,22 @@
1
- declare class MyError extends Error {
1
+ /**
2
+ * 设置全局未处理的 rejection 处理器
3
+ *
4
+ * @param handler 处理函数,接收 MqttError 作为参数
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * setUnhandledRejectionHandler((error) => {
9
+ * console.error('Unhandled MQTT error:', error);
10
+ * // 可以发送到错误监控服务
11
+ * });
12
+ * ```
13
+ */
14
+ export declare function setUnhandledRejectionHandler(handler: ((error: MqttError) => void) | null): void;
15
+ /**
16
+ * MQTT 请求错误类
17
+ * 包含错误代码和请求类型信息
18
+ */
19
+ export declare class MqttError extends Error {
2
20
  errCode: number;
3
21
  reqType: string;
4
22
  constructor(message: string, { errCode, reqType }: {
@@ -6,8 +24,43 @@ declare class MyError extends Error {
6
24
  reqType: string;
7
25
  });
8
26
  }
27
+ /**
28
+ * MQTT 响应消息类型(兼容 MQTT 响应格式)
29
+ */
30
+ export interface MqttResponseMessage {
31
+ taskId: string | number;
32
+ errCode?: number;
33
+ data?: any;
34
+ reqType?: string;
35
+ version?: string;
36
+ success?: boolean;
37
+ [key: string]: any;
38
+ }
39
+ /**
40
+ * Promise 扩展类型,支持手动拒绝
41
+ */
9
42
  export type PromiseWithRejection = Promise<any> & {
10
- reject: (reason?: MyError) => void;
43
+ reject: (reason?: MqttError) => void;
11
44
  };
12
- export declare function normalResolve(reqType: string, taskId: string): PromiseWithRejection;
13
- export {};
45
+ /**
46
+ * 创建 MQTT 请求的 Promise,监听响应消息
47
+ *
48
+ * ⚠️ 注意:此函数不再使用 taskId 进行匹配,只要接收到对应 reqType 的响应就认为匹配
49
+ * ⚠️ 风险:如果同时发起多个相同 reqType 的请求,可能会匹配到错误的响应
50
+ * ⚠️ 建议:确保业务上不会同时发起多个相同类型的请求
51
+ *
52
+ * @param reqType 请求类型,用于匹配响应消息
53
+ * @param taskId 任务ID(已废弃,保留参数以保持向后兼容)
54
+ * @param resolve Promise 的 resolve 回调
55
+ * @param reject Promise 的 reject 回调
56
+ * @param timeout 超时时间(毫秒),默认 10 秒
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * return new Promise((resolve, reject) => {
61
+ * normalResolve('carpetQry', '', resolve, reject);
62
+ * });
63
+ * ```
64
+ */
65
+ export declare function normalResolve(reqType: string, resolve: (value: any) => void, reject: (reason?: any) => void, timeout?: number): void;
66
+ export type MyError = MqttError;
@@ -1,54 +1,133 @@
1
- import { emitter } from '../utils';
1
+ import { emitter, logger } from '../utils';
2
2
 
3
- // 1. 定义 MyError 类型
4
- class MyError extends Error {
3
+ /**
4
+ * MQTT 请求超时时间(毫秒)
5
+ * 默认 10 秒
6
+ */
7
+ const DEFAULT_TIMEOUT = 10 * 1000;
8
+
9
+ /**
10
+ * 全局未处理的 rejection 处理器
11
+ * 当 Promise 被 reject 但没有被 catch 时调用
12
+ */
13
+ let globalUnhandledRejectionHandler = null;
14
+
15
+ /**
16
+ * 设置全局未处理的 rejection 处理器
17
+ *
18
+ * @param handler 处理函数,接收 MqttError 作为参数
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * setUnhandledRejectionHandler((error) => {
23
+ * console.error('Unhandled MQTT error:', error);
24
+ * // 可以发送到错误监控服务
25
+ * });
26
+ * ```
27
+ */
28
+ export function setUnhandledRejectionHandler(handler) {
29
+ globalUnhandledRejectionHandler = handler;
30
+ }
31
+
32
+ /**
33
+ * MQTT 请求错误类
34
+ * 包含错误代码和请求类型信息
35
+ */
36
+ export class MqttError extends Error {
5
37
  constructor(message, _ref) {
6
38
  let {
7
39
  errCode,
8
40
  reqType
9
41
  } = _ref;
10
42
  super(message);
43
+ this.name = 'MqttError';
11
44
  this.errCode = errCode;
12
45
  this.reqType = reqType;
46
+
47
+ // 确保错误堆栈正确
48
+ if (Error.captureStackTrace) {
49
+ Error.captureStackTrace(this, MqttError);
50
+ }
13
51
  }
14
52
  }
15
53
 
16
- // 2. 定义 Message 类型(兼容 MQTT 响应格式)
54
+ /**
55
+ * MQTT 响应消息类型(兼容 MQTT 响应格式)
56
+ */
57
+
58
+ /**
59
+ * Promise 扩展类型,支持手动拒绝
60
+ */
17
61
 
18
- // 3. 定义 PromiseWithRejection 类型
62
+ /**
63
+ * 创建 MQTT 请求的 Promise,监听响应消息
64
+ *
65
+ * ⚠️ 注意:此函数不再使用 taskId 进行匹配,只要接收到对应 reqType 的响应就认为匹配
66
+ * ⚠️ 风险:如果同时发起多个相同 reqType 的请求,可能会匹配到错误的响应
67
+ * ⚠️ 建议:确保业务上不会同时发起多个相同类型的请求
68
+ *
69
+ * @param reqType 请求类型,用于匹配响应消息
70
+ * @param taskId 任务ID(已废弃,保留参数以保持向后兼容)
71
+ * @param resolve Promise 的 resolve 回调
72
+ * @param reject Promise 的 reject 回调
73
+ * @param timeout 超时时间(毫秒),默认 10 秒
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * return new Promise((resolve, reject) => {
78
+ * normalResolve('carpetQry', '', resolve, reject);
79
+ * });
80
+ * ```
81
+ */
82
+ export function normalResolve(reqType, resolve, reject) {
83
+ let timeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : DEFAULT_TIMEOUT;
84
+ let isResolved = false;
19
85
 
20
- // 4. 定义 normalResolve 函数
21
- export function normalResolve(reqType, taskId) {
22
- return new Promise((resolve, reject) => {
23
- // 设置超时定时器
24
- const timer = setTimeout(() => {
25
- reject(new MyError(`${taskId} ${reqType} Request timed out `, {
86
+ // 设置超时定时器
87
+ const timer = setTimeout(() => {
88
+ if (!isResolved) {
89
+ isResolved = true;
90
+ // 确保在超时时也移除监听器
91
+ emitter.off(reqType, handle);
92
+ reject(new MqttError(`${reqType} Request timed out`, {
26
93
  errCode: -1,
27
94
  reqType
28
95
  }));
29
- }, 10 * 1000);
30
- const handle = message => {
31
- var _message$errCode;
32
- // 通过 taskId 匹配响应
33
- if (`${message.taskId}` !== `${taskId}`) {
34
- return;
35
- }
36
- clearTimeout(timer);
37
-
38
- // 优先使用 errCode,如果没有则使用 success 字段判断
39
- const errCode = (_message$errCode = message.errCode) !== null && _message$errCode !== void 0 ? _message$errCode : message.success === false ? -1 : 0;
40
- if (errCode === 0) {
41
- resolve(message);
42
- } else {
43
- reject(new MyError('Request failed', {
44
- errCode,
45
- reqType
46
- }));
47
- }
48
- emitter.off(reqType, handle);
49
- };
96
+ }
97
+ }, timeout);
98
+ const handle = message => {
99
+ var _response$errCode;
100
+ const response = typeof message.data === 'object' ? message.data : message;
101
+
102
+ // 如果已经处理过,直接返回(避免重复处理)
103
+ if (isResolved) {
104
+ return;
105
+ }
106
+
107
+ // 标记为已处理(防止其他监听器处理)
108
+ isResolved = true;
109
+ clearTimeout(timer);
110
+ logger('info', {
111
+ msg: `${reqType} normalResolve: response ==>${JSON.stringify(response)}`
112
+ });
113
+
114
+ // 移除监听器(使用函数引用确保移除正确的监听器)
115
+ emitter.off(reqType, handle);
116
+
117
+ // 优先使用 errCode,如果没有则使用 success 字段判断
118
+ const errCode = (_response$errCode = response.errCode) !== null && _response$errCode !== void 0 ? _response$errCode : response.success === false ? -1 : 0;
119
+ if (errCode === 0) {
120
+ resolve(response);
121
+ } else {
122
+ reject(new MqttError('Request failed', {
123
+ errCode,
124
+ reqType
125
+ }));
126
+ }
127
+ };
128
+
129
+ // 监听指定类型的消息
130
+ emitter.on(reqType, handle);
131
+ }
50
132
 
51
- // 监听指定类型的消息
52
- emitter.on(reqType, handle);
53
- });
54
- }
133
+ // 为了向后兼容,导出旧的类型别名
@@ -0,0 +1,49 @@
1
+ import * as z from 'zod/mini';
2
+ import { pointsSchema, roomIdSchema, originSchema } from './protocols/partDivisionProtocol';
3
+ export declare const ProtocolSchemas: {
4
+ query_carpet: any;
5
+ add_carpet: any;
6
+ update_carpet: any;
7
+ delete_carpet: any;
8
+ set_carpet: any;
9
+ set_schedule: any;
10
+ request_schedule: any;
11
+ set_zone_clean: any;
12
+ set_wifi_map: any;
13
+ set_voice: any;
14
+ set_virtual_wall: any;
15
+ set_virtual_area: any;
16
+ set_spot_clean: any;
17
+ set_select_room_clean: any;
18
+ set_quiet_hours: any;
19
+ set_password: any;
20
+ check_password: any;
21
+ set_part_merge: any;
22
+ delete_history_map: any;
23
+ save_map: any;
24
+ change_current_map: any;
25
+ request_furniture_list: any;
26
+ set_furniture_model: any;
27
+ set_device_model: any;
28
+ set_carpet_clean: any;
29
+ set_room_property: any;
30
+ };
31
+ export type ProtocolTypes = {
32
+ [K in keyof typeof ProtocolSchemas]: z.infer<(typeof ProtocolSchemas)[K]>;
33
+ };
34
+ export declare class MiniProtocolValidator {
35
+ validate<T extends keyof ProtocolTypes>(protocol: T, data: unknown): ProtocolTypes[T];
36
+ /**
37
+ * 验证 set_part_division 的三个独立参数
38
+ * @param points 分隔点数组
39
+ * @param roomId 房间ID(可以是 int 或 string)
40
+ * @param origin 地图原点坐标
41
+ * @returns 验证后的数据对象
42
+ */
43
+ validateSetPartDivision(points: unknown, roomId: unknown, origin: unknown): {
44
+ points: z.infer<typeof pointsSchema>;
45
+ roomId: z.infer<typeof roomIdSchema>;
46
+ origin: z.infer<typeof originSchema>;
47
+ };
48
+ }
49
+ export declare const validator: MiniProtocolValidator;