@tier0/sdk-v2 0.9.9 → 0.10.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 (250) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/LICENSE +21 -21
  3. package/README.md +165 -27
  4. package/dist/cjs/client.d.ts +79 -3
  5. package/dist/cjs/client.js +4 -6
  6. package/dist/cjs/client.js.map +1 -1
  7. package/dist/cjs/cloud-server.d.ts +33 -26
  8. package/dist/cjs/cloud-server.js +102 -100
  9. package/dist/cjs/cloud-server.js.map +1 -1
  10. package/dist/cjs/cloud-transport.d.ts +15 -20
  11. package/dist/cjs/cloud-transport.js +87 -68
  12. package/dist/cjs/cloud-transport.js.map +1 -1
  13. package/dist/cjs/connection-diagnostics.d.ts +2 -0
  14. package/dist/cjs/connection-diagnostics.js +20 -0
  15. package/dist/cjs/connection-diagnostics.js.map +1 -0
  16. package/dist/cjs/data/bootstrap.js +3 -4
  17. package/dist/cjs/data/bootstrap.js.map +1 -1
  18. package/dist/cjs/data/call.d.ts +1 -3
  19. package/dist/cjs/data/call.js +8 -12
  20. package/dist/cjs/data/call.js.map +1 -1
  21. package/dist/cjs/data/client.d.ts +8 -7
  22. package/dist/cjs/data/client.js +24 -11
  23. package/dist/cjs/data/client.js.map +1 -1
  24. package/dist/cjs/data/collection.d.ts +3 -5
  25. package/dist/cjs/data/collection.js +3 -4
  26. package/dist/cjs/data/collection.js.map +1 -1
  27. package/dist/cjs/data/context.d.ts +5 -11
  28. package/dist/cjs/data/context.js +21 -36
  29. package/dist/cjs/data/context.js.map +1 -1
  30. package/dist/cjs/data/error.d.ts +1 -1
  31. package/dist/cjs/data/error.js +3 -3
  32. package/dist/cjs/data/error.js.map +1 -1
  33. package/dist/cjs/data/index.d.ts +5 -3
  34. package/dist/cjs/data/index.js +5 -5
  35. package/dist/cjs/data/index.js.map +1 -1
  36. package/dist/cjs/data/relay.d.ts +51 -0
  37. package/dist/cjs/data/relay.js +371 -0
  38. package/dist/cjs/data/relay.js.map +1 -0
  39. package/dist/cjs/data/subscribe.d.ts +22 -38
  40. package/dist/cjs/data/subscribe.js +22 -28
  41. package/dist/cjs/data/subscribe.js.map +1 -1
  42. package/dist/cjs/event-stream.d.ts +28 -0
  43. package/dist/cjs/event-stream.js +222 -0
  44. package/dist/cjs/event-stream.js.map +1 -0
  45. package/dist/cjs/mq/client.d.ts +32 -1
  46. package/dist/cjs/mq/client.js +404 -69
  47. package/dist/cjs/mq/client.js.map +1 -1
  48. package/dist/cjs/mq/index.d.ts +1 -0
  49. package/dist/cjs/mq/index.js +3 -1
  50. package/dist/cjs/mq/index.js.map +1 -1
  51. package/dist/cjs/mq/topic.d.ts +29 -0
  52. package/dist/cjs/mq/topic.js +48 -0
  53. package/dist/cjs/mq/topic.js.map +1 -0
  54. package/dist/cjs/mq/types.d.ts +21 -1
  55. package/dist/cjs/mq/types.js.map +1 -1
  56. package/dist/cjs/openapi/api.generated.d.ts +20 -0
  57. package/dist/cjs/openapi/api.generated.js +11 -0
  58. package/dist/cjs/openapi/api.generated.js.map +1 -1
  59. package/dist/cjs/openapi/client.d.ts +46 -0
  60. package/dist/cjs/openapi/client.js +161 -12
  61. package/dist/cjs/openapi/client.js.map +1 -1
  62. package/dist/cjs/openapi/codecs.generated.d.ts +74 -0
  63. package/dist/cjs/openapi/codecs.generated.js +1 -1
  64. package/dist/cjs/openapi/codecs.generated.js.map +1 -1
  65. package/dist/cjs/openapi/types.generated.d.ts +205 -1
  66. package/dist/cjs/openapi/types.generated.js.map +1 -1
  67. package/dist/cjs/page-runtime.d.ts +48 -0
  68. package/dist/cjs/page-runtime.js +74 -0
  69. package/dist/cjs/page-runtime.js.map +1 -0
  70. package/dist/cjs/platform-proxy.d.ts +17 -0
  71. package/dist/cjs/platform-proxy.js +52 -0
  72. package/dist/cjs/platform-proxy.js.map +1 -0
  73. package/dist/cjs/runtime-context.d.ts +2 -1
  74. package/dist/cjs/runtime-context.js +6 -2
  75. package/dist/cjs/runtime-context.js.map +1 -1
  76. package/dist/cjs/runtime-env.js.map +1 -1
  77. package/dist/cjs/source.d.ts +19 -1
  78. package/dist/cjs/source.js +9 -3
  79. package/dist/cjs/source.js.map +1 -1
  80. package/dist/cjs/stream.js +3 -2
  81. package/dist/cjs/stream.js.map +1 -1
  82. package/dist/cjs/streams/contract.generated.d.ts +7 -1
  83. package/dist/cjs/streams/contract.generated.js.map +1 -1
  84. package/dist/cjs/streams/messages.js +1 -10
  85. package/dist/cjs/streams/messages.js.map +1 -1
  86. package/dist/cjs/streams/requests.d.ts +3 -0
  87. package/dist/cjs/streams/requests.js +5 -2
  88. package/dist/cjs/streams/requests.js.map +1 -1
  89. package/dist/cjs/streams/transport.d.ts +1 -13
  90. package/dist/cjs/streams/transport.js +2 -18
  91. package/dist/cjs/streams/transport.js.map +1 -1
  92. package/dist/cjs/uns-v2/client.d.ts +1 -6
  93. package/dist/cjs/uns-v2/client.js +33 -8
  94. package/dist/cjs/uns-v2/client.js.map +1 -1
  95. package/dist/cjs/uns-v2/data-client.d.ts +5 -2
  96. package/dist/cjs/uns-v2/data-client.js +7 -4
  97. package/dist/cjs/uns-v2/data-client.js.map +1 -1
  98. package/dist/cjs/uns-v2/generated.d.ts +6783 -4655
  99. package/dist/cjs/uns-v2/generated.js +221 -65
  100. package/dist/cjs/uns-v2/generated.js.map +1 -1
  101. package/dist/cjs/uns-v2/sse.d.ts +7 -1
  102. package/dist/cjs/uns-v2/sse.js +12 -2
  103. package/dist/cjs/uns-v2/sse.js.map +1 -1
  104. package/dist/esm/client.d.ts +79 -3
  105. package/dist/esm/client.js +5 -7
  106. package/dist/esm/client.js.map +1 -1
  107. package/dist/esm/cloud-server.d.ts +33 -26
  108. package/dist/esm/cloud-server.js +99 -97
  109. package/dist/esm/cloud-server.js.map +1 -1
  110. package/dist/esm/cloud-transport.d.ts +15 -20
  111. package/dist/esm/cloud-transport.js +86 -67
  112. package/dist/esm/cloud-transport.js.map +1 -1
  113. package/dist/esm/connection-diagnostics.d.ts +2 -0
  114. package/dist/esm/connection-diagnostics.js +17 -0
  115. package/dist/esm/connection-diagnostics.js.map +1 -0
  116. package/dist/esm/data/bootstrap.js +3 -4
  117. package/dist/esm/data/bootstrap.js.map +1 -1
  118. package/dist/esm/data/call.d.ts +1 -3
  119. package/dist/esm/data/call.js +9 -13
  120. package/dist/esm/data/call.js.map +1 -1
  121. package/dist/esm/data/client.d.ts +8 -7
  122. package/dist/esm/data/client.js +22 -9
  123. package/dist/esm/data/client.js.map +1 -1
  124. package/dist/esm/data/collection.d.ts +3 -5
  125. package/dist/esm/data/collection.js +3 -4
  126. package/dist/esm/data/collection.js.map +1 -1
  127. package/dist/esm/data/context.d.ts +5 -11
  128. package/dist/esm/data/context.js +19 -33
  129. package/dist/esm/data/context.js.map +1 -1
  130. package/dist/esm/data/error.d.ts +1 -1
  131. package/dist/esm/data/error.js +3 -3
  132. package/dist/esm/data/error.js.map +1 -1
  133. package/dist/esm/data/index.d.ts +5 -3
  134. package/dist/esm/data/index.js +3 -2
  135. package/dist/esm/data/index.js.map +1 -1
  136. package/dist/esm/data/relay.d.ts +51 -0
  137. package/dist/esm/data/relay.js +368 -0
  138. package/dist/esm/data/relay.js.map +1 -0
  139. package/dist/esm/data/subscribe.d.ts +22 -38
  140. package/dist/esm/data/subscribe.js +22 -27
  141. package/dist/esm/data/subscribe.js.map +1 -1
  142. package/dist/esm/event-stream.d.ts +28 -0
  143. package/dist/esm/event-stream.js +217 -0
  144. package/dist/esm/event-stream.js.map +1 -0
  145. package/dist/esm/mq/client.d.ts +32 -1
  146. package/dist/esm/mq/client.js +404 -69
  147. package/dist/esm/mq/client.js.map +1 -1
  148. package/dist/esm/mq/index.d.ts +1 -0
  149. package/dist/esm/mq/index.js +1 -0
  150. package/dist/esm/mq/index.js.map +1 -1
  151. package/dist/esm/mq/topic.d.ts +29 -0
  152. package/dist/esm/mq/topic.js +44 -0
  153. package/dist/esm/mq/topic.js.map +1 -0
  154. package/dist/esm/mq/types.d.ts +21 -1
  155. package/dist/esm/mq/types.js.map +1 -1
  156. package/dist/esm/openapi/api.generated.d.ts +20 -0
  157. package/dist/esm/openapi/api.generated.js +11 -0
  158. package/dist/esm/openapi/api.generated.js.map +1 -1
  159. package/dist/esm/openapi/client.d.ts +46 -0
  160. package/dist/esm/openapi/client.js +160 -12
  161. package/dist/esm/openapi/client.js.map +1 -1
  162. package/dist/esm/openapi/codecs.generated.d.ts +74 -0
  163. package/dist/esm/openapi/codecs.generated.js +1 -1
  164. package/dist/esm/openapi/codecs.generated.js.map +1 -1
  165. package/dist/esm/openapi/types.generated.d.ts +205 -1
  166. package/dist/esm/openapi/types.generated.js.map +1 -1
  167. package/dist/esm/page-runtime.d.ts +48 -0
  168. package/dist/esm/page-runtime.js +65 -0
  169. package/dist/esm/page-runtime.js.map +1 -0
  170. package/dist/esm/platform-proxy.d.ts +17 -0
  171. package/dist/esm/platform-proxy.js +47 -0
  172. package/dist/esm/platform-proxy.js.map +1 -0
  173. package/dist/esm/runtime-context.d.ts +2 -1
  174. package/dist/esm/runtime-context.js +6 -2
  175. package/dist/esm/runtime-context.js.map +1 -1
  176. package/dist/esm/runtime-env.js.map +1 -1
  177. package/dist/esm/source.d.ts +19 -1
  178. package/dist/esm/source.js +10 -4
  179. package/dist/esm/source.js.map +1 -1
  180. package/dist/esm/stream.js +4 -3
  181. package/dist/esm/stream.js.map +1 -1
  182. package/dist/esm/streams/contract.generated.d.ts +7 -1
  183. package/dist/esm/streams/contract.generated.js.map +1 -1
  184. package/dist/esm/streams/messages.js +1 -10
  185. package/dist/esm/streams/messages.js.map +1 -1
  186. package/dist/esm/streams/requests.d.ts +3 -0
  187. package/dist/esm/streams/requests.js +5 -2
  188. package/dist/esm/streams/requests.js.map +1 -1
  189. package/dist/esm/streams/transport.d.ts +1 -13
  190. package/dist/esm/streams/transport.js +1 -17
  191. package/dist/esm/streams/transport.js.map +1 -1
  192. package/dist/esm/uns-v2/client.d.ts +1 -6
  193. package/dist/esm/uns-v2/client.js +33 -8
  194. package/dist/esm/uns-v2/client.js.map +1 -1
  195. package/dist/esm/uns-v2/data-client.d.ts +5 -2
  196. package/dist/esm/uns-v2/data-client.js +8 -5
  197. package/dist/esm/uns-v2/data-client.js.map +1 -1
  198. package/dist/esm/uns-v2/generated.d.ts +6783 -4655
  199. package/dist/esm/uns-v2/generated.js +221 -65
  200. package/dist/esm/uns-v2/generated.js.map +1 -1
  201. package/dist/esm/uns-v2/sse.d.ts +7 -1
  202. package/dist/esm/uns-v2/sse.js +12 -2
  203. package/dist/esm/uns-v2/sse.js.map +1 -1
  204. package/package.json +25 -12
  205. package/skills/tier0-sdk-v2/SKILL.md +13 -5
  206. package/skills/tier0-sdk-v2/references/integration.md +14 -24
  207. package/skills/tier0-sdk-v2/references/local-connection.md +61 -0
  208. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +11 -5
  209. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +8 -12
  210. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +24 -5
  211. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +3 -1
  212. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +46 -13
  213. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +2 -0
  214. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +2 -2
  215. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +5 -1
  216. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +25 -0
  217. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +1 -1
  218. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +3 -3
  219. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +6 -6
  220. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +4 -4
  221. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +2 -2
  222. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +26 -36
  223. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +9 -23
  224. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +12 -29
  225. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +4 -5
  226. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +5 -5
  227. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +3 -3
  228. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +23 -9
  229. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +14 -12
  230. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/http-server.md +4 -4
  231. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +4 -3
  232. package/skills/tier0-sdk-v2/tier0-sdk-v2-streams/SKILL.md +12 -12
  233. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +3 -2
  234. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +2 -2
  235. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +47 -20
  236. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +3 -3
  237. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +11 -6
  238. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +12 -13
  239. package/dist/cjs/app-identity-contract.generated.d.ts +0 -22
  240. package/dist/cjs/app-identity-contract.generated.js +0 -51
  241. package/dist/cjs/app-identity-contract.generated.js.map +0 -1
  242. package/dist/cjs/runtime.d.ts +0 -13
  243. package/dist/cjs/runtime.js +0 -51
  244. package/dist/cjs/runtime.js.map +0 -1
  245. package/dist/esm/app-identity-contract.generated.d.ts +0 -22
  246. package/dist/esm/app-identity-contract.generated.js +0 -48
  247. package/dist/esm/app-identity-contract.generated.js.map +0 -1
  248. package/dist/esm/runtime.d.ts +0 -13
  249. package/dist/esm/runtime.js +0 -46
  250. package/dist/esm/runtime.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/mq/client.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt from 'mqtt';\nimport type { MqttClient, IClientOptions } from 'mqtt';\nimport { getEnvVar } from '../runtime-env.js';\nimport { DEFAULT_WSS_PORT, isBrowserHttps, parseMqttBroker, toWebSocketUrl } from './broker.js';\nimport type { MQTTConfig, MQTTEventMap } from './types.js';\n\n/**\n * 消息回调。公开类型保持 `void` 返回,以兼容 async handler、`push()` 简写等\n * 既有写法;运行时额外识别返回值:handler 返回严格的 `false` 视为下游停滞\n * (背压),SDK 会统计连续背压次数,配合 MQTTConfig.maxBackpressuredDeliveries\n * 可在阈值内自动移除订阅。\n */\nexport type TopicHandler = (topic: string, payload: string) => void;\n\nfunction parseWorkspaceIDFromApiKey(apiKey: string): string | undefined {\n // Match the backend's sk-<type>-ws<base36>_<secret> contract, not only\n // service keys. Other workspace-encoded keys use the same MQTT identity.\n const match = /^sk-[^-]+-ws([0-9a-zA-Z]+)_.+$/.exec(apiKey.trim());\n if (!match) return undefined;\n\n // Keep the int64 workspace ID exact; parseInt can round IDs above 2^53.\n let workspaceID = 0n;\n for (const digit of match[1]) {\n workspaceID = workspaceID * 36n + BigInt(parseInt(digit, 36));\n if (workspaceID > 9223372036854775807n) return undefined;\n }\n return workspaceID > 0n ? workspaceID.toString() : undefined;\n}\n\nfunction generateRandomString(length = 8): string {\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\ninterface Subscription {\n topic: string;\n handler: TopicHandler;\n /** handler 连续返回 false(背压)的次数,正常返回时清零。 */\n backpressuredCount?: number;\n}\n\nexport class Tier0MQClient {\n private client: MqttClient | null = null;\n private config: MQTTConfig;\n private explicitClientId: boolean;\n private explicitUsername: boolean;\n private listeners: { [K in keyof MQTTEventMap]?: Array<MQTTEventMap[K]> } = {};\n private subscriptions: Subscription[] = [];\n private connectingPromise: Promise<void> | null = null;\n private _connected = false;\n\n constructor(config?: MQTTConfig) {\n this.explicitClientId = config?.clientId !== undefined;\n this.explicitUsername = config?.username !== undefined;\n const envHost = getEnvVar('TIER0_MQTT_HOST');\n const envPort = getEnvVar('TIER0_MQTT_PORT');\n\n const host = config?.host || envHost || '';\n const port = config?.port || parseInt(envPort || '8084') || 8084;\n const password = config?.password || getEnvVar('TIER0_API_KEY') || '';\n\n // 从 apiKey 解析 workspaceID,自动生成 clientId 和 username\n const workspaceID = config?.clientId && config?.username\n ? undefined\n : parseWorkspaceIDFromApiKey(password);\n\n const autoClientId = workspaceID\n ? `${workspaceID}&${generateRandomString(8)}`\n : undefined;\n const autoUsername = workspaceID\n ? `${workspaceID}&open`\n : undefined;\n\n this.config = {\n host,\n port,\n clientId: config?.clientId || autoClientId,\n username: config?.username || autoUsername,\n password,\n keepAlive: config?.keepAlive ?? 60,\n reconnectPeriod: config?.reconnectPeriod ?? 5000,\n connectTimeout: config?.connectTimeout ?? 30000,\n clean: config?.clean ?? true,\n ...config,\n };\n }\n\n private get mqttUrl(): string {\n const { host, port, secure } = this.config;\n if (!host) {\n throw new Error(\n 'MQTT host is required. Provide it via MQTTConfig or TIER0_MQTT_HOST environment variable.'\n );\n }\n const normalizedHost = host.trim().replace(/\\/+$/, '');\n if (/^wss?:\\/\\//i.test(normalizedHost)) {\n const url = toWebSocketUrl(normalizedHost);\n if (!url) throw new TypeError('Invalid MQTT WebSocket URL');\n return url;\n }\n // 裸 host(可含端口):按运行环境自适应 ws/wss\n const endpoint = parseMqttBroker(normalizedHost);\n const hostname = endpoint?.hostname ?? normalizedHost;\n // 裸 host:port 和 ws(s) URL 的端口按 WebSocket 端口处理;\n // tcp/mqtt/mqtts 的端口是 TCP 端口(如 1883),wss 下不能沿用,回退到配置的 port\n const effectivePort =\n !endpoint?.scheme || endpoint.scheme === 'ws' || endpoint.scheme === 'wss'\n ? endpoint?.port ?? port\n : port;\n const useSecure = secure ?? (isBrowserHttps() || effectivePort === DEFAULT_WSS_PORT);\n return `${useSecure ? 'wss' : 'ws'}://${hostname}:${effectivePort}/mqtt`;\n }\n\n // 内部确保已连接(懒连接)\n private async ensureConnected(): Promise<void> {\n if (this._connected) return;\n if (this.connectingPromise) return this.connectingPromise;\n\n void this.mqttUrl;\n if (!this.config.password || !this.config.username || !this.config.clientId) {\n throw new Error('Tier0 SDK v2: provide a workspace-encoded API key or explicit MQTT username, clientId and password.');\n }\n\n this.connectingPromise = this.doConnect();\n return this.connectingPromise;\n }\n\n private doConnect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const options: IClientOptions = {\n clientId: this.config.clientId,\n username: this.config.username,\n password: this.config.password,\n keepalive: this.config.keepAlive,\n reconnectPeriod: this.config.reconnectPeriod,\n connectTimeout: this.config.connectTimeout,\n clean: this.config.clean,\n };\n\n this.client = mqtt.connect(this.mqttUrl, options);\n\n this.client.on('connect', () => {\n this._connected = true;\n this.connectingPromise = null;\n this.emit('connect');\n // 断连重连后自动恢复所有订阅\n this.resubscribeAll();\n resolve();\n });\n\n this.client.on('error', (err) => {\n this.emit('error', err);\n this.connectingPromise = null;\n reject(err);\n });\n\n this.client.on('disconnect', () => {\n this._connected = false;\n this.emit('disconnect');\n });\n\n this.client.on('close', () => {\n this._connected = false;\n });\n\n this.client.on(\n 'message',\n (topic: string, payload: Buffer, _packet: mqtt.IPublishPacket) => {\n const payloadStr = payload.toString();\n // 复制一份快照:handler 触发背压自动退订时会重建 this.subscriptions\n this.subscriptions.slice().forEach((sub) => {\n if (this.topicMatch(sub.topic, topic)) {\n try {\n // 公开类型为 void 返回(兼容 async/简写 handler),运行时仅识别严格的 false\n const accepted = (\n sub.handler as (t: string, p: string) => unknown\n )(topic, payloadStr);\n if (accepted === false) {\n sub.backpressuredCount = (sub.backpressuredCount ?? 0) + 1;\n const limit = this.config.maxBackpressuredDeliveries ?? 0;\n if (limit > 0 && sub.backpressuredCount >= limit) {\n this.unsubscribe(sub.topic, sub.handler);\n this.emit('subscriptionDropped', {\n topic: sub.topic,\n reason: `handler 连续 ${sub.backpressuredCount} 次返回背压(false),已按 maxBackpressuredDeliveries=${limit} 自动退订`,\n });\n }\n } else {\n sub.backpressuredCount = 0;\n }\n } catch (e) {\n this.emit('error', e as Error);\n }\n }\n });\n }\n );\n });\n }\n\n // 显式连接(需要等待连接完成时使用)\n async connect(config?: MQTTConfig): Promise<void> {\n if (config) {\n const previousPassword = this.config.password;\n this.config = { ...this.config, ...config };\n if (config.clientId !== undefined) this.explicitClientId = true;\n if (config.username !== undefined) this.explicitUsername = true;\n // A connect-time key may belong to a different workspace. Preserve only\n // caller-supplied identity fields, not values derived from the previous key.\n if (config.password !== undefined && config.password !== previousPassword) {\n const workspaceID = parseWorkspaceIDFromApiKey(config.password);\n if (!this.explicitClientId) {\n this.config.clientId = workspaceID ? workspaceID + '&' + generateRandomString(8) : undefined;\n }\n if (!this.explicitUsername) this.config.username = workspaceID ? workspaceID + '&open' : undefined;\n }\n }\n return this.ensureConnected();\n }\n\n // 订阅 topic,内部 qos 固定为 1,handler 接收 (topic, payload)\n // 无需先调用 connect(),自动处理连接\n subscribe(topic: string, handler: TopicHandler): void {\n // 避免重复注册同一 topic 的同一 handler\n const exists = this.subscriptions.some(\n (s) => s.topic === topic && s.handler === handler\n );\n if (exists) {\n return;\n }\n\n this.subscriptions.push({ topic, handler });\n\n if (this._connected && this.client) {\n this.client.subscribe(topic, { qos: 1 as 0 | 1 | 2 }, (err) => {\n if (err) {\n this.emit('error', err);\n // 订阅失败时回滚\n this.subscriptions = this.subscriptions.filter(\n (s) => !(s.topic === topic && s.handler === handler)\n );\n }\n });\n } else {\n // 未连接时触发懒连接,连接成功后 resubscribeAll 会自动 subscribe\n this.ensureConnected().catch((err) => this.emit('error', err));\n }\n }\n\n // 取消订阅:如果提供了 handler 则仅移除该 handler,否则移除该 topic 下所有 handler\n unsubscribe(topic: string, handler?: TopicHandler): void {\n if (handler) {\n this.subscriptions = this.subscriptions.filter(\n (s) => !(s.topic === topic && s.handler === handler)\n );\n } else {\n this.subscriptions = this.subscriptions.filter((s) => s.topic !== topic);\n }\n\n if (!this.client) return;\n\n // 如果该 topic 下已无任何 handler,则向 broker 发送 unsubscribe\n const stillHasHandler = this.subscriptions.some((s) => s.topic === topic);\n if (!stillHasHandler) {\n this.client.unsubscribe(topic, (err) => {\n if (err) {\n this.emit('error', err);\n }\n });\n }\n }\n\n // 发布消息,无需先调用 connect(),内部自动处理连接\n async publish(\n topic: string,\n payload: string | object,\n options?: { qos?: number; retain?: boolean }\n ): Promise<void> {\n await this.ensureConnected();\n\n const message =\n typeof payload === 'string' ? payload : JSON.stringify(payload);\n this.client!.publish(topic, message, {\n qos: (options?.qos ?? 0) as 0 | 1 | 2,\n retain: options?.retain ?? false,\n });\n }\n\n disconnect(): void {\n if (!this.client) return;\n\n this.client.end(true, () => {\n this.emit('disconnect');\n });\n this.client = null;\n this._connected = false;\n this.connectingPromise = null;\n this.subscriptions = [];\n }\n\n on<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void {\n if (!this.listeners[event]) {\n this.listeners[event] = [];\n }\n this.listeners[event]!.push(handler);\n }\n\n off<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void {\n const handlers = this.listeners[event];\n if (!handlers) return;\n const idx = handlers.indexOf(handler);\n if (idx !== -1) {\n handlers.splice(idx, 1);\n }\n }\n\n private emit<K extends keyof MQTTEventMap>(\n event: K,\n ...args: Parameters<MQTTEventMap[K]>\n ): void {\n const handlers = this.listeners[event];\n if (!handlers) return;\n handlers.forEach((h) => (h as any)(...args));\n }\n\n // 断连后自动重新订阅所有已注册的 topic\n private resubscribeAll(): void {\n if (!this.client) return;\n\n // 按 topic 去重,每个 topic 只订阅一次\n const uniqueTopics = Array.from(\n new Set(this.subscriptions.map((s) => s.topic))\n );\n uniqueTopics.forEach((topic) => {\n this.client!.subscribe(topic, { qos: 1 as 0 | 1 | 2 }, (err) => {\n if (err) {\n this.emit('error', err);\n }\n });\n });\n }\n\n // 判断接收到的 topic 是否匹配订阅的 topic(支持通配符 # 和 +)\n private topicMatch(subscribed: string, received: string): boolean {\n const subParts = subscribed.split('/');\n const recParts = received.split('/');\n\n for (let i = 0; i < subParts.length; i++) {\n const sp = subParts[i];\n const rp = recParts[i];\n\n if (sp === '#') {\n // # 必须是最后一个层级,匹配后面所有\n return true;\n }\n if (sp === '+') {\n // + 匹配单个层级\n continue;\n }\n if (sp !== rp) {\n return false;\n }\n }\n\n return subParts.length === recParts.length;\n }\n\n get isConnected(): boolean {\n return this._connected;\n }\n\n get subscribedTopics(): string[] {\n return Array.from(new Set(this.subscriptions.map((s) => s.topic)));\n }\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/mq/client.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt from 'mqtt';\nimport type { MqttClient, IClientOptions } from 'mqtt';\nimport { platformIdentity, platformProxyMode } from '../platform-proxy.js';\nimport { getEnvVar } from '../runtime-env.js';\nimport { DEFAULT_WSS_PORT, isBrowserHttps, parseMqttBroker, toWebSocketUrl } from './broker.js';\nimport { APP_SEGMENT } from './topic.js';\nimport type { MQTTConfig, MQTTEventMap } from './types.js';\n\n/** Design 21.6: backoff ceiling of a client that never gives up. */\nconst RECONNECT_MAX_MS = 5 * 60_000;\n/** The first reconnect after a drop is spread over this window. */\nconst FIRST_RECONNECT_MS = 500;\n\n/** One connection attempt: what the broker sees. No password through the node proxy, which fills it in. */\ninterface ConnectionParams {\n url: string;\n username: string;\n clientId: string;\n password?: string;\n}\n\n/**\n * 消息回调。公开类型保持 `void` 返回,以兼容 async handler、`push()` 简写等\n * 既有写法;运行时额外识别返回值:handler 返回严格的 `false` 视为下游停滞\n * (背压),SDK 会统计连续背压次数,配合 MQTTConfig.maxBackpressuredDeliveries\n * 可在阈值内自动移除订阅。\n */\nexport type TopicHandler = (topic: string, payload: string) => void;\n\nfunction parseWorkspaceIDFromApiKey(apiKey: string): string | undefined {\n // Match the backend's sk-<type>-ws<base36>_<secret> contract, not only\n // service keys. Other workspace-encoded keys use the same MQTT identity.\n const match = /^sk-[^-]+-ws([0-9a-zA-Z]+)_.+$/.exec(apiKey.trim());\n if (!match) return undefined;\n\n // Keep the int64 workspace ID exact; parseInt can round IDs above 2^53.\n let workspaceID = 0n;\n for (const digit of match[1]) {\n workspaceID = workspaceID * 36n + BigInt(parseInt(digit, 36));\n if (workspaceID > 9223372036854775807n) return undefined;\n }\n return workspaceID > 0n ? workspaceID.toString() : undefined;\n}\n\nfunction generateRandomString(length = 8): string {\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\nfunction snapshotConfig(config?: MQTTConfig): MQTTConfig | undefined {\n if (!config) return undefined;\n const snapshot = { ...config };\n // Preserve an explicitly supplied non-enumerable password as well.\n if (Object.hasOwn(config, 'password') && !Object.hasOwn(snapshot, 'password')) snapshot.password = config.password;\n return snapshot;\n}\n\ninterface Subscription {\n topic: string;\n handler: TopicHandler;\n /** A new subscription awaiting the first successful connection. */\n pendingConnect?: boolean;\n /** handler 连续返回 false(背压)的次数,正常返回时清零。 */\n backpressuredCount?: number;\n}\n\ninterface TopicSubscriptionAttempt {\n invalidSuback?: boolean;\n}\n\nconst CANCELLED_BY_DISCONNECT = 'MQTT connection cancelled by disconnect';\n\nexport class Tier0MQClient {\n private client: MqttClient | null = null;\n private config: MQTTConfig;\n private explicitClientId: boolean;\n private explicitUsername: boolean;\n private listeners: { [K in keyof MQTTEventMap]?: Array<MQTTEventMap[K]> } = {};\n private subscriptions: Subscription[] = [];\n // One broker subscription (including its pending SUBACK) per topic.\n private topicSubscriptions = new Map<string, TopicSubscriptionAttempt>();\n private pendingTopicPackets = new Map<string, TopicSubscriptionAttempt[]>();\n private sentTopicPackets = new Map<number, TopicSubscriptionAttempt>();\n private connectingPromise: Promise<void> | null = null;\n private rejectPendingConnect: ((error: Error) => void) | null = null;\n private _connected = false;\n /** Bumped by disconnect(); callbacks of an older generation are ignored. */\n private generation = 0;\n /** Random clientId segment; a persistent session is found again through it. */\n private readonly clientSuffix = generateRandomString(16);\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private reconnectAttempts = 0;\n private connectWaiters: Array<{ resolve(): void; reject(error: Error): void }> = [];\n\n constructor(config?: MQTTConfig) {\n config = snapshotConfig(config);\n this.explicitClientId = config?.clientId !== undefined;\n this.explicitUsername = config?.username !== undefined;\n const envHost = getEnvVar('TIER0_MQTT_URL') || getEnvVar('TIER0_MQTT_HOST');\n const envPort = getEnvVar('TIER0_MQTT_PORT');\n\n const host = config?.host || envHost || '';\n const port = config?.port || parseInt(envPort || '8084') || 8084;\n // An explicitly given password, even undefined, is never replaced by the environment key.\n const explicitPassword = !!config && Object.hasOwn(config, 'password');\n const password = explicitPassword\n ? config!.password\n : (this.tokenSource() ? '' : getEnvVar('TIER0_API_KEY')) || '';\n\n // 从 apiKey 解析 workspaceID,自动生成 clientId 和 username\n const workspaceID = config?.clientId && config?.username\n ? undefined\n : parseWorkspaceIDFromApiKey(password ?? '');\n\n // In an App's runtime the platform injects the App's key as TIER0_API_KEY: Backend accepts that hosted key\n // only with clientId `<ws>&h.<app>.<random>` (app = TIER0_APP_ID). Any other key keeps `<ws>&<random>`.\n const appId = getEnvVar('TIER0_APP_ID')?.trim();\n const hosted = !explicitPassword && !!password && config?.clientId === undefined && config?.username === undefined &&\n !!appId && APP_SEGMENT.test(appId);\n const autoClientId = workspaceID\n ? hosted ? `${workspaceID}&h.${appId}.${this.clientSuffix}` : `${workspaceID}&${generateRandomString(8)}`\n : undefined;\n const autoUsername = workspaceID\n ? `${workspaceID}&open`\n : undefined;\n\n this.config = {\n host,\n port,\n clientId: config?.clientId || autoClientId,\n username: config?.username || autoUsername,\n password,\n keepAlive: config?.keepAlive ?? 60,\n reconnectPeriod: config?.reconnectPeriod ?? 5000,\n connectTimeout: config?.connectTimeout ?? 30000,\n ...config,\n clean: config?.clean ?? false,\n };\n }\n\n private mqttUrlFor(config: MQTTConfig): string {\n const { host, port, secure } = config;\n if (!host) {\n throw new Error(\n 'MQTT host is required. Provide it via MQTTConfig or TIER0_MQTT_HOST environment variable.'\n );\n }\n const normalizedHost = host.trim().replace(/\\/+$/, '');\n if (/^wss?:\\/\\//i.test(normalizedHost)) {\n const url = toWebSocketUrl(normalizedHost);\n if (!url) throw new TypeError('Invalid MQTT WebSocket URL');\n return url;\n }\n // 裸 host(可含端口):按运行环境自适应 ws/wss\n const endpoint = parseMqttBroker(normalizedHost);\n const hostname = endpoint?.hostname ?? normalizedHost;\n // 裸 host:port 和 ws(s) URL 的端口按 WebSocket 端口处理;\n // tcp/mqtt/mqtts 的端口是 TCP 端口(如 1883),wss 下不能沿用,回退到配置的 port\n const effectivePort =\n !endpoint?.scheme || endpoint.scheme === 'ws' || endpoint.scheme === 'wss'\n ? endpoint?.port ?? port\n : port;\n const useSecure = secure ?? (isBrowserHttps() || effectivePort === DEFAULT_WSS_PORT);\n return `${useSecure ? 'wss' : 'ws'}://${hostname}:${effectivePort}/mqtt`;\n }\n\n /**\n * Where the credential comes from; undefined when a fixed password is used.\n * `proxy`: platform proxy mode, the node proxy puts in the App's key and\n * the SDK sends none.\n */\n private tokenSource(config: MQTTConfig | undefined = this.config): 'proxy' | undefined {\n if (config?.password) return undefined;\n return platformProxyMode() ? 'proxy' : undefined;\n }\n\n /** Local preflight before a transport exists: address and credentials must be usable. */\n private validateConnectionConfig(config: MQTTConfig): void {\n void this.connectionParams(config);\n }\n\n /**\n * What the next connection presents. Through the node proxy the same\n * identity reconnects, and the proxy puts in the App's current key.\n */\n private connectionParams(config: MQTTConfig = this.config): ConnectionParams {\n if (this.tokenSource(config) === 'proxy') {\n const identity = platformIdentity();\n if (!identity) {\n throw new Error('Tier0 SDK v2: TIER0_WORKSPACE_ID and TIER0_APP_ID are required for MQTT in the platform.');\n }\n // Only `mqtt://` from the platform goes over TCP to the proxy; an explicit host means WebSocket.\n const envUrl = getEnvVar('TIER0_MQTT_URL')?.trim();\n const tcp = envUrl !== undefined && /^mqtt:\\/\\//i.test(envUrl) && config.host === envUrl;\n // The proxy accepts only `<ws>&open` and `<ws>&h.<app>.<random>`, and puts the App's key in as the password.\n return {\n url: tcp ? envUrl : this.mqttUrlFor(config),\n username: config.username ?? `${identity.ws}&open`,\n clientId: config.clientId ?? `${identity.ws}&h.${identity.app}.${this.clientSuffix}`,\n };\n }\n const { username, clientId, password } = config;\n const url = this.mqttUrlFor(config);\n if (!password || !username || !clientId) {\n throw new Error('Tier0 SDK v2: provide a workspace-encoded API key or explicit MQTT username, clientId and password.');\n }\n return { url, username, clientId, password };\n }\n\n // 内部确保已连接(懒连接)。已有客户端时只等它重连,绝不另建:\n // 同一 clientId 的新旧客户端会互相顶掉。\n private async ensureConnected(onTransportCreationFailure?: () => void): Promise<void> {\n if (this._connected) return;\n if (this.connectingPromise) return this.connectingPromise;\n if (this.client) {\n return new Promise((resolve, reject) => this.connectWaiters.push({ resolve, reject }));\n }\n\n const pending = this.doConnect(this.connectionParams(), onTransportCreationFailure);\n // mqtt.connect may throw synchronously before creating a client. Do not\n // retain that already-failed attempt until the rejection microtask runs.\n if (!this.client) return pending;\n this.connectingPromise = pending;\n void pending.catch(() => {\n if (this.connectingPromise === pending) this.connectingPromise = null;\n });\n return pending;\n }\n\n private clearReconnect(): void {\n if (this.reconnectTimer !== null) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n private reconnectDelay(): number {\n const attempt = this.reconnectAttempts;\n this.reconnectAttempts += 1;\n if (attempt === 0) return Math.random() * FIRST_RECONNECT_MS;\n const base = this.config.reconnectPeriod ?? 5000;\n const ceiling = Math.min(RECONNECT_MAX_MS, base * 2 ** (attempt - 1));\n return ceiling / 2 + Math.random() * (ceiling / 2);\n }\n\n private scheduleReconnect(): void {\n if (!this.client || this._connected || this.reconnectTimer !== null) return;\n if (this.config.reconnectPeriod === 0) return;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.reconnect();\n }, this.reconnectDelay());\n }\n\n /** The same client: mqtt.js keeps its session and offline queue. */\n private reconnect(): void {\n const client = this.client;\n if (!client || this._connected) return;\n let params: ConnectionParams;\n try {\n params = this.connectionParams();\n } catch (error) {\n this.emit('error', error as Error);\n this.scheduleReconnect();\n return;\n }\n client.options.username = params.username;\n client.options.clientId = params.clientId;\n if (params.password === undefined) delete client.options.password;\n else client.options.password = params.password;\n client.reconnect();\n }\n\n private doConnect(params: ConnectionParams, onTransportCreationFailure?: () => void): Promise<void> {\n return new Promise((resolve, reject) => {\n const generation = this.generation;\n this.rejectPendingConnect = reject;\n const options: IClientOptions = {\n clientId: params.clientId,\n username: params.username,\n ...(params.password === undefined ? {} : { password: params.password }),\n keepalive: this.config.keepAlive,\n // Reconnects are ours, with their own backoff.\n reconnectPeriod: 0,\n // Without it a refused CONNACK leaves the client disconnected for good.\n reconnectOnConnackError: true,\n connectTimeout: this.config.connectTimeout,\n clean: this.config.clean,\n // The SDK owns resubscription so every SUBACK reaches its callback.\n resubscribe: false,\n };\n\n let client: MqttClient;\n try {\n client = mqtt.connect(params.url, options);\n } catch (err) {\n this.rejectPendingConnect = null;\n onTransportCreationFailure?.();\n reject(err);\n return;\n }\n this.client = client;\n const current = () => this.client === client && this.generation === generation;\n\n // mqtt.js 5.3 synthesizes the requested QoS if a malformed SUBACK has\n // no grants, and can throw when it contains too many. Track wire packet\n // ids so malformed acknowledgements never become apparent success.\n client.on('packetsend', (packet) => {\n if (!current() || packet.cmd !== 'subscribe' || packet.subscriptions.length !== 1) return;\n const topic = packet.subscriptions[0]?.topic;\n if (!topic || typeof packet.messageId !== 'number') return;\n const queue = this.pendingTopicPackets.get(topic);\n const attempt = queue?.shift();\n if (queue?.length === 0) this.pendingTopicPackets.delete(topic);\n if (attempt) this.sentTopicPackets.set(packet.messageId, attempt);\n });\n client.on('packetreceive', (packet) => {\n if (!current() || packet.cmd !== 'suback' || typeof packet.messageId !== 'number') return;\n const attempt = this.sentTopicPackets.get(packet.messageId);\n this.sentTopicPackets.delete(packet.messageId);\n if (!attempt) return;\n if (!Array.isArray(packet.granted) || packet.granted.length !== 1 ||\n (packet.granted[0] !== 0 && packet.granted[0] !== 1)) {\n attempt.invalidSuback = true;\n // Keep old mqtt.js from indexing past its single requested topic.\n packet.granted = [128];\n }\n });\n\n client.on('connect', () => {\n if (!current()) return;\n this._connected = true;\n this.clearTopicState();\n for (const sub of this.subscriptions) sub.pendingConnect = false;\n this.connectingPromise = null;\n this.rejectPendingConnect = null;\n this.clearReconnect();\n this.reconnectAttempts = 0;\n resolve();\n this.emit('connect');\n // 断连重连后自动恢复所有订阅\n if (current()) this.resubscribeAll();\n const waiters = this.connectWaiters;\n this.connectWaiters = [];\n waiters.forEach((waiter) => waiter.resolve());\n });\n\n client.on('error', (err) => {\n if (!current()) return;\n // Remove failed pending subscriptions before an error listener can\n // synchronously cause this same client to reconnect and resubscribe.\n this.subscriptions = this.subscriptions.filter((sub) => !sub.pendingConnect);\n this.connectingPromise = null;\n this.rejectPendingConnect = null;\n reject(err);\n this.emit('error', err);\n });\n\n client.on('disconnect', () => {\n if (!current()) return;\n this._connected = false;\n this.clearTopicState();\n this.emit('disconnect');\n });\n\n client.on('close', () => {\n if (!current()) return;\n this._connected = false;\n this.clearTopicState();\n this.scheduleReconnect();\n });\n\n client.on(\n 'message',\n (topic: string, payload: Buffer, _packet: mqtt.IPublishPacket) => {\n if (!current()) return;\n const payloadStr = payload.toString();\n // 复制一份快照:handler 触发背压自动退订时会重建 this.subscriptions\n this.subscriptions.slice().forEach((sub) => {\n if (!current() || !this.subscriptions.includes(sub)) return;\n if (this.topicMatch(sub.topic, topic)) {\n try {\n // 公开类型为 void 返回(兼容 async/简写 handler),运行时仅识别严格的 false\n const accepted = (\n sub.handler as (t: string, p: string) => unknown\n )(topic, payloadStr);\n if (!current() || !this.subscriptions.includes(sub)) return;\n if (accepted === false) {\n sub.backpressuredCount = (sub.backpressuredCount ?? 0) + 1;\n const limit = this.config.maxBackpressuredDeliveries ?? 0;\n if (limit > 0 && sub.backpressuredCount >= limit) {\n this.unsubscribe(sub.topic, sub.handler);\n this.emit('subscriptionDropped', {\n topic: sub.topic,\n reason: `handler 连续 ${sub.backpressuredCount} 次返回背压(false),已按 maxBackpressuredDeliveries=${limit} 自动退订`,\n });\n }\n } else {\n sub.backpressuredCount = 0;\n }\n } catch (e) {\n if (current()) this.emit('error', e as Error);\n }\n }\n });\n }\n );\n });\n }\n\n // 显式连接(需要等待连接完成时使用)\n async connect(config?: MQTTConfig): Promise<void> {\n const snapshot = snapshotConfig(config);\n // An explicitly missing password must never reuse a previous or environment key.\n if (snapshot && Object.hasOwn(snapshot, 'password') && snapshot.password === undefined) {\n throw new TypeError('MQTT password was explicitly undefined; provide a credential or omit the password field.');\n }\n // Other undefined fields mean no override, not a request to erase settings.\n const update = snapshot\n ? Object.fromEntries(Object.entries(snapshot).filter(([, value]) => value !== undefined)) as MQTTConfig\n : undefined;\n if (this.client || this.connectingPromise) {\n // mqtt.js snapshots its connection options. Changing our config while a\n // client exists (connecting, connected or reconnecting) would leave the\n // old credentials in use, including on reconnect. Refuse the change\n // before mutating anything.\n const connectionFields: (keyof MQTTConfig)[] = [\n 'host', 'port', 'secure', 'clientId', 'username', 'password',\n 'keepAlive', 'reconnectPeriod', 'connectTimeout', 'clean',\n ];\n if (update && connectionFields.some((field) =>\n update[field] !== undefined && update[field] !== this.config[field]\n )) {\n throw new Error('MQTT connection settings cannot change while a client exists; disconnect and create a new client');\n }\n const generation = this.generation;\n // A reconnecting client is waited for, never replaced: the SDK keeps reconnecting it.\n await this.ensureConnected();\n if (this.generation !== generation || !this.client || !this._connected) {\n throw new Error('MQTT connection changed before connect completed');\n }\n if (update) {\n this.config = { ...this.config, ...update };\n if (update.clientId !== undefined) this.explicitClientId = true;\n if (update.username !== undefined) this.explicitUsername = true;\n }\n return;\n }\n const previousConfig = this.config;\n const previousExplicitClientId = this.explicitClientId;\n const previousExplicitUsername = this.explicitUsername;\n const candidate = update ? { ...previousConfig, ...update } : previousConfig;\n const explicitClientId = previousExplicitClientId || update?.clientId !== undefined;\n const explicitUsername = previousExplicitUsername || update?.username !== undefined;\n if (update) {\n const previousPassword = previousConfig.password;\n // A connect-time key may belong to a different workspace. Preserve only\n // caller-supplied identity fields, not values derived from the previous key.\n if (update.password !== undefined && update.password !== previousPassword) {\n const workspaceID = parseWorkspaceIDFromApiKey(update.password);\n if (!explicitClientId) {\n candidate.clientId = workspaceID ? workspaceID + '&' + generateRandomString(8) : undefined;\n }\n if (!explicitUsername) candidate.username = workspaceID ? workspaceID + '&open' : undefined;\n }\n }\n this.validateConnectionConfig(candidate);\n const generation = this.generation;\n this.config = candidate;\n this.explicitClientId = explicitClientId;\n this.explicitUsername = explicitUsername;\n const rollbackBeforeTransport = () => {\n if (!this.client && this.generation === generation && this.config === candidate) {\n this.config = previousConfig;\n this.explicitClientId = previousExplicitClientId;\n this.explicitUsername = previousExplicitUsername;\n }\n };\n try {\n await this.ensureConnected(rollbackBeforeTransport);\n } catch (err) {\n // If no transport was created, the attempted settings have no owner.\n // Do not roll back a newer generation or another caller's settings.\n rollbackBeforeTransport();\n throw err;\n }\n if (this.generation !== generation || !this.client || !this._connected) {\n throw new Error('MQTT connection changed before connect completed');\n }\n }\n\n // 订阅 topic,内部 qos 固定为 1,handler 接收 (topic, payload)\n // 无需先调用 connect(),自动处理连接\n subscribe(topic: string, handler: TopicHandler): void {\n // 避免重复注册同一 topic 的同一 handler\n const exists = this.subscriptions.some(\n (s) => s.topic === topic && s.handler === handler\n );\n if (exists) {\n return;\n }\n\n // Only a subscription made before the first connection completes is\n // undone when that connection fails. One made while the SDK reconnects\n // an existing client is kept and restored after the reconnect.\n const pendingConnect = !this._connected && (!this.client || this.connectingPromise !== null);\n const sub: Subscription = { topic, handler, pendingConnect };\n this.subscriptions.push(sub);\n const generation = this.generation;\n\n if (this._connected && this.client) {\n this.subscribeTopic(topic, this.client, generation);\n } else {\n // 未连接时触发懒连接(已有客户端时等待它重连),连接成功后 resubscribeAll 会自动 subscribe\n this.ensureConnected().catch((err) => {\n if (this.generation === generation && this.subscriptions.includes(sub)) {\n this.subscriptions = this.subscriptions.filter((item) => item !== sub);\n this.emit('error', err);\n }\n });\n }\n }\n\n // 取消订阅:如果提供了 handler 则仅移除该 handler,否则移除该 topic 下所有 handler\n unsubscribe(topic: string, handler?: TopicHandler): void {\n if (handler) {\n this.subscriptions = this.subscriptions.filter(\n (s) => !(s.topic === topic && s.handler === handler)\n );\n } else {\n this.subscriptions = this.subscriptions.filter((s) => s.topic !== topic);\n }\n\n if (!this.client) return;\n const client = this.client;\n const generation = this.generation;\n\n // 如果该 topic 下已无任何 handler,则向 broker 发送 unsubscribe\n const stillHasHandler = this.subscriptions.some((s) => s.topic === topic);\n if (!stillHasHandler) {\n this.topicSubscriptions.delete(topic);\n client.unsubscribe(topic, (err) => {\n if (this.client !== client || this.generation !== generation) return;\n if (err) {\n this.emit('error', err);\n }\n });\n }\n }\n\n // 发布消息,无需先调用 connect(),内部自动处理连接\n async publish(\n topic: string,\n payload: string | object,\n options?: { qos?: number; retain?: boolean }\n ): Promise<void> {\n const generation = this.generation;\n // A disconnected client queues the message and sends it after reconnecting.\n if (!this.client) await this.ensureConnected();\n\n const message =\n typeof payload === 'string' ? payload : JSON.stringify(payload);\n const qos = (options?.qos ?? 0) as 0 | 1 | 2;\n const retain = options?.retain ?? false;\n const client = this.client;\n if (this.generation !== generation || !client) {\n throw new Error('MQTT connection changed before publish; message was not submitted');\n }\n client.publish(topic, message, { qos, retain });\n }\n\n disconnect(): void {\n this.clearReconnect();\n const generation = ++this.generation;\n const client = this.client;\n this.client = null;\n this._connected = false;\n this.connectingPromise = null;\n const rejectPendingConnect = this.rejectPendingConnect;\n this.rejectPendingConnect = null;\n const waiters = this.connectWaiters;\n this.connectWaiters = [];\n this.subscriptions = [];\n this.clearTopicState();\n const cancelled = new Error(CANCELLED_BY_DISCONNECT);\n rejectPendingConnect?.(cancelled);\n waiters.forEach((waiter) => waiter.reject(cancelled));\n if (!client) return;\n client.end(true, () => {\n if (!this.client && this.generation === generation) this.emit('disconnect');\n });\n }\n\n on<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void {\n if (!this.listeners[event]) {\n this.listeners[event] = [];\n }\n this.listeners[event]!.push(handler);\n }\n\n off<K extends keyof MQTTEventMap>(event: K, handler: MQTTEventMap[K]): void {\n const handlers = this.listeners[event];\n if (!handlers) return;\n const idx = handlers.indexOf(handler);\n if (idx !== -1) {\n handlers.splice(idx, 1);\n }\n }\n\n private emit<K extends keyof MQTTEventMap>(\n event: K,\n ...args: Parameters<MQTTEventMap[K]>\n ): void {\n const handlers = this.listeners[event];\n if (!handlers) return;\n handlers.forEach((h) => (h as any)(...args));\n }\n\n // 断连后自动重新订阅所有已注册的 topic\n private resubscribeAll(): void {\n if (!this.client) return;\n const client = this.client;\n const generation = this.generation;\n\n // 按 topic 去重,每个 topic 只订阅一次\n const uniqueTopics = Array.from(\n new Set(this.subscriptions.map((s) => s.topic))\n );\n uniqueTopics.forEach((topic) => this.subscribeTopic(topic, client, generation));\n }\n\n private clearTopicState(): void {\n this.topicSubscriptions.clear();\n this.pendingTopicPackets.clear();\n this.sentTopicPackets.clear();\n }\n\n private subscribeTopic(topic: string, client: MqttClient, generation: number): void {\n if (this.client !== client || this.generation !== generation || !this._connected ||\n this.topicSubscriptions.has(topic) || !this.subscriptions.some((sub) => sub.topic === topic)) return;\n const attempt: TopicSubscriptionAttempt = {};\n this.topicSubscriptions.set(topic, attempt);\n const pending = this.pendingTopicPackets.get(topic) ?? [];\n pending.push(attempt);\n this.pendingTopicPackets.set(topic, pending);\n client.subscribe(topic, { qos: 1 as 0 | 1 | 2 }, (err, granted) => {\n const queue = this.pendingTopicPackets.get(topic);\n if (queue) {\n const index = queue.indexOf(attempt);\n if (index >= 0) queue.splice(index, 1);\n if (!queue.length) this.pendingTopicPackets.delete(topic);\n }\n if (this.client !== client || this.generation !== generation || this.topicSubscriptions.get(topic) !== attempt) return;\n // mqtt.js 5.3 reports SUBACK failure codes in granted with err=null.\n // A QoS 1 request may only be granted QoS 0 or 1, for this one topic.\n const accepted = Array.isArray(granted) && granted.length === 1 &&\n granted[0]?.topic === topic && (granted[0]?.qos === 0 || granted[0]?.qos === 1);\n if (err || attempt.invalidSuback || !accepted) {\n this.topicSubscriptions.delete(topic);\n // Every handler shares this broker subscription and its SUBACK.\n this.subscriptions = this.subscriptions.filter((sub) => sub.topic !== topic);\n this.emit('error', new Error(`MQTT subscription failed for topic ${topic}`, { cause: err ?? undefined }));\n }\n });\n }\n\n // 判断接收到的 topic 是否匹配订阅的 topic(支持通配符 # 和 +)\n private topicMatch(subscribed: string, received: string): boolean {\n const subParts = subscribed.split('/');\n const recParts = received.split('/');\n\n for (let i = 0; i < subParts.length; i++) {\n const sp = subParts[i];\n const rp = recParts[i];\n\n if (sp === '#') {\n // # 必须是最后一个层级,匹配后面所有\n return true;\n }\n if (sp === '+') {\n // + 匹配单个层级\n continue;\n }\n if (sp !== rp) {\n return false;\n }\n }\n\n return subParts.length === recParts.length;\n }\n\n get isConnected(): boolean {\n return this._connected;\n }\n\n get subscribedTopics(): string[] {\n return Array.from(new Set(this.subscriptions.map((s) => s.topic)));\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  export { Tier0MQClient } from './client.js';
2
2
  export type { TopicHandler } from './client.js';
3
+ export { appTopic } from './topic.js';
3
4
  export { parseMqttBroker, toWebSocketUrl, DEFAULT_WSS_PORT, DEFAULT_WS_PATH, } from './broker.js';
4
5
  export type { MqttBrokerEndpoint, ToWebSocketUrlOptions } from './broker.js';
5
6
  export type { MQTTConfig, MQTTMessage, MQTTEventMap } from './types.js';
@@ -1,3 +1,4 @@
1
1
  export { Tier0MQClient } from './client.js';
2
+ export { appTopic } from './topic.js';
2
3
  export { parseMqttBroker, toWebSocketUrl, DEFAULT_WSS_PORT, DEFAULT_WS_PATH, } from './broker.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +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';\nexport type { TopicHandler } from './client.js';\nexport {\n parseMqttBroker,\n toWebSocketUrl,\n DEFAULT_WSS_PORT,\n DEFAULT_WS_PATH,\n} from './broker.js';\nexport type { MqttBrokerEndpoint, ToWebSocketUrlOptions } from './broker.js';\nexport type { MQTTConfig, MQTTMessage, MQTTEventMap } from './types.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mq/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAC","sourcesContent":["export { Tier0MQClient } from './client.js';\nexport type { TopicHandler } from './client.js';\nexport { appTopic } from './topic.js';\nexport {\n parseMqttBroker,\n toWebSocketUrl,\n DEFAULT_WSS_PORT,\n DEFAULT_WS_PATH,\n} from './broker.js';\nexport type { MqttBrokerEndpoint, ToWebSocketUrlOptions } from './broker.js';\nexport type { MQTTConfig, MQTTMessage, MQTTEventMap } from './types.js';\n"]}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * An App ID usable as one MQTT topic level and as the app segment of a hosted App key's clientId, as Backend
3
+ * `share/hostedappkey` accepts it: `<ws>&h.<app>.<[a-z0-9]{8,32}>`, app `[A-Za-z0-9_-]{1,64}` (no `&`, `.`, `/` or wildcards).
4
+ */
5
+ export declare const APP_SEGMENT: RegExp;
6
+ /**
7
+ * The MQTT topic `apps/<TIER0_APP_ID>/<TIER0_RUNTIME>/<suffix>` in the App's own namespace.
8
+ *
9
+ * An App's key (the `TIER0_API_KEY` the platform injects) may publish and
10
+ * subscribe under `apps/<appId>/<preview|deployed>/#` only: the Preview key
11
+ * under `preview`, the deployed key under `deployed`. Backend picks the
12
+ * segment from the key, not from the environment; the platform sets
13
+ * `TIER0_RUNTIME` to the same word in each (`preview` in Builder previews,
14
+ * `deployed` in deployments), so this helper builds the topic the key is
15
+ * allowed to use.
16
+ *
17
+ * `suffix` is the rest of the topic and may end in the `+` / `#` wildcards for
18
+ * `subscribe`, e.g. `appTopic('alarms/#')`. It must not be empty or start
19
+ * with `/`.
20
+ *
21
+ * Use it only on the platform (Builder previews and deployments). It throws
22
+ * outside the platform: when `TIER0_APP_ID` is missing or is not a valid
23
+ * topic level, or `TIER0_RUNTIME` is not `preview` or `deployed`. It never
24
+ * guesses a segment, so local development does not land in a deployed App's
25
+ * topics. Do not set `TIER0_RUNTIME` locally (only the platform sets it; it
26
+ * also picks the `members.listApp()` scope and platform proxy mode); to debug
27
+ * MQTT locally, write the full topic yourself.
28
+ */
29
+ export declare function appTopic(suffix: string): string;
@@ -0,0 +1,44 @@
1
+ import { getEnvVar } from '../runtime-env.js';
2
+ /**
3
+ * An App ID usable as one MQTT topic level and as the app segment of a hosted App key's clientId, as Backend
4
+ * `share/hostedappkey` accepts it: `<ws>&h.<app>.<[a-z0-9]{8,32}>`, app `[A-Za-z0-9_-]{1,64}` (no `&`, `.`, `/` or wildcards).
5
+ */
6
+ export const APP_SEGMENT = /^[A-Za-z0-9_-]{1,64}$/;
7
+ /**
8
+ * The MQTT topic `apps/<TIER0_APP_ID>/<TIER0_RUNTIME>/<suffix>` in the App's own namespace.
9
+ *
10
+ * An App's key (the `TIER0_API_KEY` the platform injects) may publish and
11
+ * subscribe under `apps/<appId>/<preview|deployed>/#` only: the Preview key
12
+ * under `preview`, the deployed key under `deployed`. Backend picks the
13
+ * segment from the key, not from the environment; the platform sets
14
+ * `TIER0_RUNTIME` to the same word in each (`preview` in Builder previews,
15
+ * `deployed` in deployments), so this helper builds the topic the key is
16
+ * allowed to use.
17
+ *
18
+ * `suffix` is the rest of the topic and may end in the `+` / `#` wildcards for
19
+ * `subscribe`, e.g. `appTopic('alarms/#')`. It must not be empty or start
20
+ * with `/`.
21
+ *
22
+ * Use it only on the platform (Builder previews and deployments). It throws
23
+ * outside the platform: when `TIER0_APP_ID` is missing or is not a valid
24
+ * topic level, or `TIER0_RUNTIME` is not `preview` or `deployed`. It never
25
+ * guesses a segment, so local development does not land in a deployed App's
26
+ * topics. Do not set `TIER0_RUNTIME` locally (only the platform sets it; it
27
+ * also picks the `members.listApp()` scope and platform proxy mode); to debug
28
+ * MQTT locally, write the full topic yourself.
29
+ */
30
+ export function appTopic(suffix) {
31
+ if (typeof suffix !== 'string' || suffix === '' || suffix.startsWith('/')) {
32
+ throw new TypeError('Tier0 SDK v2: appTopic(suffix) needs a non-empty topic suffix that does not start with "/".');
33
+ }
34
+ const appId = getEnvVar('TIER0_APP_ID')?.trim();
35
+ if (!appId || !APP_SEGMENT.test(appId)) {
36
+ throw new Error('Tier0 SDK v2: appTopic needs TIER0_APP_ID (the App ID the platform injects; letters, digits, "-" or "_").');
37
+ }
38
+ const runtime = getEnvVar('TIER0_RUNTIME')?.trim();
39
+ if (runtime !== 'preview' && runtime !== 'deployed') {
40
+ throw new Error(`Tier0 SDK v2: appTopic needs TIER0_RUNTIME "preview" or "deployed", not ${JSON.stringify((runtime ?? '').slice(0, 64))}.`);
41
+ }
42
+ return `apps/${appId}/${runtime}/${suffix}`;
43
+ }
44
+ //# sourceMappingURL=topic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic.js","sourceRoot":"","sources":["../../../src/mq/topic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,SAAS,CAAC,6FAA6F,CAAC,CAAC;IACrH,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,2GAA2G,CAAC,CAAC;IAC/H,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,2EAA2E,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9I,CAAC;IACD,OAAO,QAAQ,KAAK,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;AAC9C,CAAC","sourcesContent":["import { getEnvVar } from '../runtime-env.js';\n\n/**\n * An App ID usable as one MQTT topic level and as the app segment of a hosted App key's clientId, as Backend\n * `share/hostedappkey` accepts it: `<ws>&h.<app>.<[a-z0-9]{8,32}>`, app `[A-Za-z0-9_-]{1,64}` (no `&`, `.`, `/` or wildcards).\n */\nexport const APP_SEGMENT = /^[A-Za-z0-9_-]{1,64}$/;\n\n/**\n * The MQTT topic `apps/<TIER0_APP_ID>/<TIER0_RUNTIME>/<suffix>` in the App's own namespace.\n *\n * An App's key (the `TIER0_API_KEY` the platform injects) may publish and\n * subscribe under `apps/<appId>/<preview|deployed>/#` only: the Preview key\n * under `preview`, the deployed key under `deployed`. Backend picks the\n * segment from the key, not from the environment; the platform sets\n * `TIER0_RUNTIME` to the same word in each (`preview` in Builder previews,\n * `deployed` in deployments), so this helper builds the topic the key is\n * allowed to use.\n *\n * `suffix` is the rest of the topic and may end in the `+` / `#` wildcards for\n * `subscribe`, e.g. `appTopic('alarms/#')`. It must not be empty or start\n * with `/`.\n *\n * Use it only on the platform (Builder previews and deployments). It throws\n * outside the platform: when `TIER0_APP_ID` is missing or is not a valid\n * topic level, or `TIER0_RUNTIME` is not `preview` or `deployed`. It never\n * guesses a segment, so local development does not land in a deployed App's\n * topics. Do not set `TIER0_RUNTIME` locally (only the platform sets it; it\n * also picks the `members.listApp()` scope and platform proxy mode); to debug\n * MQTT locally, write the full topic yourself.\n */\nexport function appTopic(suffix: string): string {\n if (typeof suffix !== 'string' || suffix === '' || suffix.startsWith('/')) {\n throw new TypeError('Tier0 SDK v2: appTopic(suffix) needs a non-empty topic suffix that does not start with \"/\".');\n }\n const appId = getEnvVar('TIER0_APP_ID')?.trim();\n if (!appId || !APP_SEGMENT.test(appId)) {\n throw new Error('Tier0 SDK v2: appTopic needs TIER0_APP_ID (the App ID the platform injects; letters, digits, \"-\" or \"_\").');\n }\n const runtime = getEnvVar('TIER0_RUNTIME')?.trim();\n if (runtime !== 'preview' && runtime !== 'deployed') {\n throw new Error(`Tier0 SDK v2: appTopic needs TIER0_RUNTIME \"preview\" or \"deployed\", not ${JSON.stringify((runtime ?? '').slice(0, 64))}.`);\n }\n return `apps/${appId}/${runtime}/${suffix}`;\n}\n"]}
@@ -5,6 +5,9 @@ export interface MQTTConfig {
5
5
  * - 裸 `host`(可含端口,如 `host:8084`);
6
6
  * - 平台 `/openapi/v2/info` 返回的原始 `mqttBroker`(如 `tcp://host:1883`,
7
7
  * 建议先用 {@link toWebSocketUrl} 归一后再传入,见 `@tier0/sdk-v2/mq` 的 broker 工具)。
8
+ *
9
+ * 在 Tier0 预览和部署里不要传:平台注入 `TIER0_MQTT_HOST` / `TIER0_MQTT_PORT`(沙箱能连到的
10
+ * broker 入口),不传 host 时 SDK 读它们(有 `TIER0_MQTT_URL` 时它优先)。
8
11
  */
9
12
  host?: string;
10
13
  /** WebSocket port fallback when host has no embedded WebSocket port. */
@@ -16,11 +19,28 @@ export interface MQTTConfig {
16
19
  secure?: boolean;
17
20
  clientId?: string;
18
21
  username?: string;
19
- /** Original API key; connect-time changes refresh automatically derived identity fields. */
22
+ /**
23
+ * API key or MQTT password. Explicit undefined is rejected by `connect()`;
24
+ * omit it to keep existing settings. Before the first connection,
25
+ * `connect()` may change it and refreshes automatically derived identity
26
+ * fields; once a client exists, disconnect and create a new client to
27
+ * change it.
28
+ * Leave it unset in the platform: without it the SDK uses `TIER0_API_KEY`,
29
+ * the App's key the platform puts in the server process environment
30
+ * (secret), and derives username and clientId from it. Browsers do not
31
+ * connect to the broker in the platform: the App's server subscribes and
32
+ * forwards what a visitor may see.
33
+ */
20
34
  password?: string;
21
35
  keepAlive?: number;
36
+ /** Base of the reconnect backoff in milliseconds, capped at 5 minutes; 0 turns reconnecting off. */
22
37
  reconnectPeriod?: number;
23
38
  connectTimeout?: number;
39
+ /**
40
+ * Defaults to false: the persistent session keeps QoS 1 messages across a
41
+ * reconnect. Messages beyond the broker's offline queue (EMQX default 1000)
42
+ * are still lost.
43
+ */
24
44
  clean?: boolean;
25
45
  /**
26
46
  * 背压保护阈值:handler 连续返回 false(表示下游停滞/消费者已断开)达到
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mq/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface MQTTConfig {\n /**\n * broker 地址。支持三种形态:\n * - 完整 WebSocket URL,如 `wss://host:8084/mqtt`(推荐浏览器场景显式使用);\n * - 裸 `host`(可含端口,如 `host:8084`);\n * - 平台 `/openapi/v2/info` 返回的原始 `mqttBroker`(如 `tcp://host:1883`,\n * 建议先用 {@link toWebSocketUrl} 归一后再传入,见 `@tier0/sdk-v2/mq` 的 broker 工具)。\n */\n host?: string;\n /** WebSocket port fallback when host has no embedded WebSocket port. */\n port?: number;\n /**\n * 当 host 不带 ws(s) scheme 时,显式指定用 wss(true) 还是 ws(false)。\n * 缺省自适应:浏览器 https 页面或端口 8084 用 wss,其余用 ws。\n */\n secure?: boolean;\n clientId?: string;\n username?: string;\n /** Original API key; connect-time changes refresh automatically derived identity fields. */\n password?: string;\n keepAlive?: number;\n reconnectPeriod?: number;\n connectTimeout?: number;\n clean?: boolean;\n /**\n * 背压保护阈值:handler 连续返回 false(表示下游停滞/消费者已断开)达到\n * 该次数后,SDK 自动移除该订阅并向 broker 退订,避免消息在无消费者的\n * 应用内队列中持续堆积。0 或不设置表示关闭该保护(保持原有行为)。\n */\n maxBackpressuredDeliveries?: number;\n}\n\nexport type MQTTMessage = {\n topic: string;\n payload: string | Buffer;\n qos: number;\n retain: boolean;\n};\n\nexport type MQTTEventMap = {\n connect: () => void;\n disconnect: () => void;\n error: (error: Error) => void;\n message: (message: MQTTMessage) => void;\n /** 订阅因持续背压被 SDK 自动移除时触发。 */\n subscriptionDropped: (info: { topic: string; reason: string }) => void;\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mq/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface MQTTConfig {\n /**\n * broker 地址。支持三种形态:\n * - 完整 WebSocket URL,如 `wss://host:8084/mqtt`(推荐浏览器场景显式使用);\n * - 裸 `host`(可含端口,如 `host:8084`);\n * - 平台 `/openapi/v2/info` 返回的原始 `mqttBroker`(如 `tcp://host:1883`,\n * 建议先用 {@link toWebSocketUrl} 归一后再传入,见 `@tier0/sdk-v2/mq` 的 broker 工具)。\n *\n * 在 Tier0 预览和部署里不要传:平台注入 `TIER0_MQTT_HOST` / `TIER0_MQTT_PORT`(沙箱能连到的\n * broker 入口),不传 host 时 SDK 读它们(有 `TIER0_MQTT_URL` 时它优先)。\n */\n host?: string;\n /** WebSocket port fallback when host has no embedded WebSocket port. */\n port?: number;\n /**\n * 当 host 不带 ws(s) scheme 时,显式指定用 wss(true) 还是 ws(false)。\n * 缺省自适应:浏览器 https 页面或端口 8084 用 wss,其余用 ws。\n */\n secure?: boolean;\n clientId?: string;\n username?: string;\n /**\n * API key or MQTT password. Explicit undefined is rejected by `connect()`;\n * omit it to keep existing settings. Before the first connection,\n * `connect()` may change it and refreshes automatically derived identity\n * fields; once a client exists, disconnect and create a new client to\n * change it.\n * Leave it unset in the platform: without it the SDK uses `TIER0_API_KEY`,\n * the App's key the platform puts in the server process environment\n * (secret), and derives username and clientId from it. Browsers do not\n * connect to the broker in the platform: the App's server subscribes and\n * forwards what a visitor may see.\n */\n password?: string;\n keepAlive?: number;\n /** Base of the reconnect backoff in milliseconds, capped at 5 minutes; 0 turns reconnecting off. */\n reconnectPeriod?: number;\n connectTimeout?: number;\n /**\n * Defaults to false: the persistent session keeps QoS 1 messages across a\n * reconnect. Messages beyond the broker's offline queue (EMQX default 1000)\n * are still lost.\n */\n clean?: boolean;\n /**\n * 背压保护阈值:handler 连续返回 false(表示下游停滞/消费者已断开)达到\n * 该次数后,SDK 自动移除该订阅并向 broker 退订,避免消息在无消费者的\n * 应用内队列中持续堆积。0 或不设置表示关闭该保护(保持原有行为)。\n */\n maxBackpressuredDeliveries?: number;\n}\n\nexport type MQTTMessage = {\n topic: string;\n payload: string | Buffer;\n qos: number;\n retain: boolean;\n};\n\nexport type MQTTEventMap = {\n connect: () => void;\n disconnect: () => void;\n error: (error: Error) => void;\n message: (message: MQTTMessage) => void;\n /** 订阅因持续背压被 SDK 自动移除时触发。 */\n subscriptionDropped: (info: { topic: string; reason: string }) => void;\n};\n"]}
@@ -127,6 +127,16 @@ export declare const OPENAPI_OPERATIONS: {
127
127
  readonly requestSchema: "Platform_SdknotificationsGetRequest";
128
128
  readonly responseSchema: "Platform_SdknotificationsGetWire";
129
129
  };
130
+ readonly notificationsList: {
131
+ readonly name: "notificationsList";
132
+ readonly method: "POST";
133
+ readonly path: "/openapi/v2/notifications/list";
134
+ readonly pathParams: readonly [];
135
+ readonly mode: "direct";
136
+ readonly readonly: true;
137
+ readonly requestSchema: "Platform_SdknotificationsListRequest";
138
+ readonly responseSchema: "Platform_SdknotificationsListWire";
139
+ };
130
140
  readonly membersListWorkspace: {
131
141
  readonly name: "membersListWorkspace";
132
142
  readonly method: "POST";
@@ -514,6 +524,8 @@ export declare function createOpenAPI(http: HttpClient): {
514
524
  send: (body: components["schemas"]["SdknotificationsSendRequest"], options?: RequestOptions) => Promise<{
515
525
  createdAt: string;
516
526
  messageId: string;
527
+ recipientName?: string;
528
+ recipientUserId: string;
517
529
  status: string;
518
530
  }>;
519
531
  get: (body: components["schemas"]["SdknotificationsGetRequest"], options?: RequestOptions) => Promise<{
@@ -523,9 +535,17 @@ export declare function createOpenAPI(http: HttpClient): {
523
535
  errorCode?: string;
524
536
  message?: string;
525
537
  messageId: string;
538
+ recipientName?: string;
539
+ recipientUserId: string;
526
540
  status: string;
527
541
  type: string;
528
542
  }>;
543
+ list: (body?: components["schemas"]["SdknotificationsListRequest"], options?: RequestOptions) => Promise<{
544
+ list: components["schemas"]["NotificationListItem"][];
545
+ page: number | bigint;
546
+ size: number | bigint;
547
+ total: number | bigint;
548
+ }>;
529
549
  };
530
550
  members: {
531
551
  listWorkspace: (body?: components["schemas"]["SdkmembersListWorkspaceRequest"], options?: RequestOptions) => Promise<{
@@ -125,6 +125,16 @@ export const OPENAPI_OPERATIONS = {
125
125
  "requestSchema": "Platform_SdknotificationsGetRequest",
126
126
  "responseSchema": "Platform_SdknotificationsGetWire"
127
127
  },
128
+ "notificationsList": {
129
+ "name": "notificationsList",
130
+ "method": "POST",
131
+ "path": "/openapi/v2/notifications/list",
132
+ "pathParams": [],
133
+ "mode": "direct",
134
+ "readonly": true,
135
+ "requestSchema": "Platform_SdknotificationsListRequest",
136
+ "responseSchema": "Platform_SdknotificationsListWire"
137
+ },
128
138
  "membersListWorkspace": {
129
139
  "name": "membersListWorkspace",
130
140
  "method": "POST",
@@ -459,6 +469,7 @@ export function createOpenAPI(http) {
459
469
  "notifications": {
460
470
  "send": (body, options) => http.operation(OPENAPI_OPERATIONS["notificationsSend"], { body }, options),
461
471
  "get": (body, options) => http.operation(OPENAPI_OPERATIONS["notificationsGet"], { body }, options),
472
+ "list": (body, options) => http.operation(OPENAPI_OPERATIONS["notificationsList"], { body }, options),
462
473
  },
463
474
  "members": {
464
475
  "listWorkspace": (body, options) => http.operation(OPENAPI_OPERATIONS["membersListWorkspace"], { body }, options),