@revealui/core 0.12.0 → 0.12.1
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 +2 -3
- package/dist/api/rest.js +4 -4
- package/dist/client/admin/utils/csrf.d.ts +9 -6
- package/dist/client/admin/utils/csrf.d.ts.map +1 -1
- package/dist/client/admin/utils/csrf.js +9 -6
- package/dist/collections/operations/fieldValidation.d.ts +5 -16
- package/dist/collections/operations/fieldValidation.d.ts.map +1 -1
- package/dist/collections/operations/fieldValidation.js +5 -20
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +4 -2
- package/dist/database/safe-parse.js +3 -3
- package/dist/database/universal-postgres.d.ts.map +1 -1
- package/dist/database/universal-postgres.js +10 -13
- package/dist/deployment-mode.d.ts +44 -0
- package/dist/deployment-mode.d.ts.map +1 -0
- package/dist/deployment-mode.js +58 -0
- package/dist/error-handling/error-boundary.d.ts +16 -2
- package/dist/error-handling/error-boundary.d.ts.map +1 -1
- package/dist/error-handling/error-boundary.js +18 -3
- package/dist/error-handling/error-reporter.d.ts +1 -1
- package/dist/error-handling/error-reporter.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.js +6 -2
- package/dist/error-handling/index.d.ts +1 -1
- package/dist/error-handling/index.d.ts.map +1 -1
- package/dist/error-handling/index.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/instance/logger.d.ts +18 -7
- package/dist/instance/logger.d.ts.map +1 -1
- package/dist/instance/logger.js +66 -17
- package/dist/license/mint-client.d.ts +72 -0
- package/dist/license/mint-client.d.ts.map +1 -0
- package/dist/license/mint-client.js +175 -0
- package/dist/license.d.ts +6 -0
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +15 -1
- package/dist/observability/index.d.ts +5 -2
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +5 -2
- package/dist/observability/logger.d.ts +5 -3
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +5 -3
- package/dist/relationships/analyzer.js +2 -2
- package/dist/storage/object-storage.d.ts.map +1 -1
- package/dist/storage/object-storage.js +3 -3
- package/dist/utils/errors.d.ts +16 -4
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +14 -2
- package/dist/utils/json-parsing.d.ts.map +1 -1
- package/dist/utils/json-parsing.js +4 -2
- package/dist/utils/logger-client.d.ts +6 -27
- package/dist/utils/logger-client.d.ts.map +1 -1
- package/dist/utils/logger-client.js +5 -51
- package/dist/utils/logger-server.d.ts +16 -20
- package/dist/utils/logger-server.d.ts.map +1 -1
- package/dist/utils/logger-server.js +40 -53
- package/dist/utils/logger.d.ts +7 -9
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +6 -8
- package/package.json +154 -76
- package/dist/caching/index.d.ts +0 -6
- package/dist/caching/index.d.ts.map +0 -1
- package/dist/caching/index.js +0 -5
- package/dist/observability/tracing.d.ts +0 -149
- package/dist/observability/tracing.d.ts.map +0 -1
- package/dist/observability/tracing.js +0 -380
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Distributed Tracing System
|
|
3
|
-
*
|
|
4
|
-
* Implements distributed tracing for tracking requests across services
|
|
5
|
-
*/
|
|
6
|
-
export class TracingSystem {
|
|
7
|
-
activeSpans = new Map();
|
|
8
|
-
completedTraces = new Map();
|
|
9
|
-
maxTraces = 1000;
|
|
10
|
-
/**
|
|
11
|
-
* Start a new trace
|
|
12
|
-
*/
|
|
13
|
-
startTrace(name, tags) {
|
|
14
|
-
const traceId = this.generateId();
|
|
15
|
-
const spanId = this.generateId();
|
|
16
|
-
const span = {
|
|
17
|
-
traceId,
|
|
18
|
-
spanId,
|
|
19
|
-
name,
|
|
20
|
-
startTime: Date.now(),
|
|
21
|
-
tags: tags || {},
|
|
22
|
-
logs: [],
|
|
23
|
-
status: 'ok',
|
|
24
|
-
};
|
|
25
|
-
this.activeSpans.set(spanId, span);
|
|
26
|
-
return span;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Start a child span
|
|
30
|
-
*/
|
|
31
|
-
startSpan(name, parentSpan, tags) {
|
|
32
|
-
const spanId = this.generateId();
|
|
33
|
-
const span = {
|
|
34
|
-
traceId: parentSpan.traceId,
|
|
35
|
-
spanId,
|
|
36
|
-
parentSpanId: parentSpan.spanId,
|
|
37
|
-
name,
|
|
38
|
-
startTime: Date.now(),
|
|
39
|
-
tags: tags || {},
|
|
40
|
-
logs: [],
|
|
41
|
-
status: 'ok',
|
|
42
|
-
};
|
|
43
|
-
this.activeSpans.set(spanId, span);
|
|
44
|
-
return span;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* End a span
|
|
48
|
-
*/
|
|
49
|
-
endSpan(span, error) {
|
|
50
|
-
span.endTime = Date.now();
|
|
51
|
-
span.duration = span.endTime - span.startTime;
|
|
52
|
-
if (error) {
|
|
53
|
-
span.status = 'error';
|
|
54
|
-
span.error = {
|
|
55
|
-
name: error.name,
|
|
56
|
-
message: error.message,
|
|
57
|
-
stack: error.stack,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
this.activeSpans.delete(span.spanId);
|
|
61
|
-
// Add to completed traces
|
|
62
|
-
this.addToTrace(span);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Add tag to span
|
|
66
|
-
*/
|
|
67
|
-
setTag(span, key, value) {
|
|
68
|
-
span.tags[key] = value;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Log event in span
|
|
72
|
-
*/
|
|
73
|
-
log(span, message, fields) {
|
|
74
|
-
span.logs.push({
|
|
75
|
-
timestamp: Date.now(),
|
|
76
|
-
message,
|
|
77
|
-
fields,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Add span to trace
|
|
82
|
-
*/
|
|
83
|
-
addToTrace(span) {
|
|
84
|
-
let trace = this.completedTraces.get(span.traceId);
|
|
85
|
-
if (!trace) {
|
|
86
|
-
trace = {
|
|
87
|
-
traceId: span.traceId,
|
|
88
|
-
spans: [],
|
|
89
|
-
startTime: span.startTime,
|
|
90
|
-
};
|
|
91
|
-
this.completedTraces.set(span.traceId, trace);
|
|
92
|
-
// Cleanup old traces
|
|
93
|
-
if (this.completedTraces.size > this.maxTraces) {
|
|
94
|
-
const oldestTraceId = this.completedTraces.keys().next().value;
|
|
95
|
-
if (oldestTraceId !== undefined) {
|
|
96
|
-
this.completedTraces.delete(oldestTraceId);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
trace.spans.push(span);
|
|
101
|
-
// Update trace times
|
|
102
|
-
if (span.endTime && (!trace.endTime || span.endTime > trace.endTime)) {
|
|
103
|
-
trace.endTime = span.endTime;
|
|
104
|
-
}
|
|
105
|
-
if (span.startTime < trace.startTime) {
|
|
106
|
-
trace.startTime = span.startTime;
|
|
107
|
-
}
|
|
108
|
-
if (trace.endTime) {
|
|
109
|
-
trace.duration = trace.endTime - trace.startTime;
|
|
110
|
-
}
|
|
111
|
-
// Find root span
|
|
112
|
-
if (!span.parentSpanId) {
|
|
113
|
-
trace.rootSpan = span;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Get trace by ID
|
|
118
|
-
*/
|
|
119
|
-
getTrace(traceId) {
|
|
120
|
-
return this.completedTraces.get(traceId);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Get all traces
|
|
124
|
-
*/
|
|
125
|
-
getAllTraces() {
|
|
126
|
-
return Array.from(this.completedTraces.values());
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Clear all traces
|
|
130
|
-
*/
|
|
131
|
-
clearTraces() {
|
|
132
|
-
this.completedTraces.clear();
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Generate unique ID
|
|
136
|
-
*/
|
|
137
|
-
generateId() {
|
|
138
|
-
return crypto.randomUUID().replace(/-/g, '').substring(0, 16);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Export traces in Jaeger format
|
|
142
|
-
*/
|
|
143
|
-
exportJaeger() {
|
|
144
|
-
return this.getAllTraces().map((trace) => ({
|
|
145
|
-
traceID: trace.traceId,
|
|
146
|
-
spans: trace.spans.map((span) => ({
|
|
147
|
-
traceID: span.traceId,
|
|
148
|
-
spanID: span.spanId,
|
|
149
|
-
parentSpanID: span.parentSpanId,
|
|
150
|
-
operationName: span.name,
|
|
151
|
-
startTime: span.startTime * 1000, // microseconds
|
|
152
|
-
duration: span.duration ? span.duration * 1000 : 0,
|
|
153
|
-
tags: Object.entries(span.tags).map(([key, value]) => ({
|
|
154
|
-
key,
|
|
155
|
-
type: typeof value,
|
|
156
|
-
value,
|
|
157
|
-
})),
|
|
158
|
-
logs: span.logs.map((log) => ({
|
|
159
|
-
timestamp: log.timestamp * 1000,
|
|
160
|
-
fields: [
|
|
161
|
-
{
|
|
162
|
-
key: 'message',
|
|
163
|
-
type: 'string',
|
|
164
|
-
value: log.message,
|
|
165
|
-
},
|
|
166
|
-
...(log.fields
|
|
167
|
-
? Object.entries(log.fields).map(([key, value]) => ({
|
|
168
|
-
key,
|
|
169
|
-
type: typeof value,
|
|
170
|
-
value,
|
|
171
|
-
}))
|
|
172
|
-
: []),
|
|
173
|
-
],
|
|
174
|
-
})),
|
|
175
|
-
})),
|
|
176
|
-
}));
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Default tracing system
|
|
181
|
-
*/
|
|
182
|
-
export const tracing = new TracingSystem();
|
|
183
|
-
/**
|
|
184
|
-
* Trace a function
|
|
185
|
-
*/
|
|
186
|
-
export async function trace(name, fn, parentSpan) {
|
|
187
|
-
const span = parentSpan ? tracing.startSpan(name, parentSpan) : tracing.startTrace(name);
|
|
188
|
-
try {
|
|
189
|
-
const result = await fn(span);
|
|
190
|
-
tracing.endSpan(span);
|
|
191
|
-
return result;
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
tracing.endSpan(span, error instanceof Error ? error : new Error(String(error)));
|
|
195
|
-
throw error;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Trace synchronous function
|
|
200
|
-
*/
|
|
201
|
-
export function traceSync(name, fn, parentSpan) {
|
|
202
|
-
const span = parentSpan ? tracing.startSpan(name, parentSpan) : tracing.startTrace(name);
|
|
203
|
-
try {
|
|
204
|
-
const result = fn(span);
|
|
205
|
-
tracing.endSpan(span);
|
|
206
|
-
return result;
|
|
207
|
-
}
|
|
208
|
-
catch (error) {
|
|
209
|
-
tracing.endSpan(span, error instanceof Error ? error : new Error(String(error)));
|
|
210
|
-
throw error;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Extract trace context from headers
|
|
215
|
-
*/
|
|
216
|
-
export function extractTraceContext(headers) {
|
|
217
|
-
// Handle both Headers and Record<string, string>
|
|
218
|
-
const getHeader = (key) => {
|
|
219
|
-
if ('get' in headers && typeof headers.get === 'function') {
|
|
220
|
-
return headers.get(key);
|
|
221
|
-
}
|
|
222
|
-
return headers[key];
|
|
223
|
-
};
|
|
224
|
-
// Support multiple formats
|
|
225
|
-
const traceParent = getHeader('traceparent'); // W3C Trace Context
|
|
226
|
-
const b3TraceId = getHeader('x-b3-traceid'); // B3 format
|
|
227
|
-
const b3SpanId = getHeader('x-b3-spanid');
|
|
228
|
-
if (traceParent) {
|
|
229
|
-
// Parse W3C traceparent: version-traceid-spanid-flags
|
|
230
|
-
const parts = traceParent.split('-');
|
|
231
|
-
if (parts.length >= 3) {
|
|
232
|
-
return {
|
|
233
|
-
traceId: parts[1],
|
|
234
|
-
spanId: parts[2],
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (b3TraceId) {
|
|
239
|
-
return {
|
|
240
|
-
traceId: b3TraceId,
|
|
241
|
-
spanId: b3SpanId || undefined,
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
return {};
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Inject trace context into headers
|
|
248
|
-
*/
|
|
249
|
-
export function injectTraceContext(span, headers) {
|
|
250
|
-
// Handle both Headers and Record<string, string>
|
|
251
|
-
const setHeader = (key, value) => {
|
|
252
|
-
if ('set' in headers && typeof headers.set === 'function') {
|
|
253
|
-
headers.set(key, value);
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
headers[key] = value;
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
// W3C Trace Context format
|
|
260
|
-
const traceparent = `00-${span.traceId}-${span.spanId}-01`;
|
|
261
|
-
setHeader('traceparent', traceparent);
|
|
262
|
-
// B3 format (for compatibility)
|
|
263
|
-
setHeader('x-b3-traceid', span.traceId);
|
|
264
|
-
setHeader('x-b3-spanid', span.spanId);
|
|
265
|
-
if (span.parentSpanId) {
|
|
266
|
-
setHeader('x-b3-parentspanid', span.parentSpanId);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Create tracing middleware
|
|
271
|
-
*/
|
|
272
|
-
export function createTracingMiddleware() {
|
|
273
|
-
return async (request, next) => {
|
|
274
|
-
const traceContext = extractTraceContext(request.headers ?? {});
|
|
275
|
-
const url = new URL(request.url);
|
|
276
|
-
let span;
|
|
277
|
-
if (traceContext.traceId) {
|
|
278
|
-
// Continue existing trace
|
|
279
|
-
const parentSpan = {
|
|
280
|
-
traceId: traceContext.traceId,
|
|
281
|
-
spanId: traceContext.spanId || '',
|
|
282
|
-
name: 'parent',
|
|
283
|
-
startTime: Date.now(),
|
|
284
|
-
tags: {},
|
|
285
|
-
logs: [],
|
|
286
|
-
status: 'ok',
|
|
287
|
-
};
|
|
288
|
-
span = tracing.startSpan(`${request.method} ${url.pathname}`, parentSpan, {
|
|
289
|
-
'http.method': request.method,
|
|
290
|
-
'http.url': request.url,
|
|
291
|
-
'http.path': url.pathname,
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
// Start new trace
|
|
296
|
-
span = tracing.startTrace(`${request.method} ${url.pathname}`, {
|
|
297
|
-
'http.method': request.method,
|
|
298
|
-
'http.url': request.url,
|
|
299
|
-
'http.path': url.pathname,
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
try {
|
|
303
|
-
const response = await next();
|
|
304
|
-
const statusCode = response.status ?? 200;
|
|
305
|
-
tracing.setTag(span, 'http.status_code', statusCode);
|
|
306
|
-
if (statusCode >= 400) {
|
|
307
|
-
span.status = 'error';
|
|
308
|
-
}
|
|
309
|
-
tracing.endSpan(span);
|
|
310
|
-
// Inject trace context into response
|
|
311
|
-
if (response.headers) {
|
|
312
|
-
injectTraceContext(span, response.headers);
|
|
313
|
-
}
|
|
314
|
-
return response;
|
|
315
|
-
}
|
|
316
|
-
catch (error) {
|
|
317
|
-
tracing.setTag(span, 'http.status_code', 500);
|
|
318
|
-
tracing.endSpan(span, error instanceof Error ? error : new Error(String(error)));
|
|
319
|
-
throw error;
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Trace database query
|
|
325
|
-
*/
|
|
326
|
-
export async function traceDBQuery(query, fn, parentSpan) {
|
|
327
|
-
return trace('database.query', async (span) => {
|
|
328
|
-
tracing.setTag(span, 'db.statement', query);
|
|
329
|
-
tracing.setTag(span, 'db.type', 'sql');
|
|
330
|
-
const result = await fn();
|
|
331
|
-
return result;
|
|
332
|
-
}, parentSpan);
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Trace API call
|
|
336
|
-
*/
|
|
337
|
-
export async function traceAPICall(method, url, fn, parentSpan) {
|
|
338
|
-
return trace('api.call', async (span) => {
|
|
339
|
-
tracing.setTag(span, 'http.method', method);
|
|
340
|
-
tracing.setTag(span, 'http.url', url);
|
|
341
|
-
const result = await fn();
|
|
342
|
-
return result;
|
|
343
|
-
}, parentSpan);
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Trace cache operation
|
|
347
|
-
*/
|
|
348
|
-
export async function traceCacheOperation(operation, key, fn, parentSpan) {
|
|
349
|
-
return trace('cache.operation', async (span) => {
|
|
350
|
-
tracing.setTag(span, 'cache.operation', operation);
|
|
351
|
-
tracing.setTag(span, 'cache.key', key);
|
|
352
|
-
const result = await fn();
|
|
353
|
-
return result;
|
|
354
|
-
}, parentSpan);
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Get span context for propagation
|
|
358
|
-
*/
|
|
359
|
-
export function getSpanContext(span) {
|
|
360
|
-
return {
|
|
361
|
-
traceId: span.traceId,
|
|
362
|
-
spanId: span.spanId,
|
|
363
|
-
parentSpanId: span.parentSpanId,
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Create span from context
|
|
368
|
-
*/
|
|
369
|
-
export function createSpanFromContext(name, context, tags) {
|
|
370
|
-
const parentSpan = {
|
|
371
|
-
traceId: context.traceId,
|
|
372
|
-
spanId: context.parentSpanId || context.spanId,
|
|
373
|
-
name: 'parent',
|
|
374
|
-
startTime: Date.now(),
|
|
375
|
-
tags: {},
|
|
376
|
-
logs: [],
|
|
377
|
-
status: 'ok',
|
|
378
|
-
};
|
|
379
|
-
return tracing.startSpan(name, parentSpan, tags);
|
|
380
|
-
}
|