@edraj/sauron-browser 1.0.0 → 1.4.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/CHANGELOG.md +72 -0
- package/README.md +1008 -53
- package/dist/index.cjs +285 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -13
- package/dist/index.d.ts +142 -13
- package/dist/index.js +281 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4
4
|
|
|
5
5
|
// src/utils.ts
|
|
6
6
|
var SDK_NAME = "sauron.javascript";
|
|
7
|
-
var SDK_VERSION = "1.
|
|
7
|
+
var SDK_VERSION = "1.4.0";
|
|
8
8
|
function getGlobal() {
|
|
9
9
|
return globalThis;
|
|
10
10
|
}
|
|
@@ -87,6 +87,7 @@ function makeLogger(debug) {
|
|
|
87
87
|
// src/identity.ts
|
|
88
88
|
var DEVICE_ID_KEY = "sauron.device_id";
|
|
89
89
|
var SESSION_ID_KEY = "sauron.session_id";
|
|
90
|
+
var ANON_ID_KEY = "sauron.anon_id";
|
|
90
91
|
function webStorage(name) {
|
|
91
92
|
try {
|
|
92
93
|
const s = globalThis[name];
|
|
@@ -119,6 +120,7 @@ function persistentId(cached, storage, key) {
|
|
|
119
120
|
}
|
|
120
121
|
var deviceId = null;
|
|
121
122
|
var sessionId = null;
|
|
123
|
+
var anonymousId = null;
|
|
122
124
|
function getDeviceId() {
|
|
123
125
|
deviceId = persistentId(deviceId, webStorage("localStorage"), DEVICE_ID_KEY);
|
|
124
126
|
return deviceId;
|
|
@@ -127,6 +129,40 @@ function getSessionId() {
|
|
|
127
129
|
sessionId = persistentId(sessionId, webStorage("sessionStorage"), SESSION_ID_KEY);
|
|
128
130
|
return sessionId;
|
|
129
131
|
}
|
|
132
|
+
function getAnonymousId() {
|
|
133
|
+
if (anonymousId) return anonymousId;
|
|
134
|
+
const storage = webStorage("localStorage");
|
|
135
|
+
if (storage) {
|
|
136
|
+
try {
|
|
137
|
+
const existing = storage.getItem(ANON_ID_KEY);
|
|
138
|
+
if (existing) {
|
|
139
|
+
anonymousId = existing;
|
|
140
|
+
return anonymousId;
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const fresh = `anon_${uuidv4()}`;
|
|
146
|
+
if (storage) {
|
|
147
|
+
try {
|
|
148
|
+
storage.setItem(ANON_ID_KEY, fresh);
|
|
149
|
+
} catch {
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
anonymousId = fresh;
|
|
153
|
+
return anonymousId;
|
|
154
|
+
}
|
|
155
|
+
function resetAnonymousId() {
|
|
156
|
+
anonymousId = null;
|
|
157
|
+
const storage = webStorage("localStorage");
|
|
158
|
+
if (storage) {
|
|
159
|
+
try {
|
|
160
|
+
storage.removeItem(ANON_ID_KEY);
|
|
161
|
+
} catch {
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return getAnonymousId();
|
|
165
|
+
}
|
|
130
166
|
|
|
131
167
|
// src/context.ts
|
|
132
168
|
function getNavigator() {
|
|
@@ -624,12 +660,7 @@ function captureMessage(message, level = "info", hint) {
|
|
|
624
660
|
type: "error",
|
|
625
661
|
timestamp: nowIso(),
|
|
626
662
|
level,
|
|
627
|
-
|
|
628
|
-
type: null,
|
|
629
|
-
value: message,
|
|
630
|
-
mechanism: { type: "message", handled: true },
|
|
631
|
-
stacktrace: []
|
|
632
|
-
},
|
|
663
|
+
message,
|
|
633
664
|
breadcrumbs,
|
|
634
665
|
fingerprint: hint?.fingerprint ?? null,
|
|
635
666
|
session_id: getSessionId(),
|
|
@@ -832,6 +863,30 @@ var Scope = class {
|
|
|
832
863
|
}
|
|
833
864
|
};
|
|
834
865
|
|
|
866
|
+
// src/workflow.ts
|
|
867
|
+
var WORKFLOW_NAME_MAX = 120;
|
|
868
|
+
var WORKFLOW_REASON_MAX = 120;
|
|
869
|
+
var current = null;
|
|
870
|
+
function getWorkflow() {
|
|
871
|
+
return current;
|
|
872
|
+
}
|
|
873
|
+
function setWorkflowState(workflow) {
|
|
874
|
+
current = workflow;
|
|
875
|
+
}
|
|
876
|
+
function resetWorkflow() {
|
|
877
|
+
current = null;
|
|
878
|
+
}
|
|
879
|
+
function normalizeWorkflowName(name) {
|
|
880
|
+
if (typeof name !== "string") return null;
|
|
881
|
+
const trimmed = name.trim();
|
|
882
|
+
if (trimmed.length === 0 || trimmed.length > WORKFLOW_NAME_MAX) return null;
|
|
883
|
+
return trimmed;
|
|
884
|
+
}
|
|
885
|
+
function normalizeReason(reason) {
|
|
886
|
+
if (typeof reason !== "string" || reason.trim().length === 0) return "user";
|
|
887
|
+
return reason.trim().slice(0, WORKFLOW_REASON_MAX);
|
|
888
|
+
}
|
|
889
|
+
|
|
835
890
|
// src/api/product.ts
|
|
836
891
|
function track(name, properties = {}, options = {}) {
|
|
837
892
|
const client = getClient();
|
|
@@ -861,12 +916,12 @@ function setScreen(name) {
|
|
|
861
916
|
function identify(id, traits = {}) {
|
|
862
917
|
const client = getClient();
|
|
863
918
|
if (!client) return;
|
|
864
|
-
const
|
|
919
|
+
const anonymousId2 = client.getAnonymousId();
|
|
865
920
|
client.getScope().setUser({ id, traits });
|
|
866
921
|
const item = {
|
|
867
922
|
type: "identify",
|
|
868
923
|
distinct_id: id,
|
|
869
|
-
anonymous_id:
|
|
924
|
+
anonymous_id: anonymousId2,
|
|
870
925
|
traits: traits ?? {}
|
|
871
926
|
};
|
|
872
927
|
client.captureItem(item);
|
|
@@ -902,6 +957,86 @@ function trackTransaction(input) {
|
|
|
902
957
|
const item = buildTransactionItem(input, client.getDistinctId(), getSessionId());
|
|
903
958
|
client.captureItem(item);
|
|
904
959
|
}
|
|
960
|
+
var NOOP_LOGGER = makeLogger(false);
|
|
961
|
+
function emitWorkflowClose(active, eventName, reason, logger) {
|
|
962
|
+
const properties = {
|
|
963
|
+
workflow_id: active.workflowId,
|
|
964
|
+
workflow_name: active.name,
|
|
965
|
+
duration_ms: Math.max(0, Date.now() - Date.parse(active.startedAt))
|
|
966
|
+
};
|
|
967
|
+
if (eventName === "$workflow_cancel") {
|
|
968
|
+
properties.reason = normalizeReason(reason);
|
|
969
|
+
}
|
|
970
|
+
try {
|
|
971
|
+
track(eventName, properties);
|
|
972
|
+
} catch (err) {
|
|
973
|
+
logger.warn(`${eventName}: failed to emit the lifecycle event`, err);
|
|
974
|
+
} finally {
|
|
975
|
+
resetWorkflow();
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
function startWorkflow(name, options) {
|
|
979
|
+
let logger = NOOP_LOGGER;
|
|
980
|
+
try {
|
|
981
|
+
const client = getClient();
|
|
982
|
+
if (!client || !client.isEnabled()) return { status: "disabled" };
|
|
983
|
+
logger = makeLogger(client.options.debug);
|
|
984
|
+
const normalized = normalizeWorkflowName(name);
|
|
985
|
+
if (!normalized) {
|
|
986
|
+
logger.warn("startWorkflow: invalid name", name);
|
|
987
|
+
return { status: "invalid_name" };
|
|
988
|
+
}
|
|
989
|
+
const active = getWorkflow();
|
|
990
|
+
if (active && !options?.force) {
|
|
991
|
+
logger.warn(
|
|
992
|
+
`startWorkflow("${normalized}"): "${active.name}" is already active; pass { force: true } to replace it`
|
|
993
|
+
);
|
|
994
|
+
return { status: "already_active" };
|
|
995
|
+
}
|
|
996
|
+
const workflow = {
|
|
997
|
+
workflowId: uuidv4(),
|
|
998
|
+
name: normalized,
|
|
999
|
+
startedAt: nowIso()
|
|
1000
|
+
};
|
|
1001
|
+
if (active) emitWorkflowClose(active, "$workflow_cancel", "superseded", logger);
|
|
1002
|
+
setWorkflowState(workflow);
|
|
1003
|
+
try {
|
|
1004
|
+
track("$workflow_start", { workflow_id: workflow.workflowId, workflow_name: workflow.name });
|
|
1005
|
+
} catch (err) {
|
|
1006
|
+
logger.warn("startWorkflow: failed to emit $workflow_start", err);
|
|
1007
|
+
}
|
|
1008
|
+
return { status: "ok", workflowId: workflow.workflowId };
|
|
1009
|
+
} catch (err) {
|
|
1010
|
+
logger.warn("startWorkflow failed", err);
|
|
1011
|
+
return { status: "disabled" };
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
function closeWorkflow(eventName, name, reason) {
|
|
1015
|
+
let logger = NOOP_LOGGER;
|
|
1016
|
+
try {
|
|
1017
|
+
const client = getClient();
|
|
1018
|
+
if (!client || !client.isEnabled()) return { status: "disabled" };
|
|
1019
|
+
logger = makeLogger(client.options.debug);
|
|
1020
|
+
const active = getWorkflow();
|
|
1021
|
+
if (!active) return { status: "not_active" };
|
|
1022
|
+
if (name !== void 0 && normalizeWorkflowName(name) !== active.name) {
|
|
1023
|
+
logger.warn(`${eventName}: "${name}" does not match active workflow "${active.name}"`);
|
|
1024
|
+
return { status: "name_mismatch" };
|
|
1025
|
+
}
|
|
1026
|
+
const workflowId = active.workflowId;
|
|
1027
|
+
emitWorkflowClose(active, eventName, reason, logger);
|
|
1028
|
+
return { status: "ok", workflowId };
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
logger.warn(`${eventName} failed`, err);
|
|
1031
|
+
return { status: "disabled" };
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
function endWorkflow(name) {
|
|
1035
|
+
return closeWorkflow("$workflow_end", name);
|
|
1036
|
+
}
|
|
1037
|
+
function cancelWorkflow(name, options) {
|
|
1038
|
+
return closeWorkflow("$workflow_cancel", name, options?.reason);
|
|
1039
|
+
}
|
|
905
1040
|
|
|
906
1041
|
// src/integrations/performance.ts
|
|
907
1042
|
var PERF_FETCH = "__sauron_perf_fetch__";
|
|
@@ -1291,6 +1426,21 @@ var OfflineQueue = class {
|
|
|
1291
1426
|
if (entries.length) this.write([]);
|
|
1292
1427
|
return entries;
|
|
1293
1428
|
}
|
|
1429
|
+
/**
|
|
1430
|
+
* Put drained payloads BACK at the head, keeping their relative order.
|
|
1431
|
+
*
|
|
1432
|
+
* The counterpart to {@link drain}: a drain empties the store immediately, so
|
|
1433
|
+
* whatever the caller could not deliver only exists in its local array and is
|
|
1434
|
+
* lost the moment the caller returns. Re-parking at the head (rather than via
|
|
1435
|
+
* {@link enqueue}) keeps the queue oldest-first, which is what the byte-cap
|
|
1436
|
+
* eviction policy assumes — the oldest entry must stay the first one evicted.
|
|
1437
|
+
*/
|
|
1438
|
+
requeueFront(payloads) {
|
|
1439
|
+
if (!this.storage || payloads.length === 0) return;
|
|
1440
|
+
const entries = [...payloads, ...this.read()];
|
|
1441
|
+
this.evict(entries);
|
|
1442
|
+
this.write(entries);
|
|
1443
|
+
}
|
|
1294
1444
|
/** Non-destructive read of the current entries, oldest first. */
|
|
1295
1445
|
peek() {
|
|
1296
1446
|
return this.read();
|
|
@@ -1354,6 +1504,9 @@ var Transport = class {
|
|
|
1354
1504
|
__publicField(this, "pending", []);
|
|
1355
1505
|
__publicField(this, "timer", null);
|
|
1356
1506
|
__publicField(this, "onlineHandler", null);
|
|
1507
|
+
/** Permanent auto-disable latch, flipped by this transport itself the moment
|
|
1508
|
+
* it classifies a response as 401/403 — it is the source of truth for
|
|
1509
|
+
* {@link isEnabled}, not merely a mirror of something the client decided. */
|
|
1357
1510
|
__publicField(this, "disabled", false);
|
|
1358
1511
|
this.dsn = config.dsn;
|
|
1359
1512
|
this.makeEnvelope = config.makeEnvelope;
|
|
@@ -1401,6 +1554,10 @@ var Transport = class {
|
|
|
1401
1554
|
this.pending = [];
|
|
1402
1555
|
this.stop();
|
|
1403
1556
|
}
|
|
1557
|
+
/** Whether the transport still accepts items (false once auth-disabled by a 401/403). */
|
|
1558
|
+
isEnabled() {
|
|
1559
|
+
return !this.disabled;
|
|
1560
|
+
}
|
|
1404
1561
|
/** Queue an item for the next batch; flush eagerly once the batch is full. */
|
|
1405
1562
|
send(item) {
|
|
1406
1563
|
if (this.disabled) return;
|
|
@@ -1443,6 +1600,7 @@ var Transport = class {
|
|
|
1443
1600
|
return;
|
|
1444
1601
|
case "disable":
|
|
1445
1602
|
this.logger.warn("server rejected credentials; disabling client");
|
|
1603
|
+
this.disable();
|
|
1446
1604
|
this.onDisable();
|
|
1447
1605
|
return;
|
|
1448
1606
|
case "split": {
|
|
@@ -1468,11 +1626,21 @@ var Transport = class {
|
|
|
1468
1626
|
}
|
|
1469
1627
|
}
|
|
1470
1628
|
}
|
|
1471
|
-
/**
|
|
1629
|
+
/**
|
|
1630
|
+
* Re-attempt any envelopes that were parked while offline.
|
|
1631
|
+
*
|
|
1632
|
+
* `drain()` empties `localStorage` in one shot, so from here on the ONLY copy
|
|
1633
|
+
* of the backlog is the local `payloads` array. Every early return therefore
|
|
1634
|
+
* has to re-park the whole untried remainder, not just the payload that
|
|
1635
|
+
* failed: this used to re-park the failing one and return, which silently
|
|
1636
|
+
* deleted every payload behind it — the exact reconnect-then-one-500 case the
|
|
1637
|
+
* queue exists for.
|
|
1638
|
+
*/
|
|
1472
1639
|
async drainOfflineQueue() {
|
|
1473
1640
|
if (this.disabled || !this.offline.available) return;
|
|
1474
1641
|
const payloads = this.offline.drain();
|
|
1475
|
-
for (
|
|
1642
|
+
for (let i = 0; i < payloads.length; i++) {
|
|
1643
|
+
const json = payloads[i];
|
|
1476
1644
|
let outcome;
|
|
1477
1645
|
try {
|
|
1478
1646
|
outcome = await this.post(json);
|
|
@@ -1480,12 +1648,14 @@ var Transport = class {
|
|
|
1480
1648
|
outcome = { action: "retry_backoff" };
|
|
1481
1649
|
}
|
|
1482
1650
|
if (outcome.action === "disable") {
|
|
1651
|
+
this.logger.warn("server rejected credentials while draining; disabling client");
|
|
1652
|
+
this.disable();
|
|
1483
1653
|
this.onDisable();
|
|
1484
|
-
this.offline.
|
|
1654
|
+
this.offline.requeueFront(payloads.slice(i));
|
|
1485
1655
|
return;
|
|
1486
1656
|
}
|
|
1487
1657
|
if (outcome.action === "retry_after" || outcome.action === "retry_backoff") {
|
|
1488
|
-
this.offline.
|
|
1658
|
+
this.offline.requeueFront(payloads.slice(i));
|
|
1489
1659
|
return;
|
|
1490
1660
|
}
|
|
1491
1661
|
}
|
|
@@ -1595,8 +1765,17 @@ var SauronClient = class {
|
|
|
1595
1765
|
__publicField(this, "nativeFetch");
|
|
1596
1766
|
__publicField(this, "enabled", true);
|
|
1597
1767
|
__publicField(this, "installed", false);
|
|
1598
|
-
__publicField(this, "anonymousId", null);
|
|
1599
1768
|
__publicField(this, "beaconCleanup", null);
|
|
1769
|
+
/**
|
|
1770
|
+
* Whether the anonymous id has actually been USED as a `distinct_id` in this
|
|
1771
|
+
* browser session.
|
|
1772
|
+
*
|
|
1773
|
+
* A persisted id that has never been observed anonymously must not create a
|
|
1774
|
+
* permanent `identities` alias row on the server: aliasing is a durable
|
|
1775
|
+
* server-side binding of this browser profile to a named user, and an
|
|
1776
|
+
* identify() on a first-ever page load has no anonymous history to link.
|
|
1777
|
+
*/
|
|
1778
|
+
__publicField(this, "anonUsed", false);
|
|
1600
1779
|
this.options = options;
|
|
1601
1780
|
this.dsn = parseDsn(options.dsn);
|
|
1602
1781
|
this.logger = makeLogger(options.debug);
|
|
@@ -1645,22 +1824,43 @@ var SauronClient = class {
|
|
|
1645
1824
|
getScope() {
|
|
1646
1825
|
return this.scope;
|
|
1647
1826
|
}
|
|
1827
|
+
/**
|
|
1828
|
+
* False once this client was explicitly disabled/closed, OR once the
|
|
1829
|
+
* transport has auto-disabled itself on a 401/403 (revoked/invalid DSN
|
|
1830
|
+
* key) — computed from the transport's own state on every call, not a
|
|
1831
|
+
* separately mirrored flag, so a propagation regression there cannot leave
|
|
1832
|
+
* this predicate stale. `this.transport` always exists once a client
|
|
1833
|
+
* exists (it is constructed synchronously in the constructor); the
|
|
1834
|
+
* "nothing installed yet" case is instead handled one layer up, by every
|
|
1835
|
+
* module-level API (`startWorkflow`, `track`, ...) treating `getClient() ===
|
|
1836
|
+
* null` as the no-op/disabled case before it ever reaches here.
|
|
1837
|
+
*/
|
|
1648
1838
|
isEnabled() {
|
|
1649
|
-
return this.enabled;
|
|
1839
|
+
return this.enabled && this.transport.isEnabled();
|
|
1650
1840
|
}
|
|
1651
1841
|
/** The current distinct id: the user id when identified, else an anon id. */
|
|
1652
1842
|
getDistinctId() {
|
|
1653
1843
|
const user = this.scope.getUser();
|
|
1654
1844
|
if (user.id) return user.id;
|
|
1655
|
-
|
|
1845
|
+
this.anonUsed = true;
|
|
1846
|
+
return getAnonymousId();
|
|
1656
1847
|
}
|
|
1657
|
-
/** The anonymous id, or null
|
|
1848
|
+
/** The anonymous id, or null when it was never actually used as an identity. */
|
|
1658
1849
|
getAnonymousId() {
|
|
1659
|
-
return this.
|
|
1850
|
+
return this.anonUsed ? getAnonymousId() : null;
|
|
1660
1851
|
}
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1852
|
+
/**
|
|
1853
|
+
* Forget the current person: clear the scope user and mint a fresh anonymous
|
|
1854
|
+
* id.
|
|
1855
|
+
*
|
|
1856
|
+
* MUST BE CALLED ON LOGOUT. Without it, the next anonymous visitor on this
|
|
1857
|
+
* browser reuses the persisted anon id, and a later identify() aliases their
|
|
1858
|
+
* activity to the previous account server-side, permanently.
|
|
1859
|
+
*/
|
|
1860
|
+
reset() {
|
|
1861
|
+
this.scope.setUser(null);
|
|
1862
|
+
resetAnonymousId();
|
|
1863
|
+
this.anonUsed = false;
|
|
1664
1864
|
}
|
|
1665
1865
|
/** Stamp a fresh envelope (new `sent_at`, current context) around `items`. */
|
|
1666
1866
|
makeEnvelope(items) {
|
|
@@ -1668,7 +1868,6 @@ var SauronClient = class {
|
|
|
1668
1868
|
dsn: this.dsn.raw,
|
|
1669
1869
|
sdk: { name: SDK_NAME, version: SDK_VERSION },
|
|
1670
1870
|
sent_at: nowIso(),
|
|
1671
|
-
environment: this.options.environment,
|
|
1672
1871
|
release: this.options.release
|
|
1673
1872
|
};
|
|
1674
1873
|
const context = buildContext(this.options.release, this.scope.getUser());
|
|
@@ -1714,6 +1913,39 @@ var SauronClient = class {
|
|
|
1714
1913
|
item.user = this.scope.getUser();
|
|
1715
1914
|
}
|
|
1716
1915
|
}
|
|
1916
|
+
/**
|
|
1917
|
+
* Stamp the active workflow (if any) onto a signal item.
|
|
1918
|
+
*
|
|
1919
|
+
* Done HERE — the single choke point every capture path funnels through —
|
|
1920
|
+
* rather than at each item-construction site, so a capture path added later
|
|
1921
|
+
* is stamped by construction instead of by remembering to. The keys are
|
|
1922
|
+
* ASSIGNED ONLY when a workflow is active: an item with no workflow keeps
|
|
1923
|
+
* them absent entirely (not present-as-`undefined`), which is what makes
|
|
1924
|
+
* `JSON.stringify` omit them and keeps the no-workflow wire bytes identical
|
|
1925
|
+
* to pre-1.3.0.
|
|
1926
|
+
*
|
|
1927
|
+
* Only error/event/transaction carry `workflow_id`/`workflow_name` columns
|
|
1928
|
+
* server-side — identify and breadcrumb_batch items are deliberately left
|
|
1929
|
+
* alone. An item that already carries an explicit `workflow_id` is left
|
|
1930
|
+
* untouched, matching how `enrichErrorItem` defers to caller-set fields.
|
|
1931
|
+
*/
|
|
1932
|
+
stampWorkflow(item) {
|
|
1933
|
+
if (item.type !== "error" && item.type !== "event" && item.type !== "transaction") return;
|
|
1934
|
+
const hasId = item.workflow_id !== void 0;
|
|
1935
|
+
const hasName = item.workflow_name !== void 0;
|
|
1936
|
+
if (hasId || hasName) {
|
|
1937
|
+
if (hasId !== hasName) {
|
|
1938
|
+
this.logger.warn(
|
|
1939
|
+
"item sets only one of workflow_id/workflow_name; the server treats them as a pair and will drop this attribution. Set both, or neither."
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
const workflow = getWorkflow();
|
|
1945
|
+
if (!workflow) return;
|
|
1946
|
+
item.workflow_id = workflow.workflowId;
|
|
1947
|
+
item.workflow_name = workflow.name;
|
|
1948
|
+
}
|
|
1717
1949
|
/**
|
|
1718
1950
|
* Run an item through sampling (errors only) and `beforeSend`, then hand it to
|
|
1719
1951
|
* the transport. Returns silently when dropped.
|
|
@@ -1727,6 +1959,7 @@ var SauronClient = class {
|
|
|
1727
1959
|
}
|
|
1728
1960
|
this.enrichErrorItem(item, hint);
|
|
1729
1961
|
}
|
|
1962
|
+
this.stampWorkflow(item);
|
|
1730
1963
|
let processed = item;
|
|
1731
1964
|
if (this.options.beforeSend) {
|
|
1732
1965
|
try {
|
|
@@ -1763,6 +1996,7 @@ var SauronClient = class {
|
|
|
1763
1996
|
}
|
|
1764
1997
|
onNavigation(null);
|
|
1765
1998
|
resetScreen();
|
|
1999
|
+
resetWorkflow();
|
|
1766
2000
|
unpatchAll();
|
|
1767
2001
|
setDsnHost(null);
|
|
1768
2002
|
this.installed = false;
|
|
@@ -1785,7 +2019,6 @@ function resolveOptions(options) {
|
|
|
1785
2019
|
const t = options.transport ?? {};
|
|
1786
2020
|
return {
|
|
1787
2021
|
dsn: options.dsn,
|
|
1788
|
-
environment: options.environment ?? "production",
|
|
1789
2022
|
release: options.release ?? null,
|
|
1790
2023
|
sampleRate: clamp(options.sampleRate ?? 1, 0, 1),
|
|
1791
2024
|
maxBreadcrumbs: options.maxBreadcrumbs ?? 50,
|
|
@@ -1870,12 +2103,31 @@ function setScreen2(name) {
|
|
|
1870
2103
|
function getScreen2() {
|
|
1871
2104
|
return getScreen();
|
|
1872
2105
|
}
|
|
2106
|
+
function startWorkflow2(name, options) {
|
|
2107
|
+
return startWorkflow(name, options);
|
|
2108
|
+
}
|
|
2109
|
+
function endWorkflow2(name) {
|
|
2110
|
+
return endWorkflow(name);
|
|
2111
|
+
}
|
|
2112
|
+
function cancelWorkflow2(name, options) {
|
|
2113
|
+
return cancelWorkflow(name, options);
|
|
2114
|
+
}
|
|
2115
|
+
function getWorkflow2() {
|
|
2116
|
+
return getWorkflow();
|
|
2117
|
+
}
|
|
1873
2118
|
function addBreadcrumb2(breadcrumb, hint) {
|
|
1874
2119
|
addBreadcrumb(breadcrumb, hint);
|
|
1875
2120
|
}
|
|
1876
2121
|
function setUser(user) {
|
|
2122
|
+
if (user === null) {
|
|
2123
|
+
getClient()?.reset();
|
|
2124
|
+
return;
|
|
2125
|
+
}
|
|
1877
2126
|
getClient()?.getScope().setUser(user);
|
|
1878
2127
|
}
|
|
2128
|
+
function reset() {
|
|
2129
|
+
getClient()?.reset();
|
|
2130
|
+
}
|
|
1879
2131
|
function setTag(key, value) {
|
|
1880
2132
|
getClient()?.getScope().setTag(key, value);
|
|
1881
2133
|
}
|
|
@@ -1905,18 +2157,23 @@ var Sauron = {
|
|
|
1905
2157
|
identify: identify2,
|
|
1906
2158
|
addBreadcrumb: addBreadcrumb2,
|
|
1907
2159
|
setUser,
|
|
2160
|
+
reset,
|
|
1908
2161
|
setTag,
|
|
1909
2162
|
setTags,
|
|
1910
2163
|
setContext,
|
|
1911
2164
|
setExtra,
|
|
1912
2165
|
setScreen: setScreen2,
|
|
1913
2166
|
getScreen: getScreen2,
|
|
2167
|
+
startWorkflow: startWorkflow2,
|
|
2168
|
+
endWorkflow: endWorkflow2,
|
|
2169
|
+
cancelWorkflow: cancelWorkflow2,
|
|
2170
|
+
getWorkflow: getWorkflow2,
|
|
1914
2171
|
flush,
|
|
1915
2172
|
close,
|
|
1916
2173
|
getClient
|
|
1917
2174
|
};
|
|
1918
2175
|
var index_default = Sauron;
|
|
1919
2176
|
|
|
1920
|
-
export { DsnError, SDK_NAME, SDK_VERSION, Sauron, SauronClient, addBreadcrumb2 as addBreadcrumb, buildEnvelope, captureException2 as captureException, captureMessage2 as captureMessage, close, index_default as default, flush, getClient, getScreen2 as getScreen, identify2 as identify, init2 as init, isInAppFrame, parseDsn, parseError, parseStackString, setContext, setExtra, setScreen2 as setScreen, setTag, setTags, setUser, track2 as track, trackTransaction2 as trackTransaction };
|
|
2177
|
+
export { DsnError, SDK_NAME, SDK_VERSION, Sauron, SauronClient, addBreadcrumb2 as addBreadcrumb, buildEnvelope, cancelWorkflow2 as cancelWorkflow, captureException2 as captureException, captureMessage2 as captureMessage, close, index_default as default, endWorkflow2 as endWorkflow, flush, getClient, getScreen2 as getScreen, getWorkflow2 as getWorkflow, identify2 as identify, init2 as init, isInAppFrame, parseDsn, parseError, parseStackString, reset, setContext, setExtra, setScreen2 as setScreen, setTag, setTags, setUser, startWorkflow2 as startWorkflow, track2 as track, trackTransaction2 as trackTransaction };
|
|
1921
2178
|
//# sourceMappingURL=index.js.map
|
|
1922
2179
|
//# sourceMappingURL=index.js.map
|