@apex-inc/capacitor-plugin 0.3.7 → 0.3.8
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.
|
@@ -76,6 +76,11 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
|
|
|
76
76
|
// reached the server. See friction-log F6.
|
|
77
77
|
private var batchSender: NativeBatchSender?
|
|
78
78
|
private var flushTimer: Timer?
|
|
79
|
+
// MMP-207 — debounced flush. Without this, every `track()` call
|
|
80
|
+
// kicked a POST, so 8 quick taps = 8 separate single-event HTTP
|
|
81
|
+
// requests. With debounce, rapid-fire events coalesce into one
|
|
82
|
+
// batch on the next tick.
|
|
83
|
+
private var flushDebounceWork: DispatchWorkItem?
|
|
79
84
|
|
|
80
85
|
public override func load() {
|
|
81
86
|
let defaults = UserDefaults.standard
|
|
@@ -220,16 +225,29 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
|
|
|
220
225
|
}
|
|
221
226
|
}
|
|
222
227
|
|
|
223
|
-
/// Fire-and-forget flush.
|
|
224
|
-
///
|
|
228
|
+
/// Fire-and-forget flush. Track-triggered calls are debounced
|
|
229
|
+
/// 250ms so rapid tap sessions coalesce into a single batch POST.
|
|
230
|
+
/// Timer + foreground + initialize callers bypass the debounce
|
|
231
|
+
/// since they're already paced.
|
|
225
232
|
private func kickFlush(reason: String) {
|
|
226
233
|
guard let queue = offlineQueue, let sender = batchSender else { return }
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if self
|
|
230
|
-
|
|
234
|
+
let runFlush: () -> Void = { [weak self] in
|
|
235
|
+
guard let self = self else { return }
|
|
236
|
+
if self.debug { print("[apex-capacitor] flush kicked (\(reason))") }
|
|
237
|
+
sender.flush(queue: queue) { [weak self] flushed, remaining in
|
|
238
|
+
if self?.debug == true && (flushed > 0 || remaining > 0) {
|
|
239
|
+
print("[apex-capacitor] flush done — sent \(flushed), remaining \(remaining)")
|
|
240
|
+
}
|
|
231
241
|
}
|
|
232
242
|
}
|
|
243
|
+
if reason == "track" {
|
|
244
|
+
flushDebounceWork?.cancel()
|
|
245
|
+
let work = DispatchWorkItem(block: runFlush)
|
|
246
|
+
flushDebounceWork = work
|
|
247
|
+
DispatchQueue.global().asyncAfter(deadline: .now() + .milliseconds(250), execute: work)
|
|
248
|
+
} else {
|
|
249
|
+
runFlush()
|
|
250
|
+
}
|
|
233
251
|
}
|
|
234
252
|
|
|
235
253
|
// MARK: - ATT
|
|
@@ -424,6 +442,14 @@ public class ApexCapacitorPlugin: CAPPlugin, CAPBridgedPlugin, UNUserNotificatio
|
|
|
424
442
|
}
|
|
425
443
|
codablePayload["platform"] = AnyCodable("ios")
|
|
426
444
|
codablePayload["timestamp"] = AnyCodable(ISO8601DateFormatter().string(from: Date()))
|
|
445
|
+
// MMP-207 — stamp visitorId. Without this, /api/events accepts
|
|
446
|
+
// the event into the SDK firehose store but its second pass
|
|
447
|
+
// bails at `if (!visitorId) continue;` so the event never
|
|
448
|
+
// reaches the TESTEVT# / EVT# stores the debug dashboard reads.
|
|
449
|
+
// Net result before this fix: events arrived but the dashboard
|
|
450
|
+
// showed nothing. The visitor id is the stable per-install id
|
|
451
|
+
// we mint in load() and persist to UserDefaults.
|
|
452
|
+
codablePayload["visitorId"] = AnyCodable(visitorId)
|
|
427
453
|
let event = NativeQueuedEvent(
|
|
428
454
|
id: id,
|
|
429
455
|
payload: codablePayload,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apex-inc/capacitor-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Apex Capacitor plugin — iOS/Android attribution, events, deep linking, SKAN, and offline-tolerant tracking for Capacitor apps.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|