@annadata/capacitor-mqtt-quic 0.1.9 → 0.2.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 (32) hide show
  1. package/README.md +90 -9
  2. package/android/install/wolfssl-android/arm64-v8a/lib/libwolfssl.a +0 -0
  3. package/android/install/wolfssl-android/armeabi-v7a/lib/libwolfssl.a +0 -0
  4. package/android/install/wolfssl-android/x86_64/lib/libwolfssl.a +0 -0
  5. package/android/src/main/kotlin/ai/annadata/mqttquic/MqttQuicPlugin.kt +17 -0
  6. package/android/src/main/kotlin/ai/annadata/mqttquic/client/MQTTClient.kt +40 -0
  7. package/dist/esm/definitions.d.ts +8 -0
  8. package/dist/esm/definitions.d.ts.map +1 -1
  9. package/dist/esm/web.d.ts +5 -1
  10. package/dist/esm/web.d.ts.map +1 -1
  11. package/dist/esm/web.js +6 -0
  12. package/dist/esm/web.js.map +1 -1
  13. package/dist/plugin.cjs.js +6 -0
  14. package/dist/plugin.cjs.js.map +1 -1
  15. package/dist/plugin.js +6 -0
  16. package/dist/plugin.js.map +1 -1
  17. package/ios/Sources/MqttQuicPlugin/Client/MQTTClient.swift +4 -0
  18. package/ios/Sources/MqttQuicPlugin/MqttQuicPlugin.swift +14 -8
  19. package/ios/Sources/MqttQuicPlugin/Transport/QUICStreamAdapter.swift +2 -7
  20. package/ios/libs/libnghttp3.a +0 -0
  21. package/ios/libs/libngtcp2.a +0 -0
  22. package/ios/libs/libngtcp2_crypto_wolfssl.a +0 -0
  23. package/ios/libs/libwolfssl.a +0 -0
  24. package/ios/libs-simulator/libnghttp3.a +0 -0
  25. package/ios/libs-simulator/libngtcp2.a +0 -0
  26. package/ios/libs-simulator/libngtcp2_crypto_wolfssl.a +0 -0
  27. package/ios/libs-simulator/libwolfssl.a +0 -0
  28. package/ios/libs-simulator-x86_64/libnghttp3.a +0 -0
  29. package/ios/libs-simulator-x86_64/libngtcp2.a +0 -0
  30. package/ios/libs-simulator-x86_64/libngtcp2_crypto_wolfssl.a +0 -0
  31. package/ios/libs-simulator-x86_64/libwolfssl.a +0 -0
  32. package/package.json +1 -1
@@ -38,6 +38,8 @@ public final class MQTTClient {
38
38
  private var keepaliveTask: Task<Void, Never>?
39
39
  private var nextPacketId: UInt16 = 1
40
40
  private var subscribedTopics: [String: (Data) -> Void] = [:]
41
+ /// Optional global callback for every incoming PUBLISH (topic, payload). Used by plugin to forward to JS. Matches Android.
42
+ var onPublish: ((String, Data) -> Void)?
41
43
  /// Per-connection Topic Alias map (alias -> topic name) for MQTT 5.0 incoming PUBLISH.
42
44
  private var topicAliasMap: [Int: String] = [:]
43
45
  /// Handoff from message loop to subscribe() so SUBACK is not consumed by the loop (avoids race and "insufficientData(SUBACK packet ID)").
@@ -515,7 +517,9 @@ public final class MQTTClient {
515
517
 
516
518
  self.lock.lock()
517
519
  let cb = self.subscribedTopics[topic]
520
+ let globalCb = self.onPublish
518
521
  self.lock.unlock()
522
+ globalCb?(topic, payload)
519
523
  cb?(payload)
520
524
 
521
525
  if qos >= 1, let pid = packetId {
@@ -117,6 +117,19 @@ public class MqttQuicPlugin: CAPPlugin, CAPBridgedPlugin {
117
117
  break
118
118
  }
119
119
  client = MQTTClient(protocolVersion: protocolVersion)
120
+ // Forward every incoming PUBLISH to JS so addListener('message', ...) receives topic + payload (matches Android)
121
+ client.onPublish = { [weak self] topic, payload in
122
+ guard let self = self else { return }
123
+ let payloadStr: String
124
+ if let str = String(data: payload, encoding: .utf8) {
125
+ payloadStr = str
126
+ } else {
127
+ payloadStr = payload.base64EncodedString()
128
+ }
129
+ DispatchQueue.main.async {
130
+ self.notifyListeners("message", data: ["topic": topic, "payload": payloadStr])
131
+ }
132
+ }
120
133
  try await client.connect(
121
134
  host: host,
122
135
  port: UInt16(port),
@@ -257,14 +270,7 @@ public class MqttQuicPlugin: CAPPlugin, CAPBridgedPlugin {
257
270
  Task {
258
271
  do {
259
272
  try await client.subscribe(topic: topic, qos: UInt8(min(qos, 2)), subscriptionIdentifier: subscriptionIdentifier)
260
- // Deliver incoming PUBLISH for this topic to JS (avoids message loop having no handler; prevents stuck state)
261
- client.onMessage(topic) { [weak self] payload in
262
- guard let self = self else { return }
263
- let str = String(data: payload, encoding: .utf8) ?? ""
264
- DispatchQueue.main.async {
265
- self.notifyListeners("message", data: ["topic": topic, "payload": str])
266
- }
267
- }
273
+ // Incoming PUBLISH delivered via onPublish set in connect(); no per-topic handler needed
268
274
  DispatchQueue.main.async { call.resolve(["success": true]) }
269
275
  } catch {
270
276
  DispatchQueue.main.async { call.reject("\(error)") }
@@ -19,21 +19,16 @@ public final class QUICStreamReader: MQTTStreamReaderProtocol {
19
19
  try await stream.read(maxBytes: maxBytes)
20
20
  }
21
21
 
22
+ /// Read exactly n bytes. Waits indefinitely for data (matches Android behavior).
23
+ /// Previously had a 300ms limit which caused message loop to throw and disconnect before PUBLISH packets arrived.
22
24
  public func readexactly(_ n: Int) async throws -> Data {
23
25
  var acc = Data()
24
- var emptyCount = 0
25
- let maxEmptyRetries = 60 // ~300ms total (60 * 5ms) so SUBACK can arrive
26
26
  while acc.count < n {
27
27
  let chunk = try await stream.read(maxBytes: n - acc.count)
28
28
  if chunk.isEmpty {
29
- emptyCount += 1
30
- if emptyCount >= maxEmptyRetries {
31
- throw MQTTProtocolError.insufficientData("readexactly")
32
- }
33
29
  try await Task.sleep(nanoseconds: 5_000_000) // 5ms
34
30
  continue
35
31
  }
36
- emptyCount = 0
37
32
  acc.append(chunk)
38
33
  }
39
34
  return acc
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@annadata/capacitor-mqtt-quic",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "MQTT-over-QUIC client for Capacitor (iOS, Android, Web). Native: ngtcp2+WolfSSL; Web: MQTT over WebSocket (WSS), same API.",
6
6
  "main": "dist/plugin.cjs.js",