@mantiq/heartbeat 0.5.4 → 0.5.6
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/package.json
CHANGED
|
@@ -48,7 +48,13 @@ export class HeartbeatServiceProvider extends ServiceProvider {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
override async boot(): Promise<void> {
|
|
51
|
-
|
|
51
|
+
let heartbeat: Heartbeat
|
|
52
|
+
try {
|
|
53
|
+
heartbeat = this.app.make(Heartbeat)
|
|
54
|
+
} catch (e) {
|
|
55
|
+
console.warn('[Mantiq] HeartbeatServiceProvider skipped — database not configured. Run `bun mantiq migrate` to set up.')
|
|
56
|
+
return
|
|
57
|
+
}
|
|
52
58
|
const config = heartbeat.config
|
|
53
59
|
|
|
54
60
|
if (!config.enabled) return
|
|
@@ -141,36 +141,41 @@ export class HeartbeatMiddleware implements Middleware {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
// Debug mode: attach X-Heartbeat header + inject widget
|
|
144
|
+
// Only for browser requests (HTML pages or SPA navigation), not raw API calls
|
|
144
145
|
if (process.env.APP_DEBUG === 'true' && response!) {
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
146
|
+
const ct = response!.headers.get('content-type') ?? ''
|
|
147
|
+
const isHtml = ct.includes('text/html') && response!.status < 400
|
|
148
|
+
const isSPA = request.header('X-Mantiq') === 'true'
|
|
149
|
+
|
|
150
|
+
if (isHtml || isSPA) {
|
|
151
|
+
const totalDuration = performance.now() - startTime
|
|
152
|
+
const totalMemory = Math.abs(process.memoryUsage().rss - startMemory)
|
|
153
|
+
const mem = (totalMemory / 1024 / 1024).toFixed(1)
|
|
154
|
+
const statsHeader = `${Math.round(totalDuration)}ms;${mem}MB;${response!.status};0q`
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const cloned = response!.clone()
|
|
158
|
+
const body = await cloned.text()
|
|
159
|
+
const headers = new Headers(response!.headers)
|
|
160
|
+
|
|
161
|
+
headers.set('X-Heartbeat', statsHeader)
|
|
162
|
+
headers.set('Access-Control-Expose-Headers', [headers.get('Access-Control-Expose-Headers'), 'X-Heartbeat'].filter(Boolean).join(', '))
|
|
163
|
+
|
|
164
|
+
let finalBody = body
|
|
165
|
+
if (isHtml && this.heartbeat.config.widget?.enabled !== false && body.includes('</body>')) {
|
|
166
|
+
const widget = renderWidget({
|
|
167
|
+
duration: totalDuration,
|
|
168
|
+
memory: totalMemory,
|
|
169
|
+
status: response!.status,
|
|
170
|
+
queries: 0,
|
|
171
|
+
dashboardPath: this.heartbeat.config.dashboard.path,
|
|
172
|
+
})
|
|
173
|
+
finalBody = body.replace('</body>', widget + '\n</body>')
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
response = new Response(finalBody, { status: response!.status, statusText: response!.statusText, headers })
|
|
177
|
+
} catch (e) { console.error('[Heartbeat Widget]', e) }
|
|
178
|
+
}
|
|
174
179
|
}
|
|
175
180
|
|
|
176
181
|
return response!
|