@koderlabs/tasks-sdk-web-errors 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.
- package/LICENSE +179 -0
- package/README.md +9 -0
- package/dist/index.cjs +414 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +75 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.js +380 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE — ALL RIGHTS RESERVED
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 KoderLabs. All rights reserved.
|
|
4
|
+
Author: Jawaid Gadiwala <jawaidgadiwala@gmail.com>
|
|
5
|
+
|
|
6
|
+
================================================================================
|
|
7
|
+
1. NO LICENSE GRANTED BY DEFAULT
|
|
8
|
+
================================================================================
|
|
9
|
+
|
|
10
|
+
This software, including all source code, object code, documentation,
|
|
11
|
+
configuration files, build artifacts, test fixtures, and any associated
|
|
12
|
+
materials (collectively, the "Software"), is the proprietary and confidential
|
|
13
|
+
property of KoderLabs.
|
|
14
|
+
|
|
15
|
+
NO license, right, title, interest, or permission of any kind — express,
|
|
16
|
+
implied, statutory, by estoppel, by exhaustion, by patent exhaustion, or by
|
|
17
|
+
any other legal theory — is granted to any person or entity by:
|
|
18
|
+
|
|
19
|
+
(a) viewing the Software on any registry, repository, mirror, CDN,
|
|
20
|
+
cache, or other distribution channel (including but not limited to
|
|
21
|
+
npmjs.com, GitHub, GitLab, or any private registry);
|
|
22
|
+
(b) downloading, cloning, or otherwise obtaining a copy of the Software;
|
|
23
|
+
(c) the act of the Software being technically accessible due to a registry
|
|
24
|
+
requirement, mirror, or third-party distribution;
|
|
25
|
+
(d) any prior course of dealing, custom, or industry practice.
|
|
26
|
+
|
|
27
|
+
The ability to access the Software does NOT imply any permission to use it.
|
|
28
|
+
A separate, signed, written license agreement executed by an authorised
|
|
29
|
+
representative of KoderLabs is the ONLY mechanism by which any rights may be
|
|
30
|
+
granted.
|
|
31
|
+
|
|
32
|
+
================================================================================
|
|
33
|
+
2. PROHIBITED ACTIVITIES (NON-EXHAUSTIVE)
|
|
34
|
+
================================================================================
|
|
35
|
+
|
|
36
|
+
Without prior signed written permission from KoderLabs, the following are
|
|
37
|
+
expressly PROHIBITED and constitute infringement, breach of contract, and
|
|
38
|
+
unauthorised use:
|
|
39
|
+
|
|
40
|
+
(a) Copying the Software in whole or in part, in any medium;
|
|
41
|
+
(b) Modifying, adapting, translating, porting, or creating derivative works
|
|
42
|
+
of the Software;
|
|
43
|
+
(c) Distributing, republishing, mirroring, hosting, transmitting,
|
|
44
|
+
sublicensing, leasing, lending, renting, selling, offering for sale,
|
|
45
|
+
bartering, gifting, or otherwise transferring the Software or any
|
|
46
|
+
portion of it;
|
|
47
|
+
(d) Forking the Software's repository, whether on GitHub, GitLab, Bitbucket,
|
|
48
|
+
Codeberg, Sourcehut, or any other version-control hosting service;
|
|
49
|
+
(e) Reverse engineering, decompiling, disassembling, deobfuscating,
|
|
50
|
+
extracting source from compiled or minified artifacts, or attempting to
|
|
51
|
+
derive the source code, algorithms, or trade secrets;
|
|
52
|
+
(f) Removing, altering, or obscuring any copyright, trademark, license,
|
|
53
|
+
attribution, or proprietary notice;
|
|
54
|
+
(g) Using the Software, in whole or in part, to train, fine-tune,
|
|
55
|
+
evaluate, or benchmark any machine-learning model, embedding model, or
|
|
56
|
+
AI system;
|
|
57
|
+
(h) Using the Software to provide a hosted service, SaaS offering,
|
|
58
|
+
managed offering, or any form of public or commercial offering;
|
|
59
|
+
(i) Using the Software in any production, staging, development, evaluation,
|
|
60
|
+
or testing capacity, whether commercial or non-commercial;
|
|
61
|
+
(j) Bypassing, disabling, or attempting to circumvent any technical
|
|
62
|
+
protection measure (license check, telemetry, signature verification,
|
|
63
|
+
etc.) embedded in the Software;
|
|
64
|
+
(k) Combining or integrating the Software with any work licensed under a
|
|
65
|
+
copyleft licence (including but not limited to GPL, AGPL, LGPL, MPL,
|
|
66
|
+
EPL) in a manner that would purport to relicense the Software;
|
|
67
|
+
(l) Filing, prosecuting, or threatening patent litigation against KoderLabs
|
|
68
|
+
or its customers based on any feature, design, or behaviour of the
|
|
69
|
+
Software ("defensive termination" — any such action automatically and
|
|
70
|
+
immediately terminates any rights granted to the litigant elsewhere).
|
|
71
|
+
|
|
72
|
+
================================================================================
|
|
73
|
+
3. NO IMPLIED RIGHT TO INTERNAL USE
|
|
74
|
+
================================================================================
|
|
75
|
+
|
|
76
|
+
The Software is NOT licensed for internal evaluation, internal production,
|
|
77
|
+
internal testing, or any other internal use unless and until a separate
|
|
78
|
+
written commercial licence is executed. Possession of a copy of the Software,
|
|
79
|
+
by whatever means, confers no right to execute, run, deploy, or use it.
|
|
80
|
+
|
|
81
|
+
================================================================================
|
|
82
|
+
4. NO PATENT, TRADEMARK, OR OTHER IP GRANT
|
|
83
|
+
================================================================================
|
|
84
|
+
|
|
85
|
+
No patent licence, trademark licence, trade-secret disclosure, design-right
|
|
86
|
+
licence, or any other intellectual-property licence is granted under this
|
|
87
|
+
notice. KoderLabs retains all such rights.
|
|
88
|
+
|
|
89
|
+
================================================================================
|
|
90
|
+
5. CONFIDENTIALITY
|
|
91
|
+
================================================================================
|
|
92
|
+
|
|
93
|
+
The Software contains trade secrets and confidential information of
|
|
94
|
+
KoderLabs. Any party in possession of the Software shall (a) treat it as
|
|
95
|
+
confidential, (b) take reasonable measures to prevent unauthorised access or
|
|
96
|
+
disclosure, and (c) not disclose, publish, or make available the Software or
|
|
97
|
+
any portion thereof to any third party.
|
|
98
|
+
|
|
99
|
+
================================================================================
|
|
100
|
+
6. AUTOMATIC TERMINATION
|
|
101
|
+
================================================================================
|
|
102
|
+
|
|
103
|
+
Any rights that may exist under a separate written agreement terminate
|
|
104
|
+
AUTOMATICALLY AND IMMEDIATELY upon any breach of this notice, without notice
|
|
105
|
+
and without judicial action. Upon termination, the breaching party shall
|
|
106
|
+
immediately destroy all copies of the Software in its possession or control
|
|
107
|
+
and certify destruction in writing to KoderLabs.
|
|
108
|
+
|
|
109
|
+
================================================================================
|
|
110
|
+
7. NO WARRANTY
|
|
111
|
+
================================================================================
|
|
112
|
+
|
|
113
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
114
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
115
|
+
FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ACCURACY, RELIABILITY,
|
|
116
|
+
TITLE, AVAILABILITY, OR THAT THE SOFTWARE WILL OPERATE UNINTERRUPTED OR
|
|
117
|
+
ERROR-FREE.
|
|
118
|
+
|
|
119
|
+
================================================================================
|
|
120
|
+
8. NO LIABILITY
|
|
121
|
+
================================================================================
|
|
122
|
+
|
|
123
|
+
IN NO EVENT SHALL KODERLABS OR ITS AFFILIATES, OFFICERS, EMPLOYEES, AGENTS,
|
|
124
|
+
LICENSORS, OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
125
|
+
LIABILITY (INCLUDING DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
126
|
+
CONSEQUENTIAL, PUNITIVE, LOST PROFITS, LOST DATA, OR BUSINESS INTERRUPTION),
|
|
127
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT
|
|
128
|
+
LIABILITY, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE
|
|
129
|
+
SOFTWARE OR THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF ADVISED OF
|
|
130
|
+
THE POSSIBILITY OF SUCH DAMAGE. IN NO EVENT SHALL KODERLABS' TOTAL CUMULATIVE
|
|
131
|
+
LIABILITY EXCEED ONE U.S. DOLLAR (USD 1.00).
|
|
132
|
+
|
|
133
|
+
================================================================================
|
|
134
|
+
9. EQUITABLE RELIEF
|
|
135
|
+
================================================================================
|
|
136
|
+
|
|
137
|
+
The parties acknowledge that any breach of this notice would cause
|
|
138
|
+
irreparable harm to KoderLabs for which monetary damages would be inadequate.
|
|
139
|
+
KoderLabs is therefore entitled, in addition to all other remedies available
|
|
140
|
+
at law, to specific performance and injunctive relief without the need to
|
|
141
|
+
post bond.
|
|
142
|
+
|
|
143
|
+
================================================================================
|
|
144
|
+
10. GOVERNING LAW AND VENUE
|
|
145
|
+
================================================================================
|
|
146
|
+
|
|
147
|
+
This notice shall be governed by and construed in accordance with the laws
|
|
148
|
+
of the Islamic Republic of Pakistan, without regard to its conflict-of-laws
|
|
149
|
+
principles. Any dispute arising out of or in connection with this notice
|
|
150
|
+
shall be subject to the exclusive jurisdiction of the courts of Karachi,
|
|
151
|
+
Pakistan.
|
|
152
|
+
|
|
153
|
+
The United Nations Convention on Contracts for the International Sale of
|
|
154
|
+
Goods shall not apply.
|
|
155
|
+
|
|
156
|
+
================================================================================
|
|
157
|
+
11. SEVERABILITY AND ENTIRE NOTICE
|
|
158
|
+
================================================================================
|
|
159
|
+
|
|
160
|
+
If any provision of this notice is held invalid or unenforceable, the
|
|
161
|
+
remaining provisions shall continue in full force and effect. This notice,
|
|
162
|
+
together with any separate signed written licence executed between KoderLabs
|
|
163
|
+
and a licensee, constitutes the entire agreement concerning the Software and
|
|
164
|
+
supersedes all prior or contemporaneous understandings.
|
|
165
|
+
|
|
166
|
+
================================================================================
|
|
167
|
+
12. CONTACT
|
|
168
|
+
================================================================================
|
|
169
|
+
|
|
170
|
+
For licensing inquiries, audit requests, or notice of suspected
|
|
171
|
+
infringement, contact:
|
|
172
|
+
|
|
173
|
+
KoderLabs
|
|
174
|
+
Attn: Jawaid Gadiwala
|
|
175
|
+
Email: jawaidgadiwala@gmail.com
|
|
176
|
+
|
|
177
|
+
================================================================================
|
|
178
|
+
END OF LICENCE
|
|
179
|
+
================================================================================
|
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Proprietary Software
|
|
2
|
+
|
|
3
|
+
KoderLabs proprietary. All rights reserved.
|
|
4
|
+
|
|
5
|
+
See the bundled `LICENSE` for terms. No grant of any rights, express or
|
|
6
|
+
implied, is conferred by access to or possession of this package. A
|
|
7
|
+
separate signed written licence from KoderLabs is required for any use.
|
|
8
|
+
|
|
9
|
+
Licensing inquiries: jawaidgadiwala@gmail.com
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
BreadcrumbRing: () => BreadcrumbRing,
|
|
25
|
+
_registerNetworkRing: () => _registerNetworkRing,
|
|
26
|
+
addFeatureFlag: () => addFeatureFlag,
|
|
27
|
+
clearFeatureFlag: () => clearFeatureFlag,
|
|
28
|
+
errorsIntegration: () => errorsIntegration,
|
|
29
|
+
leaveBreadcrumb: () => leaveBreadcrumb,
|
|
30
|
+
notify: () => notify,
|
|
31
|
+
parseStack: () => parseStack,
|
|
32
|
+
setContext: () => setContext,
|
|
33
|
+
setUser: () => setUser
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/breadcrumbs.ts
|
|
38
|
+
var BreadcrumbRing = class {
|
|
39
|
+
static {
|
|
40
|
+
__name(this, "BreadcrumbRing");
|
|
41
|
+
}
|
|
42
|
+
buf = [];
|
|
43
|
+
max;
|
|
44
|
+
constructor(max = 50) {
|
|
45
|
+
this.max = max;
|
|
46
|
+
}
|
|
47
|
+
add(message, level = "info", category = "custom", data) {
|
|
48
|
+
const crumb = {
|
|
49
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
50
|
+
level,
|
|
51
|
+
category,
|
|
52
|
+
message,
|
|
53
|
+
data
|
|
54
|
+
};
|
|
55
|
+
this.buf.push(crumb);
|
|
56
|
+
if (this.buf.length > this.max) {
|
|
57
|
+
this.buf.shift();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
getAll() {
|
|
61
|
+
return [
|
|
62
|
+
...this.buf
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
clear() {
|
|
66
|
+
this.buf.length = 0;
|
|
67
|
+
}
|
|
68
|
+
size() {
|
|
69
|
+
return this.buf.length;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// src/enrich.ts
|
|
74
|
+
function enrich(event, opts) {
|
|
75
|
+
const enriched = {
|
|
76
|
+
...event
|
|
77
|
+
};
|
|
78
|
+
if (opts.release) enriched.release = opts.release;
|
|
79
|
+
if (opts.environment) enriched.environment = opts.environment;
|
|
80
|
+
if (opts.user) enriched.user = opts.user;
|
|
81
|
+
if (opts.breadcrumbs?.length) enriched.breadcrumbs = opts.breadcrumbs;
|
|
82
|
+
if (opts.featureFlags?.length) enriched.featureFlags = opts.featureFlags;
|
|
83
|
+
if (opts.networkRing?.length) enriched.networkRing = opts.networkRing;
|
|
84
|
+
if (opts.contexts) enriched.contexts = {
|
|
85
|
+
...enriched.contexts,
|
|
86
|
+
...opts.contexts
|
|
87
|
+
};
|
|
88
|
+
return enriched;
|
|
89
|
+
}
|
|
90
|
+
__name(enrich, "enrich");
|
|
91
|
+
|
|
92
|
+
// src/stacktrace.ts
|
|
93
|
+
function parseStack(err) {
|
|
94
|
+
const stack = typeof err === "string" ? err : err.stack ?? "";
|
|
95
|
+
const lines = stack.split("\n");
|
|
96
|
+
const frames = [];
|
|
97
|
+
for (const raw of lines) {
|
|
98
|
+
const line = raw.trim();
|
|
99
|
+
if (!line || line.startsWith("Error:") || line.startsWith("TypeError:")) continue;
|
|
100
|
+
const frame = parseV8Line(line) ?? parseFirefoxLine(line);
|
|
101
|
+
if (frame) frames.push(frame);
|
|
102
|
+
}
|
|
103
|
+
return frames;
|
|
104
|
+
}
|
|
105
|
+
__name(parseStack, "parseStack");
|
|
106
|
+
function parseV8Line(line) {
|
|
107
|
+
const atPart = line.startsWith("at ") ? line : null;
|
|
108
|
+
if (!atPart) return null;
|
|
109
|
+
const content = atPart.slice(3).trim();
|
|
110
|
+
const withFnMatch = content.match(/^(.+?)\s+\((.+?):(\d+):(\d+)\)$/);
|
|
111
|
+
if (withFnMatch) {
|
|
112
|
+
const [, fn, filename, lineno, colno] = withFnMatch;
|
|
113
|
+
return makeFrame(fn.trim(), filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));
|
|
114
|
+
}
|
|
115
|
+
const noFnMatch = content.match(/^(.+?):(\d+):(\d+)$/);
|
|
116
|
+
if (noFnMatch) {
|
|
117
|
+
const [, filename, lineno, colno] = noFnMatch;
|
|
118
|
+
return makeFrame(null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));
|
|
119
|
+
}
|
|
120
|
+
if (content.startsWith("<") || content === "eval" || content === "anonymous") {
|
|
121
|
+
return makeFrame(content, "<anonymous>", null, null);
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
__name(parseV8Line, "parseV8Line");
|
|
126
|
+
function parseFirefoxLine(line) {
|
|
127
|
+
const match = line.match(/^(.*)@(.*):(\d+):(\d+)$/);
|
|
128
|
+
if (!match) return null;
|
|
129
|
+
const [, fn, filename, lineno, colno] = match;
|
|
130
|
+
return makeFrame(fn.trim() || null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));
|
|
131
|
+
}
|
|
132
|
+
__name(parseFirefoxLine, "parseFirefoxLine");
|
|
133
|
+
function makeFrame(fn, filename, lineno, colno) {
|
|
134
|
+
return {
|
|
135
|
+
filename: filename || null,
|
|
136
|
+
function: fn || null,
|
|
137
|
+
lineno,
|
|
138
|
+
colno,
|
|
139
|
+
in_app: isInApp(filename)
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
__name(makeFrame, "makeFrame");
|
|
143
|
+
function isInApp(filename) {
|
|
144
|
+
if (!filename) return false;
|
|
145
|
+
if (filename === "<anonymous>" || filename === "?" || filename.startsWith("<")) return false;
|
|
146
|
+
if (filename.includes("[native code]")) return false;
|
|
147
|
+
if (filename.includes("node_modules") || filename.includes("/vendor/")) return false;
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
__name(isInApp, "isInApp");
|
|
151
|
+
|
|
152
|
+
// src/handlers/onerror.ts
|
|
153
|
+
function installOnError(notify2) {
|
|
154
|
+
const prev = window.onerror;
|
|
155
|
+
window.onerror = function(message, source, lineno, colno, error) {
|
|
156
|
+
let frames = [];
|
|
157
|
+
let type = "Error";
|
|
158
|
+
let value = String(message);
|
|
159
|
+
if (error) {
|
|
160
|
+
frames = parseStack(error);
|
|
161
|
+
type = error.constructor?.name ?? "Error";
|
|
162
|
+
value = error.message || value;
|
|
163
|
+
} else if (source) {
|
|
164
|
+
frames = [
|
|
165
|
+
{
|
|
166
|
+
filename: source,
|
|
167
|
+
function: null,
|
|
168
|
+
lineno: lineno ?? null,
|
|
169
|
+
colno: colno ?? null,
|
|
170
|
+
in_app: true
|
|
171
|
+
}
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
notify2({
|
|
175
|
+
kind: "error",
|
|
176
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
177
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
178
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
179
|
+
viewport: typeof window !== "undefined" ? {
|
|
180
|
+
width: window.innerWidth,
|
|
181
|
+
height: window.innerHeight
|
|
182
|
+
} : {
|
|
183
|
+
width: 0,
|
|
184
|
+
height: 0
|
|
185
|
+
},
|
|
186
|
+
level: "error",
|
|
187
|
+
exception: {
|
|
188
|
+
type,
|
|
189
|
+
value,
|
|
190
|
+
stacktrace: {
|
|
191
|
+
frames
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
if (typeof prev === "function") {
|
|
196
|
+
return prev(message, source, lineno, colno, error);
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
};
|
|
200
|
+
return () => {
|
|
201
|
+
window.onerror = prev;
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
__name(installOnError, "installOnError");
|
|
205
|
+
|
|
206
|
+
// src/handlers/unhandledrejection.ts
|
|
207
|
+
function installUnhandledRejection(notify2) {
|
|
208
|
+
const handler = /* @__PURE__ */ __name((ev) => {
|
|
209
|
+
const reason = ev.reason;
|
|
210
|
+
let type = "UnhandledRejection";
|
|
211
|
+
let value = String(reason);
|
|
212
|
+
let frames = [];
|
|
213
|
+
if (reason instanceof Error) {
|
|
214
|
+
type = reason.constructor?.name ?? "Error";
|
|
215
|
+
value = reason.message;
|
|
216
|
+
frames = parseStack(reason);
|
|
217
|
+
} else if (reason !== null && reason !== void 0) {
|
|
218
|
+
value = typeof reason === "object" ? JSON.stringify(reason) : String(reason);
|
|
219
|
+
}
|
|
220
|
+
notify2({
|
|
221
|
+
kind: "error",
|
|
222
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
223
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
224
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
225
|
+
viewport: typeof window !== "undefined" ? {
|
|
226
|
+
width: window.innerWidth,
|
|
227
|
+
height: window.innerHeight
|
|
228
|
+
} : {
|
|
229
|
+
width: 0,
|
|
230
|
+
height: 0
|
|
231
|
+
},
|
|
232
|
+
level: "error",
|
|
233
|
+
exception: {
|
|
234
|
+
type,
|
|
235
|
+
value,
|
|
236
|
+
stacktrace: {
|
|
237
|
+
frames
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}, "handler");
|
|
242
|
+
window.addEventListener("unhandledrejection", handler);
|
|
243
|
+
return () => window.removeEventListener("unhandledrejection", handler);
|
|
244
|
+
}
|
|
245
|
+
__name(installUnhandledRejection, "installUnhandledRejection");
|
|
246
|
+
|
|
247
|
+
// src/handlers/console.ts
|
|
248
|
+
var CAPTURED_METHODS = [
|
|
249
|
+
"error",
|
|
250
|
+
"warn"
|
|
251
|
+
];
|
|
252
|
+
function installConsoleCapture(notify2, leaveBreadcrumb2) {
|
|
253
|
+
const originals = {};
|
|
254
|
+
for (const method of CAPTURED_METHODS) {
|
|
255
|
+
originals[method] = console[method].bind(console);
|
|
256
|
+
console[method] = (...args) => {
|
|
257
|
+
originals[method](...args);
|
|
258
|
+
const message = args.map((a) => a instanceof Error ? a.message : typeof a === "object" ? JSON.stringify(a) : String(a)).join(" ");
|
|
259
|
+
const level = method === "error" ? "error" : "warning";
|
|
260
|
+
leaveBreadcrumb2(message, level, "console");
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return () => {
|
|
264
|
+
for (const method of CAPTURED_METHODS) {
|
|
265
|
+
console[method] = originals[method];
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
__name(installConsoleCapture, "installConsoleCapture");
|
|
270
|
+
|
|
271
|
+
// src/index.ts
|
|
272
|
+
var _ring = null;
|
|
273
|
+
var _user = null;
|
|
274
|
+
var _featureFlags = [];
|
|
275
|
+
var _contexts = {};
|
|
276
|
+
var _client = null;
|
|
277
|
+
var _opts = null;
|
|
278
|
+
var _networkRingRef = null;
|
|
279
|
+
function notify(err, extra) {
|
|
280
|
+
if (!_client || !_ring || !_opts) return;
|
|
281
|
+
const error = typeof err === "string" ? new Error(err) : err;
|
|
282
|
+
const frames = parseStack(error);
|
|
283
|
+
const event = {
|
|
284
|
+
kind: "error",
|
|
285
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
286
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
287
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
288
|
+
viewport: typeof window !== "undefined" ? {
|
|
289
|
+
width: window.innerWidth,
|
|
290
|
+
height: window.innerHeight
|
|
291
|
+
} : {
|
|
292
|
+
width: 0,
|
|
293
|
+
height: 0
|
|
294
|
+
},
|
|
295
|
+
level: extra?.level ?? "error",
|
|
296
|
+
exception: {
|
|
297
|
+
type: error.constructor?.name ?? "Error",
|
|
298
|
+
value: error.message,
|
|
299
|
+
stacktrace: {
|
|
300
|
+
frames
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
_sendEvent(event);
|
|
305
|
+
}
|
|
306
|
+
__name(notify, "notify");
|
|
307
|
+
function leaveBreadcrumb(message, level = "info", category = "custom", data) {
|
|
308
|
+
_ring?.add(message, level, category, data);
|
|
309
|
+
}
|
|
310
|
+
__name(leaveBreadcrumb, "leaveBreadcrumb");
|
|
311
|
+
function setUser(user) {
|
|
312
|
+
_user = user;
|
|
313
|
+
}
|
|
314
|
+
__name(setUser, "setUser");
|
|
315
|
+
function addFeatureFlag(name, variant) {
|
|
316
|
+
const existing = _featureFlags.findIndex((f) => f.name === name);
|
|
317
|
+
if (existing >= 0) {
|
|
318
|
+
_featureFlags[existing] = {
|
|
319
|
+
name,
|
|
320
|
+
variant
|
|
321
|
+
};
|
|
322
|
+
} else {
|
|
323
|
+
_featureFlags.push({
|
|
324
|
+
name,
|
|
325
|
+
variant
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
__name(addFeatureFlag, "addFeatureFlag");
|
|
330
|
+
function clearFeatureFlag(name) {
|
|
331
|
+
_featureFlags = _featureFlags.filter((f) => f.name !== name);
|
|
332
|
+
}
|
|
333
|
+
__name(clearFeatureFlag, "clearFeatureFlag");
|
|
334
|
+
function setContext(key, value) {
|
|
335
|
+
if (value === null) {
|
|
336
|
+
delete _contexts[key];
|
|
337
|
+
} else {
|
|
338
|
+
_contexts[key] = value;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
__name(setContext, "setContext");
|
|
342
|
+
function _registerNetworkRing(fn) {
|
|
343
|
+
_networkRingRef = fn;
|
|
344
|
+
}
|
|
345
|
+
__name(_registerNetworkRing, "_registerNetworkRing");
|
|
346
|
+
function _sendEvent(event) {
|
|
347
|
+
if (!_client || !_ring || !_opts) return;
|
|
348
|
+
const enriched = enrich(event, {
|
|
349
|
+
release: _client.options.release,
|
|
350
|
+
environment: _client.options.environment,
|
|
351
|
+
user: _user ?? _client.options.user,
|
|
352
|
+
breadcrumbs: _ring.getAll(),
|
|
353
|
+
featureFlags: _featureFlags,
|
|
354
|
+
networkRing: _networkRingRef ? _networkRingRef() : [],
|
|
355
|
+
contexts: Object.keys(_contexts).length ? _contexts : void 0
|
|
356
|
+
});
|
|
357
|
+
const final = _opts.beforeSend ? _opts.beforeSend(enriched) : enriched;
|
|
358
|
+
if (!final) return;
|
|
359
|
+
_client.send(final).catch(() => {
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
__name(_sendEvent, "_sendEvent");
|
|
363
|
+
function errorsIntegration(opts = {}) {
|
|
364
|
+
const teardowns = [];
|
|
365
|
+
return {
|
|
366
|
+
name: "errors",
|
|
367
|
+
setup(client) {
|
|
368
|
+
_client = client;
|
|
369
|
+
_opts = {
|
|
370
|
+
captureGlobalErrors: opts.captureGlobalErrors ?? true,
|
|
371
|
+
captureUnhandledRejections: opts.captureUnhandledRejections ?? true,
|
|
372
|
+
captureConsole: opts.captureConsole ?? false,
|
|
373
|
+
maxBreadcrumbs: opts.maxBreadcrumbs ?? 50,
|
|
374
|
+
beforeSend: opts.beforeSend ?? null
|
|
375
|
+
};
|
|
376
|
+
_ring = new BreadcrumbRing(_opts.maxBreadcrumbs);
|
|
377
|
+
if (_opts.captureGlobalErrors) {
|
|
378
|
+
teardowns.push(installOnError(_sendEvent));
|
|
379
|
+
}
|
|
380
|
+
if (_opts.captureUnhandledRejections) {
|
|
381
|
+
teardowns.push(installUnhandledRejection(_sendEvent));
|
|
382
|
+
}
|
|
383
|
+
if (_opts.captureConsole) {
|
|
384
|
+
teardowns.push(installConsoleCapture(_sendEvent, (msg, level, cat) => _ring.add(msg, level, cat)));
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
teardown() {
|
|
388
|
+
for (const fn of teardowns) fn();
|
|
389
|
+
teardowns.length = 0;
|
|
390
|
+
_ring = null;
|
|
391
|
+
_client = null;
|
|
392
|
+
_opts = null;
|
|
393
|
+
_user = null;
|
|
394
|
+
_featureFlags = [];
|
|
395
|
+
_contexts = {};
|
|
396
|
+
_networkRingRef = null;
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
__name(errorsIntegration, "errorsIntegration");
|
|
401
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
402
|
+
0 && (module.exports = {
|
|
403
|
+
BreadcrumbRing,
|
|
404
|
+
_registerNetworkRing,
|
|
405
|
+
addFeatureFlag,
|
|
406
|
+
clearFeatureFlag,
|
|
407
|
+
errorsIntegration,
|
|
408
|
+
leaveBreadcrumb,
|
|
409
|
+
notify,
|
|
410
|
+
parseStack,
|
|
411
|
+
setContext,
|
|
412
|
+
setUser
|
|
413
|
+
});
|
|
414
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/breadcrumbs.ts","../src/enrich.ts","../src/stacktrace.ts","../src/handlers/onerror.ts","../src/handlers/unhandledrejection.ts","../src/handlers/console.ts"],"sourcesContent":["import type { ClientInterface, Integration } from '@koderlabs/tasks-sdk';\nimport type {\n BreadcrumbCategory,\n BreadcrumbLevel,\n ErrorEvent,\n ErrorsIntegrationOptions,\n FeatureFlag,\n SdkUser,\n} from './types';\nimport { BreadcrumbRing } from './breadcrumbs';\nimport { enrich } from './enrich';\nimport { installOnError } from './handlers/onerror';\nimport { installUnhandledRejection } from './handlers/unhandledrejection';\nimport { installConsoleCapture } from './handlers/console';\nimport { parseStack } from './stacktrace';\n\nexport type { ErrorEvent, ErrorsIntegrationOptions, SdkUser, FeatureFlag } from './types';\nexport type { ErrorsApi } from './api';\nexport { BreadcrumbRing } from './breadcrumbs';\nexport { parseStack } from './stacktrace';\n\n/** Shared state exposed as module-level singletons so app code can call\n * leaveBreadcrumb(), setUser(), etc. without holding a ref to the integration. */\nlet _ring: BreadcrumbRing | null = null;\nlet _user: SdkUser | null = null;\nlet _featureFlags: FeatureFlag[] = [];\nlet _contexts: Record<string, Record<string, unknown>> = {};\nlet _client: ClientInterface | null = null;\nlet _opts: Required<ErrorsIntegrationOptions> | null = null;\nlet _networkRingRef: (() => unknown[]) | null = null;\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\n/** Manually capture an error. */\nexport function notify(\n err: Error | string,\n extra?: { level?: 'error' | 'warning' | 'info' },\n): void {\n if (!_client || !_ring || !_opts) return;\n const error = typeof err === 'string' ? new Error(err) : err;\n const frames = parseStack(error);\n const event: ErrorEvent = {\n kind: 'error',\n ts: new Date().toISOString(),\n url: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n viewport:\n typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 },\n level: extra?.level ?? 'error',\n exception: {\n type: error.constructor?.name ?? 'Error',\n value: error.message,\n stacktrace: { frames },\n },\n };\n _sendEvent(event);\n}\n\nexport function leaveBreadcrumb(\n message: string,\n level: BreadcrumbLevel = 'info',\n category: BreadcrumbCategory = 'custom',\n data?: Record<string, unknown>,\n): void {\n _ring?.add(message, level, category, data);\n}\n\nexport function setUser(user: SdkUser | null): void {\n _user = user;\n}\n\nexport function addFeatureFlag(name: string, variant: FeatureFlag['variant']): void {\n const existing = _featureFlags.findIndex(f => f.name === name);\n if (existing >= 0) {\n _featureFlags[existing] = { name, variant };\n } else {\n _featureFlags.push({ name, variant });\n }\n}\n\nexport function clearFeatureFlag(name: string): void {\n _featureFlags = _featureFlags.filter(f => f.name !== name);\n}\n\nexport function setContext(key: string, value: Record<string, unknown> | null): void {\n if (value === null) {\n delete _contexts[key];\n } else {\n _contexts[key] = value;\n }\n}\n\n/** Called by the network integration to register a ring-buffer accessor. */\nexport function _registerNetworkRing(fn: () => unknown[]): void {\n _networkRingRef = fn;\n}\n\n// ─── Internal ────────────────────────────────────────────────────────────────\n\nfunction _sendEvent(event: ErrorEvent): void {\n if (!_client || !_ring || !_opts) return;\n\n const enriched = enrich(event, {\n release: _client.options.release,\n environment: _client.options.environment,\n user: _user ?? (_client.options.user as SdkUser | undefined),\n breadcrumbs: _ring.getAll(),\n featureFlags: _featureFlags,\n networkRing: _networkRingRef ? _networkRingRef() : [],\n contexts: Object.keys(_contexts).length ? _contexts : undefined,\n });\n\n const final = _opts.beforeSend ? _opts.beforeSend(enriched) : enriched;\n if (!final) return;\n\n _client.send(final as any).catch(() => {/* silent */});\n}\n\n// ─── Integration factory ──────────────────────────────────────────────────────\n\nexport function errorsIntegration(opts: ErrorsIntegrationOptions = {}): Integration {\n const teardowns: Array<() => void> = [];\n\n return {\n name: 'errors',\n setup(client: ClientInterface) {\n _client = client;\n _opts = {\n captureGlobalErrors: opts.captureGlobalErrors ?? true,\n captureUnhandledRejections: opts.captureUnhandledRejections ?? true,\n captureConsole: opts.captureConsole ?? false,\n maxBreadcrumbs: opts.maxBreadcrumbs ?? 50,\n beforeSend: opts.beforeSend ?? null as any,\n };\n _ring = new BreadcrumbRing(_opts.maxBreadcrumbs);\n\n if (_opts.captureGlobalErrors) {\n teardowns.push(installOnError(_sendEvent));\n }\n if (_opts.captureUnhandledRejections) {\n teardowns.push(installUnhandledRejection(_sendEvent));\n }\n if (_opts.captureConsole) {\n teardowns.push(\n installConsoleCapture(_sendEvent, (msg, level, cat) =>\n _ring!.add(msg, level, cat),\n ),\n );\n }\n },\n teardown() {\n for (const fn of teardowns) fn();\n teardowns.length = 0;\n _ring = null;\n _client = null;\n _opts = null;\n _user = null;\n _featureFlags = [];\n _contexts = {};\n _networkRingRef = null;\n },\n };\n}\n","import type { Breadcrumb, BreadcrumbCategory, BreadcrumbLevel } from './types';\n\nexport class BreadcrumbRing {\n private readonly buf: Breadcrumb[] = [];\n private readonly max: number;\n\n constructor(max = 50) {\n this.max = max;\n }\n\n add(\n message: string,\n level: BreadcrumbLevel = 'info',\n category: BreadcrumbCategory = 'custom',\n data?: Record<string, unknown>,\n ): void {\n const crumb: Breadcrumb = {\n timestamp: new Date().toISOString(),\n level,\n category,\n message,\n data,\n };\n this.buf.push(crumb);\n if (this.buf.length > this.max) {\n this.buf.shift();\n }\n }\n\n getAll(): Breadcrumb[] {\n return [...this.buf];\n }\n\n clear(): void {\n this.buf.length = 0;\n }\n\n size(): number {\n return this.buf.length;\n }\n}\n","import type { Breadcrumb, ErrorEvent, FeatureFlag, SdkUser } from './types';\n\nexport interface EnrichOptions {\n release?: string;\n environment?: string;\n user?: SdkUser;\n breadcrumbs?: Breadcrumb[];\n featureFlags?: FeatureFlag[];\n networkRing?: unknown[];\n contexts?: Record<string, unknown>;\n}\n\nexport function enrich(event: ErrorEvent, opts: EnrichOptions): ErrorEvent {\n const enriched = { ...event };\n\n if (opts.release) enriched.release = opts.release;\n if (opts.environment) enriched.environment = opts.environment;\n if (opts.user) enriched.user = opts.user;\n if (opts.breadcrumbs?.length) enriched.breadcrumbs = opts.breadcrumbs;\n if (opts.featureFlags?.length) enriched.featureFlags = opts.featureFlags;\n if (opts.networkRing?.length) enriched.networkRing = opts.networkRing;\n if (opts.contexts) enriched.contexts = { ...enriched.contexts, ...opts.contexts };\n\n return enriched;\n}\n","import type { Frame } from './types';\n\n/**\n * Parse an Error.stack string into a normalized Frame[].\n * Supports V8 (Chrome/Node), Firefox, and Safari formats.\n */\nexport function parseStack(err: Error | string): Frame[] {\n const stack = typeof err === 'string' ? err : (err.stack ?? '');\n const lines = stack.split('\\n');\n const frames: Frame[] = [];\n\n for (const raw of lines) {\n const line = raw.trim();\n if (!line || line.startsWith('Error:') || line.startsWith('TypeError:')) continue;\n\n const frame = parseV8Line(line) ?? parseFirefoxLine(line);\n if (frame) frames.push(frame);\n }\n\n return frames;\n}\n\n/** V8: \" at functionName (filename:lineno:colno)\" or \" at filename:lineno:colno\" */\nfunction parseV8Line(line: string): Frame | null {\n const atPart = line.startsWith('at ') ? line : null;\n if (!atPart) return null;\n\n const content = atPart.slice(3).trim();\n\n // \"at functionName (filename:lineno:colno)\"\n const withFnMatch = content.match(/^(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)$/);\n if (withFnMatch) {\n const [, fn, filename, lineno, colno] = withFnMatch;\n return makeFrame(fn.trim(), filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));\n }\n\n // \"at filename:lineno:colno\" (anonymous)\n const noFnMatch = content.match(/^(.+?):(\\d+):(\\d+)$/);\n if (noFnMatch) {\n const [, filename, lineno, colno] = noFnMatch;\n return makeFrame(null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));\n }\n\n // \"at <anonymous>\" or \"at eval\"\n if (content.startsWith('<') || content === 'eval' || content === 'anonymous') {\n return makeFrame(content, '<anonymous>', null, null);\n }\n\n return null;\n}\n\n/** Firefox/Safari: \"functionName@filename:lineno:colno\" */\nfunction parseFirefoxLine(line: string): Frame | null {\n const match = line.match(/^(.*)@(.*):(\\d+):(\\d+)$/);\n if (!match) return null;\n const [, fn, filename, lineno, colno] = match;\n return makeFrame(fn.trim() || null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));\n}\n\nfunction makeFrame(\n fn: string | null,\n filename: string,\n lineno: number | null,\n colno: number | null,\n): Frame {\n return {\n filename: filename || null,\n function: fn || null,\n lineno,\n colno,\n in_app: isInApp(filename),\n };\n}\n\nfunction isInApp(filename: string): boolean {\n if (!filename) return false;\n if (filename === '<anonymous>' || filename === '?' || filename.startsWith('<')) return false;\n if (filename.includes('[native code]')) return false;\n if (filename.includes('node_modules') || filename.includes('/vendor/')) return false;\n return true;\n}\n","import { parseStack } from '../stacktrace';\nimport type { ErrorEvent, Frame } from '../types';\n\ntype NotifyFn = (event: ErrorEvent) => void;\n\nexport function installOnError(notify: NotifyFn): () => void {\n const prev = window.onerror;\n\n window.onerror = function (\n message: string | Event,\n source?: string,\n lineno?: number,\n colno?: number,\n error?: Error,\n ) {\n let frames: Frame[] = [];\n let type = 'Error';\n let value = String(message);\n\n if (error) {\n frames = parseStack(error);\n type = error.constructor?.name ?? 'Error';\n value = error.message || value;\n } else if (source) {\n frames = [{ filename: source, function: null, lineno: lineno ?? null, colno: colno ?? null, in_app: true }];\n }\n\n notify({\n kind: 'error',\n ts: new Date().toISOString(),\n url: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n viewport: typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 },\n level: 'error',\n exception: {\n type,\n value,\n stacktrace: { frames },\n },\n });\n\n if (typeof prev === 'function') {\n return prev(message, source, lineno, colno, error);\n }\n return false;\n };\n\n return () => {\n window.onerror = prev;\n };\n}\n","import { parseStack } from '../stacktrace';\nimport type { ErrorEvent } from '../types';\n\ntype NotifyFn = (event: ErrorEvent) => void;\n\nexport function installUnhandledRejection(notify: NotifyFn): () => void {\n const handler = (ev: PromiseRejectionEvent) => {\n const reason = ev.reason;\n let type = 'UnhandledRejection';\n let value = String(reason);\n let frames = [];\n\n if (reason instanceof Error) {\n type = reason.constructor?.name ?? 'Error';\n value = reason.message;\n frames = parseStack(reason);\n } else if (reason !== null && reason !== undefined) {\n value = typeof reason === 'object' ? JSON.stringify(reason) : String(reason);\n }\n\n notify({\n kind: 'error',\n ts: new Date().toISOString(),\n url: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n viewport: typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 },\n level: 'error',\n exception: {\n type,\n value,\n stacktrace: { frames },\n },\n });\n };\n\n window.addEventListener('unhandledrejection', handler);\n return () => window.removeEventListener('unhandledrejection', handler);\n}\n","import type { BreadcrumbLevel, ErrorEvent } from '../types';\n\ntype NotifyFn = (event: ErrorEvent) => void;\ntype LeaveBreadcrumbFn = (msg: string, level: BreadcrumbLevel, category: 'console') => void;\n\nconst CAPTURED_METHODS: Array<'error' | 'warn'> = ['error', 'warn'];\n\nexport function installConsoleCapture(\n notify: NotifyFn,\n leaveBreadcrumb: LeaveBreadcrumbFn,\n): () => void {\n const originals: Record<string, typeof console.error> = {};\n\n for (const method of CAPTURED_METHODS) {\n originals[method] = console[method].bind(console);\n // eslint-disable-next-line no-console\n console[method] = (...args: unknown[]) => {\n originals[method](...args);\n const message = args\n .map(a => (a instanceof Error ? a.message : typeof a === 'object' ? JSON.stringify(a) : String(a)))\n .join(' ');\n const level: BreadcrumbLevel = method === 'error' ? 'error' : 'warning';\n leaveBreadcrumb(message, level, 'console');\n };\n }\n\n return () => {\n for (const method of CAPTURED_METHODS) {\n (console as any)[method] = originals[method];\n }\n };\n}\n"],"mappings":"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","names":["BreadcrumbRing","buf","max","add","message","level","category","data","crumb","timestamp","Date","toISOString","push","length","shift","getAll","clear","size","enrich","event","opts","enriched","release","environment","user","breadcrumbs","length","featureFlags","networkRing","contexts","parseStack","err","stack","lines","split","frames","raw","line","trim","startsWith","frame","parseV8Line","parseFirefoxLine","push","atPart","content","slice","withFnMatch","match","fn","filename","lineno","colno","makeFrame","parseInt","noFnMatch","function","in_app","isInApp","includes","installOnError","notify","prev","window","onerror","message","source","lineno","colno","error","frames","type","value","String","parseStack","name","filename","function","in_app","kind","ts","Date","toISOString","url","location","href","userAgent","navigator","viewport","width","innerWidth","height","innerHeight","level","exception","stacktrace","installUnhandledRejection","notify","handler","ev","reason","type","value","String","frames","Error","name","message","parseStack","undefined","JSON","stringify","kind","ts","Date","toISOString","url","window","location","href","userAgent","navigator","viewport","width","innerWidth","height","innerHeight","level","exception","stacktrace","addEventListener","removeEventListener","CAPTURED_METHODS","installConsoleCapture","notify","leaveBreadcrumb","originals","method","console","bind","args","message","map","a","Error","JSON","stringify","String","join","level","_ring","_user","_featureFlags","_contexts","_client","_opts","_networkRingRef","notify","err","extra","error","Error","frames","parseStack","event","kind","ts","Date","toISOString","url","window","location","href","userAgent","navigator","viewport","width","innerWidth","height","innerHeight","level","exception","type","name","value","message","stacktrace","_sendEvent","leaveBreadcrumb","category","data","add","setUser","user","addFeatureFlag","variant","existing","findIndex","f","push","clearFeatureFlag","filter","setContext","key","_registerNetworkRing","fn","enriched","enrich","release","options","environment","breadcrumbs","getAll","featureFlags","networkRing","contexts","Object","keys","length","undefined","final","beforeSend","send","catch","errorsIntegration","opts","teardowns","setup","client","captureGlobalErrors","captureUnhandledRejections","captureConsole","maxBreadcrumbs","BreadcrumbRing","installOnError","installUnhandledRejection","installConsoleCapture","msg","cat","teardown"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Integration } from '@koderlabs/tasks-sdk';
|
|
2
|
+
import * as _koderlabs_tasks_sdk_types from '@koderlabs/tasks-sdk-types';
|
|
3
|
+
import { BreadcrumbLevel, BreadcrumbCategory, Breadcrumb, Frame } from '@koderlabs/tasks-sdk-types';
|
|
4
|
+
export { ErrorEvent } from '@koderlabs/tasks-sdk-types';
|
|
5
|
+
|
|
6
|
+
interface SdkUser {
|
|
7
|
+
id?: string;
|
|
8
|
+
email?: string;
|
|
9
|
+
username?: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface FeatureFlag {
|
|
13
|
+
name: string;
|
|
14
|
+
variant: string | boolean | number;
|
|
15
|
+
}
|
|
16
|
+
interface ErrorsIntegrationOptions {
|
|
17
|
+
/** Whether to hook window.onerror. Default true. */
|
|
18
|
+
captureGlobalErrors?: boolean;
|
|
19
|
+
/** Whether to hook unhandledrejection. Default true. */
|
|
20
|
+
captureUnhandledRejections?: boolean;
|
|
21
|
+
/** Whether to intercept console.error / console.warn. Default false. */
|
|
22
|
+
captureConsole?: boolean;
|
|
23
|
+
/** Max breadcrumbs to keep in the ring. Default 50. */
|
|
24
|
+
maxBreadcrumbs?: number;
|
|
25
|
+
/** Called before sending; return null to suppress. */
|
|
26
|
+
beforeSend?: (event: _koderlabs_tasks_sdk_types.ErrorEvent) => _koderlabs_tasks_sdk_types.ErrorEvent | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Public surface for the errors integration.
|
|
31
|
+
* The integration holds a singleton instance of ErrorsIntegrationInstance
|
|
32
|
+
* which is wired up by errorsIntegration().
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
interface ErrorsApi {
|
|
36
|
+
notify(err: Error | string, opts?: {
|
|
37
|
+
level?: 'error' | 'warning' | 'info';
|
|
38
|
+
}): void;
|
|
39
|
+
leaveBreadcrumb(message: string, level?: BreadcrumbLevel, category?: BreadcrumbCategory, data?: Record<string, unknown>): void;
|
|
40
|
+
setUser(user: SdkUser | null): void;
|
|
41
|
+
addFeatureFlag(name: string, variant: FeatureFlag['variant']): void;
|
|
42
|
+
clearFeatureFlag(name: string): void;
|
|
43
|
+
setContext(key: string, value: Record<string, unknown> | null): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
declare class BreadcrumbRing {
|
|
47
|
+
private readonly buf;
|
|
48
|
+
private readonly max;
|
|
49
|
+
constructor(max?: number);
|
|
50
|
+
add(message: string, level?: BreadcrumbLevel, category?: BreadcrumbCategory, data?: Record<string, unknown>): void;
|
|
51
|
+
getAll(): Breadcrumb[];
|
|
52
|
+
clear(): void;
|
|
53
|
+
size(): number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Parse an Error.stack string into a normalized Frame[].
|
|
58
|
+
* Supports V8 (Chrome/Node), Firefox, and Safari formats.
|
|
59
|
+
*/
|
|
60
|
+
declare function parseStack(err: Error | string): Frame[];
|
|
61
|
+
|
|
62
|
+
/** Manually capture an error. */
|
|
63
|
+
declare function notify(err: Error | string, extra?: {
|
|
64
|
+
level?: 'error' | 'warning' | 'info';
|
|
65
|
+
}): void;
|
|
66
|
+
declare function leaveBreadcrumb(message: string, level?: BreadcrumbLevel, category?: BreadcrumbCategory, data?: Record<string, unknown>): void;
|
|
67
|
+
declare function setUser(user: SdkUser | null): void;
|
|
68
|
+
declare function addFeatureFlag(name: string, variant: FeatureFlag['variant']): void;
|
|
69
|
+
declare function clearFeatureFlag(name: string): void;
|
|
70
|
+
declare function setContext(key: string, value: Record<string, unknown> | null): void;
|
|
71
|
+
/** Called by the network integration to register a ring-buffer accessor. */
|
|
72
|
+
declare function _registerNetworkRing(fn: () => unknown[]): void;
|
|
73
|
+
declare function errorsIntegration(opts?: ErrorsIntegrationOptions): Integration;
|
|
74
|
+
|
|
75
|
+
export { BreadcrumbRing, type ErrorsApi, type ErrorsIntegrationOptions, type FeatureFlag, type SdkUser, _registerNetworkRing, addFeatureFlag, clearFeatureFlag, errorsIntegration, leaveBreadcrumb, notify, parseStack, setContext, setUser };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Integration } from '@koderlabs/tasks-sdk';
|
|
2
|
+
import * as _koderlabs_tasks_sdk_types from '@koderlabs/tasks-sdk-types';
|
|
3
|
+
import { BreadcrumbLevel, BreadcrumbCategory, Breadcrumb, Frame } from '@koderlabs/tasks-sdk-types';
|
|
4
|
+
export { ErrorEvent } from '@koderlabs/tasks-sdk-types';
|
|
5
|
+
|
|
6
|
+
interface SdkUser {
|
|
7
|
+
id?: string;
|
|
8
|
+
email?: string;
|
|
9
|
+
username?: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface FeatureFlag {
|
|
13
|
+
name: string;
|
|
14
|
+
variant: string | boolean | number;
|
|
15
|
+
}
|
|
16
|
+
interface ErrorsIntegrationOptions {
|
|
17
|
+
/** Whether to hook window.onerror. Default true. */
|
|
18
|
+
captureGlobalErrors?: boolean;
|
|
19
|
+
/** Whether to hook unhandledrejection. Default true. */
|
|
20
|
+
captureUnhandledRejections?: boolean;
|
|
21
|
+
/** Whether to intercept console.error / console.warn. Default false. */
|
|
22
|
+
captureConsole?: boolean;
|
|
23
|
+
/** Max breadcrumbs to keep in the ring. Default 50. */
|
|
24
|
+
maxBreadcrumbs?: number;
|
|
25
|
+
/** Called before sending; return null to suppress. */
|
|
26
|
+
beforeSend?: (event: _koderlabs_tasks_sdk_types.ErrorEvent) => _koderlabs_tasks_sdk_types.ErrorEvent | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Public surface for the errors integration.
|
|
31
|
+
* The integration holds a singleton instance of ErrorsIntegrationInstance
|
|
32
|
+
* which is wired up by errorsIntegration().
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
interface ErrorsApi {
|
|
36
|
+
notify(err: Error | string, opts?: {
|
|
37
|
+
level?: 'error' | 'warning' | 'info';
|
|
38
|
+
}): void;
|
|
39
|
+
leaveBreadcrumb(message: string, level?: BreadcrumbLevel, category?: BreadcrumbCategory, data?: Record<string, unknown>): void;
|
|
40
|
+
setUser(user: SdkUser | null): void;
|
|
41
|
+
addFeatureFlag(name: string, variant: FeatureFlag['variant']): void;
|
|
42
|
+
clearFeatureFlag(name: string): void;
|
|
43
|
+
setContext(key: string, value: Record<string, unknown> | null): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
declare class BreadcrumbRing {
|
|
47
|
+
private readonly buf;
|
|
48
|
+
private readonly max;
|
|
49
|
+
constructor(max?: number);
|
|
50
|
+
add(message: string, level?: BreadcrumbLevel, category?: BreadcrumbCategory, data?: Record<string, unknown>): void;
|
|
51
|
+
getAll(): Breadcrumb[];
|
|
52
|
+
clear(): void;
|
|
53
|
+
size(): number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Parse an Error.stack string into a normalized Frame[].
|
|
58
|
+
* Supports V8 (Chrome/Node), Firefox, and Safari formats.
|
|
59
|
+
*/
|
|
60
|
+
declare function parseStack(err: Error | string): Frame[];
|
|
61
|
+
|
|
62
|
+
/** Manually capture an error. */
|
|
63
|
+
declare function notify(err: Error | string, extra?: {
|
|
64
|
+
level?: 'error' | 'warning' | 'info';
|
|
65
|
+
}): void;
|
|
66
|
+
declare function leaveBreadcrumb(message: string, level?: BreadcrumbLevel, category?: BreadcrumbCategory, data?: Record<string, unknown>): void;
|
|
67
|
+
declare function setUser(user: SdkUser | null): void;
|
|
68
|
+
declare function addFeatureFlag(name: string, variant: FeatureFlag['variant']): void;
|
|
69
|
+
declare function clearFeatureFlag(name: string): void;
|
|
70
|
+
declare function setContext(key: string, value: Record<string, unknown> | null): void;
|
|
71
|
+
/** Called by the network integration to register a ring-buffer accessor. */
|
|
72
|
+
declare function _registerNetworkRing(fn: () => unknown[]): void;
|
|
73
|
+
declare function errorsIntegration(opts?: ErrorsIntegrationOptions): Integration;
|
|
74
|
+
|
|
75
|
+
export { BreadcrumbRing, type ErrorsApi, type ErrorsIntegrationOptions, type FeatureFlag, type SdkUser, _registerNetworkRing, addFeatureFlag, clearFeatureFlag, errorsIntegration, leaveBreadcrumb, notify, parseStack, setContext, setUser };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/breadcrumbs.ts
|
|
5
|
+
var BreadcrumbRing = class {
|
|
6
|
+
static {
|
|
7
|
+
__name(this, "BreadcrumbRing");
|
|
8
|
+
}
|
|
9
|
+
buf = [];
|
|
10
|
+
max;
|
|
11
|
+
constructor(max = 50) {
|
|
12
|
+
this.max = max;
|
|
13
|
+
}
|
|
14
|
+
add(message, level = "info", category = "custom", data) {
|
|
15
|
+
const crumb = {
|
|
16
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17
|
+
level,
|
|
18
|
+
category,
|
|
19
|
+
message,
|
|
20
|
+
data
|
|
21
|
+
};
|
|
22
|
+
this.buf.push(crumb);
|
|
23
|
+
if (this.buf.length > this.max) {
|
|
24
|
+
this.buf.shift();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
getAll() {
|
|
28
|
+
return [
|
|
29
|
+
...this.buf
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
clear() {
|
|
33
|
+
this.buf.length = 0;
|
|
34
|
+
}
|
|
35
|
+
size() {
|
|
36
|
+
return this.buf.length;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/enrich.ts
|
|
41
|
+
function enrich(event, opts) {
|
|
42
|
+
const enriched = {
|
|
43
|
+
...event
|
|
44
|
+
};
|
|
45
|
+
if (opts.release) enriched.release = opts.release;
|
|
46
|
+
if (opts.environment) enriched.environment = opts.environment;
|
|
47
|
+
if (opts.user) enriched.user = opts.user;
|
|
48
|
+
if (opts.breadcrumbs?.length) enriched.breadcrumbs = opts.breadcrumbs;
|
|
49
|
+
if (opts.featureFlags?.length) enriched.featureFlags = opts.featureFlags;
|
|
50
|
+
if (opts.networkRing?.length) enriched.networkRing = opts.networkRing;
|
|
51
|
+
if (opts.contexts) enriched.contexts = {
|
|
52
|
+
...enriched.contexts,
|
|
53
|
+
...opts.contexts
|
|
54
|
+
};
|
|
55
|
+
return enriched;
|
|
56
|
+
}
|
|
57
|
+
__name(enrich, "enrich");
|
|
58
|
+
|
|
59
|
+
// src/stacktrace.ts
|
|
60
|
+
function parseStack(err) {
|
|
61
|
+
const stack = typeof err === "string" ? err : err.stack ?? "";
|
|
62
|
+
const lines = stack.split("\n");
|
|
63
|
+
const frames = [];
|
|
64
|
+
for (const raw of lines) {
|
|
65
|
+
const line = raw.trim();
|
|
66
|
+
if (!line || line.startsWith("Error:") || line.startsWith("TypeError:")) continue;
|
|
67
|
+
const frame = parseV8Line(line) ?? parseFirefoxLine(line);
|
|
68
|
+
if (frame) frames.push(frame);
|
|
69
|
+
}
|
|
70
|
+
return frames;
|
|
71
|
+
}
|
|
72
|
+
__name(parseStack, "parseStack");
|
|
73
|
+
function parseV8Line(line) {
|
|
74
|
+
const atPart = line.startsWith("at ") ? line : null;
|
|
75
|
+
if (!atPart) return null;
|
|
76
|
+
const content = atPart.slice(3).trim();
|
|
77
|
+
const withFnMatch = content.match(/^(.+?)\s+\((.+?):(\d+):(\d+)\)$/);
|
|
78
|
+
if (withFnMatch) {
|
|
79
|
+
const [, fn, filename, lineno, colno] = withFnMatch;
|
|
80
|
+
return makeFrame(fn.trim(), filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));
|
|
81
|
+
}
|
|
82
|
+
const noFnMatch = content.match(/^(.+?):(\d+):(\d+)$/);
|
|
83
|
+
if (noFnMatch) {
|
|
84
|
+
const [, filename, lineno, colno] = noFnMatch;
|
|
85
|
+
return makeFrame(null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));
|
|
86
|
+
}
|
|
87
|
+
if (content.startsWith("<") || content === "eval" || content === "anonymous") {
|
|
88
|
+
return makeFrame(content, "<anonymous>", null, null);
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
__name(parseV8Line, "parseV8Line");
|
|
93
|
+
function parseFirefoxLine(line) {
|
|
94
|
+
const match = line.match(/^(.*)@(.*):(\d+):(\d+)$/);
|
|
95
|
+
if (!match) return null;
|
|
96
|
+
const [, fn, filename, lineno, colno] = match;
|
|
97
|
+
return makeFrame(fn.trim() || null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));
|
|
98
|
+
}
|
|
99
|
+
__name(parseFirefoxLine, "parseFirefoxLine");
|
|
100
|
+
function makeFrame(fn, filename, lineno, colno) {
|
|
101
|
+
return {
|
|
102
|
+
filename: filename || null,
|
|
103
|
+
function: fn || null,
|
|
104
|
+
lineno,
|
|
105
|
+
colno,
|
|
106
|
+
in_app: isInApp(filename)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
__name(makeFrame, "makeFrame");
|
|
110
|
+
function isInApp(filename) {
|
|
111
|
+
if (!filename) return false;
|
|
112
|
+
if (filename === "<anonymous>" || filename === "?" || filename.startsWith("<")) return false;
|
|
113
|
+
if (filename.includes("[native code]")) return false;
|
|
114
|
+
if (filename.includes("node_modules") || filename.includes("/vendor/")) return false;
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
__name(isInApp, "isInApp");
|
|
118
|
+
|
|
119
|
+
// src/handlers/onerror.ts
|
|
120
|
+
function installOnError(notify2) {
|
|
121
|
+
const prev = window.onerror;
|
|
122
|
+
window.onerror = function(message, source, lineno, colno, error) {
|
|
123
|
+
let frames = [];
|
|
124
|
+
let type = "Error";
|
|
125
|
+
let value = String(message);
|
|
126
|
+
if (error) {
|
|
127
|
+
frames = parseStack(error);
|
|
128
|
+
type = error.constructor?.name ?? "Error";
|
|
129
|
+
value = error.message || value;
|
|
130
|
+
} else if (source) {
|
|
131
|
+
frames = [
|
|
132
|
+
{
|
|
133
|
+
filename: source,
|
|
134
|
+
function: null,
|
|
135
|
+
lineno: lineno ?? null,
|
|
136
|
+
colno: colno ?? null,
|
|
137
|
+
in_app: true
|
|
138
|
+
}
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
notify2({
|
|
142
|
+
kind: "error",
|
|
143
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
144
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
145
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
146
|
+
viewport: typeof window !== "undefined" ? {
|
|
147
|
+
width: window.innerWidth,
|
|
148
|
+
height: window.innerHeight
|
|
149
|
+
} : {
|
|
150
|
+
width: 0,
|
|
151
|
+
height: 0
|
|
152
|
+
},
|
|
153
|
+
level: "error",
|
|
154
|
+
exception: {
|
|
155
|
+
type,
|
|
156
|
+
value,
|
|
157
|
+
stacktrace: {
|
|
158
|
+
frames
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
if (typeof prev === "function") {
|
|
163
|
+
return prev(message, source, lineno, colno, error);
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
};
|
|
167
|
+
return () => {
|
|
168
|
+
window.onerror = prev;
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
__name(installOnError, "installOnError");
|
|
172
|
+
|
|
173
|
+
// src/handlers/unhandledrejection.ts
|
|
174
|
+
function installUnhandledRejection(notify2) {
|
|
175
|
+
const handler = /* @__PURE__ */ __name((ev) => {
|
|
176
|
+
const reason = ev.reason;
|
|
177
|
+
let type = "UnhandledRejection";
|
|
178
|
+
let value = String(reason);
|
|
179
|
+
let frames = [];
|
|
180
|
+
if (reason instanceof Error) {
|
|
181
|
+
type = reason.constructor?.name ?? "Error";
|
|
182
|
+
value = reason.message;
|
|
183
|
+
frames = parseStack(reason);
|
|
184
|
+
} else if (reason !== null && reason !== void 0) {
|
|
185
|
+
value = typeof reason === "object" ? JSON.stringify(reason) : String(reason);
|
|
186
|
+
}
|
|
187
|
+
notify2({
|
|
188
|
+
kind: "error",
|
|
189
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
190
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
191
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
192
|
+
viewport: typeof window !== "undefined" ? {
|
|
193
|
+
width: window.innerWidth,
|
|
194
|
+
height: window.innerHeight
|
|
195
|
+
} : {
|
|
196
|
+
width: 0,
|
|
197
|
+
height: 0
|
|
198
|
+
},
|
|
199
|
+
level: "error",
|
|
200
|
+
exception: {
|
|
201
|
+
type,
|
|
202
|
+
value,
|
|
203
|
+
stacktrace: {
|
|
204
|
+
frames
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}, "handler");
|
|
209
|
+
window.addEventListener("unhandledrejection", handler);
|
|
210
|
+
return () => window.removeEventListener("unhandledrejection", handler);
|
|
211
|
+
}
|
|
212
|
+
__name(installUnhandledRejection, "installUnhandledRejection");
|
|
213
|
+
|
|
214
|
+
// src/handlers/console.ts
|
|
215
|
+
var CAPTURED_METHODS = [
|
|
216
|
+
"error",
|
|
217
|
+
"warn"
|
|
218
|
+
];
|
|
219
|
+
function installConsoleCapture(notify2, leaveBreadcrumb2) {
|
|
220
|
+
const originals = {};
|
|
221
|
+
for (const method of CAPTURED_METHODS) {
|
|
222
|
+
originals[method] = console[method].bind(console);
|
|
223
|
+
console[method] = (...args) => {
|
|
224
|
+
originals[method](...args);
|
|
225
|
+
const message = args.map((a) => a instanceof Error ? a.message : typeof a === "object" ? JSON.stringify(a) : String(a)).join(" ");
|
|
226
|
+
const level = method === "error" ? "error" : "warning";
|
|
227
|
+
leaveBreadcrumb2(message, level, "console");
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return () => {
|
|
231
|
+
for (const method of CAPTURED_METHODS) {
|
|
232
|
+
console[method] = originals[method];
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
__name(installConsoleCapture, "installConsoleCapture");
|
|
237
|
+
|
|
238
|
+
// src/index.ts
|
|
239
|
+
var _ring = null;
|
|
240
|
+
var _user = null;
|
|
241
|
+
var _featureFlags = [];
|
|
242
|
+
var _contexts = {};
|
|
243
|
+
var _client = null;
|
|
244
|
+
var _opts = null;
|
|
245
|
+
var _networkRingRef = null;
|
|
246
|
+
function notify(err, extra) {
|
|
247
|
+
if (!_client || !_ring || !_opts) return;
|
|
248
|
+
const error = typeof err === "string" ? new Error(err) : err;
|
|
249
|
+
const frames = parseStack(error);
|
|
250
|
+
const event = {
|
|
251
|
+
kind: "error",
|
|
252
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
253
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
254
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
255
|
+
viewport: typeof window !== "undefined" ? {
|
|
256
|
+
width: window.innerWidth,
|
|
257
|
+
height: window.innerHeight
|
|
258
|
+
} : {
|
|
259
|
+
width: 0,
|
|
260
|
+
height: 0
|
|
261
|
+
},
|
|
262
|
+
level: extra?.level ?? "error",
|
|
263
|
+
exception: {
|
|
264
|
+
type: error.constructor?.name ?? "Error",
|
|
265
|
+
value: error.message,
|
|
266
|
+
stacktrace: {
|
|
267
|
+
frames
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
_sendEvent(event);
|
|
272
|
+
}
|
|
273
|
+
__name(notify, "notify");
|
|
274
|
+
function leaveBreadcrumb(message, level = "info", category = "custom", data) {
|
|
275
|
+
_ring?.add(message, level, category, data);
|
|
276
|
+
}
|
|
277
|
+
__name(leaveBreadcrumb, "leaveBreadcrumb");
|
|
278
|
+
function setUser(user) {
|
|
279
|
+
_user = user;
|
|
280
|
+
}
|
|
281
|
+
__name(setUser, "setUser");
|
|
282
|
+
function addFeatureFlag(name, variant) {
|
|
283
|
+
const existing = _featureFlags.findIndex((f) => f.name === name);
|
|
284
|
+
if (existing >= 0) {
|
|
285
|
+
_featureFlags[existing] = {
|
|
286
|
+
name,
|
|
287
|
+
variant
|
|
288
|
+
};
|
|
289
|
+
} else {
|
|
290
|
+
_featureFlags.push({
|
|
291
|
+
name,
|
|
292
|
+
variant
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
__name(addFeatureFlag, "addFeatureFlag");
|
|
297
|
+
function clearFeatureFlag(name) {
|
|
298
|
+
_featureFlags = _featureFlags.filter((f) => f.name !== name);
|
|
299
|
+
}
|
|
300
|
+
__name(clearFeatureFlag, "clearFeatureFlag");
|
|
301
|
+
function setContext(key, value) {
|
|
302
|
+
if (value === null) {
|
|
303
|
+
delete _contexts[key];
|
|
304
|
+
} else {
|
|
305
|
+
_contexts[key] = value;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
__name(setContext, "setContext");
|
|
309
|
+
function _registerNetworkRing(fn) {
|
|
310
|
+
_networkRingRef = fn;
|
|
311
|
+
}
|
|
312
|
+
__name(_registerNetworkRing, "_registerNetworkRing");
|
|
313
|
+
function _sendEvent(event) {
|
|
314
|
+
if (!_client || !_ring || !_opts) return;
|
|
315
|
+
const enriched = enrich(event, {
|
|
316
|
+
release: _client.options.release,
|
|
317
|
+
environment: _client.options.environment,
|
|
318
|
+
user: _user ?? _client.options.user,
|
|
319
|
+
breadcrumbs: _ring.getAll(),
|
|
320
|
+
featureFlags: _featureFlags,
|
|
321
|
+
networkRing: _networkRingRef ? _networkRingRef() : [],
|
|
322
|
+
contexts: Object.keys(_contexts).length ? _contexts : void 0
|
|
323
|
+
});
|
|
324
|
+
const final = _opts.beforeSend ? _opts.beforeSend(enriched) : enriched;
|
|
325
|
+
if (!final) return;
|
|
326
|
+
_client.send(final).catch(() => {
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
__name(_sendEvent, "_sendEvent");
|
|
330
|
+
function errorsIntegration(opts = {}) {
|
|
331
|
+
const teardowns = [];
|
|
332
|
+
return {
|
|
333
|
+
name: "errors",
|
|
334
|
+
setup(client) {
|
|
335
|
+
_client = client;
|
|
336
|
+
_opts = {
|
|
337
|
+
captureGlobalErrors: opts.captureGlobalErrors ?? true,
|
|
338
|
+
captureUnhandledRejections: opts.captureUnhandledRejections ?? true,
|
|
339
|
+
captureConsole: opts.captureConsole ?? false,
|
|
340
|
+
maxBreadcrumbs: opts.maxBreadcrumbs ?? 50,
|
|
341
|
+
beforeSend: opts.beforeSend ?? null
|
|
342
|
+
};
|
|
343
|
+
_ring = new BreadcrumbRing(_opts.maxBreadcrumbs);
|
|
344
|
+
if (_opts.captureGlobalErrors) {
|
|
345
|
+
teardowns.push(installOnError(_sendEvent));
|
|
346
|
+
}
|
|
347
|
+
if (_opts.captureUnhandledRejections) {
|
|
348
|
+
teardowns.push(installUnhandledRejection(_sendEvent));
|
|
349
|
+
}
|
|
350
|
+
if (_opts.captureConsole) {
|
|
351
|
+
teardowns.push(installConsoleCapture(_sendEvent, (msg, level, cat) => _ring.add(msg, level, cat)));
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
teardown() {
|
|
355
|
+
for (const fn of teardowns) fn();
|
|
356
|
+
teardowns.length = 0;
|
|
357
|
+
_ring = null;
|
|
358
|
+
_client = null;
|
|
359
|
+
_opts = null;
|
|
360
|
+
_user = null;
|
|
361
|
+
_featureFlags = [];
|
|
362
|
+
_contexts = {};
|
|
363
|
+
_networkRingRef = null;
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
__name(errorsIntegration, "errorsIntegration");
|
|
368
|
+
export {
|
|
369
|
+
BreadcrumbRing,
|
|
370
|
+
_registerNetworkRing,
|
|
371
|
+
addFeatureFlag,
|
|
372
|
+
clearFeatureFlag,
|
|
373
|
+
errorsIntegration,
|
|
374
|
+
leaveBreadcrumb,
|
|
375
|
+
notify,
|
|
376
|
+
parseStack,
|
|
377
|
+
setContext,
|
|
378
|
+
setUser
|
|
379
|
+
};
|
|
380
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/breadcrumbs.ts","../src/enrich.ts","../src/stacktrace.ts","../src/handlers/onerror.ts","../src/handlers/unhandledrejection.ts","../src/handlers/console.ts","../src/index.ts"],"sourcesContent":["import type { Breadcrumb, BreadcrumbCategory, BreadcrumbLevel } from './types';\n\nexport class BreadcrumbRing {\n private readonly buf: Breadcrumb[] = [];\n private readonly max: number;\n\n constructor(max = 50) {\n this.max = max;\n }\n\n add(\n message: string,\n level: BreadcrumbLevel = 'info',\n category: BreadcrumbCategory = 'custom',\n data?: Record<string, unknown>,\n ): void {\n const crumb: Breadcrumb = {\n timestamp: new Date().toISOString(),\n level,\n category,\n message,\n data,\n };\n this.buf.push(crumb);\n if (this.buf.length > this.max) {\n this.buf.shift();\n }\n }\n\n getAll(): Breadcrumb[] {\n return [...this.buf];\n }\n\n clear(): void {\n this.buf.length = 0;\n }\n\n size(): number {\n return this.buf.length;\n }\n}\n","import type { Breadcrumb, ErrorEvent, FeatureFlag, SdkUser } from './types';\n\nexport interface EnrichOptions {\n release?: string;\n environment?: string;\n user?: SdkUser;\n breadcrumbs?: Breadcrumb[];\n featureFlags?: FeatureFlag[];\n networkRing?: unknown[];\n contexts?: Record<string, unknown>;\n}\n\nexport function enrich(event: ErrorEvent, opts: EnrichOptions): ErrorEvent {\n const enriched = { ...event };\n\n if (opts.release) enriched.release = opts.release;\n if (opts.environment) enriched.environment = opts.environment;\n if (opts.user) enriched.user = opts.user;\n if (opts.breadcrumbs?.length) enriched.breadcrumbs = opts.breadcrumbs;\n if (opts.featureFlags?.length) enriched.featureFlags = opts.featureFlags;\n if (opts.networkRing?.length) enriched.networkRing = opts.networkRing;\n if (opts.contexts) enriched.contexts = { ...enriched.contexts, ...opts.contexts };\n\n return enriched;\n}\n","import type { Frame } from './types';\n\n/**\n * Parse an Error.stack string into a normalized Frame[].\n * Supports V8 (Chrome/Node), Firefox, and Safari formats.\n */\nexport function parseStack(err: Error | string): Frame[] {\n const stack = typeof err === 'string' ? err : (err.stack ?? '');\n const lines = stack.split('\\n');\n const frames: Frame[] = [];\n\n for (const raw of lines) {\n const line = raw.trim();\n if (!line || line.startsWith('Error:') || line.startsWith('TypeError:')) continue;\n\n const frame = parseV8Line(line) ?? parseFirefoxLine(line);\n if (frame) frames.push(frame);\n }\n\n return frames;\n}\n\n/** V8: \" at functionName (filename:lineno:colno)\" or \" at filename:lineno:colno\" */\nfunction parseV8Line(line: string): Frame | null {\n const atPart = line.startsWith('at ') ? line : null;\n if (!atPart) return null;\n\n const content = atPart.slice(3).trim();\n\n // \"at functionName (filename:lineno:colno)\"\n const withFnMatch = content.match(/^(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)$/);\n if (withFnMatch) {\n const [, fn, filename, lineno, colno] = withFnMatch;\n return makeFrame(fn.trim(), filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));\n }\n\n // \"at filename:lineno:colno\" (anonymous)\n const noFnMatch = content.match(/^(.+?):(\\d+):(\\d+)$/);\n if (noFnMatch) {\n const [, filename, lineno, colno] = noFnMatch;\n return makeFrame(null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));\n }\n\n // \"at <anonymous>\" or \"at eval\"\n if (content.startsWith('<') || content === 'eval' || content === 'anonymous') {\n return makeFrame(content, '<anonymous>', null, null);\n }\n\n return null;\n}\n\n/** Firefox/Safari: \"functionName@filename:lineno:colno\" */\nfunction parseFirefoxLine(line: string): Frame | null {\n const match = line.match(/^(.*)@(.*):(\\d+):(\\d+)$/);\n if (!match) return null;\n const [, fn, filename, lineno, colno] = match;\n return makeFrame(fn.trim() || null, filename.trim(), parseInt(lineno, 10), parseInt(colno, 10));\n}\n\nfunction makeFrame(\n fn: string | null,\n filename: string,\n lineno: number | null,\n colno: number | null,\n): Frame {\n return {\n filename: filename || null,\n function: fn || null,\n lineno,\n colno,\n in_app: isInApp(filename),\n };\n}\n\nfunction isInApp(filename: string): boolean {\n if (!filename) return false;\n if (filename === '<anonymous>' || filename === '?' || filename.startsWith('<')) return false;\n if (filename.includes('[native code]')) return false;\n if (filename.includes('node_modules') || filename.includes('/vendor/')) return false;\n return true;\n}\n","import { parseStack } from '../stacktrace';\nimport type { ErrorEvent, Frame } from '../types';\n\ntype NotifyFn = (event: ErrorEvent) => void;\n\nexport function installOnError(notify: NotifyFn): () => void {\n const prev = window.onerror;\n\n window.onerror = function (\n message: string | Event,\n source?: string,\n lineno?: number,\n colno?: number,\n error?: Error,\n ) {\n let frames: Frame[] = [];\n let type = 'Error';\n let value = String(message);\n\n if (error) {\n frames = parseStack(error);\n type = error.constructor?.name ?? 'Error';\n value = error.message || value;\n } else if (source) {\n frames = [{ filename: source, function: null, lineno: lineno ?? null, colno: colno ?? null, in_app: true }];\n }\n\n notify({\n kind: 'error',\n ts: new Date().toISOString(),\n url: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n viewport: typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 },\n level: 'error',\n exception: {\n type,\n value,\n stacktrace: { frames },\n },\n });\n\n if (typeof prev === 'function') {\n return prev(message, source, lineno, colno, error);\n }\n return false;\n };\n\n return () => {\n window.onerror = prev;\n };\n}\n","import { parseStack } from '../stacktrace';\nimport type { ErrorEvent } from '../types';\n\ntype NotifyFn = (event: ErrorEvent) => void;\n\nexport function installUnhandledRejection(notify: NotifyFn): () => void {\n const handler = (ev: PromiseRejectionEvent) => {\n const reason = ev.reason;\n let type = 'UnhandledRejection';\n let value = String(reason);\n let frames = [];\n\n if (reason instanceof Error) {\n type = reason.constructor?.name ?? 'Error';\n value = reason.message;\n frames = parseStack(reason);\n } else if (reason !== null && reason !== undefined) {\n value = typeof reason === 'object' ? JSON.stringify(reason) : String(reason);\n }\n\n notify({\n kind: 'error',\n ts: new Date().toISOString(),\n url: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n viewport: typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 },\n level: 'error',\n exception: {\n type,\n value,\n stacktrace: { frames },\n },\n });\n };\n\n window.addEventListener('unhandledrejection', handler);\n return () => window.removeEventListener('unhandledrejection', handler);\n}\n","import type { BreadcrumbLevel, ErrorEvent } from '../types';\n\ntype NotifyFn = (event: ErrorEvent) => void;\ntype LeaveBreadcrumbFn = (msg: string, level: BreadcrumbLevel, category: 'console') => void;\n\nconst CAPTURED_METHODS: Array<'error' | 'warn'> = ['error', 'warn'];\n\nexport function installConsoleCapture(\n notify: NotifyFn,\n leaveBreadcrumb: LeaveBreadcrumbFn,\n): () => void {\n const originals: Record<string, typeof console.error> = {};\n\n for (const method of CAPTURED_METHODS) {\n originals[method] = console[method].bind(console);\n // eslint-disable-next-line no-console\n console[method] = (...args: unknown[]) => {\n originals[method](...args);\n const message = args\n .map(a => (a instanceof Error ? a.message : typeof a === 'object' ? JSON.stringify(a) : String(a)))\n .join(' ');\n const level: BreadcrumbLevel = method === 'error' ? 'error' : 'warning';\n leaveBreadcrumb(message, level, 'console');\n };\n }\n\n return () => {\n for (const method of CAPTURED_METHODS) {\n (console as any)[method] = originals[method];\n }\n };\n}\n","import type { ClientInterface, Integration } from '@koderlabs/tasks-sdk';\nimport type {\n BreadcrumbCategory,\n BreadcrumbLevel,\n ErrorEvent,\n ErrorsIntegrationOptions,\n FeatureFlag,\n SdkUser,\n} from './types';\nimport { BreadcrumbRing } from './breadcrumbs';\nimport { enrich } from './enrich';\nimport { installOnError } from './handlers/onerror';\nimport { installUnhandledRejection } from './handlers/unhandledrejection';\nimport { installConsoleCapture } from './handlers/console';\nimport { parseStack } from './stacktrace';\n\nexport type { ErrorEvent, ErrorsIntegrationOptions, SdkUser, FeatureFlag } from './types';\nexport type { ErrorsApi } from './api';\nexport { BreadcrumbRing } from './breadcrumbs';\nexport { parseStack } from './stacktrace';\n\n/** Shared state exposed as module-level singletons so app code can call\n * leaveBreadcrumb(), setUser(), etc. without holding a ref to the integration. */\nlet _ring: BreadcrumbRing | null = null;\nlet _user: SdkUser | null = null;\nlet _featureFlags: FeatureFlag[] = [];\nlet _contexts: Record<string, Record<string, unknown>> = {};\nlet _client: ClientInterface | null = null;\nlet _opts: Required<ErrorsIntegrationOptions> | null = null;\nlet _networkRingRef: (() => unknown[]) | null = null;\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\n/** Manually capture an error. */\nexport function notify(\n err: Error | string,\n extra?: { level?: 'error' | 'warning' | 'info' },\n): void {\n if (!_client || !_ring || !_opts) return;\n const error = typeof err === 'string' ? new Error(err) : err;\n const frames = parseStack(error);\n const event: ErrorEvent = {\n kind: 'error',\n ts: new Date().toISOString(),\n url: typeof window !== 'undefined' ? window.location.href : '',\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\n viewport:\n typeof window !== 'undefined'\n ? { width: window.innerWidth, height: window.innerHeight }\n : { width: 0, height: 0 },\n level: extra?.level ?? 'error',\n exception: {\n type: error.constructor?.name ?? 'Error',\n value: error.message,\n stacktrace: { frames },\n },\n };\n _sendEvent(event);\n}\n\nexport function leaveBreadcrumb(\n message: string,\n level: BreadcrumbLevel = 'info',\n category: BreadcrumbCategory = 'custom',\n data?: Record<string, unknown>,\n): void {\n _ring?.add(message, level, category, data);\n}\n\nexport function setUser(user: SdkUser | null): void {\n _user = user;\n}\n\nexport function addFeatureFlag(name: string, variant: FeatureFlag['variant']): void {\n const existing = _featureFlags.findIndex(f => f.name === name);\n if (existing >= 0) {\n _featureFlags[existing] = { name, variant };\n } else {\n _featureFlags.push({ name, variant });\n }\n}\n\nexport function clearFeatureFlag(name: string): void {\n _featureFlags = _featureFlags.filter(f => f.name !== name);\n}\n\nexport function setContext(key: string, value: Record<string, unknown> | null): void {\n if (value === null) {\n delete _contexts[key];\n } else {\n _contexts[key] = value;\n }\n}\n\n/** Called by the network integration to register a ring-buffer accessor. */\nexport function _registerNetworkRing(fn: () => unknown[]): void {\n _networkRingRef = fn;\n}\n\n// ─── Internal ────────────────────────────────────────────────────────────────\n\nfunction _sendEvent(event: ErrorEvent): void {\n if (!_client || !_ring || !_opts) return;\n\n const enriched = enrich(event, {\n release: _client.options.release,\n environment: _client.options.environment,\n user: _user ?? (_client.options.user as SdkUser | undefined),\n breadcrumbs: _ring.getAll(),\n featureFlags: _featureFlags,\n networkRing: _networkRingRef ? _networkRingRef() : [],\n contexts: Object.keys(_contexts).length ? _contexts : undefined,\n });\n\n const final = _opts.beforeSend ? _opts.beforeSend(enriched) : enriched;\n if (!final) return;\n\n _client.send(final as any).catch(() => {/* silent */});\n}\n\n// ─── Integration factory ──────────────────────────────────────────────────────\n\nexport function errorsIntegration(opts: ErrorsIntegrationOptions = {}): Integration {\n const teardowns: Array<() => void> = [];\n\n return {\n name: 'errors',\n setup(client: ClientInterface) {\n _client = client;\n _opts = {\n captureGlobalErrors: opts.captureGlobalErrors ?? true,\n captureUnhandledRejections: opts.captureUnhandledRejections ?? true,\n captureConsole: opts.captureConsole ?? false,\n maxBreadcrumbs: opts.maxBreadcrumbs ?? 50,\n beforeSend: opts.beforeSend ?? null as any,\n };\n _ring = new BreadcrumbRing(_opts.maxBreadcrumbs);\n\n if (_opts.captureGlobalErrors) {\n teardowns.push(installOnError(_sendEvent));\n }\n if (_opts.captureUnhandledRejections) {\n teardowns.push(installUnhandledRejection(_sendEvent));\n }\n if (_opts.captureConsole) {\n teardowns.push(\n installConsoleCapture(_sendEvent, (msg, level, cat) =>\n _ring!.add(msg, level, cat),\n ),\n );\n }\n },\n teardown() {\n for (const fn of teardowns) fn();\n teardowns.length = 0;\n _ring = null;\n _client = null;\n _opts = null;\n _user = null;\n _featureFlags = [];\n _contexts = {};\n _networkRingRef = null;\n },\n };\n}\n"],"mappings":"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","names":["BreadcrumbRing","buf","max","add","message","level","category","data","crumb","timestamp","Date","toISOString","push","length","shift","getAll","clear","size","enrich","event","opts","enriched","release","environment","user","breadcrumbs","length","featureFlags","networkRing","contexts","parseStack","err","stack","lines","split","frames","raw","line","trim","startsWith","frame","parseV8Line","parseFirefoxLine","push","atPart","content","slice","withFnMatch","match","fn","filename","lineno","colno","makeFrame","parseInt","noFnMatch","function","in_app","isInApp","includes","installOnError","notify","prev","window","onerror","message","source","lineno","colno","error","frames","type","value","String","parseStack","name","filename","function","in_app","kind","ts","Date","toISOString","url","location","href","userAgent","navigator","viewport","width","innerWidth","height","innerHeight","level","exception","stacktrace","installUnhandledRejection","notify","handler","ev","reason","type","value","String","frames","Error","name","message","parseStack","undefined","JSON","stringify","kind","ts","Date","toISOString","url","window","location","href","userAgent","navigator","viewport","width","innerWidth","height","innerHeight","level","exception","stacktrace","addEventListener","removeEventListener","CAPTURED_METHODS","installConsoleCapture","notify","leaveBreadcrumb","originals","method","console","bind","args","message","map","a","Error","JSON","stringify","String","join","level","_ring","_user","_featureFlags","_contexts","_client","_opts","_networkRingRef","notify","err","extra","error","Error","frames","parseStack","event","kind","ts","Date","toISOString","url","window","location","href","userAgent","navigator","viewport","width","innerWidth","height","innerHeight","level","exception","type","name","value","message","stacktrace","_sendEvent","leaveBreadcrumb","category","data","add","setUser","user","addFeatureFlag","variant","existing","findIndex","f","push","clearFeatureFlag","filter","setContext","key","_registerNetworkRing","fn","enriched","enrich","release","options","environment","breadcrumbs","getAll","featureFlags","networkRing","contexts","Object","keys","length","undefined","final","beforeSend","send","catch","errorsIntegration","opts","teardowns","setup","client","captureGlobalErrors","captureUnhandledRejections","captureConsole","maxBreadcrumbs","BreadcrumbRing","installOnError","installUnhandledRejection","installConsoleCapture","msg","cat","teardown"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@koderlabs/tasks-sdk-web-errors",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser error capture for the InstantTasks SDK — window.onerror + unhandledrejection + console breadcrumbs.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"instanttasks",
|
|
7
|
+
"sdk",
|
|
8
|
+
"browser",
|
|
9
|
+
"errors"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/jawaidgadiwala/instant-tasks/tree/main/packages/sdk/web-errors#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/jawaidgadiwala/instant-tasks/issues"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/jawaidgadiwala/instant-tasks.git",
|
|
18
|
+
"directory": "packages/sdk/web-errors"
|
|
19
|
+
},
|
|
20
|
+
"license": "UNLICENSED",
|
|
21
|
+
"author": {
|
|
22
|
+
"name": "Jawaid Gadiwala",
|
|
23
|
+
"email": "jawaidgadiwala@gmail.com",
|
|
24
|
+
"url": "https://koderlabs.com"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.cjs",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"require": "./dist/index.cjs"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"sideEffects": false,
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@koderlabs/tasks-sdk": "0.1.0",
|
|
44
|
+
"@koderlabs/tasks-sdk-types": "0.1.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"tsup": "^8.3.0",
|
|
48
|
+
"typescript": "^5.5.0",
|
|
49
|
+
"vitest": "^2.1.0"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=20"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "restricted"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsup",
|
|
59
|
+
"dev": "tsup --watch",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"test:watch": "vitest"
|
|
62
|
+
}
|
|
63
|
+
}
|