@apex-inc/capacitor-plugin 0.3.6 → 0.3.7
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.
|
@@ -67,6 +67,12 @@ public final class NativeBatchSender {
|
|
|
67
67
|
/// Drains the queue, one batch at a time, with exponential backoff
|
|
68
68
|
/// on retryable failures. Safe to call concurrently — only one
|
|
69
69
|
/// flush actually runs at a time; concurrent callers no-op.
|
|
70
|
+
///
|
|
71
|
+
/// Accumulator is passed by value through the recursion (no inout).
|
|
72
|
+
/// The previous inout-based design tripped Swift's exclusivity
|
|
73
|
+
/// runtime check at line 85 because the same `totalFlushed` local
|
|
74
|
+
/// was both captured by the `done` closure and passed inout — a
|
|
75
|
+
/// classic simultaneous-access violation that traps in debug builds.
|
|
70
76
|
public func flush(queue: NativeOfflineQueue, completion: @escaping (Int, Int) -> Void) {
|
|
71
77
|
serial.async { [weak self] in
|
|
72
78
|
guard let self = self else { completion(0, 0); return }
|
|
@@ -77,54 +83,56 @@ public final class NativeBatchSender {
|
|
|
77
83
|
return
|
|
78
84
|
}
|
|
79
85
|
self.inFlight = true
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
self.drainLoop(queue: queue, accumulated: 0) { [weak self] flushed in
|
|
87
|
+
self?.serial.async {
|
|
88
|
+
self?.inFlight = false
|
|
89
|
+
let remaining = (try? queue.size()) ?? 0
|
|
90
|
+
completion(flushed, remaining)
|
|
91
|
+
}
|
|
86
92
|
}
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
|
|
96
|
+
/// Recursive drain. `accumulated` is the running total of successfully
|
|
97
|
+
/// flushed events; `done` is invoked exactly once with the final count.
|
|
90
98
|
private func drainLoop(
|
|
91
99
|
queue: NativeOfflineQueue,
|
|
92
|
-
|
|
93
|
-
done: @escaping () -> Void
|
|
100
|
+
accumulated: Int,
|
|
101
|
+
done: @escaping (Int) -> Void
|
|
94
102
|
) {
|
|
95
103
|
let batch: [NativeQueuedEvent]
|
|
96
104
|
do {
|
|
97
105
|
batch = try queue.peek(batchSize: batchSize)
|
|
98
106
|
} catch {
|
|
99
107
|
if debug { print("[apex-capacitor] peek failed: \(error)") }
|
|
100
|
-
done()
|
|
108
|
+
done(accumulated)
|
|
101
109
|
return
|
|
102
110
|
}
|
|
103
111
|
if batch.isEmpty {
|
|
104
|
-
done()
|
|
112
|
+
done(accumulated)
|
|
105
113
|
return
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
let localFlushed = flushed
|
|
109
116
|
sendBatchWithRetry(batch, attempt: 0) { [weak self] outcome in
|
|
110
|
-
guard let self = self else { done(); return }
|
|
117
|
+
guard let self = self else { done(accumulated); return }
|
|
111
118
|
self.serial.async {
|
|
112
119
|
let ids = batch.map { $0.id }
|
|
113
120
|
switch outcome {
|
|
114
121
|
case .success:
|
|
115
122
|
try? queue.markSent(ids: ids)
|
|
116
123
|
if self.debug { print("[apex-capacitor] flushed batch of \(batch.count)") }
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
self.drainLoop(
|
|
125
|
+
queue: queue,
|
|
126
|
+
accumulated: accumulated + batch.count,
|
|
127
|
+
done: done
|
|
128
|
+
)
|
|
121
129
|
case .nonRetryable(let status):
|
|
122
130
|
if self.debug { print("[apex-capacitor] non-retryable HTTP \(status); leaving events queued") }
|
|
123
|
-
done()
|
|
131
|
+
done(accumulated)
|
|
124
132
|
case .retryableExhausted(let err):
|
|
125
133
|
try? queue.markFailed(ids: ids)
|
|
126
134
|
if self.debug { print("[apex-capacitor] retries exhausted: \(err)") }
|
|
127
|
-
done()
|
|
135
|
+
done(accumulated)
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
138
|
}
|
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.7",
|
|
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",
|