@goliapkg/sentori-react-native 6.2.1 → 6.3.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 (33) hide show
  1. package/android/build.gradle +6 -0
  2. package/android/src/main/java-core/com/sentori/Sentori.kt +33 -4
  3. package/android/src/main/java-core/com/sentori/SentoriAttachment.kt +153 -0
  4. package/android/src/main/java-core/com/sentori/SentoriConfig.kt +1 -1
  5. package/android/src/main/java-core/com/sentori/SentoriCrashHandler.kt +19 -0
  6. package/android/src/main/java-core/com/sentori/SentoriFirebaseMessagingService.kt +15 -0
  7. package/android/src/main/java-core/com/sentori/SentoriNotificationTap.kt +148 -0
  8. package/android/src/main/java-core/com/sentori/SentoriPendingCrash.kt +154 -0
  9. package/android/src/main/java-core/com/sentori/SentoriPush.kt +242 -13
  10. package/android/src/main/java-core/com/sentori/SentoriPushNotifications.kt +168 -17
  11. package/android/src/main/java-core/com/sentori/SentoriScope.kt +49 -2
  12. package/android/src/main/java-core/com/sentori/SentoriTransport.kt +95 -2
  13. package/android/src/test/java-core/com/sentori/SentoriAttachmentTest.kt +413 -0
  14. package/android/src/test/java-core/com/sentori/SentoriLiveServerTest.kt +43 -0
  15. package/android/src/test/java-core/com/sentori/SentoriPendingCrashTest.kt +194 -0
  16. package/android/src/test/java-core/com/sentori/SentoriPushTest.kt +556 -0
  17. package/ios/core/SentoriAttachment.swift +129 -0
  18. package/ios/core/SentoriCrashHandler.swift +15 -0
  19. package/ios/core/SentoriPushNotifications.swift +8 -0
  20. package/lib/push.d.ts.map +1 -1
  21. package/lib/push.js +51 -1
  22. package/lib/push.js.map +1 -1
  23. package/lib/scope.d.ts +6 -0
  24. package/lib/scope.d.ts.map +1 -1
  25. package/lib/scope.js +45 -1
  26. package/lib/scope.js.map +1 -1
  27. package/lib/transport.js +1 -1
  28. package/package.json +2 -2
  29. package/src/__tests__/push.test.ts +99 -1
  30. package/src/push.ts +49 -1
  31. package/src/scope.ts +50 -1
  32. package/src/transport.ts +1 -1
  33. package/ios/core/SentoriPush.swift +0 -340
@@ -0,0 +1,129 @@
1
+ // GENERATED MIRROR — do not edit.
2
+ // Source of truth: sdk/native/ios/Sources/Sentori/SentoriAttachment.swift
3
+ // Run `node scripts/sync-native-core.mjs` after editing it.
4
+ import Foundation
5
+
6
+ /// Blobs that belong to an event: the screenshot taken as the app
7
+ /// died, the wireframe replay ring behind it.
8
+ ///
9
+ /// They upload *after* the event, never before. The server keys an
10
+ /// attachment on an event id it must already know, so an upload that
11
+ /// races the batch 404s — and it always wins that race, because the
12
+ /// batch waits for a flush and the upload does not.
13
+ ///
14
+ /// The multipart body is built by hand rather than with a form API.
15
+ /// React Native learned that the expensive way: its `FormData` file
16
+ /// part wants a `uri`, the `data:` form throws a bare network error on
17
+ /// iOS, and every JS attachment died silently for a release. Doing it
18
+ /// literally is both shorter and checkable.
19
+ enum SentoriAttachment {
20
+
21
+ /// The kinds the server's CHECK constraint accepts, from
22
+ /// `handlers/sdk/events_attachments.rs`. Anything else is a 400,
23
+ /// so it is dropped here with the round trip saved.
24
+ ///
25
+ /// This list is worth keeping honest: the first version of it had
26
+ /// three entries, and the crash handler's view tree — written on
27
+ /// both platforms, kind `viewTree` — was not one of them. It
28
+ /// would have been dropped on the way out by the very code meant
29
+ /// to deliver it, silently, with the event arriving intact and
30
+ /// the evidence missing.
31
+ static let known: Set<String> = [
32
+ "logTail", "replay", "screens", "screenshot",
33
+ "sessionTrail", "stateSnapshot", "viewTree",
34
+ ]
35
+
36
+ /// `android` | `ios` | `js`, likewise CHECK-constrained.
37
+ static let knownSources: Set<String> = ["android", "ios", "js"]
38
+
39
+ /// Test seam: capture instead of sending.
40
+ ///
41
+ /// What is worth asserting here is *what* would be uploaded and
42
+ /// *when* — the kind, the event it is keyed on, the body, and
43
+ /// that none of it moves before the batch lands. None of that is
44
+ /// about TCP. The wire itself is covered by `ios-live-ingest`,
45
+ /// which posts to a real server and reads the blob back.
46
+ static var recorderForTests: ((String, String, String) -> Void)?
47
+
48
+ /// Upload one blob against an event the server already has.
49
+ ///
50
+ /// Fire and forget: nothing here reaches the caller, and a
51
+ /// failure costs the attachment rather than the crash report it
52
+ /// belongs to.
53
+ static func upload(
54
+ eventId: String,
55
+ kind: String,
56
+ base64: String,
57
+ mediaType: String,
58
+ source: String = "ios",
59
+ completion: ((Bool) -> Void)? = nil
60
+ ) {
61
+ guard let config = SentoriConfig.current, known.contains(kind),
62
+ knownSources.contains(source),
63
+ let encodedId = eventId.addingPercentEncoding(
64
+ withAllowedCharacters: .urlPathAllowed),
65
+ let url = URL(
66
+ string: "\(config.ingestUrl)/v1/events/\(encodedId)/attachments/\(kind)")
67
+ else {
68
+ completion?(false)
69
+ return
70
+ }
71
+
72
+ let boundary = "----sentori-\(eventId)"
73
+ if let record = recorderForTests {
74
+ record(
75
+ eventId, kind,
76
+ multipartBody(
77
+ boundary: boundary, kind: kind, mediaType: mediaType, base64: base64,
78
+ source: source))
79
+ completion?(true)
80
+ return
81
+ }
82
+ var body = ""
83
+ body += "--\(boundary)\r\n"
84
+ body += "Content-Disposition: form-data; name=\"file\"; filename=\"\(kind).bin\"\r\n"
85
+ body += "Content-Type: \(mediaType)\r\n"
86
+ // The server decodes when told to. Without this header it
87
+ // stores the base64 text as the image, which renders as
88
+ // nothing and looks like a capture problem.
89
+ body += "Content-Transfer-Encoding: base64\r\n"
90
+ body += "\r\n\(base64)\r\n"
91
+ body += "--\(boundary)\r\n"
92
+ body += "Content-Disposition: form-data; name=\"source\"\r\n"
93
+ body += "\r\n\(source)\r\n"
94
+ body += "--\(boundary)--\r\n"
95
+
96
+ var request = URLRequest(url: url)
97
+ request.httpMethod = "POST"
98
+ request.setValue(
99
+ "multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
100
+ request.setValue("Bearer \(config.token)", forHTTPHeaderField: "Authorization")
101
+ request.setValue("swift/\(SentoriVersion.current)", forHTTPHeaderField: "Sentori-Sdk")
102
+ request.httpBody = body.data(using: .utf8)
103
+ request.timeoutInterval = 30
104
+
105
+ URLSession.shared.dataTask(with: request) { _, response, _ in
106
+ let code = (response as? HTTPURLResponse)?.statusCode ?? 0
107
+ completion?((200..<300).contains(code))
108
+ }.resume()
109
+ }
110
+
111
+ /// The multipart body, exposed so a test can read what would go
112
+ /// on the wire. Building it correctly is the whole job here, and
113
+ /// the failure mode is a 2xx that stored the wrong bytes.
114
+ static func multipartBody(
115
+ boundary: String, kind: String, mediaType: String, base64: String, source: String
116
+ ) -> String {
117
+ var body = ""
118
+ body += "--\(boundary)\r\n"
119
+ body += "Content-Disposition: form-data; name=\"file\"; filename=\"\(kind).bin\"\r\n"
120
+ body += "Content-Type: \(mediaType)\r\n"
121
+ body += "Content-Transfer-Encoding: base64\r\n"
122
+ body += "\r\n\(base64)\r\n"
123
+ body += "--\(boundary)\r\n"
124
+ body += "Content-Disposition: form-data; name=\"source\"\r\n"
125
+ body += "\r\n\(source)\r\n"
126
+ body += "--\(boundary)--\r\n"
127
+ return body
128
+ }
129
+ }
@@ -80,6 +80,21 @@ import MachO
80
80
  write(exception: exception)
81
81
  }
82
82
 
83
+ /// Test-only seam that writes a crash file verbatim.
84
+ ///
85
+ /// `persistForTesting(exception:)` goes through `write`, which
86
+ /// composes the file from a live exception and a live screen —
87
+ /// neither of which an XCTest can arrange. Delivery tests need to
88
+ /// state the file they are about to deliver, particularly the
89
+ /// pre-death attachments, which only exist when there was a
90
+ /// window to capture.
91
+ internal static func persistRawForTesting(_ event: [String: Any]) {
92
+ guard let dir = pendingDir(),
93
+ let data = try? JSONSerialization.data(withJSONObject: event)
94
+ else { return }
95
+ try? data.write(to: dir.appendingPathComponent("\(UUID().uuidString.lowercased()).json"))
96
+ }
97
+
83
98
  private static func write(exception: NSException) {
84
99
  let cfg = config()
85
100
  let release = (cfg["release"] as? String) ?? "unknown"
@@ -138,9 +138,17 @@ import ObjectiveC.runtime
138
138
  @objc public func handleRegisteredToken(_ deviceToken: Data) {
139
139
  let hex = deviceToken.map { String(format: "%02x", $0) }.joined()
140
140
  bufferLock.lock()
141
+ let changed = tokenHex != nil && tokenHex != hex
141
142
  tokenHex = hex
142
143
  registrationError = nil
143
144
  bufferLock.unlock()
145
+
146
+ // A token that replaced a different one is a rotation, and the
147
+ // server has to hear about it now. Buffering it in a field was
148
+ // the whole of what happened here before, so a rotation stayed
149
+ // invisible until the host next called `register` — and the
150
+ // device received nothing in between.
151
+ if changed { Sentori.push.handleRotatedToken(hex) }
144
152
  }
145
153
 
146
154
  /// Host-callable counterpart for the failure path.
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;AAqBpB,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,CAqC1F;AAyBD;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBhD;AAED;4DAC4D;AAC5D,wBAAgB,YAAY,IAAI,IAAI,GAAG,MAAM,CAE5C;AAED,sDAAsD;AACtD,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,qBAAqB,IAAI,iBAAiB,EAAE,CAAA;AAsNjF;oEACoE;AACpE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAEhE;AA+ED;;+DAE+D;AAC/D,wBAAgB,eAAe,IAAI,IAAI,CAMtC;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;AA6BpB,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;AA4NjF;oEACoE;AACpE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAEhE;AA+ED;;+DAE+D;AAC/D,wBAAgB,eAAe,IAAI,IAAI,CAUtC;AAID;qCACqC;AACrC,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAEnF"}
package/lib/push.js CHANGED
@@ -21,10 +21,18 @@
21
21
  // buffered events while the app is foreground. Pauses on
22
22
  // background, resumes on active, per the perf iron rule.
23
23
  import { logger, pushSignal } from '@goliapkg/sentori-core';
24
- import { currentUserKey } from './scope.js';
24
+ import { currentUserKey, currentUserTraits, onIdentityChange } from './scope.js';
25
25
  import { pushDrainState, pushGetStatus, pushRegister as nativePushRegister, pushRequestPermission, pushUnregister as nativePushUnregister, } from './native.js';
26
26
  const STORAGE_KEY = 'sentori.push.ipt';
27
27
  let _cachedIpt = null;
28
+ // The last token the vendor handed us, kept so a sign-in can re-send
29
+ // the registration without asking the OS for a token again.
30
+ let _lastNativeToken = null;
31
+ let _lastOptions = {};
32
+ // What the server was last told. A re-registration that would send
33
+ // the same thing is not sent: `user()` is a verb an app may call on
34
+ // every screen, and one HTTP request per call is not free to a host.
35
+ let _lastSentIdentity = null;
28
36
  let _drainInterval = null;
29
37
  let _appStateSubscription = null;
30
38
  let _backgrounded = false;
@@ -77,9 +85,13 @@ export async function register(opts = {}) {
77
85
  const token = await waitForToken(opts.tokenTimeoutMs ?? 8000);
78
86
  const ipt = await registerWithServer(cfg, token, opts);
79
87
  _cachedIpt = ipt;
88
+ _lastNativeToken = token;
89
+ _lastOptions = opts;
80
90
  void persistIpt(ipt);
81
91
  opts.onToken?.(ipt);
82
92
  bindBufferDrain(opts.onMessage, opts.onTap);
93
+ // From here on, signing in or out updates the row by itself.
94
+ onIdentityChange(reRegisterAfterIdentityChange);
83
95
  return { ok: true, ipt };
84
96
  }
85
97
  catch (e) {
@@ -95,6 +107,30 @@ function fail(opts, reason, message) {
95
107
  opts.onError?.(new Error(message));
96
108
  return { ok: false, message, reason };
97
109
  }
110
+ /**
111
+ * Send the registration again because the person changed.
112
+ *
113
+ * Only for a device that has already registered — the vendor token is
114
+ * the evidence, the same rule the native SDKs use for a rotated
115
+ * token. Nothing here throws and nothing here is awaited by the host:
116
+ * `user()` is synchronous and stays that way.
117
+ */
118
+ function reRegisterAfterIdentityChange() {
119
+ const token = _lastNativeToken;
120
+ const cfg = tryGetRuntimeConfig();
121
+ if (token == null || cfg == null)
122
+ return;
123
+ const identity = JSON.stringify([currentUserKey() ?? null, currentUserTraits() ?? null]);
124
+ if (identity === _lastSentIdentity)
125
+ return;
126
+ _lastSentIdentity = identity;
127
+ void registerWithServer(cfg, token, _lastOptions).catch((e) => {
128
+ // A failed update leaves the row pointing at the previous person,
129
+ // so the next change must be allowed to try again.
130
+ _lastSentIdentity = null;
131
+ logger.warn('push', 'updating the device after a sign-in failed', e);
132
+ });
133
+ }
98
134
  /** Internal carrier so the helpers below can name which failure they
99
135
  * are without every one of them returning a result object. */
100
136
  class PushRegisterError extends Error {
@@ -124,6 +160,9 @@ export async function unregister() {
124
160
  }
125
161
  }
126
162
  nativePushUnregister();
163
+ onIdentityChange(undefined);
164
+ _lastNativeToken = null;
165
+ _lastSentIdentity = null;
127
166
  _cachedIpt = null;
128
167
  void clearPersistedIpt();
129
168
  teardownBufferDrain();
@@ -196,6 +235,13 @@ async function registerWithServer(cfg, nativeToken, opts) {
196
235
  // not — 2026-08-11.)
197
236
  if (opts.metadata != null)
198
237
  body.metadata = opts.metadata;
238
+ // Attributes of the person rather than of the device, kept apart so
239
+ // a build channel called "pro" cannot answer a send aimed at the pro
240
+ // plan. Absent leaves whatever the row already had; `{}` clears it,
241
+ // which is what signing out sends.
242
+ const traits = currentUserTraits();
243
+ if (traits != null)
244
+ body.traits = traits;
199
245
  const res = await fetch(joinUrl(cfg.ingestUrl, '/v1/push/tokens'), {
200
246
  method: 'POST',
201
247
  headers: {
@@ -412,6 +458,10 @@ export function __resetForTests() {
412
458
  _onMessage = undefined;
413
459
  _onTap = undefined;
414
460
  _ackQueue = [];
461
+ _lastNativeToken = null;
462
+ _lastOptions = {};
463
+ _lastSentIdentity = null;
464
+ onIdentityChange(undefined);
415
465
  teardownBufferDrain();
416
466
  }
417
467
  let _platformOverride = null;
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/scope.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import type { User } from '@goliapkg/sentori-core';
2
+ /** Register interest in identity changes. Only push does. */
3
+ export declare const onIdentityChange: (fn: (() => void) | undefined) => void;
2
4
  export declare const setUser: (u: User | null) => void | undefined;
3
5
  export declare const patchContext: (patch: Record<string, unknown>) => void | undefined;
4
6
  export declare const currentUserKey: () => string | undefined;
7
+ /** The person's attributes, for the device row. Undefined when the
8
+ * host has not set any — which is different from `{}`, the value that
9
+ * clears them. */
10
+ export declare const currentUserTraits: () => Record<string, unknown> | undefined;
5
11
  export declare const currentContext: () => Record<string, unknown> | undefined;
6
12
  export declare const __resetForTests: () => void;
7
13
  //# sourceMappingURL=scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAOnD,eAAO,MAAM,OAAO,sCAmBlB,CAAC;AAEH,eAAO,MAAM,YAAY,sDAIvB,CAAC;AAEH,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,SAAqB,CAAC;AAEjE,eAAO,MAAM,cAAc,QAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SACI,CAAC;AAEjE,eAAO,MAAM,eAAe,QAAO,IAKlC,CAAC"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAoBnD,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,OAAQ,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,KAAG,IAE/D,CAAC;AAUF,eAAO,MAAM,OAAO,sCAkClB,CAAC;AAEH,eAAO,MAAM,YAAY,sDAIvB,CAAC;AAEH,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,SAAqB,CAAC;AAEjE;;mBAEmB;AACnB,eAAO,MAAM,iBAAiB,QAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SACX,CAAC;AAErD,eAAO,MAAM,cAAc,QAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SACI,CAAC;AAEjE,eAAO,MAAM,eAAe,QAAO,IAOlC,CAAC"}
package/lib/scope.js CHANGED
@@ -6,12 +6,47 @@ let _user = null;
6
6
  let _userKey;
7
7
  let _context = {};
8
8
  let _hashGeneration = 0;
9
+ let _traits;
10
+ // What to tell when the person changes.
11
+ //
12
+ // The device row carries the identity, and until now nothing updated
13
+ // it after registration: an app that registers for push at launch and
14
+ // signs in ten seconds later — which is every app with a login screen
15
+ // — held a row with no user on it for the life of the install. A send
16
+ // aimed at that user reached nobody and reported success.
17
+ //
18
+ // A callback rather than a direct call because push.ts already imports
19
+ // this file; the arrow has to point one way.
20
+ let _onIdentityChange;
21
+ /** Register interest in identity changes. Only push does. */
22
+ export const onIdentityChange = (fn) => {
23
+ _onIdentityChange = fn;
24
+ };
25
+ const announce = () => {
26
+ try {
27
+ _onIdentityChange?.();
28
+ }
29
+ catch {
30
+ // NEVER rule: whatever the listener does, user() returns.
31
+ }
32
+ };
9
33
  export const setUser = safeFn('user', function setUser(u) {
10
34
  _user = u;
11
35
  _userKey = undefined;
36
+ // A call to `user()` describes the person completely, so one made
37
+ // without traits means they have none — not "leave the last ones".
38
+ // Absent and empty are different on the wire: absent keeps what the
39
+ // row has, and a signed-out device that kept them would still be
40
+ // selectable as whoever just left.
41
+ _traits = u?.traits == null ? {} : { ...u.traits };
12
42
  const generation = ++_hashGeneration;
13
- if (u === null)
43
+ if (u === null) {
44
+ // Signing out is an identity change too, and the one where a
45
+ // stale row matters most: the device would otherwise keep
46
+ // answering to the person who just left.
47
+ announce();
14
48
  return;
49
+ }
15
50
  // The wire carries only a salted hash — raw identity never leaves
16
51
  // the device (breadth × depth needs distinctness, not identity).
17
52
  // Hashing is async (WebCrypto); the verb stays synchronous and the
@@ -21,6 +56,9 @@ export const setUser = safeFn('user', function setUser(u) {
21
56
  .then((hashes) => {
22
57
  if (generation === _hashGeneration) {
23
58
  _userKey = hashes.id ?? hashes.email;
59
+ // Announced after the hash lands, not before: the whole point
60
+ // is to send the new key, and the key is what arrives late.
61
+ announce();
24
62
  }
25
63
  })
26
64
  .catch(() => {
@@ -31,11 +69,17 @@ export const patchContext = safeFn('context', function patchContext(patch) {
31
69
  _context = { ..._context, ...patch };
32
70
  });
33
71
  export const currentUserKey = () => _userKey;
72
+ /** The person's attributes, for the device row. Undefined when the
73
+ * host has not set any — which is different from `{}`, the value that
74
+ * clears them. */
75
+ export const currentUserTraits = () => _traits === undefined ? undefined : { ..._traits };
34
76
  export const currentContext = () => Object.keys(_context).length > 0 ? { ..._context } : undefined;
35
77
  export const __resetForTests = () => {
36
78
  _user = null;
37
79
  _userKey = undefined;
80
+ _traits = undefined;
38
81
  _context = {};
82
+ _onIdentityChange = undefined;
39
83
  _hashGeneration++;
40
84
  };
41
85
  //# sourceMappingURL=scope.js.map
package/lib/scope.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,gEAAgE;AAChE,wCAAwC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhE,IAAI,KAAK,GAAgB,IAAI,CAAC;AAC9B,IAAI,QAA4B,CAAC;AACjC,IAAI,QAAQ,GAA4B,EAAE,CAAC;AAC3C,IAAI,eAAe,GAAG,CAAC,CAAC;AAExB,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,CAAc;IACnE,KAAK,GAAG,CAAC,CAAC;IACV,QAAQ,GAAG,SAAS,CAAC;IACrB,MAAM,UAAU,GAAG,EAAE,eAAe,CAAC;IACrC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO;IACvB,kEAAkE;IAClE,iEAAiE;IACjE,mEAAmE;IACnE,kEAAkE;IAClE,oDAAoD;IACpD,KAAK,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;SAC9C,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;YACnC,QAAQ,GAAG,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACV,uDAAuD;IACzD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,EAAE,SAAS,YAAY,CACjE,KAA8B;IAE9B,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAuB,EAAE,CAAC,QAAQ,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAwC,EAAE,CACtE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAS,EAAE;IACxC,KAAK,GAAG,IAAI,CAAC;IACb,QAAQ,GAAG,SAAS,CAAC;IACrB,QAAQ,GAAG,EAAE,CAAC;IACd,eAAe,EAAE,CAAC;AACpB,CAAC,CAAC"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.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.2.1';
18
+ const SDK_VERSION = '6.3.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.2.1",
3
+ "version": "6.3.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.2.0"
88
+ "@goliapkg/sentori-core": "^2.3.0"
89
89
  }
90
90
  }
@@ -15,7 +15,7 @@ import {
15
15
  register,
16
16
  } from '../push';
17
17
  import { __resetForTests as resetConfig, setConfig } from '../config';
18
- import { __resetForTests as resetScope } from '../scope';
18
+ import { __resetForTests as resetScope, setUser } from '../scope';
19
19
 
20
20
  const baseConfig = {
21
21
  token: 'st_test',
@@ -202,3 +202,101 @@ describe('push.register', () => {
202
202
  expect(seen).not.toBeNull();
203
203
  });
204
204
  });
205
+
206
+ // A device registers at launch; the person signs in ten seconds
207
+ // later. Until now nothing updated the row, so it carried no user for
208
+ // the life of the install — and a send aimed at that user reached
209
+ // nobody and reported success.
210
+ describe('push registration follows the person', () => {
211
+ /** Record every /v1/push/tokens body, so a test can say what the
212
+ * server was told rather than that it was told something. */
213
+ function recordingFetch(): Array<Record<string, unknown>> {
214
+ const seen: Array<Record<string, unknown>> = [];
215
+ globalThis.fetch = ((_url: string, init?: { body?: string }) => {
216
+ if (init?.body != null) {
217
+ seen.push(JSON.parse(init.body) as Record<string, unknown>);
218
+ }
219
+ return Promise.resolve({
220
+ ok: true,
221
+ status: 202,
222
+ json: () => Promise.resolve({ spToken: 'dev-1', token_id: 'dev-1' }),
223
+ });
224
+ }) as unknown as typeof fetch;
225
+ return seen;
226
+ }
227
+
228
+ /** `user()` hashes on a promise, so the key lands a tick later and
229
+ * the re-registration is sent after that. */
230
+ const settle = () => new Promise((r) => setTimeout(r, 10));
231
+
232
+ beforeEach(() => {
233
+ resetPush();
234
+ resetConfig();
235
+ resetScope();
236
+ setPlatform('ios');
237
+ setConfig(baseConfig);
238
+ __setNativeForTests(grantingNative());
239
+ });
240
+ afterEach(() => {
241
+ resetPush();
242
+ resetConfig();
243
+ resetScope();
244
+ setPlatform(null);
245
+ __setNativeForTests(undefined);
246
+ globalThis.fetch = realFetch;
247
+ });
248
+
249
+ it('sends the identity when the person signs in after registering', async () => {
250
+ const seen = recordingFetch();
251
+ await register();
252
+ expect(seen).toHaveLength(1);
253
+ expect(seen[0]?.userKey).toBeUndefined();
254
+
255
+ setUser({ id: 'usr_123', traits: { plan: 'pro' } });
256
+ await settle();
257
+
258
+ // Two assertions, because either alone passes on a mistake: a
259
+ // count alone passes if the update carries nothing, and a key
260
+ // alone passes if the update never happened and this is still the
261
+ // first request.
262
+ expect(seen).toHaveLength(2);
263
+ expect(typeof seen[1]?.userKey).toBe('string');
264
+ expect(seen[1]?.traits).toEqual({ plan: 'pro' });
265
+ });
266
+
267
+ it('does not send anything when the same person is set again', async () => {
268
+ const seen = recordingFetch();
269
+ await register();
270
+ setUser({ id: 'usr_123', traits: { plan: 'pro' } });
271
+ await settle();
272
+ const after = seen.length;
273
+
274
+ // `user()` is a verb an app may call on every screen. One request
275
+ // per call is not free to a host, and the iron rule is that we are.
276
+ setUser({ id: 'usr_123', traits: { plan: 'pro' } });
277
+ await settle();
278
+ expect(seen).toHaveLength(after);
279
+ });
280
+
281
+ it('clears the traits when the person signs out', async () => {
282
+ const seen = recordingFetch();
283
+ await register();
284
+ setUser({ id: 'usr_123', traits: { plan: 'pro' } });
285
+ await settle();
286
+ setUser(null);
287
+ await settle();
288
+
289
+ const last = seen[seen.length - 1];
290
+ expect(last?.userKey).toBeUndefined();
291
+ // `{}` rather than absent: absent means "keep what is there", so
292
+ // a signed-out device would stay selectable as a pro user.
293
+ expect(last?.traits).toEqual({});
294
+ });
295
+
296
+ it('does not register a device that never registered', async () => {
297
+ const seen = recordingFetch();
298
+ setUser({ id: 'usr_123' });
299
+ await settle();
300
+ expect(seen).toHaveLength(0);
301
+ });
302
+ });