@fixprompt/react-native 0.0.1

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/dist/index.js ADDED
@@ -0,0 +1,791 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+ var __commonJS = (cb, mod) => function __require2() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+
12
+ // node_modules/promise/setimmediate/core.js
13
+ var require_core = __commonJS({
14
+ "node_modules/promise/setimmediate/core.js"(exports, module) {
15
+ "use strict";
16
+ function noop() {
17
+ }
18
+ var LAST_ERROR = null;
19
+ var IS_ERROR = {};
20
+ function getThen(obj) {
21
+ try {
22
+ return obj.then;
23
+ } catch (ex) {
24
+ LAST_ERROR = ex;
25
+ return IS_ERROR;
26
+ }
27
+ }
28
+ function tryCallOne(fn, a) {
29
+ try {
30
+ return fn(a);
31
+ } catch (ex) {
32
+ LAST_ERROR = ex;
33
+ return IS_ERROR;
34
+ }
35
+ }
36
+ function tryCallTwo(fn, a, b) {
37
+ try {
38
+ fn(a, b);
39
+ } catch (ex) {
40
+ LAST_ERROR = ex;
41
+ return IS_ERROR;
42
+ }
43
+ }
44
+ module.exports = Promise2;
45
+ function Promise2(fn) {
46
+ if (typeof this !== "object") {
47
+ throw new TypeError("Promises must be constructed via new");
48
+ }
49
+ if (typeof fn !== "function") {
50
+ throw new TypeError("Promise constructor's argument is not a function");
51
+ }
52
+ this._x = 0;
53
+ this._y = 0;
54
+ this._z = null;
55
+ this._A = null;
56
+ if (fn === noop) return;
57
+ doResolve(fn, this);
58
+ }
59
+ Promise2._B = null;
60
+ Promise2._C = null;
61
+ Promise2._D = noop;
62
+ Promise2.prototype.then = function(onFulfilled, onRejected) {
63
+ if (this.constructor !== Promise2) {
64
+ return safeThen(this, onFulfilled, onRejected);
65
+ }
66
+ var res = new Promise2(noop);
67
+ handle(this, new Handler(onFulfilled, onRejected, res));
68
+ return res;
69
+ };
70
+ function safeThen(self, onFulfilled, onRejected) {
71
+ return new self.constructor(function(resolve2, reject2) {
72
+ var res = new Promise2(noop);
73
+ res.then(resolve2, reject2);
74
+ handle(self, new Handler(onFulfilled, onRejected, res));
75
+ });
76
+ }
77
+ function handle(self, deferred) {
78
+ while (self._y === 3) {
79
+ self = self._z;
80
+ }
81
+ if (Promise2._B) {
82
+ Promise2._B(self);
83
+ }
84
+ if (self._y === 0) {
85
+ if (self._x === 0) {
86
+ self._x = 1;
87
+ self._A = deferred;
88
+ return;
89
+ }
90
+ if (self._x === 1) {
91
+ self._x = 2;
92
+ self._A = [self._A, deferred];
93
+ return;
94
+ }
95
+ self._A.push(deferred);
96
+ return;
97
+ }
98
+ handleResolved(self, deferred);
99
+ }
100
+ function handleResolved(self, deferred) {
101
+ setImmediate(function() {
102
+ var cb = self._y === 1 ? deferred.onFulfilled : deferred.onRejected;
103
+ if (cb === null) {
104
+ if (self._y === 1) {
105
+ resolve(deferred.promise, self._z);
106
+ } else {
107
+ reject(deferred.promise, self._z);
108
+ }
109
+ return;
110
+ }
111
+ var ret = tryCallOne(cb, self._z);
112
+ if (ret === IS_ERROR) {
113
+ reject(deferred.promise, LAST_ERROR);
114
+ } else {
115
+ resolve(deferred.promise, ret);
116
+ }
117
+ });
118
+ }
119
+ function resolve(self, newValue) {
120
+ if (newValue === self) {
121
+ return reject(
122
+ self,
123
+ new TypeError("A promise cannot be resolved with itself.")
124
+ );
125
+ }
126
+ if (newValue && (typeof newValue === "object" || typeof newValue === "function")) {
127
+ var then = getThen(newValue);
128
+ if (then === IS_ERROR) {
129
+ return reject(self, LAST_ERROR);
130
+ }
131
+ if (then === self.then && newValue instanceof Promise2) {
132
+ self._y = 3;
133
+ self._z = newValue;
134
+ finale(self);
135
+ return;
136
+ } else if (typeof then === "function") {
137
+ doResolve(then.bind(newValue), self);
138
+ return;
139
+ }
140
+ }
141
+ self._y = 1;
142
+ self._z = newValue;
143
+ finale(self);
144
+ }
145
+ function reject(self, newValue) {
146
+ self._y = 2;
147
+ self._z = newValue;
148
+ if (Promise2._C) {
149
+ Promise2._C(self, newValue);
150
+ }
151
+ finale(self);
152
+ }
153
+ function finale(self) {
154
+ if (self._x === 1) {
155
+ handle(self, self._A);
156
+ self._A = null;
157
+ }
158
+ if (self._x === 2) {
159
+ for (var i = 0; i < self._A.length; i++) {
160
+ handle(self, self._A[i]);
161
+ }
162
+ self._A = null;
163
+ }
164
+ }
165
+ function Handler(onFulfilled, onRejected, promise) {
166
+ this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null;
167
+ this.onRejected = typeof onRejected === "function" ? onRejected : null;
168
+ this.promise = promise;
169
+ }
170
+ function doResolve(fn, promise) {
171
+ var done = false;
172
+ var res = tryCallTwo(fn, function(value) {
173
+ if (done) return;
174
+ done = true;
175
+ resolve(promise, value);
176
+ }, function(reason) {
177
+ if (done) return;
178
+ done = true;
179
+ reject(promise, reason);
180
+ });
181
+ if (!done && res === IS_ERROR) {
182
+ done = true;
183
+ reject(promise, LAST_ERROR);
184
+ }
185
+ }
186
+ }
187
+ });
188
+
189
+ // node_modules/promise/setimmediate/rejection-tracking.js
190
+ var require_rejection_tracking = __commonJS({
191
+ "node_modules/promise/setimmediate/rejection-tracking.js"(exports) {
192
+ "use strict";
193
+ var Promise2 = require_core();
194
+ var DEFAULT_WHITELIST = [
195
+ ReferenceError,
196
+ TypeError,
197
+ RangeError
198
+ ];
199
+ var enabled = false;
200
+ exports.disable = disable;
201
+ function disable() {
202
+ enabled = false;
203
+ Promise2._B = null;
204
+ Promise2._C = null;
205
+ }
206
+ exports.enable = enable;
207
+ function enable(options) {
208
+ options = options || {};
209
+ if (enabled) disable();
210
+ enabled = true;
211
+ var id = 0;
212
+ var displayId = 0;
213
+ var rejections = {};
214
+ Promise2._B = function(promise) {
215
+ if (promise._y === 2 && // IS REJECTED
216
+ rejections[promise._E]) {
217
+ if (rejections[promise._E].logged) {
218
+ onHandled(promise._E);
219
+ } else {
220
+ clearTimeout(rejections[promise._E].timeout);
221
+ }
222
+ delete rejections[promise._E];
223
+ }
224
+ };
225
+ Promise2._C = function(promise, err) {
226
+ if (promise._x === 0) {
227
+ promise._E = id++;
228
+ rejections[promise._E] = {
229
+ displayId: null,
230
+ error: err,
231
+ timeout: setTimeout(
232
+ onUnhandled.bind(null, promise._E),
233
+ // For reference errors and type errors, this almost always
234
+ // means the programmer made a mistake, so log them after just
235
+ // 100ms
236
+ // otherwise, wait 2 seconds to see if they get handled
237
+ matchWhitelist(err, DEFAULT_WHITELIST) ? 100 : 2e3
238
+ ),
239
+ logged: false
240
+ };
241
+ }
242
+ };
243
+ function onUnhandled(id2) {
244
+ if (options.allRejections || matchWhitelist(
245
+ rejections[id2].error,
246
+ options.whitelist || DEFAULT_WHITELIST
247
+ )) {
248
+ rejections[id2].displayId = displayId++;
249
+ if (options.onUnhandled) {
250
+ rejections[id2].logged = true;
251
+ options.onUnhandled(
252
+ rejections[id2].displayId,
253
+ rejections[id2].error
254
+ );
255
+ } else {
256
+ rejections[id2].logged = true;
257
+ logError(
258
+ rejections[id2].displayId,
259
+ rejections[id2].error
260
+ );
261
+ }
262
+ }
263
+ }
264
+ function onHandled(id2) {
265
+ if (rejections[id2].logged) {
266
+ if (options.onHandled) {
267
+ options.onHandled(rejections[id2].displayId, rejections[id2].error);
268
+ } else if (!rejections[id2].onUnhandled) {
269
+ console.warn(
270
+ "Promise Rejection Handled (id: " + rejections[id2].displayId + "):"
271
+ );
272
+ console.warn(
273
+ ' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' + rejections[id2].displayId + "."
274
+ );
275
+ }
276
+ }
277
+ }
278
+ }
279
+ function logError(id, error) {
280
+ console.warn("Possible Unhandled Promise Rejection (id: " + id + "):");
281
+ var errStr = (error && (error.stack || error)) + "";
282
+ errStr.split("\n").forEach(function(line) {
283
+ console.warn(" " + line);
284
+ });
285
+ }
286
+ function matchWhitelist(error, list) {
287
+ return list.some(function(cls) {
288
+ return error instanceof cls;
289
+ });
290
+ }
291
+ }
292
+ });
293
+
294
+ // src/state.ts
295
+ var STATE_KEY = "__fixprompt_rn_state__";
296
+ function globalScope() {
297
+ if (typeof globalThis !== "undefined") return globalThis;
298
+ return {};
299
+ }
300
+ function getState() {
301
+ const g = globalScope();
302
+ if (!g[STATE_KEY]) {
303
+ g[STATE_KEY] = {
304
+ initialized: false,
305
+ config: null,
306
+ sessionId: null,
307
+ deviceId: null,
308
+ user: null,
309
+ cleanup: {}
310
+ };
311
+ }
312
+ return g[STATE_KEY];
313
+ }
314
+
315
+ // src/session.ts
316
+ import AsyncStorage from "@react-native-async-storage/async-storage";
317
+ var DEVICE_KEY = "@fixprompt/device_id";
318
+ function uuid() {
319
+ if (typeof globalThis.crypto?.randomUUID === "function") {
320
+ return globalThis.crypto.randomUUID();
321
+ }
322
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
323
+ const r = Math.random() * 16 | 0;
324
+ const v = c === "x" ? r : r & 3 | 8;
325
+ return v.toString(16);
326
+ });
327
+ }
328
+ function newSessionId() {
329
+ return uuid();
330
+ }
331
+ async function getDeviceId() {
332
+ try {
333
+ const SecureStore = await tryImport("expo-secure-store");
334
+ if (SecureStore) {
335
+ const existing = await SecureStore.getItemAsync("fixprompt_device_id");
336
+ if (existing) return existing;
337
+ const fresh = uuid();
338
+ await SecureStore.setItemAsync("fixprompt_device_id", fresh);
339
+ return fresh;
340
+ }
341
+ } catch {
342
+ }
343
+ try {
344
+ const existing = await AsyncStorage.getItem(DEVICE_KEY);
345
+ if (existing) return existing;
346
+ const fresh = uuid();
347
+ await AsyncStorage.setItem(DEVICE_KEY, fresh);
348
+ return fresh;
349
+ } catch {
350
+ return uuid();
351
+ }
352
+ }
353
+ async function tryImport(spec) {
354
+ try {
355
+ return __require(spec);
356
+ } catch {
357
+ return null;
358
+ }
359
+ }
360
+
361
+ // src/buffer.ts
362
+ import AsyncStorage2 from "@react-native-async-storage/async-storage";
363
+ var STORAGE_KEY = "@fixprompt/buffer";
364
+ var MAX_BUFFER = 200;
365
+ var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
366
+ var OfflineBuffer = class {
367
+ constructor() {
368
+ this.items = [];
369
+ this.loaded = false;
370
+ this.persistTimer = null;
371
+ }
372
+ /** Load the persisted buffer once, on first use. */
373
+ async load() {
374
+ if (this.loaded) return;
375
+ this.loaded = true;
376
+ try {
377
+ const raw = await AsyncStorage2.getItem(STORAGE_KEY);
378
+ if (!raw) return;
379
+ const parsed = JSON.parse(raw);
380
+ const cutoff = Date.now() - MAX_AGE_MS;
381
+ this.items = parsed.filter((e) => e?.ts > cutoff).slice(-MAX_BUFFER);
382
+ } catch {
383
+ this.items = [];
384
+ }
385
+ }
386
+ push(payload) {
387
+ this.items.push({ ts: Date.now(), payload });
388
+ if (this.items.length > MAX_BUFFER) this.items.shift();
389
+ this.schedulePersist();
390
+ }
391
+ async drain() {
392
+ if (!this.loaded) await this.load();
393
+ const out = this.items.map((e) => e.payload);
394
+ this.items = [];
395
+ this.schedulePersist();
396
+ return out;
397
+ }
398
+ size() {
399
+ return this.items.length;
400
+ }
401
+ schedulePersist() {
402
+ if (this.persistTimer) return;
403
+ this.persistTimer = setTimeout(async () => {
404
+ this.persistTimer = null;
405
+ try {
406
+ await AsyncStorage2.setItem(STORAGE_KEY, JSON.stringify(this.items));
407
+ } catch {
408
+ }
409
+ }, 500);
410
+ }
411
+ /** Tests only. */
412
+ _resetForTests() {
413
+ this.items = [];
414
+ this.loaded = false;
415
+ if (this.persistTimer) {
416
+ clearTimeout(this.persistTimer);
417
+ this.persistTimer = null;
418
+ }
419
+ }
420
+ };
421
+ var offlineBuffer = new OfflineBuffer();
422
+
423
+ // src/device.ts
424
+ import { Platform } from "react-native";
425
+ function getDeviceAttrs() {
426
+ return {
427
+ platform: String(Platform.OS),
428
+ os_version: String(Platform.Version ?? "unknown"),
429
+ rn_version: Platform.constants?.reactNativeVersion ? Object.values(Platform.constants.reactNativeVersion).join(".") : void 0
430
+ };
431
+ }
432
+
433
+ // src/version.ts
434
+ var SDK_NAME = "@fixprompt/react-native";
435
+ var SDK_VERSION = "0.0.1";
436
+
437
+ // src/transport.ts
438
+ var REQUEST_TIMEOUT_MS = 8e3;
439
+ function sendEvent(config, payload) {
440
+ const state = getState();
441
+ const event = {
442
+ service: payload.service ?? config.service,
443
+ app: payload.app ?? config.app,
444
+ env: payload.env ?? config.env,
445
+ level: payload.level,
446
+ message: payload.message,
447
+ stack: payload.stack,
448
+ attrs: {
449
+ ...payload.attrs ?? {},
450
+ ...getDeviceAttrs(),
451
+ sdk: SDK_NAME,
452
+ sdk_version: SDK_VERSION,
453
+ release: config.release,
454
+ session_id: state.sessionId,
455
+ device_id: state.deviceId,
456
+ user_id: state.user?.id,
457
+ user_email: state.user?.email
458
+ },
459
+ synthetic: payload.synthetic
460
+ };
461
+ for (const k of Object.keys(event.attrs)) {
462
+ if (event.attrs[k] === void 0 || event.attrs[k] === null) {
463
+ delete event.attrs[k];
464
+ }
465
+ }
466
+ void postOrBuffer(config, event);
467
+ }
468
+ async function postOrBuffer(config, event) {
469
+ if (!await tryPost(
470
+ config,
471
+ event,
472
+ /* throwOnFail */
473
+ true
474
+ )) {
475
+ offlineBuffer.push(event);
476
+ return;
477
+ }
478
+ if (offlineBuffer.size() === 0) return;
479
+ const queued = await offlineBuffer.drain();
480
+ for (const buffered of queued) {
481
+ if (!await tryPost(config, buffered, true)) {
482
+ offlineBuffer.push(buffered);
483
+ for (let i = queued.indexOf(buffered) + 1; i < queued.length; i++) {
484
+ offlineBuffer.push(queued[i]);
485
+ }
486
+ return;
487
+ }
488
+ }
489
+ }
490
+ async function tryPost(config, event, throwOnFail) {
491
+ try {
492
+ const ctrl = new AbortController();
493
+ const timer = setTimeout(() => ctrl.abort(), REQUEST_TIMEOUT_MS);
494
+ try {
495
+ const res = await fetch(`${config.endpoint.replace(/\/$/, "")}/ingest/log`, {
496
+ method: "POST",
497
+ headers: {
498
+ "Content-Type": "application/json",
499
+ "x-loghub-source": config.source,
500
+ "x-loghub-key": config.projectKey
501
+ },
502
+ body: JSON.stringify(event),
503
+ signal: ctrl.signal
504
+ });
505
+ if (res.status >= 400 && res.status < 500) {
506
+ if (config.debug) {
507
+ console.warn(`[fixprompt] ${res.status} from broker \u2014 dropping event`);
508
+ }
509
+ return true;
510
+ }
511
+ return res.ok;
512
+ } finally {
513
+ clearTimeout(timer);
514
+ }
515
+ } catch (err) {
516
+ if (config.debug) {
517
+ console.warn(`[fixprompt] transport error: ${err.message}`);
518
+ }
519
+ return false;
520
+ }
521
+ }
522
+
523
+ // src/handlers.ts
524
+ function topStackFrame(stack) {
525
+ if (!stack) return "";
526
+ for (const raw of stack.split("\n")) {
527
+ const line = raw.trim();
528
+ if (!line) continue;
529
+ if (line.startsWith("Error")) continue;
530
+ if (/node_modules|@fixprompt/.test(line)) continue;
531
+ return line.slice(0, 200);
532
+ }
533
+ return stack.split("\n")[0]?.slice(0, 200) ?? "";
534
+ }
535
+ function installGlobalErrorHandler(config) {
536
+ const ErrorUtils = globalThis.ErrorUtils;
537
+ if (!ErrorUtils?.setGlobalHandler) {
538
+ return () => void 0;
539
+ }
540
+ const previous = ErrorUtils.getGlobalHandler?.();
541
+ const handler = (error, isFatal) => {
542
+ try {
543
+ sendEvent(config, {
544
+ level: isFatal ? "error" : "warn",
545
+ message: error?.message ?? "Uncaught error",
546
+ stack: typeof error?.stack === "string" ? error.stack : void 0,
547
+ attrs: {
548
+ kind: "rn.globalError",
549
+ severity: isFatal ? "critical" : "error",
550
+ error_name: error?.name,
551
+ top_frame: topStackFrame(error?.stack),
552
+ fatal: !!isFatal
553
+ }
554
+ });
555
+ } catch {
556
+ }
557
+ previous?.(error, isFatal);
558
+ };
559
+ ErrorUtils.setGlobalHandler(handler);
560
+ return () => {
561
+ if (previous) ErrorUtils.setGlobalHandler(previous);
562
+ };
563
+ }
564
+ function installRejectionHandler(config) {
565
+ let tracking;
566
+ try {
567
+ tracking = require_rejection_tracking();
568
+ } catch {
569
+ return () => void 0;
570
+ }
571
+ tracking.enable({
572
+ allRejections: true,
573
+ onUnhandled: (id, error) => {
574
+ try {
575
+ const isErr = error instanceof Error;
576
+ sendEvent(config, {
577
+ level: "error",
578
+ message: isErr ? error.message : safeJson(error),
579
+ stack: isErr && typeof error.stack === "string" ? error.stack : void 0,
580
+ attrs: {
581
+ kind: "rn.unhandledrejection",
582
+ severity: "error",
583
+ error_name: isErr ? error.name : typeof error,
584
+ top_frame: isErr ? topStackFrame(error.stack) : ""
585
+ }
586
+ });
587
+ } catch {
588
+ }
589
+ },
590
+ onHandled: () => void 0
591
+ });
592
+ return () => {
593
+ try {
594
+ tracking.disable();
595
+ } catch {
596
+ }
597
+ };
598
+ }
599
+ function safeJson(v) {
600
+ try {
601
+ return JSON.stringify(v);
602
+ } catch {
603
+ return String(v);
604
+ }
605
+ }
606
+
607
+ // src/console.ts
608
+ function shouldCapture(args, patterns) {
609
+ if (patterns.length === 0) return true;
610
+ const first = typeof args[0] === "string" ? args[0] : "";
611
+ return patterns.some((re) => re.test(first));
612
+ }
613
+ function stringify(args) {
614
+ const errArg = args.find((a) => a instanceof Error);
615
+ const message = args.map((a) => {
616
+ if (a instanceof Error) return a.message;
617
+ if (typeof a === "string") return a;
618
+ try {
619
+ return JSON.stringify(a);
620
+ } catch {
621
+ return String(a);
622
+ }
623
+ }).join(" ").slice(0, 4e3);
624
+ return {
625
+ message,
626
+ stack: errArg && typeof errArg.stack === "string" ? errArg.stack : void 0
627
+ };
628
+ }
629
+ function patchConsoleError(config) {
630
+ const original = console.error.bind(console);
631
+ console.error = (...args) => {
632
+ try {
633
+ if (shouldCapture(args, config.captureTags)) {
634
+ const { message, stack } = stringify(args);
635
+ sendEvent(config, {
636
+ level: "warn",
637
+ message,
638
+ stack,
639
+ attrs: {
640
+ kind: "console.error",
641
+ severity: "warning"
642
+ }
643
+ });
644
+ }
645
+ } catch {
646
+ }
647
+ return original(...args);
648
+ };
649
+ return () => {
650
+ console.error = original;
651
+ };
652
+ }
653
+ function patchConsoleWarn(config) {
654
+ const original = console.warn.bind(console);
655
+ console.warn = (...args) => {
656
+ try {
657
+ if (shouldCapture(args, config.captureTags)) {
658
+ const { message, stack } = stringify(args);
659
+ sendEvent(config, {
660
+ level: "warn",
661
+ message,
662
+ stack,
663
+ attrs: {
664
+ kind: "console.warn",
665
+ severity: "warning"
666
+ }
667
+ });
668
+ }
669
+ } catch {
670
+ }
671
+ return original(...args);
672
+ };
673
+ return () => {
674
+ console.warn = original;
675
+ };
676
+ }
677
+
678
+ // src/init.ts
679
+ var DEFAULT_ENDPOINT = "https://geosloghub-production.up.railway.app";
680
+ function resolveConfig(opts) {
681
+ if (!opts?.projectKey) throw new Error("initFixPrompt: projectKey is required");
682
+ if (!opts?.source) throw new Error("initFixPrompt: source is required");
683
+ if (!opts?.service) throw new Error("initFixPrompt: service is required");
684
+ if (!opts?.app) throw new Error("initFixPrompt: app is required");
685
+ return {
686
+ projectKey: opts.projectKey,
687
+ source: opts.source,
688
+ endpoint: (opts.endpoint ?? DEFAULT_ENDPOINT).replace(/\/$/, ""),
689
+ service: opts.service,
690
+ app: opts.app,
691
+ env: opts.env ?? "prod",
692
+ release: opts.release ?? null,
693
+ captureTags: opts.captureTags ?? [],
694
+ patchConsoleWarn: opts.patchConsoleWarn ?? false,
695
+ patchConsoleError: opts.patchConsoleError ?? true,
696
+ debug: opts.debug ?? false
697
+ };
698
+ }
699
+ function initFixPrompt(opts) {
700
+ const state = getState();
701
+ if (state.initialized) {
702
+ if (opts?.debug) {
703
+ console.warn("[fixprompt] already initialized \u2014 call ignored");
704
+ }
705
+ return;
706
+ }
707
+ const config = resolveConfig(opts);
708
+ state.config = config;
709
+ state.sessionId = newSessionId();
710
+ state.cleanup.removeErrorHandler = installGlobalErrorHandler(config);
711
+ state.cleanup.removeRejectionHandler = installRejectionHandler(config);
712
+ if (config.patchConsoleError) {
713
+ state.cleanup.restoreConsoleError = patchConsoleError(config);
714
+ }
715
+ if (config.patchConsoleWarn) {
716
+ state.cleanup.restoreConsoleWarn = patchConsoleWarn(config);
717
+ }
718
+ state.initialized = true;
719
+ void (async () => {
720
+ try {
721
+ state.deviceId = await getDeviceId();
722
+ await offlineBuffer.load();
723
+ if (offlineBuffer.size() > 0) {
724
+ const items = await offlineBuffer.drain();
725
+ for (const ev of items) {
726
+ offlineBuffer.push(ev);
727
+ }
728
+ sendEvent(config, {
729
+ level: "debug",
730
+ message: "[fixprompt] resumed from offline buffer",
731
+ attrs: { kind: "sdk.startup", buffered: items.length }
732
+ });
733
+ }
734
+ } catch (err) {
735
+ if (config.debug) {
736
+ console.warn(`[fixprompt] init async setup failed: ${err.message}`);
737
+ }
738
+ }
739
+ })();
740
+ if (config.debug) {
741
+ console.log("[fixprompt] initialized", {
742
+ endpoint: config.endpoint,
743
+ service: config.service,
744
+ env: config.env,
745
+ session_id: state.sessionId
746
+ });
747
+ }
748
+ }
749
+ function captureException(err, options = {}) {
750
+ const state = getState();
751
+ if (!state.initialized || !state.config) return;
752
+ const isErr = err instanceof Error;
753
+ sendEvent(state.config, {
754
+ level: "error",
755
+ message: isErr ? err.message : String(err),
756
+ stack: isErr && typeof err.stack === "string" ? err.stack : void 0,
757
+ attrs: {
758
+ kind: "captureException",
759
+ severity: "error",
760
+ error_name: isErr ? err.name : typeof err,
761
+ ...options.attrs ?? {}
762
+ },
763
+ synthetic: options.synthetic === true
764
+ });
765
+ }
766
+ function setUser(user) {
767
+ const state = getState();
768
+ state.user = user;
769
+ }
770
+ function _resetForTests() {
771
+ const state = getState();
772
+ state.cleanup.removeErrorHandler?.();
773
+ state.cleanup.removeRejectionHandler?.();
774
+ state.cleanup.restoreConsoleError?.();
775
+ state.cleanup.restoreConsoleWarn?.();
776
+ state.initialized = false;
777
+ state.config = null;
778
+ state.sessionId = null;
779
+ state.deviceId = null;
780
+ state.user = null;
781
+ state.cleanup = {};
782
+ }
783
+ export {
784
+ SDK_NAME,
785
+ SDK_VERSION,
786
+ _resetForTests,
787
+ captureException,
788
+ initFixPrompt,
789
+ setUser
790
+ };
791
+ //# sourceMappingURL=index.js.map