@tarslogs/client 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/dist/hono-DIKyVc9C.d.cts +112 -0
- package/dist/hono-DIKyVc9C.d.ts +112 -0
- package/dist/hono.cjs +328 -0
- package/dist/hono.cjs.map +1 -0
- package/dist/hono.d.cts +1 -0
- package/dist/hono.d.ts +1 -0
- package/dist/hono.js +300 -0
- package/dist/hono.js.map +1 -0
- package/dist/index.cjs +463 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +58 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +450 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface TarslogsConfig {
|
|
2
|
+
/** API URL, e.g., https://api.tarslogs.com */
|
|
3
|
+
url: string;
|
|
4
|
+
/** Project identifier */
|
|
5
|
+
projectId: string;
|
|
6
|
+
/** Project API key */
|
|
7
|
+
apiKey: string;
|
|
8
|
+
/** Environment name (production, staging, etc.) */
|
|
9
|
+
environment?: string;
|
|
10
|
+
/** App version or commit hash (for source map resolution) */
|
|
11
|
+
version?: string;
|
|
12
|
+
/** Client-side rate limit per minute (default: 30) */
|
|
13
|
+
rateLimitPerMinute?: number;
|
|
14
|
+
/** Log transport activity to console (default: false) */
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface ErrorPayload {
|
|
18
|
+
message: string;
|
|
19
|
+
stack?: string;
|
|
20
|
+
file?: string;
|
|
21
|
+
line?: number;
|
|
22
|
+
col?: number;
|
|
23
|
+
environment?: string;
|
|
24
|
+
version?: string;
|
|
25
|
+
context?: Record<string, any>;
|
|
26
|
+
timestamp?: string;
|
|
27
|
+
}
|
|
28
|
+
interface MetricPayload {
|
|
29
|
+
name: string;
|
|
30
|
+
type: 'counter' | 'gauge' | 'histogram';
|
|
31
|
+
value: number;
|
|
32
|
+
tags?: Record<string, string>;
|
|
33
|
+
timestamp?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare class TarslogsClient {
|
|
37
|
+
private config;
|
|
38
|
+
private transport;
|
|
39
|
+
private context;
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the client with configuration.
|
|
42
|
+
* Must be called before any other methods.
|
|
43
|
+
*/
|
|
44
|
+
init(config: TarslogsConfig): void;
|
|
45
|
+
/**
|
|
46
|
+
* Merge additional context that will be sent with all errors and metrics.
|
|
47
|
+
* Useful for setting userId, route, etc.
|
|
48
|
+
*/
|
|
49
|
+
setContext(ctx: Record<string, any>): void;
|
|
50
|
+
/**
|
|
51
|
+
* Clear all context (e.g., on logout).
|
|
52
|
+
*/
|
|
53
|
+
clearContext(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Capture an error and send to TarsLogs.
|
|
56
|
+
*/
|
|
57
|
+
captureError(error: Error | string, extra?: Record<string, any>): void;
|
|
58
|
+
/**
|
|
59
|
+
* Increment a counter metric.
|
|
60
|
+
*/
|
|
61
|
+
increment(name: string, value?: number, tags?: Record<string, string>): void;
|
|
62
|
+
/**
|
|
63
|
+
* Set a gauge metric (point-in-time value).
|
|
64
|
+
*/
|
|
65
|
+
gauge(name: string, value: number, tags?: Record<string, string>): void;
|
|
66
|
+
/**
|
|
67
|
+
* Record a histogram metric (distribution of values).
|
|
68
|
+
*/
|
|
69
|
+
histogram(name: string, value: number, tags?: Record<string, string>): void;
|
|
70
|
+
/**
|
|
71
|
+
* Flush all pending payloads immediately.
|
|
72
|
+
* Call before page unload or process exit.
|
|
73
|
+
*/
|
|
74
|
+
flush(): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface HonoContext {
|
|
78
|
+
req: {
|
|
79
|
+
method: string;
|
|
80
|
+
path: string;
|
|
81
|
+
url: string;
|
|
82
|
+
};
|
|
83
|
+
res: {
|
|
84
|
+
status: number;
|
|
85
|
+
};
|
|
86
|
+
json: (data: unknown, status?: number) => Response;
|
|
87
|
+
}
|
|
88
|
+
type HonoNext = () => Promise<void>;
|
|
89
|
+
interface HonoMiddleware {
|
|
90
|
+
(c: HonoContext, next: HonoNext): Promise<Response | void>;
|
|
91
|
+
}
|
|
92
|
+
interface HonoApp {
|
|
93
|
+
use: (path: string, ...handlers: HonoMiddleware[]) => void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Hono middleware factory that catches errors in route handlers
|
|
97
|
+
* and reports them to TarsLogs.
|
|
98
|
+
*
|
|
99
|
+
* Usage:
|
|
100
|
+
* app.use('*', tarslogsMiddleware(tarslogsClient))
|
|
101
|
+
*/
|
|
102
|
+
declare function tarslogsMiddleware(client: TarslogsClient): HonoMiddleware;
|
|
103
|
+
/**
|
|
104
|
+
* One-line setup: initializes a TarslogsClient and attaches
|
|
105
|
+
* the middleware to a Hono app.
|
|
106
|
+
*
|
|
107
|
+
* Usage:
|
|
108
|
+
* const tarslogs = tarslogsHono(app, { url: '...', projectId: '...', apiKey: '...' })
|
|
109
|
+
*/
|
|
110
|
+
declare function tarslogsHono(app: HonoApp, config: TarslogsConfig): TarslogsClient;
|
|
111
|
+
|
|
112
|
+
export { type ErrorPayload as E, type MetricPayload as M, type TarslogsConfig as T, TarslogsClient as a, tarslogsMiddleware as b, tarslogsHono as t };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface TarslogsConfig {
|
|
2
|
+
/** API URL, e.g., https://api.tarslogs.com */
|
|
3
|
+
url: string;
|
|
4
|
+
/** Project identifier */
|
|
5
|
+
projectId: string;
|
|
6
|
+
/** Project API key */
|
|
7
|
+
apiKey: string;
|
|
8
|
+
/** Environment name (production, staging, etc.) */
|
|
9
|
+
environment?: string;
|
|
10
|
+
/** App version or commit hash (for source map resolution) */
|
|
11
|
+
version?: string;
|
|
12
|
+
/** Client-side rate limit per minute (default: 30) */
|
|
13
|
+
rateLimitPerMinute?: number;
|
|
14
|
+
/** Log transport activity to console (default: false) */
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface ErrorPayload {
|
|
18
|
+
message: string;
|
|
19
|
+
stack?: string;
|
|
20
|
+
file?: string;
|
|
21
|
+
line?: number;
|
|
22
|
+
col?: number;
|
|
23
|
+
environment?: string;
|
|
24
|
+
version?: string;
|
|
25
|
+
context?: Record<string, any>;
|
|
26
|
+
timestamp?: string;
|
|
27
|
+
}
|
|
28
|
+
interface MetricPayload {
|
|
29
|
+
name: string;
|
|
30
|
+
type: 'counter' | 'gauge' | 'histogram';
|
|
31
|
+
value: number;
|
|
32
|
+
tags?: Record<string, string>;
|
|
33
|
+
timestamp?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare class TarslogsClient {
|
|
37
|
+
private config;
|
|
38
|
+
private transport;
|
|
39
|
+
private context;
|
|
40
|
+
/**
|
|
41
|
+
* Initialize the client with configuration.
|
|
42
|
+
* Must be called before any other methods.
|
|
43
|
+
*/
|
|
44
|
+
init(config: TarslogsConfig): void;
|
|
45
|
+
/**
|
|
46
|
+
* Merge additional context that will be sent with all errors and metrics.
|
|
47
|
+
* Useful for setting userId, route, etc.
|
|
48
|
+
*/
|
|
49
|
+
setContext(ctx: Record<string, any>): void;
|
|
50
|
+
/**
|
|
51
|
+
* Clear all context (e.g., on logout).
|
|
52
|
+
*/
|
|
53
|
+
clearContext(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Capture an error and send to TarsLogs.
|
|
56
|
+
*/
|
|
57
|
+
captureError(error: Error | string, extra?: Record<string, any>): void;
|
|
58
|
+
/**
|
|
59
|
+
* Increment a counter metric.
|
|
60
|
+
*/
|
|
61
|
+
increment(name: string, value?: number, tags?: Record<string, string>): void;
|
|
62
|
+
/**
|
|
63
|
+
* Set a gauge metric (point-in-time value).
|
|
64
|
+
*/
|
|
65
|
+
gauge(name: string, value: number, tags?: Record<string, string>): void;
|
|
66
|
+
/**
|
|
67
|
+
* Record a histogram metric (distribution of values).
|
|
68
|
+
*/
|
|
69
|
+
histogram(name: string, value: number, tags?: Record<string, string>): void;
|
|
70
|
+
/**
|
|
71
|
+
* Flush all pending payloads immediately.
|
|
72
|
+
* Call before page unload or process exit.
|
|
73
|
+
*/
|
|
74
|
+
flush(): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface HonoContext {
|
|
78
|
+
req: {
|
|
79
|
+
method: string;
|
|
80
|
+
path: string;
|
|
81
|
+
url: string;
|
|
82
|
+
};
|
|
83
|
+
res: {
|
|
84
|
+
status: number;
|
|
85
|
+
};
|
|
86
|
+
json: (data: unknown, status?: number) => Response;
|
|
87
|
+
}
|
|
88
|
+
type HonoNext = () => Promise<void>;
|
|
89
|
+
interface HonoMiddleware {
|
|
90
|
+
(c: HonoContext, next: HonoNext): Promise<Response | void>;
|
|
91
|
+
}
|
|
92
|
+
interface HonoApp {
|
|
93
|
+
use: (path: string, ...handlers: HonoMiddleware[]) => void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Hono middleware factory that catches errors in route handlers
|
|
97
|
+
* and reports them to TarsLogs.
|
|
98
|
+
*
|
|
99
|
+
* Usage:
|
|
100
|
+
* app.use('*', tarslogsMiddleware(tarslogsClient))
|
|
101
|
+
*/
|
|
102
|
+
declare function tarslogsMiddleware(client: TarslogsClient): HonoMiddleware;
|
|
103
|
+
/**
|
|
104
|
+
* One-line setup: initializes a TarslogsClient and attaches
|
|
105
|
+
* the middleware to a Hono app.
|
|
106
|
+
*
|
|
107
|
+
* Usage:
|
|
108
|
+
* const tarslogs = tarslogsHono(app, { url: '...', projectId: '...', apiKey: '...' })
|
|
109
|
+
*/
|
|
110
|
+
declare function tarslogsHono(app: HonoApp, config: TarslogsConfig): TarslogsClient;
|
|
111
|
+
|
|
112
|
+
export { type ErrorPayload as E, type MetricPayload as M, type TarslogsConfig as T, TarslogsClient as a, tarslogsMiddleware as b, tarslogsHono as t };
|
package/dist/hono.cjs
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
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 __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/hono.ts
|
|
21
|
+
var hono_exports = {};
|
|
22
|
+
__export(hono_exports, {
|
|
23
|
+
tarslogsHono: () => tarslogsHono,
|
|
24
|
+
tarslogsMiddleware: () => tarslogsMiddleware
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(hono_exports);
|
|
27
|
+
|
|
28
|
+
// src/transport.ts
|
|
29
|
+
var Transport = class {
|
|
30
|
+
config = null;
|
|
31
|
+
errorQueue = [];
|
|
32
|
+
metricQueue = [];
|
|
33
|
+
flushTimer = null;
|
|
34
|
+
rateLimitState = {
|
|
35
|
+
timestamps: [],
|
|
36
|
+
maxPerMinute: 30
|
|
37
|
+
};
|
|
38
|
+
retryQueue = [];
|
|
39
|
+
init(config) {
|
|
40
|
+
this.config = config;
|
|
41
|
+
this.rateLimitState.maxPerMinute = config.rateLimitPerMinute ?? 30;
|
|
42
|
+
this.flushTimer = setInterval(() => {
|
|
43
|
+
this.flushAll();
|
|
44
|
+
}, 5e3);
|
|
45
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
46
|
+
window.addEventListener("visibilitychange", () => {
|
|
47
|
+
if (document.visibilityState === "hidden") {
|
|
48
|
+
this.flushAllBeacon();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
window.addEventListener("pagehide", () => {
|
|
52
|
+
this.flushAllBeacon();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
destroy() {
|
|
57
|
+
if (this.flushTimer) {
|
|
58
|
+
clearInterval(this.flushTimer);
|
|
59
|
+
this.flushTimer = null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
log(...args) {
|
|
63
|
+
if (this.config?.debug) {
|
|
64
|
+
console.log("[tarslogs]", ...args);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
checkRateLimit() {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
const windowStart = now - 6e4;
|
|
70
|
+
this.rateLimitState.timestamps = this.rateLimitState.timestamps.filter(
|
|
71
|
+
(t) => t > windowStart
|
|
72
|
+
);
|
|
73
|
+
if (this.rateLimitState.timestamps.length >= this.rateLimitState.maxPerMinute) {
|
|
74
|
+
this.log("Rate limit reached, dropping payload");
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
this.rateLimitState.timestamps.push(now);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
enqueueError(payload) {
|
|
81
|
+
if (!this.config) return;
|
|
82
|
+
if (!this.checkRateLimit()) return;
|
|
83
|
+
this.errorQueue.push(payload);
|
|
84
|
+
this.log("Error queued:", payload.message);
|
|
85
|
+
if (this.errorQueue.length >= 10) {
|
|
86
|
+
this.flushErrors();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
enqueueMetric(payload) {
|
|
90
|
+
if (!this.config) return;
|
|
91
|
+
if (!this.checkRateLimit()) return;
|
|
92
|
+
this.metricQueue.push(payload);
|
|
93
|
+
this.log("Metric queued:", payload.name, payload.value);
|
|
94
|
+
if (this.metricQueue.length >= 10) {
|
|
95
|
+
this.flushMetrics();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
getHeaders() {
|
|
99
|
+
return {
|
|
100
|
+
"Content-Type": "application/json",
|
|
101
|
+
"x-tarslogs-key": this.config.apiKey
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
async sendFetch(url, body) {
|
|
105
|
+
try {
|
|
106
|
+
const res = await fetch(url, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: this.getHeaders(),
|
|
109
|
+
body
|
|
110
|
+
});
|
|
111
|
+
if (!res.ok) {
|
|
112
|
+
this.log("Send failed:", res.status, res.statusText);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
this.log("Send success:", url);
|
|
116
|
+
return true;
|
|
117
|
+
} catch (err) {
|
|
118
|
+
this.log("Send error:", err);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async sendWithRetry(url, body) {
|
|
123
|
+
const success = await this.sendFetch(url, body);
|
|
124
|
+
if (!success) {
|
|
125
|
+
this.retryQueue.push({ url, body });
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
this.processRetryQueue();
|
|
128
|
+
}, 5e3);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async processRetryQueue() {
|
|
132
|
+
const items = this.retryQueue.splice(0, this.retryQueue.length);
|
|
133
|
+
for (const item of items) {
|
|
134
|
+
await this.sendFetch(item.url, item.body);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async flushErrors() {
|
|
138
|
+
if (!this.config || this.errorQueue.length === 0) return;
|
|
139
|
+
const errors = this.errorQueue.splice(0, this.errorQueue.length);
|
|
140
|
+
const url = `${this.config.url}/ingest/errors`;
|
|
141
|
+
const body = JSON.stringify({ errors });
|
|
142
|
+
this.log(`Flushing ${errors.length} errors`);
|
|
143
|
+
await this.sendWithRetry(url, body);
|
|
144
|
+
}
|
|
145
|
+
async flushMetrics() {
|
|
146
|
+
if (!this.config || this.metricQueue.length === 0) return;
|
|
147
|
+
const metrics = this.metricQueue.splice(0, this.metricQueue.length);
|
|
148
|
+
const url = `${this.config.url}/ingest/metrics`;
|
|
149
|
+
const body = JSON.stringify({ metrics });
|
|
150
|
+
this.log(`Flushing ${metrics.length} metrics`);
|
|
151
|
+
await this.sendWithRetry(url, body);
|
|
152
|
+
}
|
|
153
|
+
flushAllBeacon() {
|
|
154
|
+
if (!this.config) return;
|
|
155
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
156
|
+
if (this.errorQueue.length > 0) {
|
|
157
|
+
const errors = this.errorQueue.splice(0, this.errorQueue.length);
|
|
158
|
+
const blob = new Blob(
|
|
159
|
+
[JSON.stringify({ errors })],
|
|
160
|
+
{ type: "application/json" }
|
|
161
|
+
);
|
|
162
|
+
navigator.sendBeacon(
|
|
163
|
+
`${this.config.url}/ingest/errors?key=${this.config.apiKey}`,
|
|
164
|
+
blob
|
|
165
|
+
);
|
|
166
|
+
this.log("Beacon sent errors:", errors.length);
|
|
167
|
+
}
|
|
168
|
+
if (this.metricQueue.length > 0) {
|
|
169
|
+
const metrics = this.metricQueue.splice(0, this.metricQueue.length);
|
|
170
|
+
const blob = new Blob(
|
|
171
|
+
[JSON.stringify({ metrics })],
|
|
172
|
+
{ type: "application/json" }
|
|
173
|
+
);
|
|
174
|
+
navigator.sendBeacon(
|
|
175
|
+
`${this.config.url}/ingest/metrics?key=${this.config.apiKey}`,
|
|
176
|
+
blob
|
|
177
|
+
);
|
|
178
|
+
this.log("Beacon sent metrics:", metrics.length);
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
this.flushAll();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async flushAll() {
|
|
185
|
+
await Promise.all([this.flushErrors(), this.flushMetrics()]);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/core.ts
|
|
190
|
+
var TarslogsClient = class {
|
|
191
|
+
config = null;
|
|
192
|
+
transport = new Transport();
|
|
193
|
+
context = {};
|
|
194
|
+
/**
|
|
195
|
+
* Initialize the client with configuration.
|
|
196
|
+
* Must be called before any other methods.
|
|
197
|
+
*/
|
|
198
|
+
init(config) {
|
|
199
|
+
this.config = config;
|
|
200
|
+
this.transport.init(config);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Merge additional context that will be sent with all errors and metrics.
|
|
204
|
+
* Useful for setting userId, route, etc.
|
|
205
|
+
*/
|
|
206
|
+
setContext(ctx) {
|
|
207
|
+
this.context = { ...this.context, ...ctx };
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Clear all context (e.g., on logout).
|
|
211
|
+
*/
|
|
212
|
+
clearContext() {
|
|
213
|
+
this.context = {};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Capture an error and send to TarsLogs.
|
|
217
|
+
*/
|
|
218
|
+
captureError(error, extra) {
|
|
219
|
+
if (!this.config) return;
|
|
220
|
+
let payload;
|
|
221
|
+
if (typeof error === "string") {
|
|
222
|
+
payload = {
|
|
223
|
+
message: error,
|
|
224
|
+
environment: this.config.environment,
|
|
225
|
+
version: this.config.version,
|
|
226
|
+
context: { ...this.context, ...extra },
|
|
227
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
228
|
+
};
|
|
229
|
+
} else {
|
|
230
|
+
payload = {
|
|
231
|
+
message: error.message,
|
|
232
|
+
stack: error.stack,
|
|
233
|
+
environment: this.config.environment,
|
|
234
|
+
version: this.config.version,
|
|
235
|
+
context: { ...this.context, ...extra },
|
|
236
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
237
|
+
};
|
|
238
|
+
if (error.stack) {
|
|
239
|
+
const match = error.stack.match(/(?:at\s+.+\s+\(|at\s+)(.+):(\d+):(\d+)\)?/);
|
|
240
|
+
if (match) {
|
|
241
|
+
payload.file = match[1];
|
|
242
|
+
payload.line = parseInt(match[2], 10);
|
|
243
|
+
payload.col = parseInt(match[3], 10);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
this.transport.enqueueError(payload);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Increment a counter metric.
|
|
251
|
+
*/
|
|
252
|
+
increment(name, value = 1, tags) {
|
|
253
|
+
if (!this.config) return;
|
|
254
|
+
const payload = {
|
|
255
|
+
name,
|
|
256
|
+
type: "counter",
|
|
257
|
+
value,
|
|
258
|
+
tags,
|
|
259
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
260
|
+
};
|
|
261
|
+
this.transport.enqueueMetric(payload);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Set a gauge metric (point-in-time value).
|
|
265
|
+
*/
|
|
266
|
+
gauge(name, value, tags) {
|
|
267
|
+
if (!this.config) return;
|
|
268
|
+
const payload = {
|
|
269
|
+
name,
|
|
270
|
+
type: "gauge",
|
|
271
|
+
value,
|
|
272
|
+
tags,
|
|
273
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
274
|
+
};
|
|
275
|
+
this.transport.enqueueMetric(payload);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Record a histogram metric (distribution of values).
|
|
279
|
+
*/
|
|
280
|
+
histogram(name, value, tags) {
|
|
281
|
+
if (!this.config) return;
|
|
282
|
+
const payload = {
|
|
283
|
+
name,
|
|
284
|
+
type: "histogram",
|
|
285
|
+
value,
|
|
286
|
+
tags,
|
|
287
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
288
|
+
};
|
|
289
|
+
this.transport.enqueueMetric(payload);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Flush all pending payloads immediately.
|
|
293
|
+
* Call before page unload or process exit.
|
|
294
|
+
*/
|
|
295
|
+
async flush() {
|
|
296
|
+
await this.transport.flushAll();
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
// src/hono.ts
|
|
301
|
+
function tarslogsMiddleware(client) {
|
|
302
|
+
return async (c, next) => {
|
|
303
|
+
try {
|
|
304
|
+
await next();
|
|
305
|
+
} catch (err) {
|
|
306
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
307
|
+
client.captureError(error, {
|
|
308
|
+
source: "hono-middleware",
|
|
309
|
+
method: c.req.method,
|
|
310
|
+
path: c.req.path,
|
|
311
|
+
url: c.req.url
|
|
312
|
+
});
|
|
313
|
+
throw err;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function tarslogsHono(app, config) {
|
|
318
|
+
const client = new TarslogsClient();
|
|
319
|
+
client.init(config);
|
|
320
|
+
app.use("*", tarslogsMiddleware(client));
|
|
321
|
+
return client;
|
|
322
|
+
}
|
|
323
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
324
|
+
0 && (module.exports = {
|
|
325
|
+
tarslogsHono,
|
|
326
|
+
tarslogsMiddleware
|
|
327
|
+
});
|
|
328
|
+
//# sourceMappingURL=hono.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hono.ts","../src/transport.ts","../src/core.ts"],"sourcesContent":["import { TarslogsClient } from './core'\nimport type { TarslogsConfig } from './types'\n\n// Server-side Hono middleware — NO browser globals (window, document, navigator)\n\ninterface HonoContext {\n req: {\n method: string\n path: string\n url: string\n }\n res: {\n status: number\n }\n json: (data: unknown, status?: number) => Response\n}\n\ntype HonoNext = () => Promise<void>\n\ninterface HonoMiddleware {\n (c: HonoContext, next: HonoNext): Promise<Response | void>\n}\n\ninterface HonoApp {\n use: (path: string, ...handlers: HonoMiddleware[]) => void\n}\n\n/**\n * Hono middleware factory that catches errors in route handlers\n * and reports them to TarsLogs.\n *\n * Usage:\n * app.use('*', tarslogsMiddleware(tarslogsClient))\n */\nexport function tarslogsMiddleware(client: TarslogsClient): HonoMiddleware {\n return async (c: HonoContext, next: HonoNext): Promise<Response | void> => {\n try {\n await next()\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err))\n\n client.captureError(error, {\n source: 'hono-middleware',\n method: c.req.method,\n path: c.req.path,\n url: c.req.url,\n })\n\n // Re-throw so Hono's error handler can deal with it\n throw err\n }\n }\n}\n\n/**\n * One-line setup: initializes a TarslogsClient and attaches\n * the middleware to a Hono app.\n *\n * Usage:\n * const tarslogs = tarslogsHono(app, { url: '...', projectId: '...', apiKey: '...' })\n */\nexport function tarslogsHono(app: HonoApp, config: TarslogsConfig): TarslogsClient {\n const client = new TarslogsClient()\n client.init(config)\n app.use('*', tarslogsMiddleware(client))\n return client\n}\n","import type { TarslogsConfig, ErrorPayload, MetricPayload } from './types'\n\ninterface RateLimitState {\n timestamps: number[]\n maxPerMinute: number\n}\n\nexport class Transport {\n private config: TarslogsConfig | null = null\n private errorQueue: ErrorPayload[] = []\n private metricQueue: MetricPayload[] = []\n private flushTimer: ReturnType<typeof setInterval> | null = null\n private rateLimitState: RateLimitState = {\n timestamps: [],\n maxPerMinute: 30,\n }\n private retryQueue: Array<{ url: string; body: string }> = []\n\n init(config: TarslogsConfig): void {\n this.config = config\n this.rateLimitState.maxPerMinute = config.rateLimitPerMinute ?? 30\n\n // Start periodic flush\n this.flushTimer = setInterval(() => {\n this.flushAll()\n }, 5000)\n\n // Register page unload handler (browser only)\n if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n this.flushAllBeacon()\n }\n })\n window.addEventListener('pagehide', () => {\n this.flushAllBeacon()\n })\n }\n }\n\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.config?.debug) {\n console.log('[tarslogs]', ...args)\n }\n }\n\n private checkRateLimit(): boolean {\n const now = Date.now()\n const windowStart = now - 60_000\n\n // Remove timestamps outside the window\n this.rateLimitState.timestamps = this.rateLimitState.timestamps.filter(\n (t) => t > windowStart\n )\n\n if (this.rateLimitState.timestamps.length >= this.rateLimitState.maxPerMinute) {\n this.log('Rate limit reached, dropping payload')\n return false\n }\n\n this.rateLimitState.timestamps.push(now)\n return true\n }\n\n enqueueError(payload: ErrorPayload): void {\n if (!this.config) return\n if (!this.checkRateLimit()) return\n\n this.errorQueue.push(payload)\n this.log('Error queued:', payload.message)\n\n if (this.errorQueue.length >= 10) {\n this.flushErrors()\n }\n }\n\n enqueueMetric(payload: MetricPayload): void {\n if (!this.config) return\n if (!this.checkRateLimit()) return\n\n this.metricQueue.push(payload)\n this.log('Metric queued:', payload.name, payload.value)\n\n if (this.metricQueue.length >= 10) {\n this.flushMetrics()\n }\n }\n\n private getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'x-tarslogs-key': this.config!.apiKey,\n }\n }\n\n private async sendFetch(url: string, body: string): Promise<boolean> {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: this.getHeaders(),\n body,\n })\n if (!res.ok) {\n this.log('Send failed:', res.status, res.statusText)\n return false\n }\n this.log('Send success:', url)\n return true\n } catch (err) {\n this.log('Send error:', err)\n return false\n }\n }\n\n private async sendWithRetry(url: string, body: string): Promise<void> {\n const success = await this.sendFetch(url, body)\n if (!success) {\n // Retry once after 5s\n this.retryQueue.push({ url, body })\n setTimeout(() => {\n this.processRetryQueue()\n }, 5000)\n }\n }\n\n private async processRetryQueue(): Promise<void> {\n const items = this.retryQueue.splice(0, this.retryQueue.length)\n for (const item of items) {\n await this.sendFetch(item.url, item.body)\n }\n }\n\n private async flushErrors(): Promise<void> {\n if (!this.config || this.errorQueue.length === 0) return\n\n const errors = this.errorQueue.splice(0, this.errorQueue.length)\n const url = `${this.config.url}/ingest/errors`\n const body = JSON.stringify({ errors })\n\n this.log(`Flushing ${errors.length} errors`)\n await this.sendWithRetry(url, body)\n }\n\n private async flushMetrics(): Promise<void> {\n if (!this.config || this.metricQueue.length === 0) return\n\n const metrics = this.metricQueue.splice(0, this.metricQueue.length)\n const url = `${this.config.url}/ingest/metrics`\n const body = JSON.stringify({ metrics })\n\n this.log(`Flushing ${metrics.length} metrics`)\n await this.sendWithRetry(url, body)\n }\n\n private flushAllBeacon(): void {\n if (!this.config) return\n\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n if (this.errorQueue.length > 0) {\n const errors = this.errorQueue.splice(0, this.errorQueue.length)\n const blob = new Blob(\n [JSON.stringify({ errors })],\n { type: 'application/json' }\n )\n // sendBeacon doesn't support custom headers, so we embed the key in the URL\n navigator.sendBeacon(\n `${this.config.url}/ingest/errors?key=${this.config.apiKey}`,\n blob\n )\n this.log('Beacon sent errors:', errors.length)\n }\n\n if (this.metricQueue.length > 0) {\n const metrics = this.metricQueue.splice(0, this.metricQueue.length)\n const blob = new Blob(\n [JSON.stringify({ metrics })],\n { type: 'application/json' }\n )\n navigator.sendBeacon(\n `${this.config.url}/ingest/metrics?key=${this.config.apiKey}`,\n blob\n )\n this.log('Beacon sent metrics:', metrics.length)\n }\n } else {\n // Fallback to fetch\n this.flushAll()\n }\n }\n\n async flushAll(): Promise<void> {\n await Promise.all([this.flushErrors(), this.flushMetrics()])\n }\n}\n","import type { TarslogsConfig, ErrorPayload, MetricPayload } from './types'\nimport { Transport } from './transport'\n\nexport type { TarslogsConfig } from './types'\n\nexport class TarslogsClient {\n private config: TarslogsConfig | null = null\n private transport = new Transport()\n private context: Record<string, any> = {}\n\n /**\n * Initialize the client with configuration.\n * Must be called before any other methods.\n */\n init(config: TarslogsConfig): void {\n this.config = config\n this.transport.init(config)\n }\n\n /**\n * Merge additional context that will be sent with all errors and metrics.\n * Useful for setting userId, route, etc.\n */\n setContext(ctx: Record<string, any>): void {\n this.context = { ...this.context, ...ctx }\n }\n\n /**\n * Clear all context (e.g., on logout).\n */\n clearContext(): void {\n this.context = {}\n }\n\n /**\n * Capture an error and send to TarsLogs.\n */\n captureError(error: Error | string, extra?: Record<string, any>): void {\n if (!this.config) return\n\n let payload: ErrorPayload\n\n if (typeof error === 'string') {\n payload = {\n message: error,\n environment: this.config.environment,\n version: this.config.version,\n context: { ...this.context, ...extra },\n timestamp: new Date().toISOString(),\n }\n } else {\n payload = {\n message: error.message,\n stack: error.stack,\n environment: this.config.environment,\n version: this.config.version,\n context: { ...this.context, ...extra },\n timestamp: new Date().toISOString(),\n }\n\n // Try to extract file/line/col from stack\n if (error.stack) {\n const match = error.stack.match(/(?:at\\s+.+\\s+\\(|at\\s+)(.+):(\\d+):(\\d+)\\)?/)\n if (match) {\n payload.file = match[1]\n payload.line = parseInt(match[2], 10)\n payload.col = parseInt(match[3], 10)\n }\n }\n }\n\n this.transport.enqueueError(payload)\n }\n\n /**\n * Increment a counter metric.\n */\n increment(name: string, value: number = 1, tags?: Record<string, string>): void {\n if (!this.config) return\n const payload: MetricPayload = {\n name,\n type: 'counter',\n value,\n tags,\n timestamp: new Date().toISOString(),\n }\n this.transport.enqueueMetric(payload)\n }\n\n /**\n * Set a gauge metric (point-in-time value).\n */\n gauge(name: string, value: number, tags?: Record<string, string>): void {\n if (!this.config) return\n const payload: MetricPayload = {\n name,\n type: 'gauge',\n value,\n tags,\n timestamp: new Date().toISOString(),\n }\n this.transport.enqueueMetric(payload)\n }\n\n /**\n * Record a histogram metric (distribution of values).\n */\n histogram(name: string, value: number, tags?: Record<string, string>): void {\n if (!this.config) return\n const payload: MetricPayload = {\n name,\n type: 'histogram',\n value,\n tags,\n timestamp: new Date().toISOString(),\n }\n this.transport.enqueueMetric(payload)\n }\n\n /**\n * Flush all pending payloads immediately.\n * Call before page unload or process exit.\n */\n async flush(): Promise<void> {\n await this.transport.flushAll()\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/hono.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as tarslogsHono, b as tarslogsMiddleware } from './hono-DIKyVc9C.cjs';
|
package/dist/hono.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as tarslogsHono, b as tarslogsMiddleware } from './hono-DIKyVc9C.js';
|