heimdall-react-native 0.1.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 (49) hide show
  1. package/README.md +157 -0
  2. package/heimdall-react-native.podspec +18 -0
  3. package/ios/HeimdallNative.h +4 -0
  4. package/ios/HeimdallNative.m +151 -0
  5. package/lib/breadcrumbs.d.ts +12 -0
  6. package/lib/breadcrumbs.d.ts.map +1 -0
  7. package/lib/breadcrumbs.js +30 -0
  8. package/lib/breadcrumbs.js.map +1 -0
  9. package/lib/client.d.ts +26 -0
  10. package/lib/client.d.ts.map +1 -0
  11. package/lib/client.js +224 -0
  12. package/lib/client.js.map +1 -0
  13. package/lib/context.d.ts +5 -0
  14. package/lib/context.d.ts.map +1 -0
  15. package/lib/context.js +50 -0
  16. package/lib/context.js.map +1 -0
  17. package/lib/fingerprint.d.ts +3 -0
  18. package/lib/fingerprint.d.ts.map +1 -0
  19. package/lib/fingerprint.js +22 -0
  20. package/lib/fingerprint.js.map +1 -0
  21. package/lib/handlers/errorBoundary.d.ts +17 -0
  22. package/lib/handlers/errorBoundary.d.ts.map +1 -0
  23. package/lib/handlers/errorBoundary.js +40 -0
  24. package/lib/handlers/errorBoundary.js.map +1 -0
  25. package/lib/handlers/jsErrorHandler.d.ts +3 -0
  26. package/lib/handlers/jsErrorHandler.d.ts.map +1 -0
  27. package/lib/handlers/jsErrorHandler.js +35 -0
  28. package/lib/handlers/jsErrorHandler.js.map +1 -0
  29. package/lib/handlers/promiseHandler.d.ts +5 -0
  30. package/lib/handlers/promiseHandler.d.ts.map +1 -0
  31. package/lib/handlers/promiseHandler.js +45 -0
  32. package/lib/handlers/promiseHandler.js.map +1 -0
  33. package/lib/index.d.ts +14 -0
  34. package/lib/index.d.ts.map +1 -0
  35. package/lib/index.js +18 -0
  36. package/lib/index.js.map +1 -0
  37. package/lib/safeExec.d.ts +4 -0
  38. package/lib/safeExec.d.ts.map +1 -0
  39. package/lib/safeExec.js +31 -0
  40. package/lib/safeExec.js.map +1 -0
  41. package/lib/transport.d.ts +5 -0
  42. package/lib/transport.d.ts.map +1 -0
  43. package/lib/transport.js +142 -0
  44. package/lib/transport.js.map +1 -0
  45. package/lib/types.d.ts +103 -0
  46. package/lib/types.d.ts.map +1 -0
  47. package/lib/types.js +3 -0
  48. package/lib/types.js.map +1 -0
  49. package/package.json +39 -0
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # heimdall-react-native
2
+
3
+ Lightweight, fault-tolerant crash tracking for React Native iOS apps. Catches JS errors, unhandled promise rejections, and native iOS crashes (via KSCrash). Reports everything to Firebase Firestore.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install heimdall-react-native
9
+ # or
10
+ yarn add heimdall-react-native
11
+ ```
12
+
13
+ ### iOS Setup
14
+
15
+ ```bash
16
+ cd ios && pod install
17
+ ```
18
+
19
+ The KSCrash dependency is automatically linked via the podspec.
20
+
21
+ ### Peer Dependencies
22
+
23
+ Make sure you have these installed:
24
+
25
+ ```bash
26
+ npm install @react-native-async-storage/async-storage
27
+ ```
28
+
29
+ ## How It Works
30
+
31
+ Heimdall uses **global-level hooks** built into React Native and iOS. You do NOT need to wrap your components or modify your code beyond a single `init()` call.
32
+
33
+ | What's caught | How | Wrapping needed? |
34
+ |---|---|---|
35
+ | JS errors (crashes, thrown exceptions) | `ErrorUtils.setGlobalHandler()` -- RN routes ALL unhandled JS errors through this | No |
36
+ | Unhandled promise rejections | Hermes `enablePromiseRejectionTracker` / JSC fallback | No |
37
+ | Native iOS crashes (SIGSEGV, SIGABRT, OOM) | KSCrash signal handlers at OS level. Written to disk, sent on next launch | No |
38
+ | React component render errors | Optional `<HeimdallErrorBoundary>` for custom fallback UI | Optional |
39
+
40
+ ## Usage
41
+
42
+ ### Minimal Setup (this is all you need)
43
+
44
+ ```typescript
45
+ // App.tsx -- add this at the very top, before anything else
46
+ import Heimdall from 'heimdall-react-native';
47
+
48
+ Heimdall.init({
49
+ apiKey: 'hm_live_your-key-here', // from the Heimdall dashboard
50
+ firebaseConfig: { // your Firebase project config
51
+ apiKey: '...',
52
+ authDomain: '...',
53
+ projectId: '...',
54
+ storageBucket: '...',
55
+ messagingSenderId: '...',
56
+ appId: '...',
57
+ },
58
+ });
59
+
60
+ export default function App() {
61
+ return <YourApp />;
62
+ }
63
+ ```
64
+
65
+ That's it. Every JS crash, unhandled promise rejection, and native iOS crash is now automatically captured and sent to your dashboard.
66
+
67
+ ### All Options
68
+
69
+ ```typescript
70
+ Heimdall.init({
71
+ apiKey: 'hm_live_...',
72
+ firebaseConfig: { ... }, // required: your Firebase config
73
+ enableNativeCrashHandling: true, // default: true
74
+ enableJsErrorHandler: true, // default: true
75
+ enablePromiseRejectionHandler: true, // default: true
76
+ maxBreadcrumbs: 100, // default: 100
77
+ debug: false, // default: false
78
+ beforeSend: (event) => {
79
+ // Modify or filter events before sending
80
+ // Return null to drop the event
81
+ return event;
82
+ },
83
+ });
84
+ ```
85
+
86
+ ### Manual Error Capture
87
+
88
+ ```typescript
89
+ try {
90
+ riskyOperation();
91
+ } catch (error) {
92
+ Heimdall.captureException(error);
93
+ }
94
+
95
+ Heimdall.captureMessage('User did something unexpected', 'warning');
96
+ ```
97
+
98
+ ### Breadcrumbs
99
+
100
+ ```typescript
101
+ Heimdall.addBreadcrumb({
102
+ category: 'navigation',
103
+ message: 'Navigated to Settings',
104
+ });
105
+
106
+ Heimdall.addBreadcrumb({
107
+ category: 'api',
108
+ message: 'POST /api/checkout failed',
109
+ level: 'error',
110
+ data: { statusCode: 500 },
111
+ });
112
+ ```
113
+
114
+ ### User Context
115
+
116
+ ```typescript
117
+ Heimdall.setUser({
118
+ id: 'user-123',
119
+ email: 'user@example.com',
120
+ });
121
+
122
+ // Clear on logout
123
+ Heimdall.clearUser();
124
+ ```
125
+
126
+ ### Error Boundary (optional)
127
+
128
+ This is **optional**. Without it, component crashes are still caught by the global JS handler above. The boundary only adds a custom fallback UI instead of a white/red screen.
129
+
130
+ ```tsx
131
+ import { HeimdallErrorBoundary } from 'heimdall-react-native';
132
+
133
+ function App() {
134
+ return (
135
+ <HeimdallErrorBoundary fallback={<Text>Something went wrong</Text>}>
136
+ <MyApp />
137
+ </HeimdallErrorBoundary>
138
+ );
139
+ }
140
+ ```
141
+
142
+ ## Fault Tolerance
143
+
144
+ Heimdall is designed to **never** affect your app:
145
+
146
+ - All operations are wrapped in try-catch
147
+ - `init()` failure = silent no-op
148
+ - Network failures queue events for retry on next launch
149
+ - Original error handlers are always chained (red screen still works in dev)
150
+ - All Firestore writes are async and non-blocking
151
+ - Init is deferred via `setTimeout(0)` to never block app startup
152
+
153
+ ## Architecture
154
+
155
+ - **JS Layer**: Catches unhandled JS errors via `ErrorUtils.setGlobalHandler()`, promise rejections (Hermes & JSC aware), and React component errors via Error Boundary
156
+ - **Native Layer**: Uses KSCrash to catch native iOS crashes (signals, Mach exceptions, ObjC exceptions). Crash reports are written to disk and sent on next launch
157
+ - **Transport**: Events go to Firebase Firestore. Failed sends are queued to AsyncStorage and retried
@@ -0,0 +1,18 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "heimdall-react-native"
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.homepage = "https://github.com/heimdall-rn/heimdall-react-native"
10
+ s.license = package['license']
11
+ s.author = "Heimdall"
12
+ s.platform = :ios, "13.0"
13
+ s.source = { :git => "https://github.com/heimdall-rn/heimdall-react-native.git", :tag => s.version }
14
+ s.source_files = "ios/**/*.{h,m}"
15
+
16
+ s.dependency "React-Core"
17
+ s.dependency "KSCrash", "~> 2.0"
18
+ end
@@ -0,0 +1,4 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface HeimdallNative : NSObject <RCTBridgeModule>
4
+ @end
@@ -0,0 +1,151 @@
1
+ #import "HeimdallNative.h"
2
+ #import <React/RCTLog.h>
3
+ #import <sys/utsname.h>
4
+ #import <mach/mach.h>
5
+ #import <KSCrash/KSCrash.h>
6
+ #import <KSCrash/KSCrashReportFilterBasic.h>
7
+
8
+ @implementation HeimdallNative
9
+
10
+ RCT_EXPORT_MODULE();
11
+
12
+ + (BOOL)requiresMainQueueSetup {
13
+ return NO;
14
+ }
15
+
16
+ RCT_EXPORT_METHOD(startNativeHandler) {
17
+ dispatch_async(dispatch_get_main_queue(), ^{
18
+ @try {
19
+ KSCrash *handler = [KSCrash sharedInstance];
20
+ [handler install];
21
+ RCTLogInfo(@"[Heimdall] Native crash handler installed");
22
+ } @catch (NSException *exception) {
23
+ RCTLogWarn(@"[Heimdall] Failed to install native crash handler: %@", exception.reason);
24
+ }
25
+ });
26
+ }
27
+
28
+ RCT_EXPORT_METHOD(getPendingCrashReports:(RCTPromiseResolveBlock)resolve
29
+ rejecter:(RCTPromiseRejectBlock)reject) {
30
+ @try {
31
+ KSCrash *handler = [KSCrash sharedInstance];
32
+
33
+ [handler reportCount];
34
+
35
+ [handler allReports:^(NSArray *reports) {
36
+ if (!reports || reports.count == 0) {
37
+ resolve(@[]);
38
+ return;
39
+ }
40
+
41
+ NSMutableArray *parsed = [NSMutableArray array];
42
+
43
+ for (NSDictionary *report in reports) {
44
+ @try {
45
+ NSDictionary *crash = report[@"crash"];
46
+ NSDictionary *error = crash[@"error"];
47
+ NSArray *threads = crash[@"threads"];
48
+
49
+ NSString *type = error[@"type"] ?: @"Unknown";
50
+ NSString *reason = error[@"reason"] ?: @"Native crash";
51
+
52
+ if ([type isEqualToString:@"nsexception"]) {
53
+ NSDictionary *nsException = error[@"nsexception"];
54
+ if (nsException) {
55
+ type = nsException[@"name"] ?: type;
56
+ reason = nsException[@"reason"] ?: reason;
57
+ }
58
+ } else if ([type isEqualToString:@"signal"]) {
59
+ NSDictionary *signal = error[@"signal"];
60
+ if (signal) {
61
+ type = signal[@"name"] ?: type;
62
+ }
63
+ } else if ([type isEqualToString:@"mach"]) {
64
+ NSDictionary *mach = error[@"mach"];
65
+ if (mach) {
66
+ type = mach[@"exception_name"] ?: type;
67
+ }
68
+ }
69
+
70
+ NSMutableArray *stacktrace = [NSMutableArray array];
71
+
72
+ NSDictionary *crashedThread = nil;
73
+ for (NSDictionary *thread in threads) {
74
+ if ([thread[@"crashed"] boolValue]) {
75
+ crashedThread = thread;
76
+ break;
77
+ }
78
+ }
79
+
80
+ NSArray *backtrace = crashedThread[@"backtrace"][@"contents"];
81
+ if (backtrace) {
82
+ for (NSDictionary *frame in backtrace) {
83
+ [stacktrace addObject:@{
84
+ @"filename": frame[@"object_name"] ?: @"<unknown>",
85
+ @"function": frame[@"symbol_name"] ?: @"<unknown>",
86
+ @"lineno": frame[@"instruction_addr"] ?: @0,
87
+ @"colno": @0,
88
+ @"in_app": @(![frame[@"object_name"] hasPrefix:@"/usr"])
89
+ }];
90
+ }
91
+ }
92
+
93
+ [parsed addObject:@{
94
+ @"type": type,
95
+ @"value": reason,
96
+ @"stacktrace": stacktrace
97
+ }];
98
+ } @catch (NSException *exception) {
99
+ RCTLogWarn(@"[Heimdall] Failed to parse crash report: %@", exception.reason);
100
+ }
101
+ }
102
+
103
+ // Delete the reports after reading
104
+ [handler deleteAllReports];
105
+
106
+ resolve(parsed);
107
+ }];
108
+ } @catch (NSException *exception) {
109
+ resolve(@[]);
110
+ }
111
+ }
112
+
113
+ RCT_EXPORT_METHOD(getDeviceInfo:(RCTPromiseResolveBlock)resolve
114
+ rejecter:(RCTPromiseRejectBlock)reject) {
115
+ @try {
116
+ struct utsname systemInfo;
117
+ uname(&systemInfo);
118
+ NSString *model = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
119
+
120
+ NSString *osVersion = [[UIDevice currentDevice] systemVersion];
121
+
122
+ mach_port_t hostPort = mach_host_self();
123
+ vm_size_t pageSize;
124
+ host_page_size(hostPort, &pageSize);
125
+
126
+ vm_statistics64_data_t vmStats;
127
+ mach_msg_type_number_t infoCount = HOST_VM_INFO64_COUNT;
128
+ host_statistics64(hostPort, HOST_VM_INFO64, (host_info64_t)&vmStats, &infoCount);
129
+
130
+ unsigned long long freeMemory = (unsigned long long)vmStats.free_count * (unsigned long long)pageSize;
131
+
132
+ NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
133
+ unsigned long long freeDisk = [attrs[NSFileSystemFreeSize] unsignedLongLongValue];
134
+
135
+ resolve(@{
136
+ @"model": model ?: @"Unknown",
137
+ @"osVersion": osVersion ?: @"Unknown",
138
+ @"freeMemory": @(freeMemory),
139
+ @"freeDisk": @(freeDisk)
140
+ });
141
+ } @catch (NSException *exception) {
142
+ resolve(@{
143
+ @"model": @"Unknown",
144
+ @"osVersion": @"Unknown",
145
+ @"freeMemory": @0,
146
+ @"freeDisk": @0
147
+ });
148
+ }
149
+ }
150
+
151
+ @end
@@ -0,0 +1,12 @@
1
+ import { Breadcrumb } from './types';
2
+ export declare class BreadcrumbTracker {
3
+ private buffer;
4
+ private maxSize;
5
+ constructor(maxSize?: number);
6
+ add(crumb: Omit<Breadcrumb, 'timestamp'> & {
7
+ timestamp?: number;
8
+ }): void;
9
+ getAll(): Breadcrumb[];
10
+ clear(): void;
11
+ }
12
+ //# sourceMappingURL=breadcrumbs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumbs.d.ts","sourceRoot":"","sources":["../src/breadcrumbs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAY;IAIjC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAgBxE,MAAM,IAAI,UAAU,EAAE;IAItB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BreadcrumbTracker = void 0;
4
+ class BreadcrumbTracker {
5
+ constructor(maxSize = 100) {
6
+ this.buffer = [];
7
+ this.maxSize = maxSize;
8
+ }
9
+ add(crumb) {
10
+ const breadcrumb = {
11
+ timestamp: crumb.timestamp ?? Date.now(),
12
+ category: crumb.category,
13
+ message: crumb.message,
14
+ level: crumb.level,
15
+ data: crumb.data,
16
+ };
17
+ this.buffer.push(breadcrumb);
18
+ if (this.buffer.length > this.maxSize) {
19
+ this.buffer = this.buffer.slice(-this.maxSize);
20
+ }
21
+ }
22
+ getAll() {
23
+ return [...this.buffer];
24
+ }
25
+ clear() {
26
+ this.buffer = [];
27
+ }
28
+ }
29
+ exports.BreadcrumbTracker = BreadcrumbTracker;
30
+ //# sourceMappingURL=breadcrumbs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breadcrumbs.js","sourceRoot":"","sources":["../src/breadcrumbs.ts"],"names":[],"mappings":";;;AAEA,MAAa,iBAAiB;IAI5B,YAAY,UAAkB,GAAG;QAHzB,WAAM,GAAiB,EAAE,CAAC;QAIhC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,KAA6D;QAC/D,MAAM,UAAU,GAAe;YAC7B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE;YACxC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE7B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;CACF;AA/BD,8CA+BC"}
@@ -0,0 +1,26 @@
1
+ import { HeimdallConfig, EventLevel, UserContext, Breadcrumb } from './types';
2
+ declare class HeimdallClient {
3
+ private config;
4
+ private breadcrumbs;
5
+ private user;
6
+ private tags;
7
+ private initialized;
8
+ private appId;
9
+ init(config: HeimdallConfig): void;
10
+ private setupHandlers;
11
+ private setupFirebase;
12
+ private checkPendingNativeCrashes;
13
+ captureException(error: Error, level?: EventLevel): void;
14
+ captureMessage(message: string, level?: EventLevel): void;
15
+ addBreadcrumb(crumb: Omit<Breadcrumb, 'timestamp'>): void;
16
+ setUser(user: UserContext): void;
17
+ setTag(key: string, value: string): void;
18
+ clearUser(): void;
19
+ private captureError;
20
+ private buildEvent;
21
+ private dispatchEvent;
22
+ destroy(): void;
23
+ }
24
+ export declare const heimdallClient: HeimdallClient;
25
+ export {};
26
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EAId,UAAU,EAEV,WAAW,EACX,UAAU,EACX,MAAM,SAAS,CAAC;AAyDjB,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAc;IAE3B,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IA6BlC,OAAO,CAAC,aAAa;YA6BP,aAAa;YAQb,yBAAyB;IAiCvC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;IAMxD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;IAczD,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,IAAI;IAMzD,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAMhC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMxC,SAAS,IAAI,IAAI;IAIjB,OAAO,CAAC,YAAY;YAeN,UAAU;YAkCV,aAAa;IAY3B,OAAO,IAAI,IAAI;CAUhB;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
package/lib/client.js ADDED
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.heimdallClient = void 0;
4
+ const react_native_1 = require("react-native");
5
+ const safeExec_1 = require("./safeExec");
6
+ const breadcrumbs_1 = require("./breadcrumbs");
7
+ const context_1 = require("./context");
8
+ const fingerprint_1 = require("./fingerprint");
9
+ const transport_1 = require("./transport");
10
+ const jsErrorHandler_1 = require("./handlers/jsErrorHandler");
11
+ const promiseHandler_1 = require("./handlers/promiseHandler");
12
+ function generateId() {
13
+ return 'hm_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
14
+ }
15
+ function parseStackTrace(stack) {
16
+ if (!stack)
17
+ return [];
18
+ const frames = [];
19
+ const lines = stack.split('\n');
20
+ for (const line of lines) {
21
+ const trimmed = line.trim();
22
+ // RN format: "at functionName (filename:line:col)" or "functionName@filename:line:col"
23
+ const atMatch = trimmed.match(/^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/);
24
+ const atAnonMatch = trimmed.match(/^at\s+(.+?):(\d+):(\d+)$/);
25
+ const hermeMatch = trimmed.match(/^(.+?)@(.+?):(\d+):(\d+)$/);
26
+ if (atMatch) {
27
+ frames.push({
28
+ function: atMatch[1],
29
+ filename: atMatch[2],
30
+ lineno: parseInt(atMatch[3], 10),
31
+ colno: parseInt(atMatch[4], 10),
32
+ in_app: !atMatch[2].includes('node_modules'),
33
+ });
34
+ }
35
+ else if (hermeMatch) {
36
+ frames.push({
37
+ function: hermeMatch[1],
38
+ filename: hermeMatch[2],
39
+ lineno: parseInt(hermeMatch[3], 10),
40
+ colno: parseInt(hermeMatch[4], 10),
41
+ in_app: !hermeMatch[2].includes('node_modules'),
42
+ });
43
+ }
44
+ else if (atAnonMatch) {
45
+ frames.push({
46
+ function: '<anonymous>',
47
+ filename: atAnonMatch[1],
48
+ lineno: parseInt(atAnonMatch[2], 10),
49
+ colno: parseInt(atAnonMatch[3], 10),
50
+ in_app: !atAnonMatch[1].includes('node_modules'),
51
+ });
52
+ }
53
+ }
54
+ return frames;
55
+ }
56
+ class HeimdallClient {
57
+ constructor() {
58
+ this.config = null;
59
+ this.breadcrumbs = new breadcrumbs_1.BreadcrumbTracker();
60
+ this.tags = {};
61
+ this.initialized = false;
62
+ this.appId = '';
63
+ }
64
+ init(config) {
65
+ (0, safeExec_1.safeExec)(() => {
66
+ if (this.initialized)
67
+ return;
68
+ this.config = {
69
+ enableNativeCrashHandling: true,
70
+ enableJsErrorHandler: true,
71
+ enablePromiseRejectionHandler: true,
72
+ maxBreadcrumbs: 100,
73
+ debug: false,
74
+ ...config,
75
+ };
76
+ if (this.config.debug) {
77
+ (0, safeExec_1.setDebugMode)(true);
78
+ }
79
+ this.breadcrumbs = new breadcrumbs_1.BreadcrumbTracker(this.config.maxBreadcrumbs);
80
+ // Defer all setup so it never blocks app startup
81
+ setTimeout(() => {
82
+ (0, safeExec_1.safeExec)(() => this.setupHandlers());
83
+ (0, safeExec_1.safeExecAsync)(() => this.setupFirebase());
84
+ }, 0);
85
+ this.initialized = true;
86
+ });
87
+ }
88
+ setupHandlers() {
89
+ if (!this.config)
90
+ return;
91
+ if (this.config.enableJsErrorHandler) {
92
+ (0, jsErrorHandler_1.installJsErrorHandler)((error, isFatal) => {
93
+ this.captureError(error, isFatal ? 'fatal' : 'error', 'jsHandler');
94
+ });
95
+ }
96
+ if (this.config.enablePromiseRejectionHandler) {
97
+ (0, promiseHandler_1.installPromiseHandler)((reason) => {
98
+ const error = reason instanceof Error ? reason : new Error(String(reason));
99
+ this.captureError(error, 'error', 'promiseRejection');
100
+ });
101
+ }
102
+ if (this.config.enableNativeCrashHandling) {
103
+ (0, safeExec_1.safeExec)(() => {
104
+ const HeimdallNative = react_native_1.NativeModules.HeimdallNative;
105
+ if (HeimdallNative) {
106
+ (0, context_1.setNativeModule)(HeimdallNative);
107
+ HeimdallNative.startNativeHandler?.();
108
+ (0, safeExec_1.safeExecAsync)(() => this.checkPendingNativeCrashes());
109
+ }
110
+ });
111
+ }
112
+ }
113
+ async setupFirebase() {
114
+ await (0, safeExec_1.safeExecAsync)(async () => {
115
+ if (!this.config?.firebaseConfig)
116
+ return;
117
+ (0, transport_1.initFirebase)(this.config.firebaseConfig);
118
+ await (0, transport_1.sendPendingEvents)();
119
+ });
120
+ }
121
+ async checkPendingNativeCrashes() {
122
+ const HeimdallNative = react_native_1.NativeModules.HeimdallNative;
123
+ if (!HeimdallNative?.getPendingCrashReports)
124
+ return;
125
+ const reports = await HeimdallNative.getPendingCrashReports();
126
+ if (!reports || !Array.isArray(reports))
127
+ return;
128
+ for (const report of reports) {
129
+ await (0, safeExec_1.safeExecAsync)(async () => {
130
+ const stacktrace = (report.stacktrace ?? []).map((f) => ({
131
+ filename: f.filename ?? '<unknown>',
132
+ function: f.function ?? '<unknown>',
133
+ lineno: f.lineno ?? 0,
134
+ colno: f.colno ?? 0,
135
+ in_app: f.in_app ?? false,
136
+ }));
137
+ const event = await this.buildEvent(report.type ?? 'SIGABRT', report.value ?? 'Native crash', stacktrace, 'nativeCrash', 'fatal', 'crash');
138
+ await this.dispatchEvent(event);
139
+ });
140
+ }
141
+ }
142
+ captureException(error, level) {
143
+ (0, safeExec_1.safeExec)(() => {
144
+ this.captureError(error, level ?? 'error', 'manual');
145
+ });
146
+ }
147
+ captureMessage(message, level) {
148
+ (0, safeExec_1.safeExecAsync)(async () => {
149
+ const event = await this.buildEvent('Message', message, [], 'manual', level ?? 'info', 'message');
150
+ await this.dispatchEvent(event);
151
+ });
152
+ }
153
+ addBreadcrumb(crumb) {
154
+ (0, safeExec_1.safeExec)(() => {
155
+ this.breadcrumbs.add(crumb);
156
+ });
157
+ }
158
+ setUser(user) {
159
+ (0, safeExec_1.safeExec)(() => {
160
+ this.user = user;
161
+ });
162
+ }
163
+ setTag(key, value) {
164
+ (0, safeExec_1.safeExec)(() => {
165
+ this.tags[key] = value;
166
+ });
167
+ }
168
+ clearUser() {
169
+ this.user = undefined;
170
+ }
171
+ captureError(error, level, mechanism) {
172
+ (0, safeExec_1.safeExecAsync)(async () => {
173
+ const stacktrace = parseStackTrace(error.stack);
174
+ const event = await this.buildEvent(error.name || 'Error', error.message || 'Unknown error', stacktrace, mechanism, level, level === 'fatal' ? 'crash' : 'error');
175
+ await this.dispatchEvent(event);
176
+ });
177
+ }
178
+ async buildEvent(errorType, errorValue, stacktrace, mechanism, level, type) {
179
+ const device = await (0, context_1.getDeviceContext)(this.config?.apiKey ? undefined : undefined);
180
+ const fingerprint = (0, fingerprint_1.generateFingerprint)(errorType, errorValue, stacktrace);
181
+ return {
182
+ id: generateId(),
183
+ apiKey: this.config?.apiKey ?? '',
184
+ appId: this.appId,
185
+ type,
186
+ level,
187
+ timestamp: Date.now(),
188
+ fingerprint,
189
+ exception: {
190
+ type: errorType,
191
+ value: errorValue,
192
+ stacktrace,
193
+ mechanism,
194
+ },
195
+ device,
196
+ breadcrumbs: this.breadcrumbs.getAll(),
197
+ user: this.user,
198
+ tags: Object.keys(this.tags).length > 0 ? { ...this.tags } : undefined,
199
+ };
200
+ }
201
+ async dispatchEvent(event) {
202
+ if (!this.config)
203
+ return;
204
+ if (this.config.beforeSend) {
205
+ const modified = this.config.beforeSend(event);
206
+ if (!modified)
207
+ return;
208
+ event = modified;
209
+ }
210
+ await (0, safeExec_1.safeExecAsync)(() => (0, transport_1.sendEvent)(event));
211
+ }
212
+ destroy() {
213
+ (0, safeExec_1.safeExec)(() => {
214
+ (0, jsErrorHandler_1.uninstallJsErrorHandler)();
215
+ (0, promiseHandler_1.uninstallPromiseHandler)();
216
+ (0, context_1.clearContextCache)();
217
+ this.breadcrumbs.clear();
218
+ this.initialized = false;
219
+ this.config = null;
220
+ });
221
+ }
222
+ }
223
+ exports.heimdallClient = new HeimdallClient();
224
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,+CAA6C;AAW7C,yCAAmE;AACnE,+CAAkD;AAClD,uCAAiF;AACjF,+CAAoD;AACpD,2CAAyE;AACzE,8DAA2F;AAC3F,8DAA2F;AAE3F,SAAS,UAAU;IACjB,OAAO,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,eAAe,CAAC,KAAyB;IAChD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,uFAAuF;QACvF,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAE9D,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBACpB,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBACpB,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAChC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;aAC7C,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;gBACvB,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;gBACvB,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACnC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAClC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;aAChD,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ,EAAE,aAAa;gBACvB,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;gBACxB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACpC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACnC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;aACjD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,cAAc;IAApB;QACU,WAAM,GAA0B,IAAI,CAAC;QACrC,gBAAW,GAAsB,IAAI,+BAAiB,EAAE,CAAC;QAEzD,SAAI,GAA2B,EAAE,CAAC;QAClC,gBAAW,GAAG,KAAK,CAAC;QACpB,UAAK,GAAW,EAAE,CAAC;IAsN7B,CAAC;IApNC,IAAI,CAAC,MAAsB;QACzB,IAAA,mBAAQ,EAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,WAAW;gBAAE,OAAO;YAE7B,IAAI,CAAC,MAAM,GAAG;gBACZ,yBAAyB,EAAE,IAAI;gBAC/B,oBAAoB,EAAE,IAAI;gBAC1B,6BAA6B,EAAE,IAAI;gBACnC,cAAc,EAAE,GAAG;gBACnB,KAAK,EAAE,KAAK;gBACZ,GAAG,MAAM;aACV,CAAC;YAEF,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACtB,IAAA,uBAAY,EAAC,IAAI,CAAC,CAAC;YACrB,CAAC;YAED,IAAI,CAAC,WAAW,GAAG,IAAI,+BAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAErE,iDAAiD;YACjD,UAAU,CAAC,GAAG,EAAE;gBACd,IAAA,mBAAQ,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;gBACrC,IAAA,wBAAa,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;YAC5C,CAAC,EAAE,CAAC,CAAC,CAAC;YAEN,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACrC,IAAA,sCAAqB,EAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;gBACvC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,6BAA6B,EAAE,CAAC;YAC9C,IAAA,sCAAqB,EAAC,CAAC,MAAM,EAAE,EAAE;gBAC/B,MAAM,KAAK,GACT,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/D,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;YACxD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,yBAAyB,EAAE,CAAC;YAC1C,IAAA,mBAAQ,EAAC,GAAG,EAAE;gBACZ,MAAM,cAAc,GAAG,4BAAa,CAAC,cAAc,CAAC;gBACpD,IAAI,cAAc,EAAE,CAAC;oBACnB,IAAA,yBAAe,EAAC,cAAc,CAAC,CAAC;oBAChC,cAAc,CAAC,kBAAkB,EAAE,EAAE,CAAC;oBACtC,IAAA,wBAAa,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,IAAA,wBAAa,EAAC,KAAK,IAAI,EAAE;YAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc;gBAAE,OAAO;YACzC,IAAA,wBAAY,EAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACzC,MAAM,IAAA,6BAAiB,GAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,yBAAyB;QACrC,MAAM,cAAc,GAAG,4BAAa,CAAC,cAAc,CAAC;QACpD,IAAI,CAAC,cAAc,EAAE,sBAAsB;YAAE,OAAO;QAEpD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,sBAAsB,EAAE,CAAC;QAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO;QAEhD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAA,wBAAa,EAAC,KAAK,IAAI,EAAE;gBAC7B,MAAM,UAAU,GAAiB,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAC5D,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBACX,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,WAAW;oBACnC,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,WAAW;oBACnC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC;oBACrB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;oBACnB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,KAAK;iBAC1B,CAAC,CACH,CAAC;gBAEF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CACjC,MAAM,CAAC,IAAI,IAAI,SAAS,EACxB,MAAM,CAAC,KAAK,IAAI,cAAc,EAC9B,UAAU,EACV,aAAa,EACb,OAAO,EACP,OAAO,CACR,CAAC;gBAEF,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,KAAY,EAAE,KAAkB;QAC/C,IAAA,mBAAQ,EAAC,GAAG,EAAE;YACZ,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,IAAI,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,cAAc,CAAC,OAAe,EAAE,KAAkB;QAChD,IAAA,wBAAa,EAAC,KAAK,IAAI,EAAE;YACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CACjC,SAAS,EACT,OAAO,EACP,EAAE,EACF,QAAQ,EACR,KAAK,IAAI,MAAM,EACf,SAAS,CACV,CAAC;YACF,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,aAAa,CAAC,KAAoC;QAChD,IAAA,mBAAQ,EAAC,GAAG,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,IAAiB;QACvB,IAAA,mBAAQ,EAAC,GAAG,EAAE;YACZ,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,KAAa;QAC/B,IAAA,mBAAQ,EAAC,GAAG,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS;QACP,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACxB,CAAC;IAEO,YAAY,CAAC,KAAY,EAAE,KAAiB,EAAE,SAAoB;QACxE,IAAA,wBAAa,EAAC,KAAK,IAAI,EAAE;YACvB,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CACjC,KAAK,CAAC,IAAI,IAAI,OAAO,EACrB,KAAK,CAAC,OAAO,IAAI,eAAe,EAChC,UAAU,EACV,SAAS,EACT,KAAK,EACL,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CACtC,CAAC;YACF,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,UAAU,CACtB,SAAiB,EACjB,UAAkB,EAClB,UAAwB,EACxB,SAAoB,EACpB,KAAiB,EACjB,IAAe;QAEf,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAgB,EACnC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAC5C,CAAC;QACF,MAAM,WAAW,GAAG,IAAA,iCAAmB,EAAC,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;QAE3E,OAAO;YACL,EAAE,EAAE,UAAU,EAAE;YAChB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI;YACJ,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,WAAW;YACX,SAAS,EAAE;gBACT,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,UAAU;gBACjB,UAAU;gBACV,SAAS;aACV;YACD,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;YACtC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,KAAiB;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,KAAK,GAAG,QAAQ,CAAC;QACnB,CAAC;QAED,MAAM,IAAA,wBAAa,EAAC,GAAG,EAAE,CAAC,IAAA,qBAAS,EAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,IAAA,mBAAQ,EAAC,GAAG,EAAE;YACZ,IAAA,wCAAuB,GAAE,CAAC;YAC1B,IAAA,wCAAuB,GAAE,CAAC;YAC1B,IAAA,2BAAiB,GAAE,CAAC;YACpB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAEY,QAAA,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { DeviceContext } from './types';
2
+ export declare function setNativeModule(mod: any): void;
3
+ export declare function getDeviceContext(appVersion?: string, buildNumber?: string): Promise<DeviceContext>;
4
+ export declare function clearContextCache(): void;
5
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMxC,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAE9C;AAED,wBAAsB,gBAAgB,CACpC,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAkCxB;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}