@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.js CHANGED
@@ -133,32 +133,105 @@ function defineConnector() {
133
133
 
134
134
  // src/widget-schemas.ts
135
135
  import { z } from "zod";
136
- var widgetSchemas = {
137
- stat: z.object({
138
- title: z.string().meta({ label: "Title", description: "Widget title." }),
139
- metric: z.string().meta({ label: "Metric", description: "Metric reference." }),
140
- window: z.string().optional().meta({ label: "Window", description: "Time window, e.g. '7d'." }),
141
- compare: z.enum(["none", "previous-period"]).default("none").meta({ label: "Compare", description: "Comparison mode." })
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
- status: z.object({
144
- title: z.string().meta({ label: "Title", description: "Widget title." }),
145
- source: z.string().meta({
146
- label: "Source",
147
- description: "Connector or data source reference."
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
- timeseries: z.object({
151
- title: z.string().meta({ label: "Title", description: "Widget title." }),
152
- metric: z.string().meta({ label: "Metric", description: "Metric reference." }),
153
- window: z.string().meta({ label: "Window", description: "Time window, e.g. '30d'." }),
154
- granularity: z.enum(["hour", "day", "week"]).default("day").meta({ label: "Granularity", description: "Time bucket size." })
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
- distribution: z.object({
157
- title: z.string().meta({ label: "Title", description: "Widget title." }),
158
- metric: z.string().meta({ label: "Metric", description: "Metric reference." }),
159
- window: z.string().meta({ label: "Window", description: "Time window, e.g. '7d'." })
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 parseInput = { ...widget };
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