@goliapkg/sentori-react-native 6.4.0 → 7.0.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.
@@ -57,5 +57,5 @@ constructor(
57
57
  * direction of a lie.
58
58
  */
59
59
  object SentoriVersion {
60
- const val CURRENT = "1.7.1"
60
+ const val CURRENT = "2.0.0"
61
61
  }
@@ -273,17 +273,24 @@ object SentoriPush {
273
273
  */
274
274
  private fun identityChanged(appContext: Context) {
275
275
  val config = SentoriConfig.current ?: return
276
- val prefs = appContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
277
- val token = prefs.getString(TOKEN_KEY, null) ?: return
278
- if (prefs.getString(HANDLE_KEY, null) == null) return
276
+ // Everything, including the preference reads, on the worker.
277
+ // `Sentori.user` is synchronous and is called from wherever
278
+ // the host signs someone in — usually the main thread — and
279
+ // reading preferences there is disk I/O on the thread that
280
+ // draws frames. Warm in practice, since this listener is only
281
+ // installed after a registration has already touched them; on
282
+ // the worker it cannot be anything else.
283
+ worker.execute {
284
+ val prefs = appContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
285
+ val token = prefs.getString(TOKEN_KEY, null) ?: return@execute
286
+ if (prefs.getString(HANDLE_KEY, null) == null) return@execute
279
287
 
280
- // `Sentori.user` is a verb an app may call on every screen,
281
- // and one request per call is not free to a host.
282
- val identity = "${SentoriScope.userKey}\u0000${SentoriScope.traits}"
283
- if (identity == lastSentIdentity) return
284
- lastSentIdentity = identity
288
+ // `Sentori.user` is a verb an app may call on every screen,
289
+ // and one request per call is not free to a host.
290
+ val identity = "${SentoriScope.userKey}\u0000${SentoriScope.traits}"
291
+ if (identity == lastSentIdentity) return@execute
292
+ lastSentIdentity = identity
285
293
 
286
- worker.execute {
287
294
  when (val r = registerWithServer(appContext, token, config)) {
288
295
  is Result.Success -> rememberHandle(appContext, r.handle, token)
289
296
  is Result.Failure -> {
@@ -319,6 +326,9 @@ object SentoriPush {
319
326
  }
320
327
  }
321
328
 
329
+ /** Hand one drained batch to the host's callbacks, for tests. */
330
+ internal fun drainForTests(state: Map<String, Any?>) = flush(state)
331
+
322
332
  /** This installation's id, minted on first use and kept after. */
323
333
  internal fun installId(ctx: Context): String {
324
334
  val prefs = ctx.applicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
@@ -350,7 +360,12 @@ object SentoriPush {
350
360
  "push register failed (${result.reason.reason}): ${result.message}",
351
361
  )
352
362
  }
353
- completion(result)
363
+ // The host's callback is the host's code. A registration that
364
+ // succeeded must not be undone by what the host does with the
365
+ // news, and this runs on the single worker thread — an
366
+ // exception here takes the thread, and with it every push
367
+ // request the process makes afterwards.
368
+ safely("register callback") { completion(result) }
354
369
  }
355
370
 
356
371
  private fun finishRegister(
@@ -439,7 +454,7 @@ object SentoriPush {
439
454
  val ok =
440
455
  try {
441
456
  conn =
442
- URL("${config.ingestUrl}/v1/push/tokens/$handle").openConnection()
457
+ URL("${config.ingestUrl}/v1/push/devices/$handle").openConnection()
443
458
  as HttpURLConnection
444
459
  conn.requestMethod = "DELETE"
445
460
  conn.setRequestProperty("Authorization", "Bearer ${config.token}")
@@ -507,7 +522,7 @@ object SentoriPush {
507
522
  var conn: HttpURLConnection? = null
508
523
  return try {
509
524
  conn =
510
- URL("${config.ingestUrl}/v1/push/tokens").openConnection() as HttpURLConnection
525
+ URL("${config.ingestUrl}/v1/push/devices").openConnection() as HttpURLConnection
511
526
  conn.requestMethod = "POST"
512
527
  conn.setRequestProperty("Content-Type", "application/json")
513
528
  conn.setRequestProperty("Authorization", "Bearer ${config.token}")
@@ -527,15 +542,9 @@ object SentoriPush {
527
542
  // The handle is the `device_tokens` row id, a bare
528
543
  // uuid. The RN SDK parsed it as an `ipt_*` string no
529
544
  // server has ever returned.
530
- // `spToken` is the name; `token_id` is the name the
531
- // server shipped under. Reading the new one first and
532
- // falling back matters in one direction that is easy
533
- // to miss: a self-hosted deployment upgrades on its
534
- // own schedule, so an SDK newer than its server is an
535
- // ordinary state, and an SDK that only knew the new
536
- // name would fail every registration against it.
545
+ // The address, by its one name.
537
546
  val json = JSONObject(text)
538
- val handle = json.optString("spToken").ifEmpty { json.optString("token_id") }
547
+ val handle = json.optString("spToken")
539
548
  if (handle.isNullOrEmpty()) {
540
549
  Result.Failure(Failure.SERVER_REJECTED, "server returned no device token id")
541
550
  } else {
@@ -558,7 +567,11 @@ object SentoriPush {
558
567
  if (drainTask != null) return
559
568
  drainTask =
560
569
  worker.scheduleWithFixedDelay(
561
- { flush(SentoriPushNotifications.drainState()) },
570
+ // Belt as well as braces: `flush` contains the
571
+ // host's code, and this contains everything else,
572
+ // because a task that throws is a task the
573
+ // executor never runs again.
574
+ { safely("drain") { flush(SentoriPushNotifications.drainState()) } },
562
575
  1,
563
576
  1,
564
577
  TimeUnit.SECONDS,
@@ -567,11 +580,36 @@ object SentoriPush {
567
580
  }
568
581
 
569
582
  @Suppress("UNCHECKED_CAST")
583
+ /**
584
+ * Hand a drained batch to the host, without letting the host reach
585
+ * back.
586
+ *
587
+ * Push is allowed to fail silently; it is never allowed to make
588
+ * the host app fail. The handlers are the host's own code running
589
+ * inside our loop, and the loop is a `scheduleWithFixedDelay` —
590
+ * where an exception out of the task makes the executor **cancel
591
+ * every future run**, silently. One throwing `onMessage` ended
592
+ * push delivery for the life of the process, and nothing anywhere
593
+ * said so.
594
+ */
570
595
  private fun flush(state: Map<String, Any?>) {
571
596
  val (message, tap) = synchronized(lock) { onMessage to onTap }
572
597
  if (message == null && tap == null) return
573
- (state["notifications"] as? List<Map<String, Any?>>)?.forEach { message?.invoke(it) }
574
- (state["taps"] as? List<Map<String, Any?>>)?.forEach { tap?.invoke(it) }
598
+ (state["notifications"] as? List<Map<String, Any?>>)?.forEach {
599
+ safely("onMessage") { message?.invoke(it) }
600
+ }
601
+ (state["taps"] as? List<Map<String, Any?>>)?.forEach {
602
+ safely("onTap") { tap?.invoke(it) }
603
+ }
604
+ }
605
+
606
+ /** Run the host's own code without letting it reach back into ours. */
607
+ private inline fun safely(what: String, body: () -> Unit) {
608
+ try {
609
+ body()
610
+ } catch (t: Throwable) {
611
+ android.util.Log.w("sentori", "push $what threw — carrying on", t)
612
+ }
575
613
  }
576
614
 
577
615
  internal fun resetForTests() {
@@ -525,7 +525,7 @@ class SentoriPushTest {
525
525
  }
526
526
  bodies.add(String(body, 0, read, Charsets.UTF_8))
527
527
  val payload =
528
- """{"spToken":"019ff000-0000-7000-8000-000000000001","is_new":false}"""
528
+ """{"spToken":"019ff000-0000-7000-8000-000000000001","isNew":false}"""
529
529
  c.getOutputStream().write(
530
530
  ("HTTP/1.1 202 Accepted\r\nContent-Type: application/json\r\n" +
531
531
  "Content-Length: ${payload.toByteArray().size}\r\n" +
@@ -704,4 +704,73 @@ class SentoriPushTest {
704
704
  assertEquals(0, rec.bodies.size)
705
705
  }
706
706
  }
707
+
708
+ /**
709
+ * Push is allowed to fail silently. It is never allowed to make
710
+ * the host app fail.
711
+ *
712
+ * The host's own handlers are the sharp edge: they are its code
713
+ * and they run inside our loop. Worse here than anywhere — the
714
+ * drain is a `scheduleWithFixedDelay`, and an exception out of a
715
+ * scheduled task makes the executor **cancel every future run**,
716
+ * silently. One throwing `onMessage` used to end push delivery for
717
+ * the life of the process, with nothing anywhere to say so.
718
+ */
719
+ @Test
720
+ fun aThrowingHandlerDoesNotStopDelivery() {
721
+ val ctx = ApplicationProvider.getApplicationContext<android.content.Context>()
722
+ SentoriConfig.set(
723
+ SentoriConfig(token = "st_test", ingestUrl = "http://127.0.0.1:9",
724
+ release = "app@1.0.0", environment = "test"),
725
+ )
726
+ val seen = mutableListOf<String>()
727
+ val latch = CountDownLatch(1)
728
+ SentoriPush.register(
729
+ ctx,
730
+ activity = null,
731
+ timeoutMs = 200,
732
+ onMessage = {
733
+ seen.add(it["title"] as? String ?: "?")
734
+ if (it["title"] == "one") error("the host threw")
735
+ },
736
+ onTap = { seen.add("tap") },
737
+ ) { latch.countDown() }
738
+ assertTrue(latch.await(30, TimeUnit.SECONDS))
739
+
740
+ // One bad handler must not swallow the rest of the batch.
741
+ SentoriPush.drainForTests(
742
+ mapOf(
743
+ "notifications" to listOf(
744
+ mapOf("title" to "one"),
745
+ mapOf("title" to "two"),
746
+ ),
747
+ "taps" to listOf(mapOf<String, Any?>("tapped" to true)),
748
+ ),
749
+ )
750
+ assertEquals(listOf("one", "two", "tap"), seen)
751
+
752
+ // And the next batch still arrives, which is what would have
753
+ // been lost when the executor cancelled the task.
754
+ SentoriPush.drainForTests(
755
+ mapOf("notifications" to listOf(mapOf("title" to "three")), "taps" to null),
756
+ )
757
+ assertEquals(listOf("one", "two", "tap", "three"), seen)
758
+ }
759
+
760
+ /** A host whose completion throws must not take the worker with it. */
761
+ @Test
762
+ fun aThrowingCompletionIsContained() {
763
+ val ctx = ApplicationProvider.getApplicationContext<android.content.Context>()
764
+ SentoriConfig.set(
765
+ SentoriConfig(token = "st_test", ingestUrl = "http://127.0.0.1:9",
766
+ release = "app@1.0.0", environment = "test"),
767
+ )
768
+ val second = CountDownLatch(1)
769
+ SentoriPush.register(ctx, activity = null, timeoutMs = 200) { error("the host threw") }
770
+ Thread.sleep(300)
771
+ // The worker is a single thread. If the first completion took
772
+ // it down, nothing after it ever runs.
773
+ SentoriPush.register(ctx, activity = null, timeoutMs = 200) { second.countDown() }
774
+ assertTrue("the worker did not survive a throwing completion", second.await(30, TimeUnit.SECONDS))
775
+ }
707
776
  }
package/lib/push.d.ts CHANGED
@@ -80,7 +80,7 @@ export type PushNotificationPayload = {
80
80
  */
81
81
  export declare function register(opts?: PushRegisterOptions): Promise<PushRegisterResult>;
82
82
  /**
83
- * Revoke the cached handle (DELETE /v1/push/tokens/{ipt}) +
83
+ * Revoke the cached handle (DELETE /v1/push/devices/{ipt}) +
84
84
  * unregister locally. Idempotent — repeat calls are no-ops.
85
85
  */
86
86
  export declare function unregister(): Promise<void>;
package/lib/push.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAqCA,OAAO,EAEL,aAAa,EAEb,qBAAqB,EAEtB,MAAM,aAAa,CAAA;AAsCpB,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;;mEAM+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC;kDAC8C;IAC9C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IACtD,sDAAsD;IACtD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAC/B;iEAC6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B;;yBAEqB;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;IAC9B;;;kBAGc;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAC3B,iBAAiB,GACjB,cAAc,GACd,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,CAAA;AAEnB;;;;mCAImC;AACnC,MAAM,MAAM,kBAAkB,GAC1B;IACE,EAAE,EAAE,IAAI,CAAA;IACR;;oDAEgD;IAChD,GAAG,EAAE,MAAM,CAAA;CACZ,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE/D,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyC1F;AAgDD;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBhD;AAED;4DAC4D;AAC5D,wBAAgB,YAAY,IAAI,IAAI,GAAG,MAAM,CAE5C;AAED,sDAAsD;AACtD,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,qBAAqB,IAAI,iBAAiB,EAAE,CAAA;AAuQjF;oEACoE;AACpE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAEhE;AA4HD;;+DAE+D;AAC/D,wBAAgB,eAAe,IAAI,IAAI,CAWtC;AAID;qCACqC;AACrC,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAEnF"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAqCA,OAAO,EAEL,aAAa,EAEb,qBAAqB,EAEtB,MAAM,aAAa,CAAA;AAsCpB,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;;mEAM+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC;kDAC8C;IAC9C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IACtD,sDAAsD;IACtD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAC/B;iEAC6D;IAC7D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B;;yBAEqB;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;IAC9B;;;kBAGc;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAC3B,iBAAiB,GACjB,cAAc,GACd,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,CAAA;AAEnB;;;;mCAImC;AACnC,MAAM,MAAM,kBAAkB,GAC1B;IACE,EAAE,EAAE,IAAI,CAAA;IACR;;oDAEgD;IAChD,GAAG,EAAE,MAAM,CAAA;CACZ,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE/D,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA6C1F;AAmDD;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBhD;AAED;4DAC4D;AAC5D,wBAAgB,YAAY,IAAI,IAAI,GAAG,MAAM,CAE5C;AAED,sDAAsD;AACtD,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,qBAAqB,IAAI,iBAAiB,EAAE,CAAA;AA+RjF;oEACoE;AACpE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAEhE;AA4HD;;+DAE+D;AAC/D,wBAAgB,eAAe,IAAI,IAAI,CAWtC;AAID;qCACqC;AACrC,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAEnF"}
package/lib/push.js CHANGED
@@ -10,7 +10,7 @@
10
10
  // asynchronously and lands in the native buffer.
11
11
  // 3. Poll `pushDrainState()` at 200 ms ticks for up to 8 s waiting
12
12
  // for the token.
13
- // 4. POST `/v1/push/tokens` with `kind: 'apns' | 'fcm'` — the
13
+ // 4. POST `/v1/push/devices` with `kind: 'apns' | 'fcm'` — the
14
14
  // server's field name; sending `provider` here earned a 422 for
15
15
  // every registration this SDK ever attempted — plus
16
16
  // `nativeToken`, `userKey`, and `env` on iOS only (FCM is a
@@ -97,7 +97,11 @@ export async function register(opts = {}) {
97
97
  _lastNativeToken = token;
98
98
  _lastOptions = opts;
99
99
  void persistIpt(ipt);
100
- opts.onToken?.(ipt);
100
+ // The registration reached the server and came back with a handle.
101
+ // What the host does with it afterwards is not our outcome — this
102
+ // used to sit inside the try, so a throwing `onToken` reported a
103
+ // successful registration as `server-rejected`.
104
+ safely('onToken', () => opts.onToken?.(ipt));
101
105
  bindBufferDrain(opts.onMessage, opts.onTap);
102
106
  // From here on, signing in or out updates the row by itself.
103
107
  onIdentityChange(reRegisterAfterIdentityChange);
@@ -113,7 +117,10 @@ export async function register(opts = {}) {
113
117
  * wants a callback, hand back the reason. */
114
118
  function fail(opts, reason, message) {
115
119
  logger.warn('push', `register failed (${reason}):`, message);
116
- opts.onError?.(new Error(message));
120
+ // `register()` never throws is the contract, and this is the one
121
+ // path that hands the host an error to look at — so it is also the
122
+ // one place where the host's own code could have broken it.
123
+ safely('onError', () => opts.onError?.(new Error(message)));
117
124
  return { ok: false, message, reason };
118
125
  }
119
126
  /**
@@ -151,7 +158,7 @@ class PushRegisterError extends Error {
151
158
  }
152
159
  }
153
160
  /**
154
- * Revoke the cached handle (DELETE /v1/push/tokens/{ipt}) +
161
+ * Revoke the cached handle (DELETE /v1/push/devices/{ipt}) +
155
162
  * unregister locally. Idempotent — repeat calls are no-ops.
156
163
  */
157
164
  export async function unregister() {
@@ -159,7 +166,7 @@ export async function unregister() {
159
166
  const ipt = _cachedIpt ?? (await readPersistedIpt());
160
167
  if (cfg && ipt) {
161
168
  try {
162
- await fetch(joinUrl(cfg.ingestUrl, `/v1/push/tokens/${ipt}`), {
169
+ await fetch(joinUrl(cfg.ingestUrl, `/v1/push/devices/${ipt}`), {
163
170
  method: 'DELETE',
164
171
  headers: { authorization: `Bearer ${cfg.token}` },
165
172
  });
@@ -255,7 +262,7 @@ async function registerWithServer(cfg, nativeToken, opts) {
255
262
  const traits = currentUserTraits();
256
263
  if (traits != null)
257
264
  body.traits = traits;
258
- const res = await fetch(joinUrl(cfg.ingestUrl, '/v1/push/tokens'), {
265
+ const res = await fetch(joinUrl(cfg.ingestUrl, '/v1/push/devices'), {
259
266
  method: 'POST',
260
267
  headers: {
261
268
  authorization: `Bearer ${cfg.token}`,
@@ -264,16 +271,16 @@ async function registerWithServer(cfg, nativeToken, opts) {
264
271
  body: JSON.stringify(body),
265
272
  });
266
273
  if (!res.ok) {
267
- throw new PushRegisterError('server-rejected', `/v1/push/tokens HTTP ${res.status}`);
274
+ throw new PushRegisterError('server-rejected', `/v1/push/devices HTTP ${res.status}`);
268
275
  }
269
276
  // The handle is the device_tokens row id — a uuid, which is what
270
277
  // the revoke and send routes take. It was parsed here as an
271
278
  // `ipt_*` string that no server has ever returned.
272
279
  const json = (await res.json());
273
- if (typeof json.token_id !== 'string' || json.token_id.length === 0) {
280
+ if (typeof json.spToken !== 'string' || json.spToken.length === 0) {
274
281
  throw new PushRegisterError('server-rejected', 'server did not return a device token id');
275
282
  }
276
- return json.token_id;
283
+ return json.spToken;
277
284
  }
278
285
  function bindBufferDrain(onMessage, onTap) {
279
286
  _onMessage = onMessage;
@@ -300,9 +307,18 @@ function teardownBufferDrain() {
300
307
  _ackQueue = [];
301
308
  }
302
309
  async function pumpOnce() {
303
- const state = await pushDrainState();
304
- flushBuffered(state.notifications, state.taps);
305
- await reportRotationIfAny(state.token);
310
+ // Nothing in a tick may reject. The caller is `void pumpOnce()` on
311
+ // an interval, so a rejection here is an unhandled rejection in the
312
+ // host's process — a red box in development, and on some setups
313
+ // worse — for something the host is entitled to have fail quietly.
314
+ try {
315
+ const state = await pushDrainState();
316
+ flushBuffered(state.notifications, state.taps);
317
+ await reportRotationIfAny(state.token);
318
+ }
319
+ catch (e) {
320
+ logger.warn('push', 'a drain tick failed — the next one still runs', e);
321
+ }
306
322
  }
307
323
  /// Tell the server when the vendor has handed the app a different
308
324
  /// token from the one it registered with.
@@ -345,17 +361,33 @@ async function reportRotationIfAny(token) {
345
361
  logger.warn('push', 'reporting a rotated token failed', e);
346
362
  }
347
363
  }
364
+ /// Run the host's own code without letting it reach back into ours.
365
+ ///
366
+ /// A push that does not arrive is a product decision the host can live
367
+ /// with. An exception out of an SDK it merely opted into is not — and
368
+ /// the host's handlers are the sharp edge here: they are its code,
369
+ /// they run inside our loop, and JavaScript throws for a living. One
370
+ /// throwing handler used to take the rest of the batch with it, then
371
+ /// the tick, then every later tick as an unhandled rejection.
372
+ function safely(what, fn) {
373
+ try {
374
+ fn();
375
+ }
376
+ catch (e) {
377
+ logger.warn('push', `${what} threw — carrying on`, e);
378
+ }
379
+ }
348
380
  function flushBuffered(notifications, taps) {
349
381
  for (const raw of notifications) {
350
382
  // v2.26 — Observability link-through (rule #4). If the server
351
383
  // injected `_sentori.msgId` in v2.25+, drop a `push` breadcrumb,
352
384
  // emit `sentori.push.received` track, and queue the ack.
353
- autoCorrelate(raw, 'received');
354
- _onMessage?.(coerceNotification(raw));
385
+ safely('autoCorrelate', () => autoCorrelate(raw, 'received'));
386
+ safely('onMessage', () => _onMessage?.(coerceNotification(raw)));
355
387
  }
356
388
  for (const raw of taps) {
357
- autoCorrelate(raw, 'opened');
358
- _onTap?.(raw.userInfo ?? raw);
389
+ safely('autoCorrelate', () => autoCorrelate(raw, 'opened'));
390
+ safely('onTap', () => _onTap?.(raw.userInfo ?? raw));
359
391
  }
360
392
  }
361
393
  /** v2.26 — process one drained notification or tap for downstream
@@ -415,7 +447,7 @@ async function drainAckQueue() {
415
447
  // the user flow.
416
448
  for (const msgId of batch) {
417
449
  try {
418
- await fetch(joinUrl(cfg.ingestUrl, `/v1/push/sends/${msgId}/ack`), {
450
+ await fetch(joinUrl(cfg.ingestUrl, `/v1/push/deliveries/${msgId}/ack`), {
419
451
  body: JSON.stringify({ eventType: 'received', sessionId: _sessionId }),
420
452
  headers: {
421
453
  authorization: `Bearer ${cfg.token}`,
package/lib/push.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"push.js","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"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"}
package/lib/transport.js CHANGED
@@ -15,7 +15,7 @@ const MAX_RETRY = 3;
15
15
  const STORAGE_KEY = '@sentori/pending';
16
16
  const MAX_PERSISTED = 1000;
17
17
  // Pinned to package.json by a test — bump both together.
18
- const SDK_VERSION = '6.4.0';
18
+ const SDK_VERSION = '7.0.0';
19
19
  let _queue = [];
20
20
  let _assertStats = new Map();
21
21
  let _flushTimer = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goliapkg/sentori-react-native",
3
- "version": "6.4.0",
3
+ "version": "7.0.0",
4
4
  "description": "Sentori SDK for React Native — JS-layer error capture, native crash handlers (iOS / Android), batched transport, fetch + react-navigation tracing.",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "author": "GOLIA K.K. <takagi@golia.jp> (https://golia.jp)",
@@ -85,6 +85,6 @@
85
85
  "access": "public"
86
86
  },
87
87
  "dependencies": {
88
- "@goliapkg/sentori-core": "^2.3.0"
88
+ "@goliapkg/sentori-core": "^3.0.0"
89
89
  }
90
90
  }
@@ -17,6 +17,14 @@ import {
17
17
  startTransport,
18
18
  } from '../transport';
19
19
  import { verbs } from '../verbs';
20
+ import { __setNativeForTests as setNative } from '../native';
21
+ import {
22
+ __resetForTests as resetPush,
23
+ __setPlatformForTests as setPlatform,
24
+ getCachedIpt,
25
+ register as pushRegister,
26
+ unregister as pushUnregister,
27
+ } from '../push';
20
28
 
21
29
  const baseConfig = {
22
30
  token: 'st_test',
@@ -126,3 +134,113 @@ describe('iron rule: init timing', () => {
126
134
  expect(ms).toBeLessThan(50);
127
135
  });
128
136
  });
137
+
138
+ // Dimension 3, for push specifically.
139
+ //
140
+ // The rule was written down and the gate did not reach here: this file
141
+ // covered the five event verbs and mentioned push nowhere, while push
142
+ // is the surface with the most ways to go wrong — an OS permission, a
143
+ // vendor token, a network round trip, a background loop, and the
144
+ // host's own handlers running inside it.
145
+ //
146
+ // A notification that does not arrive is something the host can live
147
+ // with. An exception out of an SDK it merely opted into is not.
148
+ describe('iron rule: push never reaches the host', () => {
149
+ beforeEach(() => {
150
+ resetAll();
151
+ resetPush();
152
+ setPlatform('ios');
153
+ setConfig(baseConfig);
154
+ });
155
+ afterEach(() => {
156
+ globalThis.fetch = originalFetch;
157
+ setPlatform(null);
158
+ setNative(undefined);
159
+ resetPush();
160
+ resetAll();
161
+ });
162
+
163
+ const granting = {
164
+ pushRequestPermission: () => Promise.resolve('granted'),
165
+ pushGetStatus: () => Promise.resolve('granted'),
166
+ pushRegister: () => undefined,
167
+ pushUnregister: () => undefined,
168
+ pushDrainState: () => Promise.resolve({ notifications: [], taps: [], token: 'abc' }),
169
+ };
170
+
171
+ it('a server that answers 500 is an outcome, not an exception', async () => {
172
+ setNative(granting);
173
+ globalThis.fetch = (async () => new Response('boom', { status: 500 })) as typeof fetch;
174
+ const r = await pushRegister();
175
+ expect(r.ok).toBe(false);
176
+ });
177
+
178
+ it('a network that is down is an outcome, not an exception', async () => {
179
+ setNative(granting);
180
+ globalThis.fetch = (async () => {
181
+ throw new Error('offline');
182
+ }) as typeof fetch;
183
+ const r = await pushRegister();
184
+ expect(r.ok).toBe(false);
185
+ });
186
+
187
+ it('a server that answers nonsense is an outcome, not an exception', async () => {
188
+ setNative(granting);
189
+ globalThis.fetch = (async () => new Response('<html>not json</html>', { status: 200 })) as typeof fetch;
190
+ const r = await pushRegister();
191
+ expect(r.ok).toBe(false);
192
+ });
193
+
194
+ it('a native module that throws is an outcome, not an exception', async () => {
195
+ setNative({
196
+ ...granting,
197
+ pushRequestPermission: () => {
198
+ throw new Error('bridge died');
199
+ },
200
+ });
201
+ const r = await pushRegister();
202
+ expect(r.ok).toBe(false);
203
+ });
204
+
205
+ it('fuzz: the push verbs accept garbage without throwing', async () => {
206
+ setNative(granting);
207
+ globalThis.fetch = (async () =>
208
+ new Response(JSON.stringify({ spToken: 'dev-1' }), { status: 200 })) as typeof fetch;
209
+ const circular: Record<string, unknown> = { a: 1 };
210
+ circular.self = circular;
211
+ const garbage = [
212
+ undefined,
213
+ null,
214
+ {},
215
+ { metadata: circular },
216
+ { metadata: { huge: 'x'.repeat(200_000) } },
217
+ { onMessage: 'not a function' },
218
+ { tokenTimeoutMs: -1 },
219
+ { tokenTimeoutMs: Number.NaN },
220
+ ];
221
+ for (const g of garbage) {
222
+ const r = await pushRegister(g as never);
223
+ expect(typeof r.ok).toBe('boolean');
224
+ }
225
+ });
226
+
227
+ it('every push verb before init is a quiet outcome', async () => {
228
+ resetConfig();
229
+ setNative(granting);
230
+ const r = await pushRegister();
231
+ expect(r).toEqual({ ok: false, message: 'sentori.init() has not run', reason: 'not-initialised' });
232
+ await pushUnregister();
233
+ expect(await getCachedIpt()).toBe(null);
234
+ });
235
+
236
+ it('unregister cannot fail, whatever the server does', async () => {
237
+ setNative(granting);
238
+ globalThis.fetch = (async () =>
239
+ new Response(JSON.stringify({ spToken: 'dev-1' }), { status: 200 })) as typeof fetch;
240
+ await pushRegister();
241
+ globalThis.fetch = (async () => {
242
+ throw new Error('offline');
243
+ }) as typeof fetch;
244
+ await pushUnregister();
245
+ });
246
+ });
@@ -13,6 +13,7 @@ import {
13
13
  __resetForTests as resetPush,
14
14
  __setPlatformForTests as setPlatform,
15
15
  register,
16
+ unregister,
16
17
  } from '../push';
17
18
  import { __resetForTests as resetConfig, setConfig } from '../config';
18
19
  import { __resetForTests as resetScope, setUser } from '../scope';
@@ -43,7 +44,7 @@ function grantingNative(over: Record<string, unknown> = {}) {
43
44
 
44
45
  const realFetch = globalThis.fetch;
45
46
 
46
- /** Answer /v1/push/tokens with `body` under `status`. */
47
+ /** Answer /v1/push/devices with `body` under `status`. */
47
48
  function stubFetch(status: number, body: unknown): void {
48
49
  globalThis.fetch = (() =>
49
50
  Promise.resolve({
@@ -72,7 +73,7 @@ describe('push.register', () => {
72
73
 
73
74
  it('returns the device handle when the whole flow works', async () => {
74
75
  __setNativeForTests(grantingNative());
75
- stubFetch(200, { token_id: '018f0000-0000-7000-8000-000000000001', is_new: true });
76
+ stubFetch(200, { spToken: '018f0000-0000-7000-8000-000000000001', isNew: true });
76
77
 
77
78
  const r = await register();
78
79
 
@@ -88,7 +89,7 @@ describe('push.register', () => {
88
89
  return Promise.resolve({
89
90
  ok: true,
90
91
  status: 200,
91
- json: () => Promise.resolve({ token_id: 'id-1' }),
92
+ json: () => Promise.resolve({ spToken: 'id-1' }),
92
93
  });
93
94
  }) as unknown as typeof fetch;
94
95
 
@@ -107,7 +108,7 @@ describe('push.register', () => {
107
108
  return Promise.resolve({
108
109
  ok: true,
109
110
  status: 200,
110
- json: () => Promise.resolve({ token_id: 'id-1' }),
111
+ json: () => Promise.resolve({ spToken: 'id-1' }),
111
112
  });
112
113
  }) as unknown as typeof fetch;
113
114
 
@@ -208,7 +209,7 @@ describe('push.register', () => {
208
209
  // the life of the install — and a send aimed at that user reached
209
210
  // nobody and reported success.
210
211
  describe('push registration follows the person', () => {
211
- /** Record every /v1/push/tokens body, so a test can say what the
212
+ /** Record every /v1/push/devices body, so a test can say what the
212
213
  * server was told rather than that it was told something. */
213
214
  function recordingFetch(): Array<Record<string, unknown>> {
214
215
  const seen: Array<Record<string, unknown>> = [];
@@ -219,7 +220,7 @@ describe('push registration follows the person', () => {
219
220
  return Promise.resolve({
220
221
  ok: true,
221
222
  status: 202,
222
- json: () => Promise.resolve({ spToken: 'dev-1', token_id: 'dev-1' }),
223
+ json: () => Promise.resolve({ spToken: 'dev-1' }),
223
224
  });
224
225
  }) as unknown as typeof fetch;
225
226
  return seen;
@@ -321,7 +322,7 @@ describe('push survives the vendor rotating its token', () => {
321
322
  return Promise.resolve({
322
323
  ok: true,
323
324
  status: 202,
324
- json: () => Promise.resolve({ spToken: 'dev-1', token_id: 'dev-1' }),
325
+ json: () => Promise.resolve({ spToken: 'dev-1' }),
325
326
  });
326
327
  }) as unknown as typeof fetch;
327
328
  return seen;
@@ -404,3 +405,147 @@ describe('push survives the vendor rotating its token', () => {
404
405
  expect(seen).toHaveLength(1);
405
406
  });
406
407
  });
408
+
409
+ // Push is allowed to fail silently. It is never allowed to make the
410
+ // host app fail — a notification that does not arrive is a product
411
+ // decision the host can live with; an exception out of an SDK the host
412
+ // merely opted into is not.
413
+ //
414
+ // The host's own handlers are the sharp edge: they are its code, they
415
+ // run inside our loop, and JavaScript throws for a living.
416
+ describe('nothing the host does can reach back into the app', () => {
417
+ const boom = () => {
418
+ throw new Error('the host threw');
419
+ };
420
+
421
+ /** Hands the batch over once and is empty after, the way the real
422
+ * native drain is — a stub that keeps re-delivering makes a second
423
+ * tick look like a bug in the SDK. */
424
+ function drainingNative(notifications: unknown[], taps: unknown[]) {
425
+ let drained = false;
426
+ return grantingNative({
427
+ pushDrainState: () => {
428
+ const batch = drained
429
+ ? { notifications: [], taps: [] }
430
+ : { notifications, taps };
431
+ drained = true;
432
+ return Promise.resolve({ ...batch, token: 'abc123' });
433
+ },
434
+ });
435
+ }
436
+
437
+ function okFetch(): void {
438
+ globalThis.fetch = (() =>
439
+ Promise.resolve({
440
+ ok: true,
441
+ status: 202,
442
+ json: () => Promise.resolve({ spToken: 'dev-1' }),
443
+ })) as unknown as typeof fetch;
444
+ }
445
+
446
+ beforeEach(() => {
447
+ resetPush();
448
+ resetConfig();
449
+ resetScope();
450
+ setPlatform('ios');
451
+ setConfig(baseConfig);
452
+ okFetch();
453
+ });
454
+ afterEach(() => {
455
+ resetPush();
456
+ resetConfig();
457
+ resetScope();
458
+ setPlatform(null);
459
+ __setNativeForTests(undefined);
460
+ globalThis.fetch = realFetch;
461
+ });
462
+
463
+ it('keeps delivering after a handler throws', async () => {
464
+ const seen: string[] = [];
465
+ __setNativeForTests(
466
+ drainingNative(
467
+ [{ title: 'one' }, { title: 'two' }],
468
+ [{ tapped: true }],
469
+ ),
470
+ );
471
+ const r = await register({
472
+ onMessage: (n) => {
473
+ seen.push(String(n.title));
474
+ // The first one throws. The second one, and the tap after it,
475
+ // still have to arrive: one bad handler must not swallow the
476
+ // rest of the batch.
477
+ if (n.title === 'one') boom();
478
+ },
479
+ onTap: () => seen.push('tap'),
480
+ });
481
+ expect(r.ok).toBe(true);
482
+ await new Promise((res) => setTimeout(res, 1400));
483
+ expect(seen).toEqual(['one', 'two', 'tap']);
484
+ });
485
+
486
+ it('keeps ticking after a handler throws', async () => {
487
+ let ticks = 0;
488
+ __setNativeForTests(
489
+ grantingNative({
490
+ pushDrainState: () => {
491
+ ticks += 1;
492
+ return Promise.resolve({
493
+ notifications: [{ title: 'n' }],
494
+ taps: [],
495
+ token: 'abc123',
496
+ });
497
+ },
498
+ }),
499
+ );
500
+ await register({ onMessage: boom });
501
+ const first = ticks;
502
+ await new Promise((res) => setTimeout(res, 2400));
503
+ // A throwing handler that stops the loop is worse than one that
504
+ // drops a notification: every later push is gone too, silently.
505
+ expect(ticks).toBeGreaterThan(first + 1);
506
+ });
507
+
508
+ it('survives a native module that rejects', async () => {
509
+ let ticks = 0;
510
+ __setNativeForTests(
511
+ grantingNative({
512
+ pushDrainState: () => {
513
+ ticks += 1;
514
+ return ticks === 1
515
+ ? Promise.resolve({ notifications: [], taps: [], token: 'abc123' })
516
+ : Promise.reject(new Error('bridge died'));
517
+ },
518
+ }),
519
+ );
520
+ await register();
521
+ await new Promise((res) => setTimeout(res, 2400));
522
+ expect(ticks).toBeGreaterThan(2);
523
+ });
524
+
525
+ it('does not report a failure because onToken threw', async () => {
526
+ __setNativeForTests(grantingNative());
527
+ const r = await register({ onToken: boom });
528
+ // The registration reached the server and came back with a handle.
529
+ // What the host did with it afterwards is not our outcome.
530
+ expect(r).toEqual({ ok: true, ipt: 'dev-1' });
531
+ });
532
+
533
+ it('still resolves when onError throws', async () => {
534
+ // `register()` never throws is the documented contract, and the
535
+ // one path that reports failure is the one that hands the host an
536
+ // error to look at.
537
+ __setNativeForTests(
538
+ grantingNative({ pushRequestPermission: () => Promise.resolve('denied') }),
539
+ );
540
+ const r = await register({ onError: boom });
541
+ expect(r.ok).toBe(false);
542
+ });
543
+
544
+ it('unregister does not throw when the server is unreachable', async () => {
545
+ __setNativeForTests(grantingNative());
546
+ await register();
547
+ globalThis.fetch = (() => Promise.reject(new Error('offline'))) as unknown as typeof fetch;
548
+ // Signing out must not be something that can fail.
549
+ await unregister();
550
+ });
551
+ });
package/src/push.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  // asynchronously and lands in the native buffer.
11
11
  // 3. Poll `pushDrainState()` at 200 ms ticks for up to 8 s waiting
12
12
  // for the token.
13
- // 4. POST `/v1/push/tokens` with `kind: 'apns' | 'fcm'` — the
13
+ // 4. POST `/v1/push/devices` with `kind: 'apns' | 'fcm'` — the
14
14
  // server's field name; sending `provider` here earned a 422 for
15
15
  // every registration this SDK ever attempted — plus
16
16
  // `nativeToken`, `userKey`, and `env` on iOS only (FCM is a
@@ -196,7 +196,11 @@ export async function register(opts: PushRegisterOptions = {}): Promise<PushRegi
196
196
  _lastNativeToken = token
197
197
  _lastOptions = opts
198
198
  void persistIpt(ipt)
199
- opts.onToken?.(ipt)
199
+ // The registration reached the server and came back with a handle.
200
+ // What the host does with it afterwards is not our outcome — this
201
+ // used to sit inside the try, so a throwing `onToken` reported a
202
+ // successful registration as `server-rejected`.
203
+ safely('onToken', () => opts.onToken?.(ipt))
200
204
  bindBufferDrain(opts.onMessage, opts.onTap)
201
205
  // From here on, signing in or out updates the row by itself.
202
206
  onIdentityChange(reRegisterAfterIdentityChange)
@@ -216,7 +220,10 @@ function fail(
216
220
  message: string,
217
221
  ): PushRegisterResult {
218
222
  logger.warn('push', `register failed (${reason}):`, message)
219
- opts.onError?.(new Error(message))
223
+ // `register()` never throws is the contract, and this is the one
224
+ // path that hands the host an error to look at — so it is also the
225
+ // one place where the host's own code could have broken it.
226
+ safely('onError', () => opts.onError?.(new Error(message)))
220
227
  return { ok: false, message, reason }
221
228
  }
222
229
 
@@ -255,7 +262,7 @@ class PushRegisterError extends Error {
255
262
  }
256
263
 
257
264
  /**
258
- * Revoke the cached handle (DELETE /v1/push/tokens/{ipt}) +
265
+ * Revoke the cached handle (DELETE /v1/push/devices/{ipt}) +
259
266
  * unregister locally. Idempotent — repeat calls are no-ops.
260
267
  */
261
268
  export async function unregister(): Promise<void> {
@@ -263,7 +270,7 @@ export async function unregister(): Promise<void> {
263
270
  const ipt = _cachedIpt ?? (await readPersistedIpt())
264
271
  if (cfg && ipt) {
265
272
  try {
266
- await fetch(joinUrl(cfg.ingestUrl, `/v1/push/tokens/${ipt}`), {
273
+ await fetch(joinUrl(cfg.ingestUrl, `/v1/push/devices/${ipt}`), {
267
274
  method: 'DELETE',
268
275
  headers: { authorization: `Bearer ${cfg.token}` },
269
276
  })
@@ -367,7 +374,7 @@ async function registerWithServer(
367
374
  // which is what signing out sends.
368
375
  const traits = currentUserTraits()
369
376
  if (traits != null) body.traits = traits
370
- const res = await fetch(joinUrl(cfg.ingestUrl, '/v1/push/tokens'), {
377
+ const res = await fetch(joinUrl(cfg.ingestUrl, '/v1/push/devices'), {
371
378
  method: 'POST',
372
379
  headers: {
373
380
  authorization: `Bearer ${cfg.token}`,
@@ -376,16 +383,16 @@ async function registerWithServer(
376
383
  body: JSON.stringify(body),
377
384
  })
378
385
  if (!res.ok) {
379
- throw new PushRegisterError('server-rejected', `/v1/push/tokens HTTP ${res.status}`)
386
+ throw new PushRegisterError('server-rejected', `/v1/push/devices HTTP ${res.status}`)
380
387
  }
381
388
  // The handle is the device_tokens row id — a uuid, which is what
382
389
  // the revoke and send routes take. It was parsed here as an
383
390
  // `ipt_*` string that no server has ever returned.
384
- const json = (await res.json()) as { token_id?: string }
385
- if (typeof json.token_id !== 'string' || json.token_id.length === 0) {
391
+ const json = (await res.json()) as { spToken?: string }
392
+ if (typeof json.spToken !== 'string' || json.spToken.length === 0) {
386
393
  throw new PushRegisterError('server-rejected', 'server did not return a device token id')
387
394
  }
388
- return json.token_id
395
+ return json.spToken
389
396
  }
390
397
 
391
398
  function bindBufferDrain(
@@ -417,9 +424,17 @@ function teardownBufferDrain(): void {
417
424
  }
418
425
 
419
426
  async function pumpOnce(): Promise<void> {
420
- const state = await pushDrainState()
421
- flushBuffered(state.notifications, state.taps)
422
- await reportRotationIfAny(state.token)
427
+ // Nothing in a tick may reject. The caller is `void pumpOnce()` on
428
+ // an interval, so a rejection here is an unhandled rejection in the
429
+ // host's process — a red box in development, and on some setups
430
+ // worse — for something the host is entitled to have fail quietly.
431
+ try {
432
+ const state = await pushDrainState()
433
+ flushBuffered(state.notifications, state.taps)
434
+ await reportRotationIfAny(state.token)
435
+ } catch (e) {
436
+ logger.warn('push', 'a drain tick failed — the next one still runs', e)
437
+ }
423
438
  }
424
439
 
425
440
  /// Tell the server when the vendor has handed the app a different
@@ -460,6 +475,22 @@ async function reportRotationIfAny(token: string | undefined): Promise<void> {
460
475
  }
461
476
  }
462
477
 
478
+ /// Run the host's own code without letting it reach back into ours.
479
+ ///
480
+ /// A push that does not arrive is a product decision the host can live
481
+ /// with. An exception out of an SDK it merely opted into is not — and
482
+ /// the host's handlers are the sharp edge here: they are its code,
483
+ /// they run inside our loop, and JavaScript throws for a living. One
484
+ /// throwing handler used to take the rest of the batch with it, then
485
+ /// the tick, then every later tick as an unhandled rejection.
486
+ function safely(what: string, fn: () => void): void {
487
+ try {
488
+ fn()
489
+ } catch (e) {
490
+ logger.warn('push', `${what} threw — carrying on`, e)
491
+ }
492
+ }
493
+
463
494
  function flushBuffered(
464
495
  notifications: Array<Record<string, unknown>>,
465
496
  taps: Array<Record<string, unknown>>,
@@ -468,12 +499,12 @@ function flushBuffered(
468
499
  // v2.26 — Observability link-through (rule #4). If the server
469
500
  // injected `_sentori.msgId` in v2.25+, drop a `push` breadcrumb,
470
501
  // emit `sentori.push.received` track, and queue the ack.
471
- autoCorrelate(raw, 'received')
472
- _onMessage?.(coerceNotification(raw))
502
+ safely('autoCorrelate', () => autoCorrelate(raw, 'received'))
503
+ safely('onMessage', () => _onMessage?.(coerceNotification(raw)))
473
504
  }
474
505
  for (const raw of taps) {
475
- autoCorrelate(raw, 'opened')
476
- _onTap?.(raw.userInfo ?? raw)
506
+ safely('autoCorrelate', () => autoCorrelate(raw, 'opened'))
507
+ safely('onTap', () => _onTap?.(raw.userInfo ?? raw))
477
508
  }
478
509
  }
479
510
 
@@ -536,7 +567,7 @@ async function drainAckQueue(): Promise<void> {
536
567
  // the user flow.
537
568
  for (const msgId of batch) {
538
569
  try {
539
- await fetch(joinUrl(cfg.ingestUrl, `/v1/push/sends/${msgId}/ack`), {
570
+ await fetch(joinUrl(cfg.ingestUrl, `/v1/push/deliveries/${msgId}/ack`), {
540
571
  body: JSON.stringify({ eventType: 'received', sessionId: _sessionId }),
541
572
  headers: {
542
573
  authorization: `Bearer ${cfg.token}`,
package/src/transport.ts CHANGED
@@ -20,7 +20,7 @@ const STORAGE_KEY = '@sentori/pending';
20
20
  const MAX_PERSISTED = 1000;
21
21
 
22
22
  // Pinned to package.json by a test — bump both together.
23
- const SDK_VERSION = '6.4.0';
23
+ const SDK_VERSION = '7.0.0';
24
24
 
25
25
  let _queue: WireEvent[] = [];
26
26
  let _assertStats = new Map<string, AssertStat>();