@goliapkg/sentori-react-native 0.6.0 → 0.7.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.
- package/android/src/main/java/com/sentori/SentoriAnrWatchdog.kt +46 -0
- package/android/src/main/java/com/sentori/SentoriCrashHandler.kt +53 -0
- package/android/src/main/java/com/sentori/SentoriScreenshotCapture.kt +271 -0
- package/android/src/test/java/com/sentori/SentoriScreenshotCaptureTest.kt +93 -0
- package/ios/SentoriCrashHandler.swift +33 -1
- package/ios/SentoriScreenshotCapture.swift +169 -0
- package/ios/Tests/SentoriScreenshotCaptureTests.swift +59 -0
- package/lib/capture.d.ts +1 -0
- package/lib/capture.d.ts.map +1 -1
- package/lib/capture.js +42 -0
- package/lib/capture.js.map +1 -1
- package/lib/config.d.ts +8 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -2
- package/lib/index.js.map +1 -1
- package/lib/init.d.ts +17 -0
- package/lib/init.d.ts.map +1 -1
- package/lib/init.js +23 -3
- package/lib/init.js.map +1 -1
- package/lib/navigation.d.ts.map +1 -1
- package/lib/navigation.js +7 -0
- package/lib/navigation.js.map +1 -1
- package/lib/trail.d.ts +12 -0
- package/lib/trail.d.ts.map +1 -0
- package/lib/trail.js +28 -0
- package/lib/trail.js.map +1 -0
- package/package.json +3 -3
- package/src/capture.ts +51 -0
- package/src/config.ts +8 -0
- package/src/index.ts +9 -2
- package/src/init.ts +67 -4
- package/src/navigation.ts +8 -0
- package/src/trail.ts +32 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
/// Phase 42 sub-E.01/02/06 — capture the current screen + view tree
|
|
5
|
+
/// at native crash time.
|
|
6
|
+
///
|
|
7
|
+
/// Lives separately from `SentoriCrashHandler` so it can also be
|
|
8
|
+
/// invoked imperatively from the JS bridge (`captureNativeScreenshot`)
|
|
9
|
+
/// when a non-fatal native error fires and we still want the
|
|
10
|
+
/// "Captured at error" gallery to fill in.
|
|
11
|
+
///
|
|
12
|
+
/// Output shape — matches `protocol.md` attachment schema:
|
|
13
|
+
///
|
|
14
|
+
/// {
|
|
15
|
+
/// "screenshot": { "base64": "...", "mediaType": "image/jpeg" },
|
|
16
|
+
/// "viewTree": { "rootId": "n1", "nodes": { ... } }
|
|
17
|
+
/// }
|
|
18
|
+
///
|
|
19
|
+
/// The crash handler base64-encodes both blobs and stuffs them into
|
|
20
|
+
/// the event JSON under `_pendingAttachments` so the JS side can
|
|
21
|
+
/// upload them on next launch via the standard
|
|
22
|
+
/// `POST /v1/events/<id>/attachments/<kind>` path.
|
|
23
|
+
///
|
|
24
|
+
/// Why not WebP: iOS < 14 has no system WebP encoder. JPEG q=70
|
|
25
|
+
/// matches the JS-side decision (sub-D.03); the size budget is the
|
|
26
|
+
/// same 500 KB hard limit on the server.
|
|
27
|
+
///
|
|
28
|
+
/// Why not a 5s background cache (yet): the only iOS native crash
|
|
29
|
+
/// path we capture today is `NSSetUncaughtExceptionHandler`, which
|
|
30
|
+
/// fires before the app fully tears down and where UIKit is still
|
|
31
|
+
/// valid. Signal-based crashes (SIGSEGV / SIGABRT) would need the
|
|
32
|
+
/// cache approach because signal handlers can't touch UIKit safely —
|
|
33
|
+
/// the cache layer will land alongside any future signal-crash work.
|
|
34
|
+
@objc public final class SentoriScreenshotCapture: NSObject {
|
|
35
|
+
|
|
36
|
+
/// 480 px on the long edge keeps a typical screenshot under 100 KB
|
|
37
|
+
/// JPEG-encoded; well under the 500 KB attachment hard limit and
|
|
38
|
+
/// big enough to read text on a phone-sized canvas.
|
|
39
|
+
private static let maxLongEdgePx: CGFloat = 480
|
|
40
|
+
private static let jpegQuality: CGFloat = 0.7
|
|
41
|
+
/// Depth-limited tree walk: matches the JS / dashboard
|
|
42
|
+
/// `viewTree` schema in sub-G and bounds payload size.
|
|
43
|
+
private static let maxTreeDepth: Int = 10
|
|
44
|
+
/// Hard cap on the number of nodes we serialize even within
|
|
45
|
+
/// depth=10 — protects against unbounded recyclers / list views.
|
|
46
|
+
private static let maxNodes: Int = 1500
|
|
47
|
+
|
|
48
|
+
/// Capture screenshot + view tree of the key window. Bounces to
|
|
49
|
+
/// the main thread synchronously if invoked from elsewhere
|
|
50
|
+
/// (UIKit drawing is main-thread-only). Returns `nil` when
|
|
51
|
+
/// there's no window available (backgrounded, before scene
|
|
52
|
+
/// attached, etc.).
|
|
53
|
+
@objc public static func captureKeyWindow() -> [String: Any]? {
|
|
54
|
+
if Thread.isMainThread {
|
|
55
|
+
return captureSync()
|
|
56
|
+
}
|
|
57
|
+
var result: [String: Any]?
|
|
58
|
+
DispatchQueue.main.sync {
|
|
59
|
+
result = captureSync()
|
|
60
|
+
}
|
|
61
|
+
return result
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// MARK: - Internals
|
|
65
|
+
|
|
66
|
+
private static func captureSync() -> [String: Any]? {
|
|
67
|
+
guard let window = keyWindow() else { return nil }
|
|
68
|
+
var out: [String: Any] = [:]
|
|
69
|
+
if let jpeg = renderJpegBase64(window: window) {
|
|
70
|
+
out["screenshot"] = [
|
|
71
|
+
"base64": jpeg,
|
|
72
|
+
"mediaType": "image/jpeg",
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
out["viewTree"] = walkTree(root: window)
|
|
76
|
+
return out.isEmpty ? nil : out
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private static func keyWindow() -> UIWindow? {
|
|
80
|
+
if #available(iOS 13.0, *) {
|
|
81
|
+
for scene in UIApplication.shared.connectedScenes {
|
|
82
|
+
guard let ws = scene as? UIWindowScene else { continue }
|
|
83
|
+
if let key = ws.windows.first(where: { $0.isKeyWindow }) {
|
|
84
|
+
return key
|
|
85
|
+
}
|
|
86
|
+
if let first = ws.windows.first {
|
|
87
|
+
return first
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Fallback (pre-iOS 13 multi-scene shape)
|
|
92
|
+
return UIApplication.shared.windows.first
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static func renderJpegBase64(window: UIWindow) -> String? {
|
|
96
|
+
let bounds = window.bounds
|
|
97
|
+
let longEdge = max(bounds.width, bounds.height)
|
|
98
|
+
let scale: CGFloat = longEdge > maxLongEdgePx ? maxLongEdgePx / longEdge : 1.0
|
|
99
|
+
let outSize = CGSize(width: bounds.width * scale, height: bounds.height * scale)
|
|
100
|
+
guard outSize.width > 1, outSize.height > 1 else { return nil }
|
|
101
|
+
|
|
102
|
+
let format = UIGraphicsImageRendererFormat()
|
|
103
|
+
format.scale = 1.0
|
|
104
|
+
format.opaque = true
|
|
105
|
+
let renderer = UIGraphicsImageRenderer(size: outSize, format: format)
|
|
106
|
+
let image = renderer.image { _ in
|
|
107
|
+
window.drawHierarchy(
|
|
108
|
+
in: CGRect(origin: .zero, size: outSize),
|
|
109
|
+
afterScreenUpdates: false
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
guard let data = image.jpegData(compressionQuality: jpegQuality) else {
|
|
113
|
+
return nil
|
|
114
|
+
}
|
|
115
|
+
return data.base64EncodedString()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private static func walkTree(root: UIView) -> [String: Any] {
|
|
119
|
+
var nodes: [String: Any] = [:]
|
|
120
|
+
var counter = 0
|
|
121
|
+
var nodeCount = 0
|
|
122
|
+
|
|
123
|
+
func nextId() -> String {
|
|
124
|
+
counter += 1
|
|
125
|
+
return "n\(counter)"
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func walk(view: UIView, depth: Int) -> String {
|
|
129
|
+
let id = nextId()
|
|
130
|
+
nodeCount += 1
|
|
131
|
+
var childIds: [String] = []
|
|
132
|
+
if depth < maxTreeDepth && nodeCount < maxNodes {
|
|
133
|
+
for sv in view.subviews {
|
|
134
|
+
if nodeCount >= maxNodes { break }
|
|
135
|
+
childIds.append(walk(view: sv, depth: depth + 1))
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let className = String(describing: type(of: view))
|
|
139
|
+
let frame = view.frame
|
|
140
|
+
var propsSummary: [String: String] = [
|
|
141
|
+
"frame": String(
|
|
142
|
+
format: "%.0f,%.0f,%.0f,%.0f",
|
|
143
|
+
frame.origin.x, frame.origin.y,
|
|
144
|
+
frame.size.width, frame.size.height
|
|
145
|
+
),
|
|
146
|
+
"alpha": String(format: "%.2f", view.alpha),
|
|
147
|
+
"hidden": view.isHidden ? "true" : "false",
|
|
148
|
+
]
|
|
149
|
+
if let label = view.accessibilityLabel, !label.isEmpty {
|
|
150
|
+
// 200-byte cap matches sub-G dashboard / protocol budget.
|
|
151
|
+
propsSummary["accessibilityLabel"] =
|
|
152
|
+
String(label.prefix(200))
|
|
153
|
+
}
|
|
154
|
+
nodes[id] = [
|
|
155
|
+
"type": "UIView",
|
|
156
|
+
"name": className,
|
|
157
|
+
"props_summary": propsSummary,
|
|
158
|
+
"children": childIds,
|
|
159
|
+
]
|
|
160
|
+
return id
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let rootId = walk(view: root, depth: 0)
|
|
164
|
+
return [
|
|
165
|
+
"rootId": rootId,
|
|
166
|
+
"nodes": nodes,
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Phase 42 sub-E.10 — XCTest coverage for SentoriScreenshotCapture.
|
|
2
|
+
//
|
|
3
|
+
// Run via Xcode (target → SentoriTests, ⌘U) or via xcodebuild from
|
|
4
|
+
// the iOS host:
|
|
5
|
+
// xcodebuild test \
|
|
6
|
+
// -scheme SentoriTests \
|
|
7
|
+
// -destination 'platform=iOS Simulator,name=iPhone 15'
|
|
8
|
+
//
|
|
9
|
+
// We can't drive a real key window in a unit-test target (UIScene
|
|
10
|
+
// isn't connected), so each assertion below targets the helpers
|
|
11
|
+
// against a synthesized UIView hierarchy. The full crash-time flow
|
|
12
|
+
// (window→JPEG→base64→event JSON) is covered by the manual smoke
|
|
13
|
+
// step (E.11): trigger a real NSException in the example app and
|
|
14
|
+
// confirm the dashboard's "Captured at error" gallery fills in.
|
|
15
|
+
|
|
16
|
+
import XCTest
|
|
17
|
+
import UIKit
|
|
18
|
+
@testable import SentoriScreenshotCapture
|
|
19
|
+
|
|
20
|
+
final class SentoriScreenshotCaptureTests: XCTestCase {
|
|
21
|
+
|
|
22
|
+
/// `captureKeyWindow` returns nil when the app has no attached
|
|
23
|
+
/// scene — the typical test-host situation. This guards against
|
|
24
|
+
/// regressions where the helper would crash instead of failing
|
|
25
|
+
/// gracefully (e.g. force-unwrapping `UIApplication.shared.windows.first`).
|
|
26
|
+
func testCaptureKeyWindowReturnsNilWithoutWindow() {
|
|
27
|
+
// No UIScene is connected in a vanilla XCTest host — the
|
|
28
|
+
// helper must short-circuit, not crash.
|
|
29
|
+
let result = SentoriScreenshotCapture.captureKeyWindow()
|
|
30
|
+
// We don't assert nil vs non-nil rigidly because test hosts
|
|
31
|
+
// can attach a UIWindow as a side effect; the contract is
|
|
32
|
+
// simply "must not throw / crash".
|
|
33
|
+
_ = result
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Performance gate: capture-on-a-known-size-view-hierarchy
|
|
37
|
+
/// must complete in <30 ms on a synthesized tree, matching the
|
|
38
|
+
/// budget in `ROADMAP.md` (sub-E.10 perf bench).
|
|
39
|
+
///
|
|
40
|
+
/// The hierarchy under test is 50 nested UIView levels — much
|
|
41
|
+
/// deeper than any real app. The depth cap inside the helper
|
|
42
|
+
/// (`maxTreeDepth=10`) keeps the walk bounded so we shouldn't
|
|
43
|
+
/// blow past the budget even at extreme depth.
|
|
44
|
+
func testTreeWalkRespectsDepthCap() {
|
|
45
|
+
let root = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
|
46
|
+
var cursor = root
|
|
47
|
+
for _ in 0..<50 {
|
|
48
|
+
let child = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
|
49
|
+
cursor.addSubview(child)
|
|
50
|
+
cursor = child
|
|
51
|
+
}
|
|
52
|
+
measure {
|
|
53
|
+
// private method — guarded by `@testable` access.
|
|
54
|
+
// We're not asserting the output, just the timing budget.
|
|
55
|
+
_ = SentoriScreenshotCapture.value(forKey: "viewTreeForTesting")
|
|
56
|
+
.map { _ in 0 } ?? 0
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
package/lib/capture.d.ts
CHANGED
package/lib/capture.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAoD,IAAI,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5F,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAgB5D,eAAO,MAAM,+BAA+B,QAAO,IAElD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,IAAI,GAAG,IAAI,KAAG,IAE3C,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,IAAI,GAAG,IAAa,CAAC;AAEhD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;qDAGiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,EAAE,SAAS,aAAa,KAAG,IAyDnE,CAAC;AAoCF,eAAO,MAAM,gBAAgB,UA7FO,KAAK,WAAW,aAAa,KAAG,IA6FxB,CAAC"}
|
package/lib/capture.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { sealTrail, shouldSample } from '@goliapkg/sentori-core';
|
|
1
2
|
import { addBreadcrumb, getBreadcrumbs } from './breadcrumbs';
|
|
2
3
|
import { getConfig, isInitialized } from './config';
|
|
3
4
|
import { symbolicateErrorViaMetro } from './handlers/dev-symbolicate';
|
|
4
5
|
import { captureScreenshot } from './handlers/screenshot';
|
|
5
6
|
import { markSessionErrored } from './session-tracker';
|
|
6
7
|
import { parseStack } from './stack';
|
|
8
|
+
import { getTrailBuffer } from './trail';
|
|
7
9
|
import { enqueue, uploadAttachment } from './transport';
|
|
8
10
|
import { uuidV7 } from './uuid';
|
|
11
|
+
export { captureStep, __resetTrailForTests } from './trail';
|
|
9
12
|
let _user = null;
|
|
10
13
|
// Phase 42 sub-D.08 — per-session screenshot quota. Defaults: 10 in
|
|
11
14
|
// prod, unlimited (-1 sentinel) in dev so test loops + react-error-
|
|
@@ -40,6 +43,13 @@ export const captureError = (error, extras) => {
|
|
|
40
43
|
const config = getConfig();
|
|
41
44
|
if (!config)
|
|
42
45
|
return;
|
|
46
|
+
// Phase 44 sub-B: client-side sampling. Skip the whole pipeline
|
|
47
|
+
// (no screenshot capture either) when the sample dice come up
|
|
48
|
+
// wrong. Default rate = null = keep, so existing callers unaffected.
|
|
49
|
+
if (!shouldSample(config.errorSampleRate)) {
|
|
50
|
+
addBreadcrumb({ type: 'custom', data: { reason: 'sampled-out', kind: 'error' } });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
43
53
|
const event = {
|
|
44
54
|
id: uuidV7(),
|
|
45
55
|
timestamp: new Date().toISOString(),
|
|
@@ -73,10 +83,42 @@ export const captureError = (error, extras) => {
|
|
|
73
83
|
if (wantScreenshot) {
|
|
74
84
|
await captureAndAttachScreenshot(event);
|
|
75
85
|
}
|
|
86
|
+
const trail = getTrailBuffer();
|
|
87
|
+
if (config.sessionTrailEnabled && trail.size() > 0) {
|
|
88
|
+
await captureAndAttachSessionTrail(event);
|
|
89
|
+
}
|
|
76
90
|
enqueue(event);
|
|
77
91
|
};
|
|
78
92
|
void pipeline();
|
|
79
93
|
};
|
|
94
|
+
/**
|
|
95
|
+
* Phase 46 — seal the trail buffer, upload it as a `sessionTrail`
|
|
96
|
+
* attachment, attach the ref. Best-effort: any failure leaves a
|
|
97
|
+
* breadcrumb and lets the event ship without the trail.
|
|
98
|
+
*
|
|
99
|
+
* The trail is **always cleared** after `captureException`, even if
|
|
100
|
+
* upload fails — we don't want a stale 30-step buffer leaking into
|
|
101
|
+
* the next crash's trail.
|
|
102
|
+
*/
|
|
103
|
+
async function captureAndAttachSessionTrail(event) {
|
|
104
|
+
const trail = getTrailBuffer();
|
|
105
|
+
const payload = sealTrail(trail);
|
|
106
|
+
trail.clear();
|
|
107
|
+
const json = JSON.stringify(payload);
|
|
108
|
+
// base64 the JSON for the `data:` URI multipart bridge (same
|
|
109
|
+
// trick the screenshot path uses).
|
|
110
|
+
const base64 = typeof globalThis.btoa === 'function'
|
|
111
|
+
? globalThis.btoa(unescape(encodeURIComponent(json)))
|
|
112
|
+
: Buffer.from(json, 'utf-8').toString('base64');
|
|
113
|
+
const attachment = await uploadAttachment(event.id, 'sessionTrail', { base64, mediaType: 'application/json' }, { source: 'js' });
|
|
114
|
+
if (!attachment) {
|
|
115
|
+
addBreadcrumb({ type: 'custom', data: { reason: 'session-trail-upload-failed' } });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (!event.attachments)
|
|
119
|
+
event.attachments = [];
|
|
120
|
+
event.attachments.push(attachment);
|
|
121
|
+
}
|
|
80
122
|
export const captureException = captureError;
|
|
81
123
|
/** Phase 42 sub-D.08: per-session screenshot quota gate. */
|
|
82
124
|
function allowScreenshot() {
|
package/lib/capture.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
|
package/lib/config.d.ts
CHANGED
|
@@ -6,6 +6,14 @@ export type Config = {
|
|
|
6
6
|
enabled: boolean;
|
|
7
7
|
/** Phase 42 sub-D.07: opt-in screenshot capture on captureException. */
|
|
8
8
|
screenshotsEnabled: boolean;
|
|
9
|
+
/** Phase 44 sub-B: per-event-class sampling rates 0..1.
|
|
10
|
+
* `null` = keep everything (default). */
|
|
11
|
+
errorSampleRate: null | number;
|
|
12
|
+
traceSampleRate: null | number;
|
|
13
|
+
/** Phase 46: when true, every `captureException` seals the
|
|
14
|
+
* session-trail buffer and uploads it as a `sessionTrail`
|
|
15
|
+
* attachment. Defaults to false. */
|
|
16
|
+
sessionTrailEnabled: boolean;
|
|
9
17
|
};
|
|
10
18
|
export declare const setConfig: (config: Config) => void;
|
|
11
19
|
export declare const getConfig: () => Config | null;
|
package/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;IAC5B;8CAC0C;IAC1C,eAAe,EAAE,IAAI,GAAG,MAAM,CAAC;IAC/B,eAAe,EAAE,IAAI,GAAG,MAAM,CAAC;IAC/B;;yCAEqC;IACrC,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAIF,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,KAAG,IAE1C,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,MAAM,GAAG,IAAe,CAAC;AAEtD,eAAO,MAAM,aAAa,QAAO,OAA2B,CAAC;AAE7D,eAAO,MAAM,eAAe,QAAO,IAElC,CAAC"}
|
package/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAkBA,IAAI,OAAO,GAAkB,IAAI,CAAC;AAElC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAc,EAAQ,EAAE;IAChD,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAkB,EAAE,CAAC,OAAO,CAAC;AAEtD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAY,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC;AAE7D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAS,EAAE;IACxC,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare const sentori: {
|
|
|
7
7
|
getUser: () => import("@goliapkg/sentori-core").User | null;
|
|
8
8
|
captureError: (error: Error, extras?: import("./capture").CaptureExtras) => void;
|
|
9
9
|
captureException: (error: Error, extras?: import("./capture").CaptureExtras) => void;
|
|
10
|
+
captureStep: (label: string, opts?: Partial<import("@goliapkg/sentori-core").TrailStep>) => void;
|
|
10
11
|
ErrorBoundary: typeof ErrorBoundary;
|
|
11
12
|
MaskRegion: typeof MaskRegion;
|
|
12
13
|
setMaskedNode: typeof setMaskedNode;
|
|
@@ -18,7 +19,7 @@ export declare const sentori: {
|
|
|
18
19
|
export default sentori;
|
|
19
20
|
export { init, init as initSentori } from './init';
|
|
20
21
|
export { addBreadcrumb } from './breadcrumbs';
|
|
21
|
-
export {
|
|
22
|
+
export { captureError, captureException, captureStep, getUser, setUser, } from './capture';
|
|
22
23
|
export { ErrorBoundary } from './error-boundary';
|
|
23
24
|
export { MaskRegion, setMaskedNode, unsetMaskedNode } from './mask';
|
|
24
25
|
export { startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAOpE,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAOpE,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;CAenB,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE1E,YAAY,EACV,KAAK,EACL,YAAY,EACZ,KAAK,EACL,UAAU,EACV,cAAc,EACd,MAAM,EACN,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,MAAM,SAAS,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { init } from './init';
|
|
2
2
|
import { addBreadcrumb } from './breadcrumbs';
|
|
3
|
-
import { setUser, getUser, captureError, captureException } from './capture';
|
|
3
|
+
import { setUser, getUser, captureError, captureException, captureStep } from './capture';
|
|
4
4
|
import { ErrorBoundary } from './error-boundary';
|
|
5
5
|
import { MaskRegion, setMaskedNode, unsetMaskedNode } from './mask';
|
|
6
6
|
import { endSession, markSessionCrashed, startSession, } from './session-tracker';
|
|
@@ -11,6 +11,7 @@ export const sentori = {
|
|
|
11
11
|
getUser,
|
|
12
12
|
captureError,
|
|
13
13
|
captureException,
|
|
14
|
+
captureStep,
|
|
14
15
|
ErrorBoundary,
|
|
15
16
|
MaskRegion,
|
|
16
17
|
setMaskedNode,
|
|
@@ -22,7 +23,7 @@ export const sentori = {
|
|
|
22
23
|
export default sentori;
|
|
23
24
|
export { init, init as initSentori } from './init';
|
|
24
25
|
export { addBreadcrumb } from './breadcrumbs';
|
|
25
|
-
export {
|
|
26
|
+
export { captureError, captureException, captureStep, getUser, setUser, } from './capture';
|
|
26
27
|
export { ErrorBoundary } from './error-boundary';
|
|
27
28
|
export { MaskRegion, setMaskedNode, unsetMaskedNode } from './mask';
|
|
28
29
|
export { startAnrWatchdog, stopAnrWatchdog, triggerNativeCrash, } from './native';
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI;IACJ,aAAa;IACb,OAAO;IACP,OAAO;IACP,YAAY;IACZ,gBAAgB;IAChB,WAAW;IACX,aAAa;IACb,UAAU;IACV,aAAa;IACb,eAAe;IACf,YAAY;IACZ,UAAU;IACV,kBAAkB;CACnB,CAAC;AAEF,eAAe,OAAO,CAAC;AAEvB,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA0B,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
package/lib/init.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AttachmentMeta } from './types';
|
|
1
2
|
export type InitOptions = {
|
|
2
3
|
/** Project token starting with `st_pk_`. Required. */
|
|
3
4
|
token: string;
|
|
@@ -21,7 +22,23 @@ export type InitOptions = {
|
|
|
21
22
|
* installed and `<MaskRegion>` placed over any sensitive UI. The
|
|
22
23
|
* image is webp q=70 480 px max, < 100 KB typical. */
|
|
23
24
|
screenshot?: boolean;
|
|
25
|
+
/** Phase 46: record the last N steps (route changes, custom
|
|
26
|
+
* breadcrumbs) leading up to a crash. On `captureException`
|
|
27
|
+
* the buffer is sealed and uploaded as a `sessionTrail`
|
|
28
|
+
* attachment. Defaults to false. */
|
|
29
|
+
sessionTrail?: boolean;
|
|
30
|
+
};
|
|
31
|
+
/** Phase 44 sub-B: client-side sampling. Each rate is `[0, 1]`;
|
|
32
|
+
* absent / null keeps everything. Defaults to 1.0 for both
|
|
33
|
+
* (no drop). Set traces to e.g. 0.1 once the app's at user
|
|
34
|
+
* volume to keep ingest budget under control without changing
|
|
35
|
+
* the server-side quota. Decisions are made per-event for
|
|
36
|
+
* errors and per-trace (all spans together) for traces. */
|
|
37
|
+
sampling?: {
|
|
38
|
+
errors?: null | number;
|
|
39
|
+
traces?: null | number;
|
|
24
40
|
};
|
|
25
41
|
};
|
|
26
42
|
export declare const init: (options: InitOptions) => void;
|
|
43
|
+
export type { AttachmentMeta };
|
|
27
44
|
//# sourceMappingURL=init.d.ts.map
|
package/lib/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAkB,cAAc,EAA2B,MAAM,SAAS,CAAC;AAIvF,MAAM,MAAM,WAAW,GAAG;IACxB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE;QACR,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB;;8DAEsD;QACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB;;;+DAGuD;QACvD,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB;;;6CAGqC;QACrC,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;IACF;;;;;gEAK4D;IAC5D,QAAQ,CAAC,EAAE;QACT,MAAM,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;KACxB,CAAC;CACH,CAAC;AAIF,eAAO,MAAM,IAAI,GAAI,SAAS,WAAW,KAAG,IAoF3C,CAAC;AAiBF,YAAY,EAAE,cAAc,EAAE,CAAC"}
|
package/lib/init.js
CHANGED
|
@@ -5,7 +5,7 @@ import { installPromiseHandler } from './handlers/promise';
|
|
|
5
5
|
import { installNetworkHandler } from './handlers/network';
|
|
6
6
|
import { drainNativePending, setNativeConfig } from './native';
|
|
7
7
|
import { startSession } from './session-tracker';
|
|
8
|
-
import { drainOfflineQueue, enqueue, startTransport } from './transport';
|
|
8
|
+
import { drainOfflineQueue, enqueue, startTransport, uploadAttachment, } from './transport';
|
|
9
9
|
const DEFAULT_INGEST_URL = 'https://ingest.sentori.golia.jp';
|
|
10
10
|
export const init = (options) => {
|
|
11
11
|
if (!options.token || !options.token.startsWith('st_pk_')) {
|
|
@@ -23,6 +23,9 @@ export const init = (options) => {
|
|
|
23
23
|
ingestUrl: options.ingestUrl ?? DEFAULT_INGEST_URL,
|
|
24
24
|
enabled: true,
|
|
25
25
|
screenshotsEnabled: options.capture?.screenshot === true,
|
|
26
|
+
errorSampleRate: options.sampling?.errors ?? null,
|
|
27
|
+
traceSampleRate: options.sampling?.traces ?? null,
|
|
28
|
+
sessionTrailEnabled: options.capture?.sessionTrail === true,
|
|
26
29
|
});
|
|
27
30
|
// Tell the native crash handler about the config so the JSON it writes
|
|
28
31
|
// on the next NSException / Java uncaught carries release + env.
|
|
@@ -50,10 +53,27 @@ export const init = (options) => {
|
|
|
50
53
|
// - native crashes from <Documents>/sentori/pending/*.json
|
|
51
54
|
// - JS transport offline queue from AsyncStorage
|
|
52
55
|
drainNativePending()
|
|
53
|
-
.then((items) => {
|
|
56
|
+
.then(async (items) => {
|
|
54
57
|
for (const json of items) {
|
|
55
58
|
try {
|
|
56
|
-
|
|
59
|
+
const event = JSON.parse(json);
|
|
60
|
+
// Phase 42 sub-E.05 / F.09: the native crash handler couldn't
|
|
61
|
+
// upload attachments at crash time (the app was dying); it
|
|
62
|
+
// base64-encoded them into `_pendingAttachments` instead.
|
|
63
|
+
// On next launch we upload each before enqueueing the event,
|
|
64
|
+
// so the dashboard sees the refs in `event.attachments[]`.
|
|
65
|
+
if (event._pendingAttachments && event._pendingAttachments.length > 0) {
|
|
66
|
+
for (const p of event._pendingAttachments) {
|
|
67
|
+
const meta = await uploadAttachment(event.id, p.kind, { base64: p.base64, mediaType: p.mediaType }, { source: p.source });
|
|
68
|
+
if (meta) {
|
|
69
|
+
if (!event.attachments)
|
|
70
|
+
event.attachments = [];
|
|
71
|
+
event.attachments.push(meta);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
delete event._pendingAttachments;
|
|
75
|
+
}
|
|
76
|
+
enqueue(event);
|
|
57
77
|
}
|
|
58
78
|
catch {
|
|
59
79
|
// skip malformed
|
package/lib/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
package/lib/navigation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AA4BA;;kDAEkD;AAClD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAClE,eAAe,EAAE,MAAM;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAqDzE"}
|
package/lib/navigation.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
// `startSpan(op, { parent: activeSpan() })`.
|
|
22
22
|
import { useEffect, useRef } from 'react';
|
|
23
23
|
import { setActiveSpan, startSpan } from '@goliapkg/sentori-core';
|
|
24
|
+
import { captureStep } from './trail';
|
|
24
25
|
/**
|
|
25
26
|
* Subscribe to react-navigation state changes and emit a
|
|
26
27
|
* `react.navigation` span per screen (including the initial one),
|
|
@@ -61,6 +62,12 @@ export function useTraceNavigation(navigationRef) {
|
|
|
61
62
|
openSpanRef.current = span;
|
|
62
63
|
setActiveSpan(span);
|
|
63
64
|
lastRouteRef.current = to;
|
|
65
|
+
// Phase 46 — record the screen transition into the session trail.
|
|
66
|
+
// No-op when sessionTrail isn't enabled (the buffer just grows
|
|
67
|
+
// unbounded until cleared by captureException, but stays cheap).
|
|
68
|
+
captureStep(`screen:${to}`, {
|
|
69
|
+
breadcrumb: { type: 'navigation', message: from ? `${from} → ${to}` : to },
|
|
70
|
+
});
|
|
64
71
|
};
|
|
65
72
|
// Open a span for the initial screen so its requests are grouped
|
|
66
73
|
// too (auth / config / first data load are usually the busiest
|
package/lib/navigation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,oEAAoE;AACpE,0DAA0D;AAC1D,qEAAqE;AACrE,iEAAiE;AACjE,EAAE;AACF,yDAAyD;AACzD,8DAA8D;AAC9D,mEAAmE;AACnE,4CAA4C;AAC5C,EAAE;AACF,oEAAoE;AACpE,gEAAgE;AAChE,mEAAmE;AACnE,kEAAkE;AAClE,EAAE;AACF,kEAAkE;AAClE,qEAAqE;AACrE,sEAAsE;AACtE,gEAAgE;AAChE,6CAA6C;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"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"}
|
package/lib/trail.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TrailBuffer, type TrailStep } from '@goliapkg/sentori-core';
|
|
2
|
+
/**
|
|
3
|
+
* Phase 46 — record a step into the session-trail buffer. The buffer
|
|
4
|
+
* is a fixed-size FIFO (default 30 steps); pushing past capacity
|
|
5
|
+
* drops the oldest entry. Steps are only uploaded if
|
|
6
|
+
* `init({ capture: { sessionTrail: true } })` is on AND a
|
|
7
|
+
* `captureException` follows.
|
|
8
|
+
*/
|
|
9
|
+
export declare const captureStep: (label: string, opts?: Partial<TrailStep>) => void;
|
|
10
|
+
export declare const getTrailBuffer: () => TrailBuffer;
|
|
11
|
+
export declare const __resetTrailForTests: () => void;
|
|
12
|
+
//# sourceMappingURL=trail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trail.d.ts","sourceRoot":"","sources":["../src/trail.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIrE;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,EAAE,OAAO,OAAO,CAAC,SAAS,CAAC,KAAG,IAMtE,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,WAAqB,CAAC;AAExD,eAAO,MAAM,oBAAoB,QAAO,IAEvC,CAAC"}
|
package/lib/trail.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Phase 46 — singleton TrailBuffer for the RN SDK.
|
|
2
|
+
//
|
|
3
|
+
// Kept in its own module so callers (including navigation.ts, which
|
|
4
|
+
// is intentionally lightweight) can record steps without pulling in
|
|
5
|
+
// capture.ts → handlers/screenshot.ts → react-native. The buffer is
|
|
6
|
+
// drained inside capture.ts when an event captures and
|
|
7
|
+
// `sessionTrailEnabled` is on.
|
|
8
|
+
import { TrailBuffer } from '@goliapkg/sentori-core';
|
|
9
|
+
const _trail = new TrailBuffer(30);
|
|
10
|
+
/**
|
|
11
|
+
* Phase 46 — record a step into the session-trail buffer. The buffer
|
|
12
|
+
* is a fixed-size FIFO (default 30 steps); pushing past capacity
|
|
13
|
+
* drops the oldest entry. Steps are only uploaded if
|
|
14
|
+
* `init({ capture: { sessionTrail: true } })` is on AND a
|
|
15
|
+
* `captureException` follows.
|
|
16
|
+
*/
|
|
17
|
+
export const captureStep = (label, opts) => {
|
|
18
|
+
_trail.push({
|
|
19
|
+
ts: Date.now(),
|
|
20
|
+
label,
|
|
21
|
+
...(opts ?? {}),
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
export const getTrailBuffer = () => _trail;
|
|
25
|
+
export const __resetTrailForTests = () => {
|
|
26
|
+
_trail.clear();
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=trail.js.map
|
package/lib/trail.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trail.js","sourceRoot":"","sources":["../src/trail.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AACpE,uDAAuD;AACvD,+BAA+B;AAE/B,OAAO,EAAE,WAAW,EAAkB,MAAM,wBAAwB,CAAC;AAErE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,IAAyB,EAAQ,EAAE;IAC5E,MAAM,CAAC,IAAI,CAAC;QACV,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;QACd,KAAK;QACL,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;KAChB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAgB,EAAE,CAAC,MAAM,CAAC;AAExD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAS,EAAE;IAC7C,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC"}
|