@tier0/sdk-v2 0.0.0-stage → 0.1.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.
Files changed (298) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +7 -0
  3. package/README.md +201 -2
  4. package/dist/cjs/app-identity-contract.generated.d.ts +22 -0
  5. package/dist/cjs/app-identity-contract.generated.js +51 -0
  6. package/dist/cjs/app-identity-contract.generated.js.map +1 -0
  7. package/dist/cjs/capabilities.d.ts +54 -0
  8. package/dist/cjs/capabilities.js +134 -0
  9. package/dist/cjs/capabilities.js.map +1 -0
  10. package/dist/cjs/client.d.ts +604 -0
  11. package/dist/cjs/client.js +35 -0
  12. package/dist/cjs/client.js.map +1 -0
  13. package/dist/cjs/cloud-server.d.ts +31 -0
  14. package/dist/cjs/cloud-server.js +114 -0
  15. package/dist/cjs/cloud-server.js.map +1 -0
  16. package/dist/cjs/cloud-transport.d.ts +46 -0
  17. package/dist/cjs/cloud-transport.js +192 -0
  18. package/dist/cjs/cloud-transport.js.map +1 -0
  19. package/dist/cjs/controls.d.ts +93 -0
  20. package/dist/cjs/controls.js +169 -0
  21. package/dist/cjs/controls.js.map +1 -0
  22. package/dist/cjs/data/bootstrap.d.ts +66 -0
  23. package/dist/cjs/data/bootstrap.js +282 -0
  24. package/dist/cjs/data/bootstrap.js.map +1 -0
  25. package/dist/cjs/data/call.d.ts +16 -0
  26. package/dist/cjs/data/call.js +51 -0
  27. package/dist/cjs/data/call.js.map +1 -0
  28. package/dist/cjs/data/client.d.ts +92 -0
  29. package/dist/cjs/data/client.js +102 -0
  30. package/dist/cjs/data/client.js.map +1 -0
  31. package/dist/cjs/data/collection.d.ts +238 -0
  32. package/dist/cjs/data/collection.js +441 -0
  33. package/dist/cjs/data/collection.js.map +1 -0
  34. package/dist/cjs/data/context.d.ts +10 -0
  35. package/dist/cjs/data/context.js +39 -0
  36. package/dist/cjs/data/context.js.map +1 -0
  37. package/dist/cjs/data/declarations.d.ts +11 -0
  38. package/dist/cjs/data/declarations.js +18 -0
  39. package/dist/cjs/data/declarations.js.map +1 -0
  40. package/dist/cjs/data/define.d.ts +69 -0
  41. package/dist/cjs/data/define.js +31 -0
  42. package/dist/cjs/data/define.js.map +1 -0
  43. package/dist/cjs/data/error.d.ts +60 -0
  44. package/dist/cjs/data/error.js +184 -0
  45. package/dist/cjs/data/error.js.map +1 -0
  46. package/dist/cjs/data/index.d.ts +21 -0
  47. package/dist/cjs/data/index.js +43 -0
  48. package/dist/cjs/data/index.js.map +1 -0
  49. package/dist/cjs/data/schema.d.ts +82 -0
  50. package/dist/cjs/data/schema.js +607 -0
  51. package/dist/cjs/data/schema.js.map +1 -0
  52. package/dist/cjs/data/sort.d.ts +8 -0
  53. package/dist/cjs/data/sort.js +21 -0
  54. package/dist/cjs/data/sort.js.map +1 -0
  55. package/dist/cjs/files.d.ts +67 -0
  56. package/dist/cjs/files.js +119 -0
  57. package/dist/cjs/files.js.map +1 -0
  58. package/dist/cjs/framework-scope.d.ts +1 -0
  59. package/dist/cjs/framework-scope.js +14 -0
  60. package/dist/cjs/framework-scope.js.map +1 -0
  61. package/dist/cjs/index.d.ts +14 -0
  62. package/dist/cjs/index.js +33 -0
  63. package/dist/cjs/index.js.map +1 -0
  64. package/dist/cjs/mq/broker.d.ts +65 -0
  65. package/dist/cjs/mq/broker.js +115 -0
  66. package/dist/cjs/mq/broker.js.map +1 -0
  67. package/dist/cjs/mq/client.d.ts +37 -0
  68. package/dist/cjs/mq/client.js +321 -0
  69. package/dist/cjs/mq/client.js.map +1 -0
  70. package/dist/cjs/mq/index.d.ts +5 -0
  71. package/dist/cjs/mq/index.js +11 -0
  72. package/dist/cjs/mq/index.js.map +1 -0
  73. package/dist/cjs/mq/types.d.ts +48 -0
  74. package/dist/cjs/mq/types.js +3 -0
  75. package/dist/cjs/mq/types.js.map +1 -0
  76. package/dist/cjs/openapi/api.generated.d.ts +820 -0
  77. package/dist/cjs/openapi/api.generated.js +607 -0
  78. package/dist/cjs/openapi/api.generated.js.map +1 -0
  79. package/dist/cjs/openapi/client.d.ts +56 -0
  80. package/dist/cjs/openapi/client.js +219 -0
  81. package/dist/cjs/openapi/client.js.map +1 -0
  82. package/dist/cjs/openapi/codecs.generated.d.ts +2234 -0
  83. package/dist/cjs/openapi/codecs.generated.js +6 -0
  84. package/dist/cjs/openapi/codecs.generated.js.map +1 -0
  85. package/dist/cjs/openapi/index.d.ts +5 -0
  86. package/dist/cjs/openapi/index.js +12 -0
  87. package/dist/cjs/openapi/index.js.map +1 -0
  88. package/dist/cjs/openapi/types.generated.d.ts +3227 -0
  89. package/dist/cjs/openapi/types.generated.js +3 -0
  90. package/dist/cjs/openapi/types.generated.js.map +1 -0
  91. package/dist/cjs/package.json +1 -0
  92. package/dist/cjs/react.d.ts +9 -0
  93. package/dist/cjs/react.js +16 -0
  94. package/dist/cjs/react.js.map +1 -0
  95. package/dist/cjs/runtime-context.d.ts +9 -0
  96. package/dist/cjs/runtime-context.js +25 -0
  97. package/dist/cjs/runtime-context.js.map +1 -0
  98. package/dist/cjs/runtime-env.d.ts +1 -0
  99. package/dist/cjs/runtime-env.js +18 -0
  100. package/dist/cjs/runtime-env.js.map +1 -0
  101. package/dist/cjs/source.d.ts +39 -0
  102. package/dist/cjs/source.js +29 -0
  103. package/dist/cjs/source.js.map +1 -0
  104. package/dist/cjs/stream.d.ts +40 -0
  105. package/dist/cjs/stream.js +33 -0
  106. package/dist/cjs/stream.js.map +1 -0
  107. package/dist/cjs/uns-v2/client.d.ts +54 -0
  108. package/dist/cjs/uns-v2/client.js +177 -0
  109. package/dist/cjs/uns-v2/client.js.map +1 -0
  110. package/dist/cjs/uns-v2/codec.d.ts +11 -0
  111. package/dist/cjs/uns-v2/codec.js +290 -0
  112. package/dist/cjs/uns-v2/codec.js.map +1 -0
  113. package/dist/cjs/uns-v2/data-client.d.ts +10 -0
  114. package/dist/cjs/uns-v2/data-client.js +18 -0
  115. package/dist/cjs/uns-v2/data-client.js.map +1 -0
  116. package/dist/cjs/uns-v2/generated.d.ts +15551 -0
  117. package/dist/cjs/uns-v2/generated.js +139 -0
  118. package/dist/cjs/uns-v2/generated.js.map +1 -0
  119. package/dist/cjs/uns-v2/index.d.ts +5 -0
  120. package/dist/cjs/uns-v2/index.js +24 -0
  121. package/dist/cjs/uns-v2/index.js.map +1 -0
  122. package/dist/cjs/vue.d.ts +9 -0
  123. package/dist/cjs/vue.js +39 -0
  124. package/dist/cjs/vue.js.map +1 -0
  125. package/dist/esm/app-identity-contract.generated.d.ts +22 -0
  126. package/dist/esm/app-identity-contract.generated.js +48 -0
  127. package/dist/esm/app-identity-contract.generated.js.map +1 -0
  128. package/dist/esm/capabilities.d.ts +54 -0
  129. package/dist/esm/capabilities.js +129 -0
  130. package/dist/esm/capabilities.js.map +1 -0
  131. package/dist/esm/client.d.ts +604 -0
  132. package/dist/esm/client.js +32 -0
  133. package/dist/esm/client.js.map +1 -0
  134. package/dist/esm/cloud-server.d.ts +31 -0
  135. package/dist/esm/cloud-server.js +109 -0
  136. package/dist/esm/cloud-server.js.map +1 -0
  137. package/dist/esm/cloud-transport.d.ts +46 -0
  138. package/dist/esm/cloud-transport.js +187 -0
  139. package/dist/esm/cloud-transport.js.map +1 -0
  140. package/dist/esm/controls.d.ts +93 -0
  141. package/dist/esm/controls.js +163 -0
  142. package/dist/esm/controls.js.map +1 -0
  143. package/dist/esm/data/bootstrap.d.ts +66 -0
  144. package/dist/esm/data/bootstrap.js +277 -0
  145. package/dist/esm/data/bootstrap.js.map +1 -0
  146. package/dist/esm/data/call.d.ts +16 -0
  147. package/dist/esm/data/call.js +47 -0
  148. package/dist/esm/data/call.js.map +1 -0
  149. package/dist/esm/data/client.d.ts +92 -0
  150. package/dist/esm/data/client.js +99 -0
  151. package/dist/esm/data/client.js.map +1 -0
  152. package/dist/esm/data/collection.d.ts +238 -0
  153. package/dist/esm/data/collection.js +434 -0
  154. package/dist/esm/data/collection.js.map +1 -0
  155. package/dist/esm/data/context.d.ts +10 -0
  156. package/dist/esm/data/context.js +34 -0
  157. package/dist/esm/data/context.js.map +1 -0
  158. package/dist/esm/data/declarations.d.ts +11 -0
  159. package/dist/esm/data/declarations.js +10 -0
  160. package/dist/esm/data/declarations.js.map +1 -0
  161. package/dist/esm/data/define.d.ts +69 -0
  162. package/dist/esm/data/define.js +27 -0
  163. package/dist/esm/data/define.js.map +1 -0
  164. package/dist/esm/data/error.d.ts +60 -0
  165. package/dist/esm/data/error.js +178 -0
  166. package/dist/esm/data/error.js.map +1 -0
  167. package/dist/esm/data/index.d.ts +21 -0
  168. package/dist/esm/data/index.js +18 -0
  169. package/dist/esm/data/index.js.map +1 -0
  170. package/dist/esm/data/schema.d.ts +82 -0
  171. package/dist/esm/data/schema.js +596 -0
  172. package/dist/esm/data/schema.js.map +1 -0
  173. package/dist/esm/data/sort.d.ts +8 -0
  174. package/dist/esm/data/sort.js +18 -0
  175. package/dist/esm/data/sort.js.map +1 -0
  176. package/dist/esm/files.d.ts +67 -0
  177. package/dist/esm/files.js +113 -0
  178. package/dist/esm/files.js.map +1 -0
  179. package/dist/esm/framework-scope.d.ts +1 -0
  180. package/dist/esm/framework-scope.js +11 -0
  181. package/dist/esm/framework-scope.js.map +1 -0
  182. package/dist/esm/index.d.ts +14 -0
  183. package/dist/esm/index.js +10 -0
  184. package/dist/esm/index.js.map +1 -0
  185. package/dist/esm/mq/broker.d.ts +65 -0
  186. package/dist/esm/mq/broker.js +109 -0
  187. package/dist/esm/mq/broker.js.map +1 -0
  188. package/dist/esm/mq/client.d.ts +37 -0
  189. package/dist/esm/mq/client.js +314 -0
  190. package/dist/esm/mq/client.js.map +1 -0
  191. package/dist/esm/mq/index.d.ts +5 -0
  192. package/dist/esm/mq/index.js +3 -0
  193. package/dist/esm/mq/index.js.map +1 -0
  194. package/dist/esm/mq/types.d.ts +48 -0
  195. package/dist/esm/mq/types.js +2 -0
  196. package/dist/esm/mq/types.js.map +1 -0
  197. package/dist/esm/openapi/api.generated.d.ts +820 -0
  198. package/dist/esm/openapi/api.generated.js +603 -0
  199. package/dist/esm/openapi/api.generated.js.map +1 -0
  200. package/dist/esm/openapi/client.d.ts +56 -0
  201. package/dist/esm/openapi/client.js +210 -0
  202. package/dist/esm/openapi/client.js.map +1 -0
  203. package/dist/esm/openapi/codecs.generated.d.ts +2234 -0
  204. package/dist/esm/openapi/codecs.generated.js +3 -0
  205. package/dist/esm/openapi/codecs.generated.js.map +1 -0
  206. package/dist/esm/openapi/index.d.ts +5 -0
  207. package/dist/esm/openapi/index.js +3 -0
  208. package/dist/esm/openapi/index.js.map +1 -0
  209. package/dist/esm/openapi/types.generated.d.ts +3227 -0
  210. package/dist/esm/openapi/types.generated.js +2 -0
  211. package/dist/esm/openapi/types.generated.js.map +1 -0
  212. package/dist/esm/package.json +1 -0
  213. package/dist/esm/react.d.ts +9 -0
  214. package/dist/esm/react.js +12 -0
  215. package/dist/esm/react.js.map +1 -0
  216. package/dist/esm/runtime-context.d.ts +9 -0
  217. package/dist/esm/runtime-context.js +22 -0
  218. package/dist/esm/runtime-context.js.map +1 -0
  219. package/dist/esm/runtime-env.d.ts +1 -0
  220. package/dist/esm/runtime-env.js +15 -0
  221. package/dist/esm/runtime-env.js.map +1 -0
  222. package/dist/esm/source.d.ts +39 -0
  223. package/dist/esm/source.js +25 -0
  224. package/dist/esm/source.js.map +1 -0
  225. package/dist/esm/stream.d.ts +40 -0
  226. package/dist/esm/stream.js +29 -0
  227. package/dist/esm/stream.js.map +1 -0
  228. package/dist/esm/uns-v2/client.d.ts +54 -0
  229. package/dist/esm/uns-v2/client.js +170 -0
  230. package/dist/esm/uns-v2/client.js.map +1 -0
  231. package/dist/esm/uns-v2/codec.d.ts +11 -0
  232. package/dist/esm/uns-v2/codec.js +284 -0
  233. package/dist/esm/uns-v2/codec.js.map +1 -0
  234. package/dist/esm/uns-v2/data-client.d.ts +10 -0
  235. package/dist/esm/uns-v2/data-client.js +14 -0
  236. package/dist/esm/uns-v2/data-client.js.map +1 -0
  237. package/dist/esm/uns-v2/generated.d.ts +15551 -0
  238. package/dist/esm/uns-v2/generated.js +136 -0
  239. package/dist/esm/uns-v2/generated.js.map +1 -0
  240. package/dist/esm/uns-v2/index.d.ts +5 -0
  241. package/dist/esm/uns-v2/index.js +5 -0
  242. package/dist/esm/uns-v2/index.js.map +1 -0
  243. package/dist/esm/vue.d.ts +9 -0
  244. package/dist/esm/vue.js +36 -0
  245. package/dist/esm/vue.js.map +1 -0
  246. package/docs/acceptance-2026-10-22.md +88 -0
  247. package/package.json +242 -4
  248. package/skills/tier0-sdk-v2/SKILL.md +66 -0
  249. package/skills/tier0-sdk-v2/references/integration.md +72 -0
  250. package/skills/tier0-sdk-v2-agent/SKILL.md +73 -0
  251. package/skills/tier0-sdk-v2-agent/references/results.md +45 -0
  252. package/skills/tier0-sdk-v2-controls/SKILL.md +63 -0
  253. package/skills/tier0-sdk-v2-data/SKILL.md +57 -0
  254. package/skills/tier0-sdk-v2-data/references/consistency.md +70 -0
  255. package/skills/tier0-sdk-v2-data/references/errors.md +69 -0
  256. package/skills/tier0-sdk-v2-data/references/modeling.md +77 -0
  257. package/skills/tier0-sdk-v2-data/references/read-write.md +72 -0
  258. package/skills/tier0-sdk-v2-data/references/schema-evolution.md +36 -0
  259. package/skills/tier0-sdk-v2-files/SKILL.md +85 -0
  260. package/skills/tier0-sdk-v2-files/references/delete.md +22 -0
  261. package/skills/tier0-sdk-v2-files/references/download.md +49 -0
  262. package/skills/tier0-sdk-v2-files/references/multipart.md +42 -0
  263. package/skills/tier0-sdk-v2-files/references/upload.md +27 -0
  264. package/skills/tier0-sdk-v2-files/references/url.md +22 -0
  265. package/skills/tier0-sdk-v2-members/SKILL.md +56 -0
  266. package/skills/tier0-sdk-v2-members/references/app-members.md +41 -0
  267. package/skills/tier0-sdk-v2-members/references/platform-members.md +56 -0
  268. package/skills/tier0-sdk-v2-mq/SKILL.md +78 -0
  269. package/skills/tier0-sdk-v2-mq/references/quickstart.md +69 -0
  270. package/skills/tier0-sdk-v2-notifications/SKILL.md +42 -0
  271. package/skills/tier0-sdk-v2-notifications/references/get.md +34 -0
  272. package/skills/tier0-sdk-v2-notifications/references/send.md +72 -0
  273. package/skills/tier0-sdk-v2-source/SKILL.md +38 -0
  274. package/skills/tier0-sdk-v2-source/references/changes.md +40 -0
  275. package/skills/tier0-sdk-v2-source/references/create.md +63 -0
  276. package/skills/tier0-sdk-v2-source/references/delete.md +47 -0
  277. package/skills/tier0-sdk-v2-source/references/protocols.md +36 -0
  278. package/skills/tier0-sdk-v2-source/references/read.md +34 -0
  279. package/skills/tier0-sdk-v2-source/references/state.md +37 -0
  280. package/skills/tier0-sdk-v2-source/references/update.md +61 -0
  281. package/skills/tier0-sdk-v2-stream/SKILL.md +43 -0
  282. package/skills/tier0-sdk-v2-stream/references/create.md +55 -0
  283. package/skills/tier0-sdk-v2-stream/references/delete.md +35 -0
  284. package/skills/tier0-sdk-v2-stream/references/deploy.md +63 -0
  285. package/skills/tier0-sdk-v2-stream/references/lifecycle.md +25 -0
  286. package/skills/tier0-sdk-v2-stream/references/read.md +35 -0
  287. package/skills/tier0-sdk-v2-stream/references/update.md +35 -0
  288. package/skills/tier0-sdk-v2-system/SKILL.md +64 -0
  289. package/skills/tier0-sdk-v2-system/references/info.md +23 -0
  290. package/skills/tier0-sdk-v2-system/references/whoami.md +21 -0
  291. package/skills/tier0-sdk-v2-uns/SKILL.md +53 -0
  292. package/skills/tier0-sdk-v2-uns/references/create.md +85 -0
  293. package/skills/tier0-sdk-v2-uns/references/data-workflows.md +73 -0
  294. package/skills/tier0-sdk-v2-uns/references/delete.md +69 -0
  295. package/skills/tier0-sdk-v2-uns/references/namespace.md +75 -0
  296. package/skills/tier0-sdk-v2-uns/references/read.md +32 -0
  297. package/skills/tier0-sdk-v2-uns/references/restore.md +41 -0
  298. package/skills/tier0-sdk-v2-uns/references/update.md +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/mq/broker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * MQTT broker 地址归一化工具。\r\n *\r\n * 平台 `/openapi/v1/info` 返回的 `mqttBroker` 格式随环境变化,不保证统一:\r\n * - enterprise:env 为空时后端兜底返回 `tcp://<host>:1883`(面向边缘/服务端客户端的连接串);\r\n * - SaaS(Tier0 Cloud):env 原样透传,常见为 `host:port` 或裸 `host`。\r\n *\r\n * 浏览器 wss 客户端不应直接把它当 hostname 拼 URL(会得到 `wss://tcp://...`\r\n * 这类非法地址),先经本模块解析/推导,再交给 `Tier0MQClient`。\r\n */\r\n\r\n/** 解析后的 broker 端点。hostname 保证为裸主机(无 scheme、无端口、无路径)。 */\r\nexport interface MqttBrokerEndpoint {\r\n /** 裸主机名(已剥离 scheme/path/query,不含端口)。 */\r\n hostname: string;\r\n /**\r\n * 原始端口。注意:对 `tcp://host:1883` 这是 **tcp 端口**,浏览器 wss 场景\r\n * 不能直接沿用(wss 通常是 8084),由 `toWebSocketUrl` 的 `wssPort` 决定。\r\n */\r\n port?: number;\r\n /** 原始 scheme(tcp/mqtt/mqtts/ws/wss/...),裸 host 输入时为 undefined。 */\r\n scheme?: string;\r\n}\r\n\r\nconst SCHEME_RE = /^([a-zA-Z][a-zA-Z0-9+.-]*):\\/\\//;\r\n\r\n/**\r\n * 解析各种形态的 broker 字符串为结构化端点。\r\n *\r\n * 兼容输入:`tcp://host:1883`、`mqtts://host:8883`、`wss://host:8084/mqtt`、\r\n * `host:1883`、裸 `host`。无法解析(空串、非法 URL)返回 undefined。\r\n */\r\nexport function parseMqttBroker(broker?: string | null): MqttBrokerEndpoint | undefined {\r\n const raw = broker?.trim();\r\n if (!raw) return undefined;\r\n\r\n if (SCHEME_RE.test(raw)) {\r\n try {\r\n const u = new URL(raw);\r\n if (!u.hostname) return undefined;\r\n const scheme = SCHEME_RE.exec(raw)?.[1]?.toLowerCase();\r\n return {\r\n hostname: u.hostname,\r\n port: u.port ? Number.parseInt(u.port, 10) : undefined,\r\n scheme,\r\n };\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n // 无 scheme:`host:port` 或裸 `host`;含路径/空白的是垃圾输入,拒绝\r\n if (/[\\s/]/.test(raw)) return undefined;\r\n const i = raw.lastIndexOf(':');\r\n if (i > 0 && /^\\d+$/.test(raw.slice(i + 1))) {\r\n const hostname = raw.slice(0, i);\r\n if (!hostname) return undefined;\r\n return { hostname, port: Number.parseInt(raw.slice(i + 1), 10) };\r\n }\r\n return { hostname: raw };\r\n}\r\n\r\n/** 浏览器 wss 默认端口(与平台 OS_MQTT_WEBSOCKET_TSL_PORT 默认值一致)。 */\r\nexport const DEFAULT_WSS_PORT = 8084;\r\n/** MQTT over WebSocket 路径。 */\r\nexport const DEFAULT_WS_PATH = '/mqtt';\r\n\r\nexport interface ToWebSocketUrlOptions {\r\n /** wss 端口,默认 {@link DEFAULT_WSS_PORT}(8084)。 */\r\n wssPort?: number;\r\n /**\r\n * 显式指定 ws(false)/wss(true)。缺省自适应:浏览器 https 页面用 wss,\r\n * 或 WebSocket 端口为 8084 时用 wss,其余用 ws。\r\n */\r\n secure?: boolean;\r\n}\r\n\r\n/**\r\n * 当前运行环境是否处于 https 安全上下文。\r\n *\r\n * 用 `globalThis.location` 而不是 `window.location`:Web Worker\r\n * (dedicated/shared)里 `window` 不存在,但 `location.protocol` 同样是 `https:`,\r\n * 应同等视为安全上下文(否则会被降级为 ws 而被浏览器按 mixed content 拦截)。\r\n */\r\nexport function isBrowserHttps(): boolean {\r\n const loc = (globalThis as { location?: { protocol?: string } }).location;\r\n return typeof loc?.protocol === 'string' && loc.protocol === 'https:';\r\n}\r\n\r\n/**\r\n * 把 `mqttBroker`(或 {@link MqttBrokerEndpoint})推导为可直接传给\r\n * `Tier0MQClient` 的 WebSocket URL。\r\n *\r\n * 规则:\r\n * - 输入已是 `ws(s)://` URL:原样归一(补 `/mqtt` 路径,端口、path、query 均保留);\r\n * - 输入 `tcp://host:1883` / `host:port` / 裸 `host`:按 `secure` 推导 scheme,\r\n * 端口一律用 `wssPort`(8084),**不沿用** tcp 端口;\r\n * - 输入为空/无法解析:返回 undefined(调用方应回退或报错,勿硬拼 URL)。\r\n *\r\n * @example\r\n * toWebSocketUrl('tcp://example.tier0.dev:1883', { secure: true });\r\n * // → 'wss://example.tier0.dev:8084/mqtt'\r\n */\r\nexport function toWebSocketUrl(\r\n broker: string | MqttBrokerEndpoint | undefined | null,\r\n opts: ToWebSocketUrlOptions = {},\r\n): string | undefined {\r\n if (broker == null || broker === '') return undefined;\r\n\r\n // 已是 ws(s) URL:解析后归一直通(保留其 scheme/端口/path/query,仅补 /mqtt 路径)\r\n if (typeof broker === 'string' && /^wss?:\\/\\//i.test(broker.trim())) {\r\n try {\r\n const u = new URL(broker.trim());\r\n if (!u.hostname) return undefined;\r\n if (!u.pathname || u.pathname === '/') {\r\n u.pathname = DEFAULT_WS_PATH;\r\n }\r\n return u.toString();\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n const endpoint = typeof broker === 'string' ? parseMqttBroker(broker) : broker;\r\n if (!endpoint?.hostname) return undefined;\r\n\r\n // ws(s) 端点:保留其 scheme 与端口(\"已是 WebSocket 地址\"的直通语义)\r\n if (endpoint.scheme === 'ws' || endpoint.scheme === 'wss') {\r\n const port = endpoint.port ? `:${endpoint.port}` : '';\r\n return `${endpoint.scheme}://${endpoint.hostname}${port}${DEFAULT_WS_PATH}`;\r\n }\r\n\r\n const port = opts.wssPort ?? DEFAULT_WSS_PORT;\r\n const secure = opts.secure ?? (isBrowserHttps() || port === DEFAULT_WSS_PORT);\r\n return `${secure ? 'wss' : 'ws'}://${endpoint.hostname}:${port}${DEFAULT_WS_PATH}`;\r\n}\r\n"]}
@@ -0,0 +1,37 @@
1
+ import type { MQTTConfig, MQTTEventMap } from './types.js';
2
+ /**
3
+ * 消息回调。公开类型保持 `void` 返回,以兼容 async handler、`push()` 简写等
4
+ * 既有写法;运行时额外识别返回值:handler 返回严格的 `false` 视为下游停滞
5
+ * (背压),SDK 会统计连续背压次数,配合 MQTTConfig.maxBackpressuredDeliveries
6
+ * 可在阈值内自动移除订阅。
7
+ */
8
+ export type TopicHandler = (topic: string, payload: string) => void;
9
+ export declare class Tier0MQClient {
10
+ private client;
11
+ private config;
12
+ private explicitClientId;
13
+ private explicitUsername;
14
+ private listeners;
15
+ private subscriptions;
16
+ private connectingPromise;
17
+ private _connected;
18
+ constructor(config?: MQTTConfig);
19
+ private get mqttUrl();
20
+ private ensureConnected;
21
+ private doConnect;
22
+ connect(config?: MQTTConfig): Promise<void>;
23
+ subscribe(topic: string, handler: TopicHandler): void;
24
+ unsubscribe(topic: string, handler?: TopicHandler): void;
25
+ publish(topic: string, payload: string | object, options?: {
26
+ qos?: number;
27
+ retain?: boolean;
28
+ }): Promise<void>;
29
+ disconnect(): void;
30
+ on<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void;
31
+ off<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void;
32
+ private emit;
33
+ private resubscribeAll;
34
+ private topicMatch;
35
+ get isConnected(): boolean;
36
+ get subscribedTopics(): string[];
37
+ }
@@ -0,0 +1,314 @@
1
+ import mqtt from 'mqtt';
2
+ import { getEnvVar } from '../runtime-env.js';
3
+ import { DEFAULT_WSS_PORT, isBrowserHttps, parseMqttBroker, toWebSocketUrl } from './broker.js';
4
+ function parseWorkspaceIDFromApiKey(apiKey) {
5
+ // Match the backend's sk-<type>-ws<base36>_<secret> contract, not only
6
+ // service keys. Other workspace-encoded keys use the same MQTT identity.
7
+ const match = /^sk-[^-]+-ws([0-9a-zA-Z]+)_.+$/.exec(apiKey.trim());
8
+ if (!match)
9
+ return undefined;
10
+ // Keep the int64 workspace ID exact; parseInt can round IDs above 2^53.
11
+ let workspaceID = 0n;
12
+ for (const digit of match[1]) {
13
+ workspaceID = workspaceID * 36n + BigInt(parseInt(digit, 36));
14
+ if (workspaceID > 9223372036854775807n)
15
+ return undefined;
16
+ }
17
+ return workspaceID > 0n ? workspaceID.toString() : undefined;
18
+ }
19
+ function generateRandomString(length = 8) {
20
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
21
+ let result = '';
22
+ for (let i = 0; i < length; i++) {
23
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
24
+ }
25
+ return result;
26
+ }
27
+ export class Tier0MQClient {
28
+ client = null;
29
+ config;
30
+ explicitClientId;
31
+ explicitUsername;
32
+ listeners = {};
33
+ subscriptions = [];
34
+ connectingPromise = null;
35
+ _connected = false;
36
+ constructor(config) {
37
+ this.explicitClientId = config?.clientId !== undefined;
38
+ this.explicitUsername = config?.username !== undefined;
39
+ const envHost = getEnvVar('TIER0_MQTT_HOST');
40
+ const envPort = getEnvVar('TIER0_MQTT_PORT');
41
+ const host = config?.host || envHost || '';
42
+ const port = config?.port || parseInt(envPort || '8084') || 8084;
43
+ const password = config?.password || getEnvVar('TIER0_API_KEY') || '';
44
+ // 从 apiKey 解析 workspaceID,自动生成 clientId 和 username
45
+ const workspaceID = config?.clientId && config?.username
46
+ ? undefined
47
+ : parseWorkspaceIDFromApiKey(password);
48
+ const autoClientId = workspaceID
49
+ ? `${workspaceID}&${generateRandomString(8)}`
50
+ : undefined;
51
+ const autoUsername = workspaceID
52
+ ? `${workspaceID}&open`
53
+ : undefined;
54
+ this.config = {
55
+ host,
56
+ port,
57
+ clientId: config?.clientId || autoClientId,
58
+ username: config?.username || autoUsername,
59
+ password,
60
+ keepAlive: config?.keepAlive ?? 60,
61
+ reconnectPeriod: config?.reconnectPeriod ?? 5000,
62
+ connectTimeout: config?.connectTimeout ?? 30000,
63
+ clean: config?.clean ?? true,
64
+ ...config,
65
+ };
66
+ }
67
+ get mqttUrl() {
68
+ const { host, port, secure } = this.config;
69
+ if (!host) {
70
+ throw new Error('MQTT host is required. Provide it via MQTTConfig or TIER0_MQTT_HOST environment variable.');
71
+ }
72
+ const normalizedHost = host.trim().replace(/\/+$/, '');
73
+ if (/^wss?:\/\//i.test(normalizedHost)) {
74
+ const url = toWebSocketUrl(normalizedHost);
75
+ if (!url)
76
+ throw new TypeError('Invalid MQTT WebSocket URL');
77
+ return url;
78
+ }
79
+ // 裸 host(可含端口):按运行环境自适应 ws/wss
80
+ const endpoint = parseMqttBroker(normalizedHost);
81
+ const hostname = endpoint?.hostname ?? normalizedHost;
82
+ // 裸 host:port 和 ws(s) URL 的端口按 WebSocket 端口处理;
83
+ // tcp/mqtt/mqtts 的端口是 TCP 端口(如 1883),wss 下不能沿用,回退到配置的 port
84
+ const effectivePort = !endpoint?.scheme || endpoint.scheme === 'ws' || endpoint.scheme === 'wss'
85
+ ? endpoint?.port ?? port
86
+ : port;
87
+ const useSecure = secure ?? (isBrowserHttps() || effectivePort === DEFAULT_WSS_PORT);
88
+ return `${useSecure ? 'wss' : 'ws'}://${hostname}:${effectivePort}/mqtt`;
89
+ }
90
+ // 内部确保已连接(懒连接)
91
+ async ensureConnected() {
92
+ if (this._connected)
93
+ return;
94
+ if (this.connectingPromise)
95
+ return this.connectingPromise;
96
+ void this.mqttUrl;
97
+ if (!this.config.password || !this.config.username || !this.config.clientId) {
98
+ throw new Error('Tier0 SDK v2: provide a workspace-encoded API key or explicit MQTT username, clientId and password.');
99
+ }
100
+ this.connectingPromise = this.doConnect();
101
+ return this.connectingPromise;
102
+ }
103
+ doConnect() {
104
+ return new Promise((resolve, reject) => {
105
+ const options = {
106
+ clientId: this.config.clientId,
107
+ username: this.config.username,
108
+ password: this.config.password,
109
+ keepalive: this.config.keepAlive,
110
+ reconnectPeriod: this.config.reconnectPeriod,
111
+ connectTimeout: this.config.connectTimeout,
112
+ clean: this.config.clean,
113
+ };
114
+ this.client = mqtt.connect(this.mqttUrl, options);
115
+ this.client.on('connect', () => {
116
+ this._connected = true;
117
+ this.connectingPromise = null;
118
+ this.emit('connect');
119
+ // 断连重连后自动恢复所有订阅
120
+ this.resubscribeAll();
121
+ resolve();
122
+ });
123
+ this.client.on('error', (err) => {
124
+ this.emit('error', err);
125
+ this.connectingPromise = null;
126
+ reject(err);
127
+ });
128
+ this.client.on('disconnect', () => {
129
+ this._connected = false;
130
+ this.emit('disconnect');
131
+ });
132
+ this.client.on('close', () => {
133
+ this._connected = false;
134
+ });
135
+ this.client.on('message', (topic, payload, _packet) => {
136
+ const payloadStr = payload.toString();
137
+ // 复制一份快照:handler 触发背压自动退订时会重建 this.subscriptions
138
+ this.subscriptions.slice().forEach((sub) => {
139
+ if (this.topicMatch(sub.topic, topic)) {
140
+ try {
141
+ // 公开类型为 void 返回(兼容 async/简写 handler),运行时仅识别严格的 false
142
+ const accepted = sub.handler(topic, payloadStr);
143
+ if (accepted === false) {
144
+ sub.backpressuredCount = (sub.backpressuredCount ?? 0) + 1;
145
+ const limit = this.config.maxBackpressuredDeliveries ?? 0;
146
+ if (limit > 0 && sub.backpressuredCount >= limit) {
147
+ this.unsubscribe(sub.topic, sub.handler);
148
+ this.emit('subscriptionDropped', {
149
+ topic: sub.topic,
150
+ reason: `handler 连续 ${sub.backpressuredCount} 次返回背压(false),已按 maxBackpressuredDeliveries=${limit} 自动退订`,
151
+ });
152
+ }
153
+ }
154
+ else {
155
+ sub.backpressuredCount = 0;
156
+ }
157
+ }
158
+ catch (e) {
159
+ this.emit('error', e);
160
+ }
161
+ }
162
+ });
163
+ });
164
+ });
165
+ }
166
+ // 显式连接(需要等待连接完成时使用)
167
+ async connect(config) {
168
+ if (config) {
169
+ const previousPassword = this.config.password;
170
+ this.config = { ...this.config, ...config };
171
+ if (config.clientId !== undefined)
172
+ this.explicitClientId = true;
173
+ if (config.username !== undefined)
174
+ this.explicitUsername = true;
175
+ // A connect-time key may belong to a different workspace. Preserve only
176
+ // caller-supplied identity fields, not values derived from the previous key.
177
+ if (config.password !== undefined && config.password !== previousPassword) {
178
+ const workspaceID = parseWorkspaceIDFromApiKey(config.password);
179
+ if (!this.explicitClientId) {
180
+ this.config.clientId = workspaceID ? workspaceID + '&' + generateRandomString(8) : undefined;
181
+ }
182
+ if (!this.explicitUsername)
183
+ this.config.username = workspaceID ? workspaceID + '&open' : undefined;
184
+ }
185
+ }
186
+ return this.ensureConnected();
187
+ }
188
+ // 订阅 topic,内部 qos 固定为 1,handler 接收 (topic, payload)
189
+ // 无需先调用 connect(),自动处理连接
190
+ subscribe(topic, handler) {
191
+ // 避免重复注册同一 topic 的同一 handler
192
+ const exists = this.subscriptions.some((s) => s.topic === topic && s.handler === handler);
193
+ if (exists) {
194
+ return;
195
+ }
196
+ this.subscriptions.push({ topic, handler });
197
+ if (this._connected && this.client) {
198
+ this.client.subscribe(topic, { qos: 1 }, (err) => {
199
+ if (err) {
200
+ this.emit('error', err);
201
+ // 订阅失败时回滚
202
+ this.subscriptions = this.subscriptions.filter((s) => !(s.topic === topic && s.handler === handler));
203
+ }
204
+ });
205
+ }
206
+ else {
207
+ // 未连接时触发懒连接,连接成功后 resubscribeAll 会自动 subscribe
208
+ this.ensureConnected().catch((err) => this.emit('error', err));
209
+ }
210
+ }
211
+ // 取消订阅:如果提供了 handler 则仅移除该 handler,否则移除该 topic 下所有 handler
212
+ unsubscribe(topic, handler) {
213
+ if (handler) {
214
+ this.subscriptions = this.subscriptions.filter((s) => !(s.topic === topic && s.handler === handler));
215
+ }
216
+ else {
217
+ this.subscriptions = this.subscriptions.filter((s) => s.topic !== topic);
218
+ }
219
+ if (!this.client)
220
+ return;
221
+ // 如果该 topic 下已无任何 handler,则向 broker 发送 unsubscribe
222
+ const stillHasHandler = this.subscriptions.some((s) => s.topic === topic);
223
+ if (!stillHasHandler) {
224
+ this.client.unsubscribe(topic, (err) => {
225
+ if (err) {
226
+ this.emit('error', err);
227
+ }
228
+ });
229
+ }
230
+ }
231
+ // 发布消息,无需先调用 connect(),内部自动处理连接
232
+ async publish(topic, payload, options) {
233
+ await this.ensureConnected();
234
+ const message = typeof payload === 'string' ? payload : JSON.stringify(payload);
235
+ this.client.publish(topic, message, {
236
+ qos: (options?.qos ?? 0),
237
+ retain: options?.retain ?? false,
238
+ });
239
+ }
240
+ disconnect() {
241
+ if (!this.client)
242
+ return;
243
+ this.client.end(true, () => {
244
+ this.emit('disconnect');
245
+ });
246
+ this.client = null;
247
+ this._connected = false;
248
+ this.connectingPromise = null;
249
+ this.subscriptions = [];
250
+ }
251
+ on(event, handler) {
252
+ if (!this.listeners[event]) {
253
+ this.listeners[event] = [];
254
+ }
255
+ this.listeners[event].push(handler);
256
+ }
257
+ off(event, handler) {
258
+ const handlers = this.listeners[event];
259
+ if (!handlers)
260
+ return;
261
+ const idx = handlers.indexOf(handler);
262
+ if (idx !== -1) {
263
+ handlers.splice(idx, 1);
264
+ }
265
+ }
266
+ emit(event, ...args) {
267
+ const handlers = this.listeners[event];
268
+ if (!handlers)
269
+ return;
270
+ handlers.forEach((h) => h(...args));
271
+ }
272
+ // 断连后自动重新订阅所有已注册的 topic
273
+ resubscribeAll() {
274
+ if (!this.client)
275
+ return;
276
+ // 按 topic 去重,每个 topic 只订阅一次
277
+ const uniqueTopics = Array.from(new Set(this.subscriptions.map((s) => s.topic)));
278
+ uniqueTopics.forEach((topic) => {
279
+ this.client.subscribe(topic, { qos: 1 }, (err) => {
280
+ if (err) {
281
+ this.emit('error', err);
282
+ }
283
+ });
284
+ });
285
+ }
286
+ // 判断接收到的 topic 是否匹配订阅的 topic(支持通配符 # 和 +)
287
+ topicMatch(subscribed, received) {
288
+ const subParts = subscribed.split('/');
289
+ const recParts = received.split('/');
290
+ for (let i = 0; i < subParts.length; i++) {
291
+ const sp = subParts[i];
292
+ const rp = recParts[i];
293
+ if (sp === '#') {
294
+ // # 必须是最后一个层级,匹配后面所有
295
+ return true;
296
+ }
297
+ if (sp === '+') {
298
+ // + 匹配单个层级
299
+ continue;
300
+ }
301
+ if (sp !== rp) {
302
+ return false;
303
+ }
304
+ }
305
+ return subParts.length === recParts.length;
306
+ }
307
+ get isConnected() {
308
+ return this._connected;
309
+ }
310
+ get subscribedTopics() {
311
+ return Array.from(new Set(this.subscriptions.map((s) => s.topic)));
312
+ }
313
+ }
314
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/mq/client.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAWhG,SAAS,0BAA0B,CAAC,MAAc;IAChD,uEAAuE;IACvE,yEAAyE;IACzE,MAAM,KAAK,GAAG,gCAAgC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAE7B,wEAAwE;IACxE,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,WAAW,GAAG,WAAW,GAAG,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9D,IAAI,WAAW,GAAG,oBAAoB;YAAE,OAAO,SAAS,CAAC;IAC3D,CAAC;IACD,OAAO,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAM,GAAG,CAAC;IACtC,MAAM,KAAK,GAAG,sCAAsC,CAAC;IACrD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AASD,MAAM,OAAO,aAAa;IAChB,MAAM,GAAsB,IAAI,CAAC;IACjC,MAAM,CAAa;IACnB,gBAAgB,CAAU;IAC1B,gBAAgB,CAAU;IAC1B,SAAS,GAA2D,EAAE,CAAC;IACvE,aAAa,GAAmB,EAAE,CAAC;IACnC,iBAAiB,GAAyB,IAAI,CAAC;IAC/C,UAAU,GAAG,KAAK,CAAC;IAE3B,YAAY,MAAmB;QAC7B,IAAI,CAAC,gBAAgB,GAAG,MAAM,EAAE,QAAQ,KAAK,SAAS,CAAC;QACvD,IAAI,CAAC,gBAAgB,GAAG,MAAM,EAAE,QAAQ,KAAK,SAAS,CAAC;QACvD,MAAM,OAAO,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAE7C,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,OAAO,IAAI,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,QAAQ,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC;QACjE,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;QAEtE,mDAAmD;QACnD,MAAM,WAAW,GAAG,MAAM,EAAE,QAAQ,IAAI,MAAM,EAAE,QAAQ;YACtD,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;QAEzC,MAAM,YAAY,GAAG,WAAW;YAC9B,CAAC,CAAC,GAAG,WAAW,IAAI,oBAAoB,CAAC,CAAC,CAAC,EAAE;YAC7C,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,YAAY,GAAG,WAAW;YAC9B,CAAC,CAAC,GAAG,WAAW,OAAO;YACvB,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,CAAC,MAAM,GAAG;YACZ,IAAI;YACJ,IAAI;YACJ,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,YAAY;YAC1C,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,YAAY;YAC1C,QAAQ;YACR,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,EAAE;YAClC,eAAe,EAAE,MAAM,EAAE,eAAe,IAAI,IAAI;YAChD,cAAc,EAAE,MAAM,EAAE,cAAc,IAAI,KAAK;YAC/C,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;YAC5B,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAED,IAAY,OAAO;QACjB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,SAAS,CAAC,4BAA4B,CAAC,CAAC;YAC5D,OAAO,GAAG,CAAC;QACb,CAAC;QACD,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,QAAQ,EAAE,QAAQ,IAAI,cAAc,CAAC;QACtD,+CAA+C;QAC/C,2DAA2D;QAC3D,MAAM,aAAa,GACjB,CAAC,QAAQ,EAAE,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK;YACxE,CAAC,CAAC,QAAQ,EAAE,IAAI,IAAI,IAAI;YACxB,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,IAAI,aAAa,KAAK,gBAAgB,CAAC,CAAC;QACrF,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,QAAQ,IAAI,aAAa,OAAO,CAAC;IAC3E,CAAC;IAED,eAAe;IACP,KAAK,CAAC,eAAe;QAC3B,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,IAAI,IAAI,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC,iBAAiB,CAAC;QAE1D,KAAK,IAAI,CAAC,OAAO,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC5E,MAAM,IAAI,KAAK,CAAC,qGAAqG,CAAC,CAAC;QACzH,CAAC;QAED,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IAEO,SAAS;QACf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,OAAO,GAAmB;gBAC9B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;gBAChC,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;gBAC5C,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc;gBAC1C,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;aACzB,CAAC;YAEF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAElD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACrB,gBAAgB;gBAChB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACtB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC9B,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;gBAChC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;gBACxB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBAC3B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YAC1B,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,SAAS,EACT,CAAC,KAAa,EAAE,OAAe,EAAE,OAA4B,EAAE,EAAE;gBAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACtC,iDAAiD;gBACjD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;oBACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;wBACtC,IAAI,CAAC;4BACH,qDAAqD;4BACrD,MAAM,QAAQ,GACZ,GAAG,CAAC,OACL,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;4BACrB,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gCACvB,GAAG,CAAC,kBAAkB,GAAG,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gCAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,IAAI,CAAC,CAAC;gCAC1D,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,kBAAkB,IAAI,KAAK,EAAE,CAAC;oCACjD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;oCACzC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;wCAC/B,KAAK,EAAE,GAAG,CAAC,KAAK;wCAChB,MAAM,EAAE,cAAc,GAAG,CAAC,kBAAkB,+CAA+C,KAAK,OAAO;qCACxG,CAAC,CAAC;gCACL,CAAC;4BACH,CAAC;iCAAM,CAAC;gCACN,GAAG,CAAC,kBAAkB,GAAG,CAAC,CAAC;4BAC7B,CAAC;wBACH,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAU,CAAC,CAAC;wBACjC,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,oBAAoB;IACpB,KAAK,CAAC,OAAO,CAAC,MAAmB;QAC/B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YAC9C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;YAC5C,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;gBAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAChE,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;gBAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAChE,wEAAwE;YACxE,6EAA6E;YAC7E,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;gBAC1E,MAAM,WAAW,GAAG,0BAA0B,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAChE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC/F,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,gBAAgB;oBAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YACrG,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAChC,CAAC;IAED,oDAAoD;IACpD,yBAAyB;IACzB,SAAS,CAAC,KAAa,EAAE,OAAqB;QAC5C,6BAA6B;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAClD,CAAC;QACF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAc,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC5D,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;oBACxB,UAAU;oBACV,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CACrD,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,+CAA+C;YAC/C,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,WAAW,CAAC,KAAa,EAAE,OAAsB;QAC/C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CACrD,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAC3E,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,mDAAmD;QACnD,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QAC1E,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACrC,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,OAAO,CACX,KAAa,EACb,OAAwB,EACxB,OAA4C;QAE5C,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAE7B,MAAM,OAAO,GACX,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClE,IAAI,CAAC,MAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE;YACnC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAc;YACrC,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACjC,CAAC,CAAC;IACL,CAAC;IAED,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE;YACzB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,EAAE,CAA+B,KAAQ,EAAE,OAAwB;QACjE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,GAAG,CAA+B,KAAQ,EAAE,OAAwB;QAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAEO,IAAI,CACV,KAAQ,EACR,GAAG,IAAiC;QAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAS,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,wBAAwB;IAChB,cAAc;QACpB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,4BAA4B;QAC5B,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAC7B,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAChD,CAAC;QACF,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7B,IAAI,CAAC,MAAO,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAc,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC7D,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0CAA0C;IAClC,UAAU,CAAC,UAAkB,EAAE,QAAgB;QACrD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAEvB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACf,qBAAqB;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACf,WAAW;gBACX,SAAS;YACX,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;IAC7C,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;CACF","sourcesContent":["import mqtt from 'mqtt';\r\nimport type { MqttClient, IClientOptions } from 'mqtt';\r\nimport { getEnvVar } from '../runtime-env.js';\r\nimport { DEFAULT_WSS_PORT, isBrowserHttps, parseMqttBroker, toWebSocketUrl } from './broker.js';\r\nimport type { MQTTConfig, MQTTEventMap } from './types.js';\r\n\r\n/**\r\n * 消息回调。公开类型保持 `void` 返回,以兼容 async handler、`push()` 简写等\r\n * 既有写法;运行时额外识别返回值:handler 返回严格的 `false` 视为下游停滞\r\n * (背压),SDK 会统计连续背压次数,配合 MQTTConfig.maxBackpressuredDeliveries\r\n * 可在阈值内自动移除订阅。\r\n */\r\nexport type TopicHandler = (topic: string, payload: string) => void;\r\n\r\nfunction parseWorkspaceIDFromApiKey(apiKey: string): string | undefined {\r\n // Match the backend's sk-<type>-ws<base36>_<secret> contract, not only\r\n // service keys. Other workspace-encoded keys use the same MQTT identity.\r\n const match = /^sk-[^-]+-ws([0-9a-zA-Z]+)_.+$/.exec(apiKey.trim());\r\n if (!match) return undefined;\r\n\r\n // Keep the int64 workspace ID exact; parseInt can round IDs above 2^53.\r\n let workspaceID = 0n;\r\n for (const digit of match[1]) {\r\n workspaceID = workspaceID * 36n + BigInt(parseInt(digit, 36));\r\n if (workspaceID > 9223372036854775807n) return undefined;\r\n }\r\n return workspaceID > 0n ? workspaceID.toString() : undefined;\r\n}\r\n\r\nfunction generateRandomString(length = 8): string {\r\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\r\n let result = '';\r\n for (let i = 0; i < length; i++) {\r\n result += chars.charAt(Math.floor(Math.random() * chars.length));\r\n }\r\n return result;\r\n}\r\n\r\ninterface Subscription {\r\n topic: string;\r\n handler: TopicHandler;\r\n /** handler 连续返回 false(背压)的次数,正常返回时清零。 */\r\n backpressuredCount?: number;\r\n}\r\n\r\nexport class Tier0MQClient {\r\n private client: MqttClient | null = null;\r\n private config: MQTTConfig;\r\n private explicitClientId: boolean;\r\n private explicitUsername: boolean;\r\n private listeners: { [K in keyof MQTTEventMap]?: Array<MQTTEventMap[K]> } = {};\r\n private subscriptions: Subscription[] = [];\r\n private connectingPromise: Promise<void> | null = null;\r\n private _connected = false;\r\n\r\n constructor(config?: MQTTConfig) {\r\n this.explicitClientId = config?.clientId !== undefined;\r\n this.explicitUsername = config?.username !== undefined;\r\n const envHost = getEnvVar('TIER0_MQTT_HOST');\r\n const envPort = getEnvVar('TIER0_MQTT_PORT');\r\n\r\n const host = config?.host || envHost || '';\r\n const port = config?.port || parseInt(envPort || '8084') || 8084;\r\n const password = config?.password || getEnvVar('TIER0_API_KEY') || '';\r\n\r\n // 从 apiKey 解析 workspaceID,自动生成 clientId 和 username\r\n const workspaceID = config?.clientId && config?.username\r\n ? undefined\r\n : parseWorkspaceIDFromApiKey(password);\r\n\r\n const autoClientId = workspaceID\r\n ? `${workspaceID}&${generateRandomString(8)}`\r\n : undefined;\r\n const autoUsername = workspaceID\r\n ? `${workspaceID}&open`\r\n : undefined;\r\n\r\n this.config = {\r\n host,\r\n port,\r\n clientId: config?.clientId || autoClientId,\r\n username: config?.username || autoUsername,\r\n password,\r\n keepAlive: config?.keepAlive ?? 60,\r\n reconnectPeriod: config?.reconnectPeriod ?? 5000,\r\n connectTimeout: config?.connectTimeout ?? 30000,\r\n clean: config?.clean ?? true,\r\n ...config,\r\n };\r\n }\r\n\r\n private get mqttUrl(): string {\r\n const { host, port, secure } = this.config;\r\n if (!host) {\r\n throw new Error(\r\n 'MQTT host is required. Provide it via MQTTConfig or TIER0_MQTT_HOST environment variable.'\r\n );\r\n }\r\n const normalizedHost = host.trim().replace(/\\/+$/, '');\r\n if (/^wss?:\\/\\//i.test(normalizedHost)) {\r\n const url = toWebSocketUrl(normalizedHost);\r\n if (!url) throw new TypeError('Invalid MQTT WebSocket URL');\r\n return url;\r\n }\r\n // 裸 host(可含端口):按运行环境自适应 ws/wss\r\n const endpoint = parseMqttBroker(normalizedHost);\r\n const hostname = endpoint?.hostname ?? normalizedHost;\r\n // 裸 host:port 和 ws(s) URL 的端口按 WebSocket 端口处理;\r\n // tcp/mqtt/mqtts 的端口是 TCP 端口(如 1883),wss 下不能沿用,回退到配置的 port\r\n const effectivePort =\r\n !endpoint?.scheme || endpoint.scheme === 'ws' || endpoint.scheme === 'wss'\r\n ? endpoint?.port ?? port\r\n : port;\r\n const useSecure = secure ?? (isBrowserHttps() || effectivePort === DEFAULT_WSS_PORT);\r\n return `${useSecure ? 'wss' : 'ws'}://${hostname}:${effectivePort}/mqtt`;\r\n }\r\n\r\n // 内部确保已连接(懒连接)\r\n private async ensureConnected(): Promise<void> {\r\n if (this._connected) return;\r\n if (this.connectingPromise) return this.connectingPromise;\r\n\r\n void this.mqttUrl;\r\n if (!this.config.password || !this.config.username || !this.config.clientId) {\r\n throw new Error('Tier0 SDK v2: provide a workspace-encoded API key or explicit MQTT username, clientId and password.');\r\n }\r\n\r\n this.connectingPromise = this.doConnect();\r\n return this.connectingPromise;\r\n }\r\n\r\n private doConnect(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const options: IClientOptions = {\r\n clientId: this.config.clientId,\r\n username: this.config.username,\r\n password: this.config.password,\r\n keepalive: this.config.keepAlive,\r\n reconnectPeriod: this.config.reconnectPeriod,\r\n connectTimeout: this.config.connectTimeout,\r\n clean: this.config.clean,\r\n };\r\n\r\n this.client = mqtt.connect(this.mqttUrl, options);\r\n\r\n this.client.on('connect', () => {\r\n this._connected = true;\r\n this.connectingPromise = null;\r\n this.emit('connect');\r\n // 断连重连后自动恢复所有订阅\r\n this.resubscribeAll();\r\n resolve();\r\n });\r\n\r\n this.client.on('error', (err) => {\r\n this.emit('error', err);\r\n this.connectingPromise = null;\r\n reject(err);\r\n });\r\n\r\n this.client.on('disconnect', () => {\r\n this._connected = false;\r\n this.emit('disconnect');\r\n });\r\n\r\n this.client.on('close', () => {\r\n this._connected = false;\r\n });\r\n\r\n this.client.on(\r\n 'message',\r\n (topic: string, payload: Buffer, _packet: mqtt.IPublishPacket) => {\r\n const payloadStr = payload.toString();\r\n // 复制一份快照:handler 触发背压自动退订时会重建 this.subscriptions\r\n this.subscriptions.slice().forEach((sub) => {\r\n if (this.topicMatch(sub.topic, topic)) {\r\n try {\r\n // 公开类型为 void 返回(兼容 async/简写 handler),运行时仅识别严格的 false\r\n const accepted = (\r\n sub.handler as (t: string, p: string) => unknown\r\n )(topic, payloadStr);\r\n if (accepted === false) {\r\n sub.backpressuredCount = (sub.backpressuredCount ?? 0) + 1;\r\n const limit = this.config.maxBackpressuredDeliveries ?? 0;\r\n if (limit > 0 && sub.backpressuredCount >= limit) {\r\n this.unsubscribe(sub.topic, sub.handler);\r\n this.emit('subscriptionDropped', {\r\n topic: sub.topic,\r\n reason: `handler 连续 ${sub.backpressuredCount} 次返回背压(false),已按 maxBackpressuredDeliveries=${limit} 自动退订`,\r\n });\r\n }\r\n } else {\r\n sub.backpressuredCount = 0;\r\n }\r\n } catch (e) {\r\n this.emit('error', e as Error);\r\n }\r\n }\r\n });\r\n }\r\n );\r\n });\r\n }\r\n\r\n // 显式连接(需要等待连接完成时使用)\r\n async connect(config?: MQTTConfig): Promise<void> {\r\n if (config) {\r\n const previousPassword = this.config.password;\r\n this.config = { ...this.config, ...config };\r\n if (config.clientId !== undefined) this.explicitClientId = true;\r\n if (config.username !== undefined) this.explicitUsername = true;\r\n // A connect-time key may belong to a different workspace. Preserve only\r\n // caller-supplied identity fields, not values derived from the previous key.\r\n if (config.password !== undefined && config.password !== previousPassword) {\r\n const workspaceID = parseWorkspaceIDFromApiKey(config.password);\r\n if (!this.explicitClientId) {\r\n this.config.clientId = workspaceID ? workspaceID + '&' + generateRandomString(8) : undefined;\r\n }\r\n if (!this.explicitUsername) this.config.username = workspaceID ? workspaceID + '&open' : undefined;\r\n }\r\n }\r\n return this.ensureConnected();\r\n }\r\n\r\n // 订阅 topic,内部 qos 固定为 1,handler 接收 (topic, payload)\r\n // 无需先调用 connect(),自动处理连接\r\n subscribe(topic: string, handler: TopicHandler): void {\r\n // 避免重复注册同一 topic 的同一 handler\r\n const exists = this.subscriptions.some(\r\n (s) => s.topic === topic && s.handler === handler\r\n );\r\n if (exists) {\r\n return;\r\n }\r\n\r\n this.subscriptions.push({ topic, handler });\r\n\r\n if (this._connected && this.client) {\r\n this.client.subscribe(topic, { qos: 1 as 0 | 1 | 2 }, (err) => {\r\n if (err) {\r\n this.emit('error', err);\r\n // 订阅失败时回滚\r\n this.subscriptions = this.subscriptions.filter(\r\n (s) => !(s.topic === topic && s.handler === handler)\r\n );\r\n }\r\n });\r\n } else {\r\n // 未连接时触发懒连接,连接成功后 resubscribeAll 会自动 subscribe\r\n this.ensureConnected().catch((err) => this.emit('error', err));\r\n }\r\n }\r\n\r\n // 取消订阅:如果提供了 handler 则仅移除该 handler,否则移除该 topic 下所有 handler\r\n unsubscribe(topic: string, handler?: TopicHandler): void {\r\n if (handler) {\r\n this.subscriptions = this.subscriptions.filter(\r\n (s) => !(s.topic === topic && s.handler === handler)\r\n );\r\n } else {\r\n this.subscriptions = this.subscriptions.filter((s) => s.topic !== topic);\r\n }\r\n\r\n if (!this.client) return;\r\n\r\n // 如果该 topic 下已无任何 handler,则向 broker 发送 unsubscribe\r\n const stillHasHandler = this.subscriptions.some((s) => s.topic === topic);\r\n if (!stillHasHandler) {\r\n this.client.unsubscribe(topic, (err) => {\r\n if (err) {\r\n this.emit('error', err);\r\n }\r\n });\r\n }\r\n }\r\n\r\n // 发布消息,无需先调用 connect(),内部自动处理连接\r\n async publish(\r\n topic: string,\r\n payload: string | object,\r\n options?: { qos?: number; retain?: boolean }\r\n ): Promise<void> {\r\n await this.ensureConnected();\r\n\r\n const message =\r\n typeof payload === 'string' ? payload : JSON.stringify(payload);\r\n this.client!.publish(topic, message, {\r\n qos: (options?.qos ?? 0) as 0 | 1 | 2,\r\n retain: options?.retain ?? false,\r\n });\r\n }\r\n\r\n disconnect(): void {\r\n if (!this.client) return;\r\n\r\n this.client.end(true, () => {\r\n this.emit('disconnect');\r\n });\r\n this.client = null;\r\n this._connected = false;\r\n this.connectingPromise = null;\r\n this.subscriptions = [];\r\n }\r\n\r\n on<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void {\r\n if (!this.listeners[event]) {\r\n this.listeners[event] = [];\r\n }\r\n this.listeners[event]!.push(handler);\r\n }\r\n\r\n off<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void {\r\n const handlers = this.listeners[event];\r\n if (!handlers) return;\r\n const idx = handlers.indexOf(handler);\r\n if (idx !== -1) {\r\n handlers.splice(idx, 1);\r\n }\r\n }\r\n\r\n private emit<K extends keyof MQTTEventMap>(\r\n event: K,\r\n ...args: Parameters<MQTTEventMap[K]>\r\n ): void {\r\n const handlers = this.listeners[event];\r\n if (!handlers) return;\r\n handlers.forEach((h) => (h as any)(...args));\r\n }\r\n\r\n // 断连后自动重新订阅所有已注册的 topic\r\n private resubscribeAll(): void {\r\n if (!this.client) return;\r\n\r\n // 按 topic 去重,每个 topic 只订阅一次\r\n const uniqueTopics = Array.from(\r\n new Set(this.subscriptions.map((s) => s.topic))\r\n );\r\n uniqueTopics.forEach((topic) => {\r\n this.client!.subscribe(topic, { qos: 1 as 0 | 1 | 2 }, (err) => {\r\n if (err) {\r\n this.emit('error', err);\r\n }\r\n });\r\n });\r\n }\r\n\r\n // 判断接收到的 topic 是否匹配订阅的 topic(支持通配符 # 和 +)\r\n private topicMatch(subscribed: string, received: string): boolean {\r\n const subParts = subscribed.split('/');\r\n const recParts = received.split('/');\r\n\r\n for (let i = 0; i < subParts.length; i++) {\r\n const sp = subParts[i];\r\n const rp = recParts[i];\r\n\r\n if (sp === '#') {\r\n // # 必须是最后一个层级,匹配后面所有\r\n return true;\r\n }\r\n if (sp === '+') {\r\n // + 匹配单个层级\r\n continue;\r\n }\r\n if (sp !== rp) {\r\n return false;\r\n }\r\n }\r\n\r\n return subParts.length === recParts.length;\r\n }\r\n\r\n get isConnected(): boolean {\r\n return this._connected;\r\n }\r\n\r\n get subscribedTopics(): string[] {\r\n return Array.from(new Set(this.subscriptions.map((s) => s.topic)));\r\n }\r\n}\r\n"]}
@@ -0,0 +1,5 @@
1
+ export { Tier0MQClient } from './client.js';
2
+ export type { TopicHandler } from './client.js';
3
+ export { parseMqttBroker, toWebSocketUrl, DEFAULT_WSS_PORT, DEFAULT_WS_PATH, } from './broker.js';
4
+ export type { MqttBrokerEndpoint, ToWebSocketUrlOptions } from './broker.js';
5
+ export type { MQTTConfig, MQTTMessage, MQTTEventMap } from './types.js';
@@ -0,0 +1,3 @@
1
+ export { Tier0MQClient } from './client.js';
2
+ export { parseMqttBroker, toWebSocketUrl, DEFAULT_WSS_PORT, DEFAULT_WS_PATH, } from './broker.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mq/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAC","sourcesContent":["export { Tier0MQClient } from './client.js';\r\nexport type { TopicHandler } from './client.js';\r\nexport {\r\n parseMqttBroker,\r\n toWebSocketUrl,\r\n DEFAULT_WSS_PORT,\r\n DEFAULT_WS_PATH,\r\n} from './broker.js';\r\nexport type { MqttBrokerEndpoint, ToWebSocketUrlOptions } from './broker.js';\r\nexport type { MQTTConfig, MQTTMessage, MQTTEventMap } from './types.js';\r\n"]}
@@ -0,0 +1,48 @@
1
+ export interface MQTTConfig {
2
+ /**
3
+ * broker 地址。支持三种形态:
4
+ * - 完整 WebSocket URL,如 `wss://host:8084/mqtt`(推荐浏览器场景显式使用);
5
+ * - 裸 `host`(可含端口,如 `host:8084`);
6
+ * - 平台 `/openapi/v1/info` 返回的原始 `mqttBroker`(如 `tcp://host:1883`,
7
+ * 建议先用 {@link toWebSocketUrl} 归一后再传入,见 `@tier0/sdk-v2/mq` 的 broker 工具)。
8
+ */
9
+ host?: string;
10
+ /** WebSocket port fallback when host has no embedded WebSocket port. */
11
+ port?: number;
12
+ /**
13
+ * 当 host 不带 ws(s) scheme 时,显式指定用 wss(true) 还是 ws(false)。
14
+ * 缺省自适应:浏览器 https 页面或端口 8084 用 wss,其余用 ws。
15
+ */
16
+ secure?: boolean;
17
+ clientId?: string;
18
+ username?: string;
19
+ /** Original API key; connect-time changes refresh automatically derived identity fields. */
20
+ password?: string;
21
+ keepAlive?: number;
22
+ reconnectPeriod?: number;
23
+ connectTimeout?: number;
24
+ clean?: boolean;
25
+ /**
26
+ * 背压保护阈值:handler 连续返回 false(表示下游停滞/消费者已断开)达到
27
+ * 该次数后,SDK 自动移除该订阅并向 broker 退订,避免消息在无消费者的
28
+ * 应用内队列中持续堆积。0 或不设置表示关闭该保护(保持原有行为)。
29
+ */
30
+ maxBackpressuredDeliveries?: number;
31
+ }
32
+ export type MQTTMessage = {
33
+ topic: string;
34
+ payload: string | Buffer;
35
+ qos: number;
36
+ retain: boolean;
37
+ };
38
+ export type MQTTEventMap = {
39
+ connect: () => void;
40
+ disconnect: () => void;
41
+ error: (error: Error) => void;
42
+ message: (message: MQTTMessage) => void;
43
+ /** 订阅因持续背压被 SDK 自动移除时触发。 */
44
+ subscriptionDropped: (info: {
45
+ topic: string;
46
+ reason: string;
47
+ }) => void;
48
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mq/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface MQTTConfig {\r\n /**\r\n * broker 地址。支持三种形态:\r\n * - 完整 WebSocket URL,如 `wss://host:8084/mqtt`(推荐浏览器场景显式使用);\r\n * - 裸 `host`(可含端口,如 `host:8084`);\r\n * - 平台 `/openapi/v1/info` 返回的原始 `mqttBroker`(如 `tcp://host:1883`,\r\n * 建议先用 {@link toWebSocketUrl} 归一后再传入,见 `@tier0/sdk-v2/mq` 的 broker 工具)。\r\n */\r\n host?: string;\r\n /** WebSocket port fallback when host has no embedded WebSocket port. */\r\n port?: number;\r\n /**\r\n * 当 host 不带 ws(s) scheme 时,显式指定用 wss(true) 还是 ws(false)。\r\n * 缺省自适应:浏览器 https 页面或端口 8084 用 wss,其余用 ws。\r\n */\r\n secure?: boolean;\r\n clientId?: string;\r\n username?: string;\r\n /** Original API key; connect-time changes refresh automatically derived identity fields. */\r\n password?: string;\r\n keepAlive?: number;\r\n reconnectPeriod?: number;\r\n connectTimeout?: number;\r\n clean?: boolean;\r\n /**\r\n * 背压保护阈值:handler 连续返回 false(表示下游停滞/消费者已断开)达到\r\n * 该次数后,SDK 自动移除该订阅并向 broker 退订,避免消息在无消费者的\r\n * 应用内队列中持续堆积。0 或不设置表示关闭该保护(保持原有行为)。\r\n */\r\n maxBackpressuredDeliveries?: number;\r\n}\r\n\r\nexport type MQTTMessage = {\r\n topic: string;\r\n payload: string | Buffer;\r\n qos: number;\r\n retain: boolean;\r\n};\r\n\r\nexport type MQTTEventMap = {\r\n connect: () => void;\r\n disconnect: () => void;\r\n error: (error: Error) => void;\r\n message: (message: MQTTMessage) => void;\r\n /** 订阅因持续背压被 SDK 自动移除时触发。 */\r\n subscriptionDropped: (info: { topic: string; reason: string }) => void;\r\n};\r\n"]}