@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.cjs
CHANGED
|
@@ -8,7 +8,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
8
8
|
|
|
9
9
|
// src/utils.ts
|
|
10
10
|
var SDK_NAME = "sauron.javascript";
|
|
11
|
-
var SDK_VERSION = "1.
|
|
11
|
+
var SDK_VERSION = "1.4.0";
|
|
12
12
|
function getGlobal() {
|
|
13
13
|
return globalThis;
|
|
14
14
|
}
|
|
@@ -91,6 +91,7 @@ function makeLogger(debug) {
|
|
|
91
91
|
// src/identity.ts
|
|
92
92
|
var DEVICE_ID_KEY = "sauron.device_id";
|
|
93
93
|
var SESSION_ID_KEY = "sauron.session_id";
|
|
94
|
+
var ANON_ID_KEY = "sauron.anon_id";
|
|
94
95
|
function webStorage(name) {
|
|
95
96
|
try {
|
|
96
97
|
const s = globalThis[name];
|
|
@@ -123,6 +124,7 @@ function persistentId(cached, storage, key) {
|
|
|
123
124
|
}
|
|
124
125
|
var deviceId = null;
|
|
125
126
|
var sessionId = null;
|
|
127
|
+
var anonymousId = null;
|
|
126
128
|
function getDeviceId() {
|
|
127
129
|
deviceId = persistentId(deviceId, webStorage("localStorage"), DEVICE_ID_KEY);
|
|
128
130
|
return deviceId;
|
|
@@ -131,6 +133,40 @@ function getSessionId() {
|
|
|
131
133
|
sessionId = persistentId(sessionId, webStorage("sessionStorage"), SESSION_ID_KEY);
|
|
132
134
|
return sessionId;
|
|
133
135
|
}
|
|
136
|
+
function getAnonymousId() {
|
|
137
|
+
if (anonymousId) return anonymousId;
|
|
138
|
+
const storage = webStorage("localStorage");
|
|
139
|
+
if (storage) {
|
|
140
|
+
try {
|
|
141
|
+
const existing = storage.getItem(ANON_ID_KEY);
|
|
142
|
+
if (existing) {
|
|
143
|
+
anonymousId = existing;
|
|
144
|
+
return anonymousId;
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const fresh = `anon_${uuidv4()}`;
|
|
150
|
+
if (storage) {
|
|
151
|
+
try {
|
|
152
|
+
storage.setItem(ANON_ID_KEY, fresh);
|
|
153
|
+
} catch {
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
anonymousId = fresh;
|
|
157
|
+
return anonymousId;
|
|
158
|
+
}
|
|
159
|
+
function resetAnonymousId() {
|
|
160
|
+
anonymousId = null;
|
|
161
|
+
const storage = webStorage("localStorage");
|
|
162
|
+
if (storage) {
|
|
163
|
+
try {
|
|
164
|
+
storage.removeItem(ANON_ID_KEY);
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return getAnonymousId();
|
|
169
|
+
}
|
|
134
170
|
|
|
135
171
|
// src/context.ts
|
|
136
172
|
function getNavigator() {
|
|
@@ -628,12 +664,7 @@ function captureMessage(message, level = "info", hint) {
|
|
|
628
664
|
type: "error",
|
|
629
665
|
timestamp: nowIso(),
|
|
630
666
|
level,
|
|
631
|
-
|
|
632
|
-
type: null,
|
|
633
|
-
value: message,
|
|
634
|
-
mechanism: { type: "message", handled: true },
|
|
635
|
-
stacktrace: []
|
|
636
|
-
},
|
|
667
|
+
message,
|
|
637
668
|
breadcrumbs,
|
|
638
669
|
fingerprint: hint?.fingerprint ?? null,
|
|
639
670
|
session_id: getSessionId(),
|
|
@@ -836,6 +867,30 @@ var Scope = class {
|
|
|
836
867
|
}
|
|
837
868
|
};
|
|
838
869
|
|
|
870
|
+
// src/workflow.ts
|
|
871
|
+
var WORKFLOW_NAME_MAX = 120;
|
|
872
|
+
var WORKFLOW_REASON_MAX = 120;
|
|
873
|
+
var current = null;
|
|
874
|
+
function getWorkflow() {
|
|
875
|
+
return current;
|
|
876
|
+
}
|
|
877
|
+
function setWorkflowState(workflow) {
|
|
878
|
+
current = workflow;
|
|
879
|
+
}
|
|
880
|
+
function resetWorkflow() {
|
|
881
|
+
current = null;
|
|
882
|
+
}
|
|
883
|
+
function normalizeWorkflowName(name) {
|
|
884
|
+
if (typeof name !== "string") return null;
|
|
885
|
+
const trimmed = name.trim();
|
|
886
|
+
if (trimmed.length === 0 || trimmed.length > WORKFLOW_NAME_MAX) return null;
|
|
887
|
+
return trimmed;
|
|
888
|
+
}
|
|
889
|
+
function normalizeReason(reason) {
|
|
890
|
+
if (typeof reason !== "string" || reason.trim().length === 0) return "user";
|
|
891
|
+
return reason.trim().slice(0, WORKFLOW_REASON_MAX);
|
|
892
|
+
}
|
|
893
|
+
|
|
839
894
|
// src/api/product.ts
|
|
840
895
|
function track(name, properties = {}, options = {}) {
|
|
841
896
|
const client = getClient();
|
|
@@ -865,12 +920,12 @@ function setScreen(name) {
|
|
|
865
920
|
function identify(id, traits = {}) {
|
|
866
921
|
const client = getClient();
|
|
867
922
|
if (!client) return;
|
|
868
|
-
const
|
|
923
|
+
const anonymousId2 = client.getAnonymousId();
|
|
869
924
|
client.getScope().setUser({ id, traits });
|
|
870
925
|
const item = {
|
|
871
926
|
type: "identify",
|
|
872
927
|
distinct_id: id,
|
|
873
|
-
anonymous_id:
|
|
928
|
+
anonymous_id: anonymousId2,
|
|
874
929
|
traits: traits ?? {}
|
|
875
930
|
};
|
|
876
931
|
client.captureItem(item);
|
|
@@ -906,6 +961,86 @@ function trackTransaction(input) {
|
|
|
906
961
|
const item = buildTransactionItem(input, client.getDistinctId(), getSessionId());
|
|
907
962
|
client.captureItem(item);
|
|
908
963
|
}
|
|
964
|
+
var NOOP_LOGGER = makeLogger(false);
|
|
965
|
+
function emitWorkflowClose(active, eventName, reason, logger) {
|
|
966
|
+
const properties = {
|
|
967
|
+
workflow_id: active.workflowId,
|
|
968
|
+
workflow_name: active.name,
|
|
969
|
+
duration_ms: Math.max(0, Date.now() - Date.parse(active.startedAt))
|
|
970
|
+
};
|
|
971
|
+
if (eventName === "$workflow_cancel") {
|
|
972
|
+
properties.reason = normalizeReason(reason);
|
|
973
|
+
}
|
|
974
|
+
try {
|
|
975
|
+
track(eventName, properties);
|
|
976
|
+
} catch (err) {
|
|
977
|
+
logger.warn(`${eventName}: failed to emit the lifecycle event`, err);
|
|
978
|
+
} finally {
|
|
979
|
+
resetWorkflow();
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
function startWorkflow(name, options) {
|
|
983
|
+
let logger = NOOP_LOGGER;
|
|
984
|
+
try {
|
|
985
|
+
const client = getClient();
|
|
986
|
+
if (!client || !client.isEnabled()) return { status: "disabled" };
|
|
987
|
+
logger = makeLogger(client.options.debug);
|
|
988
|
+
const normalized = normalizeWorkflowName(name);
|
|
989
|
+
if (!normalized) {
|
|
990
|
+
logger.warn("startWorkflow: invalid name", name);
|
|
991
|
+
return { status: "invalid_name" };
|
|
992
|
+
}
|
|
993
|
+
const active = getWorkflow();
|
|
994
|
+
if (active && !options?.force) {
|
|
995
|
+
logger.warn(
|
|
996
|
+
`startWorkflow("${normalized}"): "${active.name}" is already active; pass { force: true } to replace it`
|
|
997
|
+
);
|
|
998
|
+
return { status: "already_active" };
|
|
999
|
+
}
|
|
1000
|
+
const workflow = {
|
|
1001
|
+
workflowId: uuidv4(),
|
|
1002
|
+
name: normalized,
|
|
1003
|
+
startedAt: nowIso()
|
|
1004
|
+
};
|
|
1005
|
+
if (active) emitWorkflowClose(active, "$workflow_cancel", "superseded", logger);
|
|
1006
|
+
setWorkflowState(workflow);
|
|
1007
|
+
try {
|
|
1008
|
+
track("$workflow_start", { workflow_id: workflow.workflowId, workflow_name: workflow.name });
|
|
1009
|
+
} catch (err) {
|
|
1010
|
+
logger.warn("startWorkflow: failed to emit $workflow_start", err);
|
|
1011
|
+
}
|
|
1012
|
+
return { status: "ok", workflowId: workflow.workflowId };
|
|
1013
|
+
} catch (err) {
|
|
1014
|
+
logger.warn("startWorkflow failed", err);
|
|
1015
|
+
return { status: "disabled" };
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
function closeWorkflow(eventName, name, reason) {
|
|
1019
|
+
let logger = NOOP_LOGGER;
|
|
1020
|
+
try {
|
|
1021
|
+
const client = getClient();
|
|
1022
|
+
if (!client || !client.isEnabled()) return { status: "disabled" };
|
|
1023
|
+
logger = makeLogger(client.options.debug);
|
|
1024
|
+
const active = getWorkflow();
|
|
1025
|
+
if (!active) return { status: "not_active" };
|
|
1026
|
+
if (name !== void 0 && normalizeWorkflowName(name) !== active.name) {
|
|
1027
|
+
logger.warn(`${eventName}: "${name}" does not match active workflow "${active.name}"`);
|
|
1028
|
+
return { status: "name_mismatch" };
|
|
1029
|
+
}
|
|
1030
|
+
const workflowId = active.workflowId;
|
|
1031
|
+
emitWorkflowClose(active, eventName, reason, logger);
|
|
1032
|
+
return { status: "ok", workflowId };
|
|
1033
|
+
} catch (err) {
|
|
1034
|
+
logger.warn(`${eventName} failed`, err);
|
|
1035
|
+
return { status: "disabled" };
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function endWorkflow(name) {
|
|
1039
|
+
return closeWorkflow("$workflow_end", name);
|
|
1040
|
+
}
|
|
1041
|
+
function cancelWorkflow(name, options) {
|
|
1042
|
+
return closeWorkflow("$workflow_cancel", name, options?.reason);
|
|
1043
|
+
}
|
|
909
1044
|
|
|
910
1045
|
// src/integrations/performance.ts
|
|
911
1046
|
var PERF_FETCH = "__sauron_perf_fetch__";
|
|
@@ -1295,6 +1430,21 @@ var OfflineQueue = class {
|
|
|
1295
1430
|
if (entries.length) this.write([]);
|
|
1296
1431
|
return entries;
|
|
1297
1432
|
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Put drained payloads BACK at the head, keeping their relative order.
|
|
1435
|
+
*
|
|
1436
|
+
* The counterpart to {@link drain}: a drain empties the store immediately, so
|
|
1437
|
+
* whatever the caller could not deliver only exists in its local array and is
|
|
1438
|
+
* lost the moment the caller returns. Re-parking at the head (rather than via
|
|
1439
|
+
* {@link enqueue}) keeps the queue oldest-first, which is what the byte-cap
|
|
1440
|
+
* eviction policy assumes — the oldest entry must stay the first one evicted.
|
|
1441
|
+
*/
|
|
1442
|
+
requeueFront(payloads) {
|
|
1443
|
+
if (!this.storage || payloads.length === 0) return;
|
|
1444
|
+
const entries = [...payloads, ...this.read()];
|
|
1445
|
+
this.evict(entries);
|
|
1446
|
+
this.write(entries);
|
|
1447
|
+
}
|
|
1298
1448
|
/** Non-destructive read of the current entries, oldest first. */
|
|
1299
1449
|
peek() {
|
|
1300
1450
|
return this.read();
|
|
@@ -1358,6 +1508,9 @@ var Transport = class {
|
|
|
1358
1508
|
__publicField(this, "pending", []);
|
|
1359
1509
|
__publicField(this, "timer", null);
|
|
1360
1510
|
__publicField(this, "onlineHandler", null);
|
|
1511
|
+
/** Permanent auto-disable latch, flipped by this transport itself the moment
|
|
1512
|
+
* it classifies a response as 401/403 — it is the source of truth for
|
|
1513
|
+
* {@link isEnabled}, not merely a mirror of something the client decided. */
|
|
1361
1514
|
__publicField(this, "disabled", false);
|
|
1362
1515
|
this.dsn = config.dsn;
|
|
1363
1516
|
this.makeEnvelope = config.makeEnvelope;
|
|
@@ -1405,6 +1558,10 @@ var Transport = class {
|
|
|
1405
1558
|
this.pending = [];
|
|
1406
1559
|
this.stop();
|
|
1407
1560
|
}
|
|
1561
|
+
/** Whether the transport still accepts items (false once auth-disabled by a 401/403). */
|
|
1562
|
+
isEnabled() {
|
|
1563
|
+
return !this.disabled;
|
|
1564
|
+
}
|
|
1408
1565
|
/** Queue an item for the next batch; flush eagerly once the batch is full. */
|
|
1409
1566
|
send(item) {
|
|
1410
1567
|
if (this.disabled) return;
|
|
@@ -1447,6 +1604,7 @@ var Transport = class {
|
|
|
1447
1604
|
return;
|
|
1448
1605
|
case "disable":
|
|
1449
1606
|
this.logger.warn("server rejected credentials; disabling client");
|
|
1607
|
+
this.disable();
|
|
1450
1608
|
this.onDisable();
|
|
1451
1609
|
return;
|
|
1452
1610
|
case "split": {
|
|
@@ -1472,11 +1630,21 @@ var Transport = class {
|
|
|
1472
1630
|
}
|
|
1473
1631
|
}
|
|
1474
1632
|
}
|
|
1475
|
-
/**
|
|
1633
|
+
/**
|
|
1634
|
+
* Re-attempt any envelopes that were parked while offline.
|
|
1635
|
+
*
|
|
1636
|
+
* `drain()` empties `localStorage` in one shot, so from here on the ONLY copy
|
|
1637
|
+
* of the backlog is the local `payloads` array. Every early return therefore
|
|
1638
|
+
* has to re-park the whole untried remainder, not just the payload that
|
|
1639
|
+
* failed: this used to re-park the failing one and return, which silently
|
|
1640
|
+
* deleted every payload behind it — the exact reconnect-then-one-500 case the
|
|
1641
|
+
* queue exists for.
|
|
1642
|
+
*/
|
|
1476
1643
|
async drainOfflineQueue() {
|
|
1477
1644
|
if (this.disabled || !this.offline.available) return;
|
|
1478
1645
|
const payloads = this.offline.drain();
|
|
1479
|
-
for (
|
|
1646
|
+
for (let i = 0; i < payloads.length; i++) {
|
|
1647
|
+
const json = payloads[i];
|
|
1480
1648
|
let outcome;
|
|
1481
1649
|
try {
|
|
1482
1650
|
outcome = await this.post(json);
|
|
@@ -1484,12 +1652,14 @@ var Transport = class {
|
|
|
1484
1652
|
outcome = { action: "retry_backoff" };
|
|
1485
1653
|
}
|
|
1486
1654
|
if (outcome.action === "disable") {
|
|
1655
|
+
this.logger.warn("server rejected credentials while draining; disabling client");
|
|
1656
|
+
this.disable();
|
|
1487
1657
|
this.onDisable();
|
|
1488
|
-
this.offline.
|
|
1658
|
+
this.offline.requeueFront(payloads.slice(i));
|
|
1489
1659
|
return;
|
|
1490
1660
|
}
|
|
1491
1661
|
if (outcome.action === "retry_after" || outcome.action === "retry_backoff") {
|
|
1492
|
-
this.offline.
|
|
1662
|
+
this.offline.requeueFront(payloads.slice(i));
|
|
1493
1663
|
return;
|
|
1494
1664
|
}
|
|
1495
1665
|
}
|
|
@@ -1599,8 +1769,17 @@ var SauronClient = class {
|
|
|
1599
1769
|
__publicField(this, "nativeFetch");
|
|
1600
1770
|
__publicField(this, "enabled", true);
|
|
1601
1771
|
__publicField(this, "installed", false);
|
|
1602
|
-
__publicField(this, "anonymousId", null);
|
|
1603
1772
|
__publicField(this, "beaconCleanup", null);
|
|
1773
|
+
/**
|
|
1774
|
+
* Whether the anonymous id has actually been USED as a `distinct_id` in this
|
|
1775
|
+
* browser session.
|
|
1776
|
+
*
|
|
1777
|
+
* A persisted id that has never been observed anonymously must not create a
|
|
1778
|
+
* permanent `identities` alias row on the server: aliasing is a durable
|
|
1779
|
+
* server-side binding of this browser profile to a named user, and an
|
|
1780
|
+
* identify() on a first-ever page load has no anonymous history to link.
|
|
1781
|
+
*/
|
|
1782
|
+
__publicField(this, "anonUsed", false);
|
|
1604
1783
|
this.options = options;
|
|
1605
1784
|
this.dsn = parseDsn(options.dsn);
|
|
1606
1785
|
this.logger = makeLogger(options.debug);
|
|
@@ -1649,22 +1828,43 @@ var SauronClient = class {
|
|
|
1649
1828
|
getScope() {
|
|
1650
1829
|
return this.scope;
|
|
1651
1830
|
}
|
|
1831
|
+
/**
|
|
1832
|
+
* False once this client was explicitly disabled/closed, OR once the
|
|
1833
|
+
* transport has auto-disabled itself on a 401/403 (revoked/invalid DSN
|
|
1834
|
+
* key) — computed from the transport's own state on every call, not a
|
|
1835
|
+
* separately mirrored flag, so a propagation regression there cannot leave
|
|
1836
|
+
* this predicate stale. `this.transport` always exists once a client
|
|
1837
|
+
* exists (it is constructed synchronously in the constructor); the
|
|
1838
|
+
* "nothing installed yet" case is instead handled one layer up, by every
|
|
1839
|
+
* module-level API (`startWorkflow`, `track`, ...) treating `getClient() ===
|
|
1840
|
+
* null` as the no-op/disabled case before it ever reaches here.
|
|
1841
|
+
*/
|
|
1652
1842
|
isEnabled() {
|
|
1653
|
-
return this.enabled;
|
|
1843
|
+
return this.enabled && this.transport.isEnabled();
|
|
1654
1844
|
}
|
|
1655
1845
|
/** The current distinct id: the user id when identified, else an anon id. */
|
|
1656
1846
|
getDistinctId() {
|
|
1657
1847
|
const user = this.scope.getUser();
|
|
1658
1848
|
if (user.id) return user.id;
|
|
1659
|
-
|
|
1849
|
+
this.anonUsed = true;
|
|
1850
|
+
return getAnonymousId();
|
|
1660
1851
|
}
|
|
1661
|
-
/** The anonymous id, or null
|
|
1852
|
+
/** The anonymous id, or null when it was never actually used as an identity. */
|
|
1662
1853
|
getAnonymousId() {
|
|
1663
|
-
return this.
|
|
1854
|
+
return this.anonUsed ? getAnonymousId() : null;
|
|
1664
1855
|
}
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1856
|
+
/**
|
|
1857
|
+
* Forget the current person: clear the scope user and mint a fresh anonymous
|
|
1858
|
+
* id.
|
|
1859
|
+
*
|
|
1860
|
+
* MUST BE CALLED ON LOGOUT. Without it, the next anonymous visitor on this
|
|
1861
|
+
* browser reuses the persisted anon id, and a later identify() aliases their
|
|
1862
|
+
* activity to the previous account server-side, permanently.
|
|
1863
|
+
*/
|
|
1864
|
+
reset() {
|
|
1865
|
+
this.scope.setUser(null);
|
|
1866
|
+
resetAnonymousId();
|
|
1867
|
+
this.anonUsed = false;
|
|
1668
1868
|
}
|
|
1669
1869
|
/** Stamp a fresh envelope (new `sent_at`, current context) around `items`. */
|
|
1670
1870
|
makeEnvelope(items) {
|
|
@@ -1672,7 +1872,6 @@ var SauronClient = class {
|
|
|
1672
1872
|
dsn: this.dsn.raw,
|
|
1673
1873
|
sdk: { name: SDK_NAME, version: SDK_VERSION },
|
|
1674
1874
|
sent_at: nowIso(),
|
|
1675
|
-
environment: this.options.environment,
|
|
1676
1875
|
release: this.options.release
|
|
1677
1876
|
};
|
|
1678
1877
|
const context = buildContext(this.options.release, this.scope.getUser());
|
|
@@ -1718,6 +1917,39 @@ var SauronClient = class {
|
|
|
1718
1917
|
item.user = this.scope.getUser();
|
|
1719
1918
|
}
|
|
1720
1919
|
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Stamp the active workflow (if any) onto a signal item.
|
|
1922
|
+
*
|
|
1923
|
+
* Done HERE — the single choke point every capture path funnels through —
|
|
1924
|
+
* rather than at each item-construction site, so a capture path added later
|
|
1925
|
+
* is stamped by construction instead of by remembering to. The keys are
|
|
1926
|
+
* ASSIGNED ONLY when a workflow is active: an item with no workflow keeps
|
|
1927
|
+
* them absent entirely (not present-as-`undefined`), which is what makes
|
|
1928
|
+
* `JSON.stringify` omit them and keeps the no-workflow wire bytes identical
|
|
1929
|
+
* to pre-1.3.0.
|
|
1930
|
+
*
|
|
1931
|
+
* Only error/event/transaction carry `workflow_id`/`workflow_name` columns
|
|
1932
|
+
* server-side — identify and breadcrumb_batch items are deliberately left
|
|
1933
|
+
* alone. An item that already carries an explicit `workflow_id` is left
|
|
1934
|
+
* untouched, matching how `enrichErrorItem` defers to caller-set fields.
|
|
1935
|
+
*/
|
|
1936
|
+
stampWorkflow(item) {
|
|
1937
|
+
if (item.type !== "error" && item.type !== "event" && item.type !== "transaction") return;
|
|
1938
|
+
const hasId = item.workflow_id !== void 0;
|
|
1939
|
+
const hasName = item.workflow_name !== void 0;
|
|
1940
|
+
if (hasId || hasName) {
|
|
1941
|
+
if (hasId !== hasName) {
|
|
1942
|
+
this.logger.warn(
|
|
1943
|
+
"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."
|
|
1944
|
+
);
|
|
1945
|
+
}
|
|
1946
|
+
return;
|
|
1947
|
+
}
|
|
1948
|
+
const workflow = getWorkflow();
|
|
1949
|
+
if (!workflow) return;
|
|
1950
|
+
item.workflow_id = workflow.workflowId;
|
|
1951
|
+
item.workflow_name = workflow.name;
|
|
1952
|
+
}
|
|
1721
1953
|
/**
|
|
1722
1954
|
* Run an item through sampling (errors only) and `beforeSend`, then hand it to
|
|
1723
1955
|
* the transport. Returns silently when dropped.
|
|
@@ -1731,6 +1963,7 @@ var SauronClient = class {
|
|
|
1731
1963
|
}
|
|
1732
1964
|
this.enrichErrorItem(item, hint);
|
|
1733
1965
|
}
|
|
1966
|
+
this.stampWorkflow(item);
|
|
1734
1967
|
let processed = item;
|
|
1735
1968
|
if (this.options.beforeSend) {
|
|
1736
1969
|
try {
|
|
@@ -1767,6 +2000,7 @@ var SauronClient = class {
|
|
|
1767
2000
|
}
|
|
1768
2001
|
onNavigation(null);
|
|
1769
2002
|
resetScreen();
|
|
2003
|
+
resetWorkflow();
|
|
1770
2004
|
unpatchAll();
|
|
1771
2005
|
setDsnHost(null);
|
|
1772
2006
|
this.installed = false;
|
|
@@ -1789,7 +2023,6 @@ function resolveOptions(options) {
|
|
|
1789
2023
|
const t = options.transport ?? {};
|
|
1790
2024
|
return {
|
|
1791
2025
|
dsn: options.dsn,
|
|
1792
|
-
environment: options.environment ?? "production",
|
|
1793
2026
|
release: options.release ?? null,
|
|
1794
2027
|
sampleRate: clamp(options.sampleRate ?? 1, 0, 1),
|
|
1795
2028
|
maxBreadcrumbs: options.maxBreadcrumbs ?? 50,
|
|
@@ -1874,12 +2107,31 @@ function setScreen2(name) {
|
|
|
1874
2107
|
function getScreen2() {
|
|
1875
2108
|
return getScreen();
|
|
1876
2109
|
}
|
|
2110
|
+
function startWorkflow2(name, options) {
|
|
2111
|
+
return startWorkflow(name, options);
|
|
2112
|
+
}
|
|
2113
|
+
function endWorkflow2(name) {
|
|
2114
|
+
return endWorkflow(name);
|
|
2115
|
+
}
|
|
2116
|
+
function cancelWorkflow2(name, options) {
|
|
2117
|
+
return cancelWorkflow(name, options);
|
|
2118
|
+
}
|
|
2119
|
+
function getWorkflow2() {
|
|
2120
|
+
return getWorkflow();
|
|
2121
|
+
}
|
|
1877
2122
|
function addBreadcrumb2(breadcrumb, hint) {
|
|
1878
2123
|
addBreadcrumb(breadcrumb, hint);
|
|
1879
2124
|
}
|
|
1880
2125
|
function setUser(user) {
|
|
2126
|
+
if (user === null) {
|
|
2127
|
+
getClient()?.reset();
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
1881
2130
|
getClient()?.getScope().setUser(user);
|
|
1882
2131
|
}
|
|
2132
|
+
function reset() {
|
|
2133
|
+
getClient()?.reset();
|
|
2134
|
+
}
|
|
1883
2135
|
function setTag(key, value) {
|
|
1884
2136
|
getClient()?.getScope().setTag(key, value);
|
|
1885
2137
|
}
|
|
@@ -1909,12 +2161,17 @@ var Sauron = {
|
|
|
1909
2161
|
identify: identify2,
|
|
1910
2162
|
addBreadcrumb: addBreadcrumb2,
|
|
1911
2163
|
setUser,
|
|
2164
|
+
reset,
|
|
1912
2165
|
setTag,
|
|
1913
2166
|
setTags,
|
|
1914
2167
|
setContext,
|
|
1915
2168
|
setExtra,
|
|
1916
2169
|
setScreen: setScreen2,
|
|
1917
2170
|
getScreen: getScreen2,
|
|
2171
|
+
startWorkflow: startWorkflow2,
|
|
2172
|
+
endWorkflow: endWorkflow2,
|
|
2173
|
+
cancelWorkflow: cancelWorkflow2,
|
|
2174
|
+
getWorkflow: getWorkflow2,
|
|
1918
2175
|
flush,
|
|
1919
2176
|
close,
|
|
1920
2177
|
getClient
|
|
@@ -1928,25 +2185,30 @@ exports.Sauron = Sauron;
|
|
|
1928
2185
|
exports.SauronClient = SauronClient;
|
|
1929
2186
|
exports.addBreadcrumb = addBreadcrumb2;
|
|
1930
2187
|
exports.buildEnvelope = buildEnvelope;
|
|
2188
|
+
exports.cancelWorkflow = cancelWorkflow2;
|
|
1931
2189
|
exports.captureException = captureException2;
|
|
1932
2190
|
exports.captureMessage = captureMessage2;
|
|
1933
2191
|
exports.close = close;
|
|
1934
2192
|
exports.default = index_default;
|
|
2193
|
+
exports.endWorkflow = endWorkflow2;
|
|
1935
2194
|
exports.flush = flush;
|
|
1936
2195
|
exports.getClient = getClient;
|
|
1937
2196
|
exports.getScreen = getScreen2;
|
|
2197
|
+
exports.getWorkflow = getWorkflow2;
|
|
1938
2198
|
exports.identify = identify2;
|
|
1939
2199
|
exports.init = init2;
|
|
1940
2200
|
exports.isInAppFrame = isInAppFrame;
|
|
1941
2201
|
exports.parseDsn = parseDsn;
|
|
1942
2202
|
exports.parseError = parseError;
|
|
1943
2203
|
exports.parseStackString = parseStackString;
|
|
2204
|
+
exports.reset = reset;
|
|
1944
2205
|
exports.setContext = setContext;
|
|
1945
2206
|
exports.setExtra = setExtra;
|
|
1946
2207
|
exports.setScreen = setScreen2;
|
|
1947
2208
|
exports.setTag = setTag;
|
|
1948
2209
|
exports.setTags = setTags;
|
|
1949
2210
|
exports.setUser = setUser;
|
|
2211
|
+
exports.startWorkflow = startWorkflow2;
|
|
1950
2212
|
exports.track = track2;
|
|
1951
2213
|
exports.trackTransaction = trackTransaction2;
|
|
1952
2214
|
//# sourceMappingURL=index.cjs.map
|