@rawdash/core 0.1.1 → 0.2.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/index.d.ts +821 -207
- package/dist/index.js +619 -33
- package/dist/index.js.map +1 -1
- package/dist/libsql.d.ts +23 -0
- package/dist/libsql.js +509 -0
- package/dist/libsql.js.map +1 -0
- package/dist/server-storage-BGSLkDoF.d.ts +209 -0
- package/package.json +22 -8
- package/LICENSE +0 -202
package/dist/index.js
CHANGED
|
@@ -133,32 +133,105 @@ function defineConnector() {
|
|
|
133
133
|
|
|
134
134
|
// src/widget-schemas.ts
|
|
135
135
|
import { z } from "zod";
|
|
136
|
-
var
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
var shapeSchema = z.enum([
|
|
137
|
+
"event",
|
|
138
|
+
"entity",
|
|
139
|
+
"metric",
|
|
140
|
+
"edge",
|
|
141
|
+
"distribution"
|
|
142
|
+
]);
|
|
143
|
+
var aggFnSchema = z.enum([
|
|
144
|
+
"count",
|
|
145
|
+
"sum",
|
|
146
|
+
"avg",
|
|
147
|
+
"min",
|
|
148
|
+
"max",
|
|
149
|
+
"latest",
|
|
150
|
+
"first"
|
|
151
|
+
]);
|
|
152
|
+
var filterOperatorSchema = z.enum([
|
|
153
|
+
"eq",
|
|
154
|
+
"neq",
|
|
155
|
+
"gt",
|
|
156
|
+
"gte",
|
|
157
|
+
"lt",
|
|
158
|
+
"lte",
|
|
159
|
+
"contains"
|
|
160
|
+
]);
|
|
161
|
+
var filterConditionSchema = z.object({
|
|
162
|
+
field: z.string(),
|
|
163
|
+
op: filterOperatorSchema,
|
|
164
|
+
value: z.union([z.string(), z.number(), z.boolean()])
|
|
165
|
+
});
|
|
166
|
+
var filterClauseSchema = z.union([
|
|
167
|
+
filterConditionSchema,
|
|
168
|
+
z.object({ or: z.array(filterConditionSchema) })
|
|
169
|
+
]);
|
|
170
|
+
var groupBySchema = z.object({
|
|
171
|
+
field: z.string(),
|
|
172
|
+
granularity: z.enum(["hour", "day", "week", "month"])
|
|
173
|
+
});
|
|
174
|
+
var resolvedMetricSchema = z.object({
|
|
175
|
+
connectorId: z.string(),
|
|
176
|
+
shape: shapeSchema,
|
|
177
|
+
name: z.string().optional(),
|
|
178
|
+
entityType: z.string().optional(),
|
|
179
|
+
field: z.string(),
|
|
180
|
+
fn: z.string(),
|
|
181
|
+
window: z.string().optional(),
|
|
182
|
+
filter: z.array(filterClauseSchema).optional(),
|
|
183
|
+
groupBy: groupBySchema.optional()
|
|
184
|
+
});
|
|
185
|
+
var titleField = z.string().meta({ label: "Title", description: "Widget title." });
|
|
186
|
+
var statWidgetSchema = z.object({
|
|
187
|
+
kind: z.literal("stat"),
|
|
188
|
+
title: titleField,
|
|
189
|
+
metric: resolvedMetricSchema.meta({
|
|
190
|
+
label: "Metric",
|
|
191
|
+
description: "Resolved metric definition."
|
|
142
192
|
}),
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
193
|
+
window: z.string().optional().meta({ label: "Window", description: "Time window, e.g. '7d'." }),
|
|
194
|
+
compare: z.enum(["none", "previous-period"]).default("none").meta({ label: "Compare", description: "Comparison mode." })
|
|
195
|
+
});
|
|
196
|
+
var statusWidgetSchema = z.object({
|
|
197
|
+
kind: z.literal("status"),
|
|
198
|
+
title: titleField,
|
|
199
|
+
source: z.string().meta({
|
|
200
|
+
label: "Source",
|
|
201
|
+
description: "Connector or data source reference."
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
var timeseriesWidgetSchema = z.object({
|
|
205
|
+
kind: z.literal("timeseries"),
|
|
206
|
+
title: titleField,
|
|
207
|
+
metric: resolvedMetricSchema.meta({
|
|
208
|
+
label: "Metric",
|
|
209
|
+
description: "Resolved metric definition."
|
|
149
210
|
}),
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
211
|
+
window: z.string().meta({ label: "Window", description: "Time window, e.g. '30d'." }),
|
|
212
|
+
granularity: z.enum(["hour", "day", "week"]).default("day").meta({ label: "Granularity", description: "Time bucket size." })
|
|
213
|
+
});
|
|
214
|
+
var distributionWidgetSchema = z.object({
|
|
215
|
+
kind: z.literal("distribution"),
|
|
216
|
+
title: titleField,
|
|
217
|
+
metric: resolvedMetricSchema.meta({
|
|
218
|
+
label: "Metric",
|
|
219
|
+
description: "Resolved metric definition."
|
|
155
220
|
}),
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
221
|
+
window: z.string().meta({ label: "Window", description: "Time window, e.g. '7d'." })
|
|
222
|
+
});
|
|
223
|
+
var widgetSchemas = {
|
|
224
|
+
stat: statWidgetSchema,
|
|
225
|
+
status: statusWidgetSchema,
|
|
226
|
+
timeseries: timeseriesWidgetSchema,
|
|
227
|
+
distribution: distributionWidgetSchema
|
|
161
228
|
};
|
|
229
|
+
var widgetSchema = z.discriminatedUnion("kind", [
|
|
230
|
+
statWidgetSchema,
|
|
231
|
+
statusWidgetSchema,
|
|
232
|
+
timeseriesWidgetSchema,
|
|
233
|
+
distributionWidgetSchema
|
|
234
|
+
]);
|
|
162
235
|
function getWidgetSchema(kind) {
|
|
163
236
|
return widgetSchemas[kind];
|
|
164
237
|
}
|
|
@@ -173,17 +246,7 @@ function defineDashboard(options) {
|
|
|
173
246
|
);
|
|
174
247
|
}
|
|
175
248
|
const schema = getWidgetSchema(widget.kind);
|
|
176
|
-
const
|
|
177
|
-
if (widget.kind !== "status") {
|
|
178
|
-
const m = widget.metric;
|
|
179
|
-
if (typeof m !== "object" || m === null) {
|
|
180
|
-
throw new Error(
|
|
181
|
-
`Widget "${key}" (kind "${widget.kind}"): metric is required`
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
parseInput.metric = "placeholder";
|
|
185
|
-
}
|
|
186
|
-
const result = schema.safeParse(parseInput);
|
|
249
|
+
const result = schema.safeParse(widget);
|
|
187
250
|
if (!result.success) {
|
|
188
251
|
throw new Error(
|
|
189
252
|
`Widget "${key}" (kind "${widget.kind}"): ${result.error.issues.map((i) => i.message).join("; ")}`
|
|
@@ -336,20 +399,543 @@ function defineConfigFields(schema) {
|
|
|
336
399
|
}
|
|
337
400
|
return schema;
|
|
338
401
|
}
|
|
402
|
+
|
|
403
|
+
// src/compute.ts
|
|
404
|
+
function matchesCondition(record, cond) {
|
|
405
|
+
const val = record[cond.field];
|
|
406
|
+
switch (cond.op) {
|
|
407
|
+
case "eq":
|
|
408
|
+
return val === cond.value;
|
|
409
|
+
case "neq":
|
|
410
|
+
return val !== cond.value;
|
|
411
|
+
case "gt":
|
|
412
|
+
if (typeof val !== "number" || typeof cond.value !== "number") {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
return val > cond.value;
|
|
416
|
+
case "gte":
|
|
417
|
+
if (typeof val !== "number" || typeof cond.value !== "number") {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
return val >= cond.value;
|
|
421
|
+
case "lt":
|
|
422
|
+
if (typeof val !== "number" || typeof cond.value !== "number") {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
return val < cond.value;
|
|
426
|
+
case "lte":
|
|
427
|
+
if (typeof val !== "number" || typeof cond.value !== "number") {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
return val <= cond.value;
|
|
431
|
+
case "contains":
|
|
432
|
+
return String(val).includes(String(cond.value));
|
|
433
|
+
default:
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function applyFilter(record, filter) {
|
|
438
|
+
if (!filter) {
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
for (const clause of filter) {
|
|
442
|
+
if ("or" in clause) {
|
|
443
|
+
if (!clause.or.some((cond) => matchesCondition(record, cond))) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
} else {
|
|
447
|
+
if (!matchesCondition(record, clause)) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return true;
|
|
453
|
+
}
|
|
454
|
+
var WINDOW_MS = {
|
|
455
|
+
h: 36e5,
|
|
456
|
+
d: 864e5,
|
|
457
|
+
w: 6048e5,
|
|
458
|
+
m: 2592e6
|
|
459
|
+
};
|
|
460
|
+
function parseWindowMs(window) {
|
|
461
|
+
const match = /^(\d+)(h|d|w|m)$/.exec(window);
|
|
462
|
+
if (!match) {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
const unitMs = WINDOW_MS[match[2]];
|
|
466
|
+
if (unitMs === void 0) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
return parseInt(match[1]) * unitMs;
|
|
470
|
+
}
|
|
471
|
+
function truncateToGranularity(ts, granularity) {
|
|
472
|
+
const d = new Date(ts);
|
|
473
|
+
switch (granularity) {
|
|
474
|
+
case "hour":
|
|
475
|
+
d.setUTCMinutes(0, 0, 0);
|
|
476
|
+
return d.toISOString();
|
|
477
|
+
case "day":
|
|
478
|
+
d.setUTCHours(0, 0, 0, 0);
|
|
479
|
+
return d.toISOString().slice(0, 10);
|
|
480
|
+
case "week": {
|
|
481
|
+
d.setUTCDate(d.getUTCDate() - d.getUTCDay());
|
|
482
|
+
d.setUTCHours(0, 0, 0, 0);
|
|
483
|
+
return d.toISOString().slice(0, 10);
|
|
484
|
+
}
|
|
485
|
+
case "month":
|
|
486
|
+
d.setUTCDate(1);
|
|
487
|
+
d.setUTCHours(0, 0, 0, 0);
|
|
488
|
+
return d.toISOString().slice(0, 7);
|
|
489
|
+
default:
|
|
490
|
+
return d.toISOString().slice(0, 10);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
function computeAgg(records, field, fn) {
|
|
494
|
+
if (fn === "count") {
|
|
495
|
+
return records.length;
|
|
496
|
+
}
|
|
497
|
+
if (fn === "latest") {
|
|
498
|
+
return records.at(-1)?.[field] ?? null;
|
|
499
|
+
}
|
|
500
|
+
if (fn === "first") {
|
|
501
|
+
return records[0]?.[field] ?? null;
|
|
502
|
+
}
|
|
503
|
+
const values = records.map((r) => r[field]).filter((v) => v !== void 0 && v !== null);
|
|
504
|
+
const nonNumeric = values.find((v) => typeof v !== "number");
|
|
505
|
+
if (nonNumeric !== void 0) {
|
|
506
|
+
throw new Error(
|
|
507
|
+
`computeAgg: fn "${fn}" requires numeric values for field "${field}", got ${typeof nonNumeric} (${String(nonNumeric)})`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
const numbers = values;
|
|
511
|
+
if (fn === "sum") {
|
|
512
|
+
return numbers.reduce((a, b) => a + b, 0);
|
|
513
|
+
}
|
|
514
|
+
if (fn === "avg") {
|
|
515
|
+
return numbers.length > 0 ? numbers.reduce((a, b) => a + b, 0) / numbers.length : null;
|
|
516
|
+
}
|
|
517
|
+
if (fn === "min") {
|
|
518
|
+
return numbers.length > 0 ? numbers.reduce((a, b) => a < b ? a : b) : null;
|
|
519
|
+
}
|
|
520
|
+
if (fn === "max") {
|
|
521
|
+
return numbers.length > 0 ? numbers.reduce((a, b) => a > b ? a : b) : null;
|
|
522
|
+
}
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
function sortByTs(records, tsField) {
|
|
526
|
+
return [...records].sort((a, b) => {
|
|
527
|
+
return a[tsField] - b[tsField];
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
function computeGroupBy(records, metric, tsField) {
|
|
531
|
+
const { field, granularity } = metric.groupBy;
|
|
532
|
+
const groups = /* @__PURE__ */ new Map();
|
|
533
|
+
for (const record of records) {
|
|
534
|
+
const ts = record[field];
|
|
535
|
+
if (ts === void 0 || typeof ts !== "number") {
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
const key = truncateToGranularity(ts, granularity);
|
|
539
|
+
if (!groups.has(key)) {
|
|
540
|
+
groups.set(key, []);
|
|
541
|
+
}
|
|
542
|
+
groups.get(key).push(record);
|
|
543
|
+
}
|
|
544
|
+
return [...groups.entries()].map(([key, groupRecords]) => ({
|
|
545
|
+
date: key,
|
|
546
|
+
value: computeAgg(
|
|
547
|
+
sortByTs(groupRecords, tsField),
|
|
548
|
+
metric.field,
|
|
549
|
+
metric.fn
|
|
550
|
+
)
|
|
551
|
+
})).sort((a, b) => a.date < b.date ? -1 : 1);
|
|
552
|
+
}
|
|
553
|
+
function getTimestampField(shape) {
|
|
554
|
+
switch (shape) {
|
|
555
|
+
case "event":
|
|
556
|
+
return "start_ts";
|
|
557
|
+
case "metric":
|
|
558
|
+
case "distribution":
|
|
559
|
+
return "ts";
|
|
560
|
+
case "entity":
|
|
561
|
+
case "edge":
|
|
562
|
+
return "updated_at";
|
|
563
|
+
default:
|
|
564
|
+
return "start_ts";
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async function computeMetric(storage, metric) {
|
|
568
|
+
const tsField = getTimestampField(metric.shape);
|
|
569
|
+
const windowMs = metric.window ? parseWindowMs(metric.window) : null;
|
|
570
|
+
const windowStart = windowMs !== null ? Date.now() - windowMs : void 0;
|
|
571
|
+
let records;
|
|
572
|
+
switch (metric.shape) {
|
|
573
|
+
case "event": {
|
|
574
|
+
const events = await storage.queryEvents({
|
|
575
|
+
name: metric.name,
|
|
576
|
+
start: windowStart
|
|
577
|
+
});
|
|
578
|
+
records = events.map((e) => ({
|
|
579
|
+
...e.attributes,
|
|
580
|
+
name: e.name,
|
|
581
|
+
start_ts: e.start_ts,
|
|
582
|
+
end_ts: e.end_ts
|
|
583
|
+
}));
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
case "entity": {
|
|
587
|
+
const type = metric.entityType ?? metric.name ?? "";
|
|
588
|
+
const entities = await storage.queryEntities({ type });
|
|
589
|
+
records = entities.map((e) => ({
|
|
590
|
+
...e.attributes,
|
|
591
|
+
type: e.type,
|
|
592
|
+
id: e.id,
|
|
593
|
+
updated_at: e.updated_at
|
|
594
|
+
}));
|
|
595
|
+
if (windowStart !== void 0) {
|
|
596
|
+
records = records.filter((r) => r[tsField] >= windowStart);
|
|
597
|
+
}
|
|
598
|
+
break;
|
|
599
|
+
}
|
|
600
|
+
case "metric": {
|
|
601
|
+
const metrics = await storage.queryMetrics({
|
|
602
|
+
name: metric.name,
|
|
603
|
+
start: windowStart
|
|
604
|
+
});
|
|
605
|
+
records = metrics.map((m) => ({
|
|
606
|
+
...m.attributes,
|
|
607
|
+
name: m.name,
|
|
608
|
+
ts: m.ts,
|
|
609
|
+
value: m.value
|
|
610
|
+
}));
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
case "edge": {
|
|
614
|
+
const edges = await storage.traverse({ kind: metric.name });
|
|
615
|
+
records = edges.map((e) => ({
|
|
616
|
+
...e.attributes,
|
|
617
|
+
from_type: e.from_type,
|
|
618
|
+
from_id: e.from_id,
|
|
619
|
+
kind: e.kind,
|
|
620
|
+
to_type: e.to_type,
|
|
621
|
+
to_id: e.to_id,
|
|
622
|
+
updated_at: e.updated_at
|
|
623
|
+
}));
|
|
624
|
+
if (windowStart !== void 0) {
|
|
625
|
+
records = records.filter((r) => r[tsField] >= windowStart);
|
|
626
|
+
}
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
case "distribution": {
|
|
630
|
+
const distributions = await storage.queryDistributions({
|
|
631
|
+
name: metric.name,
|
|
632
|
+
start: windowStart
|
|
633
|
+
});
|
|
634
|
+
records = distributions.map((d) => ({
|
|
635
|
+
...d.attributes,
|
|
636
|
+
name: d.name,
|
|
637
|
+
ts: d.ts,
|
|
638
|
+
kind: d.kind,
|
|
639
|
+
data: d.data
|
|
640
|
+
}));
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
default:
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
const filtered = records.filter((r) => applyFilter(r, metric.filter));
|
|
647
|
+
const sorted = sortByTs(filtered, tsField);
|
|
648
|
+
if (metric.groupBy) {
|
|
649
|
+
return computeGroupBy(sorted, metric, tsField);
|
|
650
|
+
}
|
|
651
|
+
return computeAgg(sorted, metric.field, metric.fn);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// src/resolve-widget.ts
|
|
655
|
+
async function resolveWidget(id, widget, connectors, storage) {
|
|
656
|
+
if (widget.kind === "status") {
|
|
657
|
+
return {
|
|
658
|
+
id,
|
|
659
|
+
widgetId: id,
|
|
660
|
+
connectorId: widget.source,
|
|
661
|
+
data: null,
|
|
662
|
+
cachedAt: null
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
const { connectorId } = widget.metric;
|
|
666
|
+
const connectorEntry = connectors.find((e) => e.connector.id === connectorId);
|
|
667
|
+
if (!connectorEntry) {
|
|
668
|
+
return void 0;
|
|
669
|
+
}
|
|
670
|
+
const handle = storage.getStorageHandle(connectorId);
|
|
671
|
+
const data = await computeMetric(handle, widget.metric);
|
|
672
|
+
return {
|
|
673
|
+
id,
|
|
674
|
+
widgetId: id,
|
|
675
|
+
connectorId,
|
|
676
|
+
data,
|
|
677
|
+
cachedAt: (await storage.getSyncState()).lastSyncAt
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// src/in-memory-storage.ts
|
|
682
|
+
var InMemoryStorage = class {
|
|
683
|
+
eventStore = /* @__PURE__ */ new Map();
|
|
684
|
+
entityStore = /* @__PURE__ */ new Map();
|
|
685
|
+
metricStore = /* @__PURE__ */ new Map();
|
|
686
|
+
edgeStore = /* @__PURE__ */ new Map();
|
|
687
|
+
distributionStore = /* @__PURE__ */ new Map();
|
|
688
|
+
syncState = {
|
|
689
|
+
status: "idle",
|
|
690
|
+
lastSyncAt: null,
|
|
691
|
+
lastError: null
|
|
692
|
+
};
|
|
693
|
+
getStorageHandle(connectorId) {
|
|
694
|
+
const getEntityMap = () => {
|
|
695
|
+
if (!this.entityStore.has(connectorId)) {
|
|
696
|
+
this.entityStore.set(connectorId, /* @__PURE__ */ new Map());
|
|
697
|
+
}
|
|
698
|
+
return this.entityStore.get(connectorId);
|
|
699
|
+
};
|
|
700
|
+
const upsertEntities = (es) => {
|
|
701
|
+
const byType = getEntityMap();
|
|
702
|
+
for (const e of es) {
|
|
703
|
+
if (!byType.has(e.type)) {
|
|
704
|
+
byType.set(e.type, /* @__PURE__ */ new Map());
|
|
705
|
+
}
|
|
706
|
+
byType.get(e.type).set(e.id, e);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
const upsertEdges = (es) => {
|
|
710
|
+
const existing = this.edgeStore.get(connectorId) ?? [];
|
|
711
|
+
const index = /* @__PURE__ */ new Map();
|
|
712
|
+
for (let i = 0; i < existing.length; i++) {
|
|
713
|
+
const e = existing[i];
|
|
714
|
+
index.set(
|
|
715
|
+
`${e.from_type}:${e.from_id}:${e.kind}:${e.to_type}:${e.to_id}`,
|
|
716
|
+
i
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
for (const e of es) {
|
|
720
|
+
const key = `${e.from_type}:${e.from_id}:${e.kind}:${e.to_type}:${e.to_id}`;
|
|
721
|
+
const idx = index.get(key);
|
|
722
|
+
if (idx !== void 0) {
|
|
723
|
+
existing[idx] = e;
|
|
724
|
+
} else {
|
|
725
|
+
index.set(key, existing.length);
|
|
726
|
+
existing.push(e);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
this.edgeStore.set(connectorId, existing);
|
|
730
|
+
};
|
|
731
|
+
return {
|
|
732
|
+
event: async (e) => {
|
|
733
|
+
if (!this.eventStore.has(connectorId)) {
|
|
734
|
+
this.eventStore.set(connectorId, []);
|
|
735
|
+
}
|
|
736
|
+
this.eventStore.get(connectorId).push(e);
|
|
737
|
+
},
|
|
738
|
+
entity: async (e) => {
|
|
739
|
+
upsertEntities([e]);
|
|
740
|
+
},
|
|
741
|
+
metric: async (m) => {
|
|
742
|
+
if (!this.metricStore.has(connectorId)) {
|
|
743
|
+
this.metricStore.set(connectorId, []);
|
|
744
|
+
}
|
|
745
|
+
this.metricStore.get(connectorId).push(m);
|
|
746
|
+
},
|
|
747
|
+
edge: async (e) => {
|
|
748
|
+
upsertEdges([e]);
|
|
749
|
+
},
|
|
750
|
+
distribution: async (d) => {
|
|
751
|
+
if (!this.distributionStore.has(connectorId)) {
|
|
752
|
+
this.distributionStore.set(connectorId, []);
|
|
753
|
+
}
|
|
754
|
+
this.distributionStore.get(connectorId).push(d);
|
|
755
|
+
},
|
|
756
|
+
events: async (es, scope) => {
|
|
757
|
+
const names = new Set(scope?.names ?? es.map((e) => e.name));
|
|
758
|
+
const kept = (this.eventStore.get(connectorId) ?? []).filter(
|
|
759
|
+
(e) => !names.has(e.name)
|
|
760
|
+
);
|
|
761
|
+
this.eventStore.set(connectorId, [...kept, ...es]);
|
|
762
|
+
},
|
|
763
|
+
entities: async (es, scope) => {
|
|
764
|
+
const byType = getEntityMap();
|
|
765
|
+
const types = new Set(scope?.types ?? es.map((e) => e.type));
|
|
766
|
+
for (const type of types) {
|
|
767
|
+
byType.set(type, /* @__PURE__ */ new Map());
|
|
768
|
+
}
|
|
769
|
+
upsertEntities(es);
|
|
770
|
+
},
|
|
771
|
+
metrics: async (ms, scope) => {
|
|
772
|
+
const names = new Set(scope?.names ?? ms.map((m) => m.name));
|
|
773
|
+
const kept = (this.metricStore.get(connectorId) ?? []).filter(
|
|
774
|
+
(m) => !names.has(m.name)
|
|
775
|
+
);
|
|
776
|
+
this.metricStore.set(connectorId, [...kept, ...ms]);
|
|
777
|
+
},
|
|
778
|
+
edges: async (es, scope) => {
|
|
779
|
+
const kinds = new Set(scope?.kinds ?? es.map((e) => e.kind));
|
|
780
|
+
const kept = (this.edgeStore.get(connectorId) ?? []).filter(
|
|
781
|
+
(e) => !kinds.has(e.kind)
|
|
782
|
+
);
|
|
783
|
+
this.edgeStore.set(connectorId, kept);
|
|
784
|
+
upsertEdges(es);
|
|
785
|
+
},
|
|
786
|
+
distributions: async (ds, scope) => {
|
|
787
|
+
const names = new Set(scope?.names ?? ds.map((d) => d.name));
|
|
788
|
+
const kept = (this.distributionStore.get(connectorId) ?? []).filter(
|
|
789
|
+
(d) => !names.has(d.name)
|
|
790
|
+
);
|
|
791
|
+
this.distributionStore.set(connectorId, [...kept, ...ds]);
|
|
792
|
+
},
|
|
793
|
+
queryEvents: async (q) => {
|
|
794
|
+
let results = this.eventStore.get(connectorId) ?? [];
|
|
795
|
+
if (q.name !== void 0) {
|
|
796
|
+
results = results.filter((e) => e.name === q.name);
|
|
797
|
+
}
|
|
798
|
+
if (q.start !== void 0) {
|
|
799
|
+
results = results.filter((e) => e.start_ts >= q.start);
|
|
800
|
+
}
|
|
801
|
+
if (q.end !== void 0) {
|
|
802
|
+
results = results.filter((e) => e.start_ts <= q.end);
|
|
803
|
+
}
|
|
804
|
+
return results;
|
|
805
|
+
},
|
|
806
|
+
getEntity: async (type, id) => {
|
|
807
|
+
return getEntityMap().get(type)?.get(id) ?? null;
|
|
808
|
+
},
|
|
809
|
+
queryEntities: async (q) => {
|
|
810
|
+
const byType = getEntityMap().get(q.type);
|
|
811
|
+
if (!byType) {
|
|
812
|
+
return [];
|
|
813
|
+
}
|
|
814
|
+
return Array.from(byType.values());
|
|
815
|
+
},
|
|
816
|
+
queryMetrics: async (q) => {
|
|
817
|
+
let results = this.metricStore.get(connectorId) ?? [];
|
|
818
|
+
if (q.name !== void 0) {
|
|
819
|
+
results = results.filter((m) => m.name === q.name);
|
|
820
|
+
}
|
|
821
|
+
if (q.start !== void 0) {
|
|
822
|
+
results = results.filter((m) => m.ts >= q.start);
|
|
823
|
+
}
|
|
824
|
+
if (q.end !== void 0) {
|
|
825
|
+
results = results.filter((m) => m.ts <= q.end);
|
|
826
|
+
}
|
|
827
|
+
return results;
|
|
828
|
+
},
|
|
829
|
+
traverse: async (q) => {
|
|
830
|
+
let results = this.edgeStore.get(connectorId) ?? [];
|
|
831
|
+
if (q.fromType !== void 0) {
|
|
832
|
+
results = results.filter((e) => e.from_type === q.fromType);
|
|
833
|
+
}
|
|
834
|
+
if (q.fromId !== void 0) {
|
|
835
|
+
results = results.filter((e) => e.from_id === q.fromId);
|
|
836
|
+
}
|
|
837
|
+
if (q.kind !== void 0) {
|
|
838
|
+
results = results.filter((e) => e.kind === q.kind);
|
|
839
|
+
}
|
|
840
|
+
if (q.toType !== void 0) {
|
|
841
|
+
results = results.filter((e) => e.to_type === q.toType);
|
|
842
|
+
}
|
|
843
|
+
if (q.toId !== void 0) {
|
|
844
|
+
results = results.filter((e) => e.to_id === q.toId);
|
|
845
|
+
}
|
|
846
|
+
return results;
|
|
847
|
+
},
|
|
848
|
+
queryDistributions: async (q) => {
|
|
849
|
+
let results = this.distributionStore.get(connectorId) ?? [];
|
|
850
|
+
if (q.name !== void 0) {
|
|
851
|
+
results = results.filter((d) => d.name === q.name);
|
|
852
|
+
}
|
|
853
|
+
if (q.start !== void 0) {
|
|
854
|
+
results = results.filter((d) => d.ts >= q.start);
|
|
855
|
+
}
|
|
856
|
+
if (q.end !== void 0) {
|
|
857
|
+
results = results.filter((d) => d.ts <= q.end);
|
|
858
|
+
}
|
|
859
|
+
return results;
|
|
860
|
+
},
|
|
861
|
+
deleteOlderThan: async (shape, tsUnixMs) => {
|
|
862
|
+
if (shape === "events") {
|
|
863
|
+
const before = this.eventStore.get(connectorId) ?? [];
|
|
864
|
+
const after = before.filter((e) => e.start_ts >= tsUnixMs);
|
|
865
|
+
this.eventStore.set(connectorId, after);
|
|
866
|
+
return { rowsDeleted: before.length - after.length };
|
|
867
|
+
} else if (shape === "metrics") {
|
|
868
|
+
const before = this.metricStore.get(connectorId) ?? [];
|
|
869
|
+
const after = before.filter((m) => m.ts >= tsUnixMs);
|
|
870
|
+
this.metricStore.set(connectorId, after);
|
|
871
|
+
return { rowsDeleted: before.length - after.length };
|
|
872
|
+
} else if (shape === "distributions") {
|
|
873
|
+
const before = this.distributionStore.get(connectorId) ?? [];
|
|
874
|
+
const after = before.filter((d) => d.ts >= tsUnixMs);
|
|
875
|
+
this.distributionStore.set(connectorId, after);
|
|
876
|
+
return { rowsDeleted: before.length - after.length };
|
|
877
|
+
} else {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`Unsupported shape for deleteOlderThan: ${String(shape)}`
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
async getSyncState() {
|
|
886
|
+
return { ...this.syncState };
|
|
887
|
+
}
|
|
888
|
+
async setSyncing() {
|
|
889
|
+
if (this.syncState.status === "syncing") {
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
this.syncState = { ...this.syncState, status: "syncing" };
|
|
893
|
+
return true;
|
|
894
|
+
}
|
|
895
|
+
async setSyncSuccess() {
|
|
896
|
+
this.syncState = {
|
|
897
|
+
status: "idle",
|
|
898
|
+
lastSyncAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
899
|
+
lastError: null
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
async setSyncError(error) {
|
|
903
|
+
this.syncState = {
|
|
904
|
+
status: "error",
|
|
905
|
+
lastSyncAt: this.syncState.lastSyncAt,
|
|
906
|
+
lastError: error
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
};
|
|
339
910
|
export {
|
|
340
911
|
BaseConnector,
|
|
341
912
|
EnvSecretsResolver,
|
|
913
|
+
InMemoryStorage,
|
|
914
|
+
aggFnSchema,
|
|
915
|
+
computeMetric,
|
|
342
916
|
computeRetention,
|
|
343
917
|
defineConfig,
|
|
344
918
|
defineConfigFields,
|
|
345
919
|
defineConnector,
|
|
346
920
|
defineDashboard,
|
|
347
921
|
defineMetric,
|
|
922
|
+
distributionWidgetSchema,
|
|
923
|
+
filterClauseSchema,
|
|
924
|
+
filterConditionSchema,
|
|
925
|
+
filterOperatorSchema,
|
|
348
926
|
getWidgetSchema,
|
|
927
|
+
groupBySchema,
|
|
349
928
|
isSecretRef,
|
|
350
929
|
resolveSecretRefs,
|
|
930
|
+
resolveWidget,
|
|
931
|
+
resolvedMetricSchema,
|
|
351
932
|
secret,
|
|
352
933
|
selectForDeletion,
|
|
934
|
+
shapeSchema,
|
|
935
|
+
statWidgetSchema,
|
|
936
|
+
statusWidgetSchema,
|
|
937
|
+
timeseriesWidgetSchema,
|
|
938
|
+
widgetSchema,
|
|
353
939
|
widgetSchemas
|
|
354
940
|
};
|
|
355
941
|
//# sourceMappingURL=index.js.map
|