@adjedaini/clockwork-node 0.0.1 → 0.0.4
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/README.md +6 -0
- package/dist/index.js +5 -193
- package/dist/public/assets/index-BLGoZ6Eh.js +223 -0
- package/dist/public/assets/index-zTRMtvJU.css +1 -0
- package/dist/public/index.html +12 -2
- package/node_modules/@adjedaini/clockwork-core/dist/index.d.ts +3 -0
- package/node_modules/@adjedaini/clockwork-core/dist/index.js +72 -2
- package/node_modules/@adjedaini/clockwork-core/src/index.ts +72 -2
- package/package.json +5 -1
- package/dist/public/assets/index-B2HEyS_P.css +0 -1
- package/dist/public/assets/index-B83PrqXa.css +0 -1
- package/dist/public/assets/index-CdsiP1dN.css +0 -1
- package/dist/public/assets/index-Df9idoqY.js +0 -198
- package/dist/public/assets/index-KmGT-iQM.js +0 -198
- package/dist/public/assets/index-znhjCgo1.js +0 -198
package/README.md
CHANGED
|
@@ -214,6 +214,12 @@ clockwork.registerPlugin(pgPlugin);
|
|
|
214
214
|
|
|
215
215
|
---
|
|
216
216
|
|
|
217
|
+
## Dashboard
|
|
218
|
+
|
|
219
|
+
The built-in UI at `{path}/app` is aligned with [Clockwork](https://underground.works/clockwork/) (PHP): requests list, request detail with **Request**, **Log**, **Database**, and **Timeline** tabs. Override the base path with the `path` option (default `/__clockwork`).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
217
223
|
- **Build:** `npm run build` → packages → UI → root bundle → copy UI to `dist/public`.
|
|
218
224
|
- **Packages:** Plugins live under `packages/`: `clockwork-plugins` (context, console, process-errors, getDefaultPlugins), `clockwork-log-interceptor` (pino, winston), `clockwork-db-interceptor` (pg, mysql2). Root depends on `clockwork-plugins`, which aggregates the others.
|
|
219
225
|
- **Scripts:** `build`, `dev:example`, `dev:ui`, `test`, `clean`, `version` (changesets), `release`.
|
package/dist/index.js
CHANGED
|
@@ -24,196 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
mod
|
|
25
25
|
));
|
|
26
26
|
|
|
27
|
-
// packages/core/dist/index.js
|
|
28
|
-
var require_dist = __commonJS({
|
|
29
|
-
"packages/core/dist/index.js"(exports, module) {
|
|
30
|
-
"use strict";
|
|
31
|
-
var __defProp2 = Object.defineProperty;
|
|
32
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
33
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
34
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
35
|
-
var __export = (target, all) => {
|
|
36
|
-
for (var name in all)
|
|
37
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
38
|
-
};
|
|
39
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
40
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
41
|
-
for (let key of __getOwnPropNames2(from))
|
|
42
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
43
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
44
|
-
}
|
|
45
|
-
return to;
|
|
46
|
-
};
|
|
47
|
-
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
48
|
-
var index_exports = {};
|
|
49
|
-
__export(index_exports, {
|
|
50
|
-
MonitorCore: () => MonitorCore2
|
|
51
|
-
});
|
|
52
|
-
module.exports = __toCommonJS(index_exports);
|
|
53
|
-
var RequestRingBuffer = class {
|
|
54
|
-
constructor(capacity = 100) {
|
|
55
|
-
this.buffer = /* @__PURE__ */ new Map();
|
|
56
|
-
this.order = [];
|
|
57
|
-
this.capacity = Math.max(1, capacity);
|
|
58
|
-
}
|
|
59
|
-
push(id, request) {
|
|
60
|
-
if (this.buffer.has(id)) {
|
|
61
|
-
this.buffer.set(id, request);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
while (this.order.length >= this.capacity && this.order.length > 0) {
|
|
65
|
-
const oldest = this.order.shift();
|
|
66
|
-
this.buffer.delete(oldest);
|
|
67
|
-
}
|
|
68
|
-
this.order.push(id);
|
|
69
|
-
this.buffer.set(id, request);
|
|
70
|
-
}
|
|
71
|
-
get(id) {
|
|
72
|
-
return this.buffer.get(id);
|
|
73
|
-
}
|
|
74
|
-
getAll(limit = 100) {
|
|
75
|
-
const ids = this.order.slice(-limit).reverse();
|
|
76
|
-
return ids.map((id) => this.buffer.get(id)).filter(Boolean);
|
|
77
|
-
}
|
|
78
|
-
getLatest() {
|
|
79
|
-
if (this.order.length === 0) return void 0;
|
|
80
|
-
return this.buffer.get(this.order[this.order.length - 1]);
|
|
81
|
-
}
|
|
82
|
-
count() {
|
|
83
|
-
return this.buffer.size;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
var DEFAULT_MAX_REQUESTS = 100;
|
|
87
|
-
var MonitorCore2 = class {
|
|
88
|
-
constructor(config = {}) {
|
|
89
|
-
this.current = /* @__PURE__ */ new Map();
|
|
90
|
-
this.startedAt = 0;
|
|
91
|
-
this.config = {
|
|
92
|
-
maxRequests: config.maxRequests ?? DEFAULT_MAX_REQUESTS
|
|
93
|
-
};
|
|
94
|
-
this.buffer = config.storage ?? new RequestRingBuffer(this.config.maxRequests);
|
|
95
|
-
}
|
|
96
|
-
/** Start the monitor (call once at bootstrap). */
|
|
97
|
-
start() {
|
|
98
|
-
this.startedAt = Date.now();
|
|
99
|
-
}
|
|
100
|
-
/** Begin capturing a request. Returns request id. */
|
|
101
|
-
captureRequest(initial) {
|
|
102
|
-
const id = initial.id || `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 9)}`;
|
|
103
|
-
const startTime = Date.now();
|
|
104
|
-
const heapAtStart = process.memoryUsage().heapUsed;
|
|
105
|
-
const snapshot = {
|
|
106
|
-
id,
|
|
107
|
-
type: "http",
|
|
108
|
-
method: initial.method ?? "",
|
|
109
|
-
uri: initial.uri ?? "",
|
|
110
|
-
headers: initial.headers ?? {},
|
|
111
|
-
getData: initial.getData ?? {},
|
|
112
|
-
postData: initial.postData,
|
|
113
|
-
cookies: initial.cookies,
|
|
114
|
-
responseStatus: 0,
|
|
115
|
-
responseTime: startTime,
|
|
116
|
-
responseDuration: 0,
|
|
117
|
-
memoryUsage: heapAtStart,
|
|
118
|
-
time: startTime / 1e3,
|
|
119
|
-
log: [],
|
|
120
|
-
databaseQueries: [],
|
|
121
|
-
timelineData: [],
|
|
122
|
-
controller: initial.controller
|
|
123
|
-
};
|
|
124
|
-
this.current.set(id, snapshot);
|
|
125
|
-
return id;
|
|
126
|
-
}
|
|
127
|
-
/** Attach a log entry to a request. */
|
|
128
|
-
captureLog(requestId, level, message, context) {
|
|
129
|
-
const req = this.current.get(requestId);
|
|
130
|
-
if (!req) return;
|
|
131
|
-
const startTime = req.time * 1e3;
|
|
132
|
-
req.log.push({
|
|
133
|
-
level,
|
|
134
|
-
message,
|
|
135
|
-
context,
|
|
136
|
-
time: (Date.now() - startTime) / 1e3,
|
|
137
|
-
source: "clockwork"
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
/** Attach a native (e.g. console) log entry. */
|
|
141
|
-
captureNativeLog(requestId, level, message, context, timeOffset) {
|
|
142
|
-
const req = this.current.get(requestId);
|
|
143
|
-
if (!req) return;
|
|
144
|
-
const startTime = req.time * 1e3;
|
|
145
|
-
req.log.push({
|
|
146
|
-
level,
|
|
147
|
-
message,
|
|
148
|
-
context,
|
|
149
|
-
time: timeOffset ?? (Date.now() - startTime) / 1e3,
|
|
150
|
-
source: "native"
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
/** Capture an error. If requestId is set, also attach to that request's log. */
|
|
154
|
-
captureError(error, requestId) {
|
|
155
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
156
|
-
const context = error instanceof Error ? { name: error.name, stack: error.stack } : void 0;
|
|
157
|
-
if (requestId) {
|
|
158
|
-
this.captureLog(requestId, "error", message, context);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
/** Add a query to a request. */
|
|
162
|
-
addQuery(requestId, data) {
|
|
163
|
-
const req = this.current.get(requestId);
|
|
164
|
-
if (!req) return;
|
|
165
|
-
req.databaseQueries.push(data);
|
|
166
|
-
}
|
|
167
|
-
/** Add a timeline event to a request. */
|
|
168
|
-
addEvent(requestId, data) {
|
|
169
|
-
const req = this.current.get(requestId);
|
|
170
|
-
if (!req) return;
|
|
171
|
-
req.timelineData.push(data);
|
|
172
|
-
}
|
|
173
|
-
/** Update request data (e.g. response status, duration, body). */
|
|
174
|
-
finalizeRequest(requestId, update) {
|
|
175
|
-
const req = this.current.get(requestId);
|
|
176
|
-
if (!req) return;
|
|
177
|
-
req.responseStatus = update.responseStatus;
|
|
178
|
-
req.responseDuration = update.responseDuration;
|
|
179
|
-
if (update.responseData !== void 0) req.responseData = update.responseData;
|
|
180
|
-
req.memoryUsage = process.memoryUsage().heapUsed - req.memoryUsage;
|
|
181
|
-
this.buffer.push(requestId, req);
|
|
182
|
-
this.current.delete(requestId);
|
|
183
|
-
}
|
|
184
|
-
/** Get full request by id. */
|
|
185
|
-
getRequest(id) {
|
|
186
|
-
return this.current.get(id) ?? this.buffer.get(id);
|
|
187
|
-
}
|
|
188
|
-
/** Get snapshot for UI: list of requests + optional metrics. */
|
|
189
|
-
getSnapshot(limit = 50) {
|
|
190
|
-
const all = this.buffer.getAll(limit);
|
|
191
|
-
const requests = all.map((r) => ({
|
|
192
|
-
id: r.id,
|
|
193
|
-
method: r.method,
|
|
194
|
-
uri: r.uri,
|
|
195
|
-
controller: r.controller,
|
|
196
|
-
responseStatus: r.responseStatus,
|
|
197
|
-
responseDuration: r.responseDuration,
|
|
198
|
-
time: r.time
|
|
199
|
-
}));
|
|
200
|
-
return {
|
|
201
|
-
requests,
|
|
202
|
-
metrics: {
|
|
203
|
-
timestamp: Date.now() / 1e3,
|
|
204
|
-
spans: []
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
/** For plugin/collector registration later. */
|
|
209
|
-
registerCollector(_name, _fn) {
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
|
|
215
27
|
// packages/transport-http/dist/index.js
|
|
216
|
-
var
|
|
28
|
+
var require_dist = __commonJS({
|
|
217
29
|
"packages/transport-http/dist/index.js"(exports, module) {
|
|
218
30
|
"use strict";
|
|
219
31
|
var __defProp2 = Object.defineProperty;
|
|
@@ -515,8 +327,8 @@ var require_dist2 = __commonJS({
|
|
|
515
327
|
});
|
|
516
328
|
|
|
517
329
|
// src/index.ts
|
|
518
|
-
var
|
|
519
|
-
|
|
330
|
+
var import_clockwork_transport_http = __toESM(require_dist(), 1);
|
|
331
|
+
import { MonitorCore } from "@adjedaini/clockwork-core";
|
|
520
332
|
import * as path2 from "path";
|
|
521
333
|
import { fileURLToPath } from "url";
|
|
522
334
|
|
|
@@ -598,7 +410,7 @@ function getPathPrefix(p) {
|
|
|
598
410
|
}
|
|
599
411
|
function startClockwork(options = {}) {
|
|
600
412
|
const coreConfig = options.core ?? {};
|
|
601
|
-
const core = new
|
|
413
|
+
const core = new MonitorCore(coreConfig);
|
|
602
414
|
core.start();
|
|
603
415
|
let getRequestIdRef = () => void 0;
|
|
604
416
|
let contextRunnerRef = null;
|
|
@@ -664,7 +476,7 @@ function startClockwork(options = {}) {
|
|
|
664
476
|
}
|
|
665
477
|
var index_default = {
|
|
666
478
|
startClockwork,
|
|
667
|
-
MonitorCore
|
|
479
|
+
MonitorCore,
|
|
668
480
|
createHttpAdapter: import_clockwork_transport_http.createHttpAdapter,
|
|
669
481
|
contextPlugin,
|
|
670
482
|
consolePlugin,
|