@rawdash/core 0.3.0 → 0.4.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/README.md CHANGED
@@ -68,11 +68,11 @@ Validates and returns a `Dashboard`. Widget keys must be URL-safe (`[a-zA-Z0-9_-
68
68
 
69
69
  ### `defineMetric(options)`
70
70
 
71
- Returns a `ResolvedMetric` that can be used in stat, timeseries, and distribution widgets.
71
+ Returns a `ComputedMetric` that can be used in stat, timeseries, and distribution widgets.
72
72
 
73
73
  ### `secret(name)`
74
74
 
75
- Returns a `SecretRef` that resolves the named environment variable at runtime. Connectors that accept a `token` or API key should use this to avoid hardcoding credentials.
75
+ Returns a `Secret` that resolves the named environment variable at runtime. Connectors that accept a `token` or API key should use this to avoid hardcoding credentials.
76
76
 
77
77
  ### `defineConnector(options)`
78
78
 
package/dist/index.d.ts CHANGED
@@ -1,20 +1,205 @@
1
- import { E as Event, M as Metric, D as Distribution, S as StorageHandle, C as Connector, a as ServerStorage, W as WidgetEntry, b as SyncState } from './server-storage-BGSLkDoF.js';
2
- export { B as BaseConnector, c as CredentialEntry, d as CredentialSchema, e as DistributionQuery, f as Edge, g as EdgeQuery, h as Entity, i as EntityQuery, j as EnvSecretsResolver, k as EventQuery, I as InferCredentialInput, l as InferCredentials, J as JSONValue, m as MetricQuery, n as SecretRef, o as SecretsResolver, p as SyncRequest, q as defineConnector, r as isSecretRef, s as resolveSecretRefs, t as secret } from './server-storage-BGSLkDoF.js';
3
1
  import { z } from 'zod';
4
2
 
3
+ type Secret = {
4
+ $secret: string;
5
+ };
6
+ declare function secret(name: string): Secret;
7
+ declare function isSecret(value: unknown): value is Secret;
8
+ interface SecretsResolver {
9
+ resolve(name: string): string | undefined;
10
+ }
11
+ declare class EnvSecretsResolver implements SecretsResolver {
12
+ resolve(name: string): string | undefined;
13
+ }
14
+ declare function resolveSecrets<T>(obj: T, resolver: SecretsResolver): T;
15
+
16
+ type JSONValue = string | number | boolean | null | JSONValue[] | {
17
+ [key: string]: JSONValue;
18
+ };
19
+ interface Event {
20
+ name: string;
21
+ start_ts: number;
22
+ end_ts: number | null;
23
+ attributes: Record<string, JSONValue>;
24
+ }
25
+ interface Entity {
26
+ type: string;
27
+ id: string;
28
+ attributes: Record<string, JSONValue>;
29
+ updated_at: number;
30
+ }
31
+ interface MetricSample {
32
+ name: string;
33
+ ts: number;
34
+ value: number;
35
+ attributes: Record<string, JSONValue>;
36
+ }
37
+ interface Edge {
38
+ from_type: string;
39
+ from_id: string;
40
+ kind: string;
41
+ to_type: string;
42
+ to_id: string;
43
+ attributes: Record<string, JSONValue>;
44
+ updated_at: number;
45
+ }
46
+ type Distribution = {
47
+ name: string;
48
+ ts: number;
49
+ kind: 'histogram';
50
+ data: {
51
+ buckets: Array<{
52
+ le: number;
53
+ count: number;
54
+ }>;
55
+ count: number;
56
+ sum: number;
57
+ };
58
+ attributes: Record<string, JSONValue>;
59
+ } | {
60
+ name: string;
61
+ ts: number;
62
+ kind: 'summary';
63
+ data: {
64
+ quantiles: Array<{
65
+ q: number;
66
+ value: number;
67
+ }>;
68
+ count: number;
69
+ sum: number;
70
+ };
71
+ attributes: Record<string, JSONValue>;
72
+ };
73
+ interface EventQuery {
74
+ name?: string;
75
+ start?: number;
76
+ end?: number;
77
+ }
78
+ interface EntityQuery {
79
+ type: string;
80
+ }
81
+ interface MetricQuery {
82
+ name?: string;
83
+ start?: number;
84
+ end?: number;
85
+ }
86
+ interface EdgeQuery {
87
+ fromType?: string;
88
+ fromId?: string;
89
+ kind?: string;
90
+ toType?: string;
91
+ toId?: string;
92
+ }
93
+ interface DistributionQuery {
94
+ name?: string;
95
+ start?: number;
96
+ end?: number;
97
+ }
98
+ interface StorageHandle {
99
+ event(e: Event): Promise<void>;
100
+ entity(e: Entity): Promise<void>;
101
+ metric(m: MetricSample): Promise<void>;
102
+ edge(e: Edge): Promise<void>;
103
+ distribution(d: Distribution): Promise<void>;
104
+ events(es: Event[], scope?: {
105
+ names?: string[];
106
+ }): Promise<void>;
107
+ entities(es: Entity[], scope?: {
108
+ types?: string[];
109
+ }): Promise<void>;
110
+ metrics(ms: MetricSample[], scope?: {
111
+ names?: string[];
112
+ }): Promise<void>;
113
+ edges(es: Edge[], scope?: {
114
+ kinds?: string[];
115
+ }): Promise<void>;
116
+ distributions(ds: Distribution[], scope?: {
117
+ names?: string[];
118
+ }): Promise<void>;
119
+ queryEvents(q: EventQuery): Promise<Event[]>;
120
+ getEntity(type: string, id: string): Promise<Entity | null>;
121
+ queryEntities(q: EntityQuery): Promise<Entity[]>;
122
+ queryMetrics(q: MetricQuery): Promise<MetricSample[]>;
123
+ traverse(q: EdgeQuery): Promise<Edge[]>;
124
+ queryDistributions(q: DistributionQuery): Promise<Distribution[]>;
125
+ deleteOlderThan(shape: 'events' | 'metrics' | 'distributions', tsUnixMs: number): Promise<{
126
+ rowsDeleted: number;
127
+ }>;
128
+ }
129
+ interface CredentialField {
130
+ description: string;
131
+ auth?: 'none' | 'optional' | 'required';
132
+ }
133
+ type CredentialsSchema = Record<string, CredentialField>;
134
+ type InferCredentials<TCreds extends CredentialsSchema> = {
135
+ [K in keyof TCreds]: TCreds[K] extends {
136
+ auth: 'required';
137
+ } ? string : string | undefined;
138
+ };
139
+ type InferCredentialInput<TCreds extends CredentialsSchema> = {
140
+ [K in keyof TCreds]: TCreds[K] extends {
141
+ auth: 'required';
142
+ } ? string | Secret : string | Secret | undefined;
143
+ };
144
+ interface SyncOptions {
145
+ mode: 'full' | 'latest';
146
+ since?: string;
147
+ }
148
+ interface Connector {
149
+ readonly id: string;
150
+ readonly credentials?: CredentialsSchema;
151
+ serializeConfig(): Record<string, unknown>;
152
+ sync(options: SyncOptions, storage: StorageHandle, signal?: AbortSignal): Promise<void>;
153
+ }
154
+ interface RetryPolicy {
155
+ maxAttempts?: number;
156
+ initialDelayMs?: number;
157
+ maxDelayMs?: number;
158
+ signal?: AbortSignal;
159
+ }
160
+ declare abstract class BaseConnector<TSettings = unknown, TCreds extends CredentialsSchema = CredentialsSchema> implements Connector {
161
+ abstract readonly id: string;
162
+ readonly credentials?: TCreds;
163
+ protected settings: TSettings;
164
+ protected creds: InferCredentials<TCreds>;
165
+ private rawCredInput;
166
+ constructor(settings: TSettings, creds?: InferCredentialInput<TCreds>);
167
+ serializeConfig(): Record<string, unknown>;
168
+ protected sleep(ms: number, signal?: AbortSignal): Promise<void>;
169
+ protected withRetry<T>(fn: (signal?: AbortSignal) => Promise<{
170
+ status: 'done';
171
+ value: T;
172
+ } | {
173
+ status: 'retry';
174
+ }>, options?: RetryPolicy): Promise<T | null>;
175
+ abstract sync(options: SyncOptions, storage: StorageHandle, signal?: AbortSignal): Promise<void>;
176
+ }
177
+ declare function defineConnector<TSettings>(): <TCreds extends CredentialsSchema = Record<string, never>>(def: {
178
+ id: string;
179
+ credentials?: TCreds;
180
+ sync: (this: {
181
+ settings: TSettings;
182
+ creds: InferCredentials<TCreds>;
183
+ }, options: SyncOptions, storage: StorageHandle, signal?: AbortSignal) => Promise<void>;
184
+ }) => {
185
+ new (settings: TSettings, creds?: InferCredentialInput<TCreds>): Connector;
186
+ readonly id: string;
187
+ readonly credentials: TCreds | undefined;
188
+ };
189
+
5
190
  interface RetentionConfig {
6
191
  maxAge?: number;
7
192
  maxSize?: number;
8
193
  floor?: number;
9
194
  intervalMs?: number;
10
195
  }
11
- interface RetentionCandidates {
196
+ interface RetentionDeletionPlan {
12
197
  events: Event[];
13
- metrics: Metric[];
198
+ metrics: MetricSample[];
14
199
  distributions: Distribution[];
15
200
  }
16
201
  declare function selectForDeletion<T>(rows: T[], getTs: (row: T) => number, config: RetentionConfig, nowMs?: number): T[];
17
- declare function computeRetention(handle: StorageHandle, config: RetentionConfig, nowMs?: number): Promise<RetentionCandidates>;
202
+ declare function computeRetention(handle: StorageHandle, config: RetentionConfig, nowMs?: number): Promise<RetentionDeletionPlan>;
18
203
 
19
204
  declare const shapeSchema: z.ZodEnum<{
20
205
  event: "event";
@@ -90,7 +275,7 @@ declare const groupBySchema: z.ZodObject<{
90
275
  month: "month";
91
276
  }>;
92
277
  }, z.core.$strip>;
93
- declare const resolvedMetricSchema: z.ZodObject<{
278
+ declare const computedMetricSchema: z.ZodObject<{
94
279
  connectorId: z.ZodString;
95
280
  shape: z.ZodEnum<{
96
281
  event: "event";
@@ -986,7 +1171,7 @@ interface GroupBy {
986
1171
  field: string;
987
1172
  granularity: 'hour' | 'day' | 'week' | 'month';
988
1173
  }
989
- interface MetricDef {
1174
+ interface Metric {
990
1175
  connector: {
991
1176
  id: string;
992
1177
  };
@@ -999,7 +1184,7 @@ interface MetricDef {
999
1184
  filter?: FilterClause[];
1000
1185
  groupBy?: GroupBy;
1001
1186
  }
1002
- interface ResolvedMetric {
1187
+ interface ComputedMetric {
1003
1188
  readonly connectorId: string;
1004
1189
  readonly shape: Shape;
1005
1190
  readonly name?: string;
@@ -1013,7 +1198,7 @@ interface ResolvedMetric {
1013
1198
  interface StatWidget {
1014
1199
  kind: 'stat';
1015
1200
  title: string;
1016
- metric: ResolvedMetric;
1201
+ metric: ComputedMetric;
1017
1202
  window?: string;
1018
1203
  compare?: 'none' | 'previous-period';
1019
1204
  }
@@ -1025,41 +1210,62 @@ interface StatusWidget {
1025
1210
  interface TimeseriesWidget {
1026
1211
  kind: 'timeseries';
1027
1212
  title: string;
1028
- metric: ResolvedMetric;
1213
+ metric: ComputedMetric;
1029
1214
  window: string;
1030
1215
  granularity?: 'hour' | 'day' | 'week';
1031
1216
  }
1032
1217
  interface DistributionWidget {
1033
1218
  kind: 'distribution';
1034
1219
  title: string;
1035
- metric: ResolvedMetric;
1220
+ metric: ComputedMetric;
1036
1221
  window: string;
1037
1222
  }
1038
1223
  type Widget = StatWidget | StatusWidget | TimeseriesWidget | DistributionWidget;
1039
1224
 
1040
- interface ConnectorEntry {
1225
+ interface ConfiguredConnector {
1041
1226
  connector: Connector;
1042
1227
  }
1043
1228
  interface Dashboard {
1044
1229
  widgets: Record<string, Widget>;
1045
1230
  }
1046
1231
  interface DashboardConfig {
1047
- connectors: ConnectorEntry[];
1232
+ connectors: ConfiguredConnector[];
1048
1233
  dashboards: Record<string, Dashboard>;
1049
1234
  retention?: RetentionConfig;
1050
1235
  }
1051
1236
  declare function defineDashboard(options: {
1052
1237
  widgets: Record<string, Widget>;
1053
1238
  }): Dashboard;
1054
- declare function defineMetric(options: MetricDef): ResolvedMetric;
1239
+ declare function defineMetric(options: Metric): ComputedMetric;
1055
1240
  declare function defineConfig(config: DashboardConfig): DashboardConfig;
1056
1241
 
1242
+ interface CachedWidget {
1243
+ id: string;
1244
+ widgetId: string;
1245
+ connectorId: string;
1246
+ data: unknown;
1247
+ cachedAt: string | null;
1248
+ }
1249
+ interface SyncState {
1250
+ status: 'idle' | 'syncing' | 'error';
1251
+ lastSyncAt: string | null;
1252
+ lastError: string | null;
1253
+ }
1254
+
1057
1255
  type ConfigFieldsSchema = z.ZodObject<z.ZodRawShape>;
1058
1256
  declare function defineConfigFields<T extends z.ZodRawShape>(schema: z.ZodObject<T>): z.ZodObject<T>;
1059
1257
 
1060
- declare function computeMetric(storage: StorageHandle, metric: ResolvedMetric): Promise<unknown>;
1258
+ declare function computeMetric(storage: StorageHandle, metric: ComputedMetric): Promise<unknown>;
1259
+
1260
+ interface ServerStorage {
1261
+ getStorageHandle(connectorId: string): StorageHandle;
1262
+ getSyncState(): Promise<SyncState>;
1263
+ setSyncing(): Promise<boolean>;
1264
+ setSyncSuccess(): Promise<void>;
1265
+ setSyncError(error: string): Promise<void>;
1266
+ }
1061
1267
 
1062
- declare function resolveWidget(id: string, widget: Widget, connectors: ConnectorEntry[] | readonly string[] | undefined, storage: ServerStorage): Promise<WidgetEntry | undefined>;
1268
+ declare function resolveWidget(id: string, widget: Widget, connectors: ConfiguredConnector[] | readonly string[] | undefined, storage: ServerStorage): Promise<CachedWidget | undefined>;
1063
1269
 
1064
1270
  declare class InMemoryStorage implements ServerStorage {
1065
1271
  private eventStore;
@@ -1075,4 +1281,4 @@ declare class InMemoryStorage implements ServerStorage {
1075
1281
  setSyncError(error: string): Promise<void>;
1076
1282
  }
1077
1283
 
1078
- export { type AggFn, type ConfigFieldsSchema, Connector, type ConnectorEntry, type Dashboard, type DashboardConfig, Distribution, type DistributionWidget, Event, type FilterClause, type FilterCondition, type FilterOperator, type GroupBy, InMemoryStorage, Metric, type MetricDef, type ResolvedMetric, type RetentionCandidates, type RetentionConfig, ServerStorage, type Shape, type StatWidget, type StatusWidget, StorageHandle, SyncState, type TimeseriesWidget, type Widget, WidgetEntry, type WidgetKind, aggFnSchema, computeMetric, computeRetention, defineConfig, defineConfigFields, defineDashboard, defineMetric, distributionWidgetSchema, filterClauseSchema, filterConditionSchema, filterOperatorSchema, getWidgetSchema, groupBySchema, resolveWidget, resolvedMetricSchema, selectForDeletion, shapeSchema, statWidgetSchema, statusWidgetSchema, timeseriesWidgetSchema, widgetSchema, widgetSchemas };
1284
+ export { type AggFn, BaseConnector, type CachedWidget, type ComputedMetric, type ConfigFieldsSchema, type ConfiguredConnector, type Connector, type CredentialField, type CredentialsSchema, type Dashboard, type DashboardConfig, type Distribution, type DistributionQuery, type DistributionWidget, type Edge, type EdgeQuery, type Entity, type EntityQuery, EnvSecretsResolver, type Event, type EventQuery, type FilterClause, type FilterCondition, type FilterOperator, type GroupBy, InMemoryStorage, type InferCredentialInput, type InferCredentials, type JSONValue, type Metric, type MetricQuery, type MetricSample, type RetentionConfig, type RetentionDeletionPlan, type Secret, type SecretsResolver, type ServerStorage, type Shape, type StatWidget, type StatusWidget, type StorageHandle, type SyncOptions, type SyncState, type TimeseriesWidget, type Widget, type WidgetKind, aggFnSchema, computeMetric, computeRetention, computedMetricSchema, defineConfig, defineConfigFields, defineConnector, defineDashboard, defineMetric, distributionWidgetSchema, filterClauseSchema, filterConditionSchema, filterOperatorSchema, getWidgetSchema, groupBySchema, isSecret, resolveSecrets, resolveWidget, secret, selectForDeletion, shapeSchema, statWidgetSchema, statusWidgetSchema, timeseriesWidgetSchema, widgetSchema, widgetSchemas };
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ function secret(name) {
7
7
  }
8
8
  return { $secret: name };
9
9
  }
10
- function isSecretRef(value) {
10
+ function isSecret(value) {
11
11
  return typeof value === "object" && value !== null && "$secret" in value && typeof value.$secret === "string";
12
12
  }
13
13
  var EnvSecretsResolver = class {
@@ -16,8 +16,8 @@ var EnvSecretsResolver = class {
16
16
  return env?.[name];
17
17
  }
18
18
  };
19
- function resolveSecretRefs(obj, resolver) {
20
- if (isSecretRef(obj)) {
19
+ function resolveSecrets(obj, resolver) {
20
+ if (isSecret(obj)) {
21
21
  const name = obj.$secret;
22
22
  const value = resolver.resolve(name);
23
23
  if (value === void 0) {
@@ -28,13 +28,13 @@ function resolveSecretRefs(obj, resolver) {
28
28
  return value;
29
29
  }
30
30
  if (Array.isArray(obj)) {
31
- return obj.map((item) => resolveSecretRefs(item, resolver));
31
+ return obj.map((item) => resolveSecrets(item, resolver));
32
32
  }
33
33
  if (typeof obj === "object" && obj !== null) {
34
34
  const result = {};
35
35
  for (const [key, val] of Object.entries(obj)) {
36
36
  Object.defineProperty(result, key, {
37
- value: resolveSecretRefs(val, resolver),
37
+ value: resolveSecrets(val, resolver),
38
38
  enumerable: true,
39
39
  configurable: true,
40
40
  writable: true
@@ -54,7 +54,7 @@ var BaseConnector = class {
54
54
  constructor(settings, creds) {
55
55
  this.settings = settings;
56
56
  this.rawCredInput = creds;
57
- this.creds = creds ? resolveSecretRefs(
57
+ this.creds = creds ? resolveSecrets(
58
58
  creds,
59
59
  new EnvSecretsResolver()
60
60
  ) : {};
@@ -118,10 +118,10 @@ function defineConnector() {
118
118
  static credentials = def.credentials;
119
119
  id = def.id;
120
120
  credentials = def.credentials;
121
- async sync(request, storage, signal) {
121
+ async sync(options, storage, signal) {
122
122
  return def.sync.call(
123
123
  { settings: this.settings, creds: this.creds },
124
- request,
124
+ options,
125
125
  storage,
126
126
  signal
127
127
  );
@@ -171,7 +171,7 @@ var groupBySchema = z.object({
171
171
  field: z.string(),
172
172
  granularity: z.enum(["hour", "day", "week", "month"])
173
173
  });
174
- var resolvedMetricSchema = z.object({
174
+ var computedMetricSchema = z.object({
175
175
  connectorId: z.string(),
176
176
  shape: shapeSchema,
177
177
  name: z.string().optional(),
@@ -189,9 +189,9 @@ var titleField = z.string().meta({ label: "Title", description: "Widget title."
189
189
  var statWidgetSchema = z.object({
190
190
  kind: z.literal("stat"),
191
191
  title: titleField,
192
- metric: resolvedMetricSchema.meta({
192
+ metric: computedMetricSchema.meta({
193
193
  label: "Metric",
194
- description: "Resolved metric definition."
194
+ description: "Computed metric definition."
195
195
  }),
196
196
  window: z.string().optional().meta({ label: "Window", description: "Time window, e.g. '7d'." }),
197
197
  compare: z.enum(["none", "previous-period"]).default("none").meta({ label: "Compare", description: "Comparison mode." })
@@ -207,9 +207,9 @@ var statusWidgetSchema = z.object({
207
207
  var timeseriesWidgetSchema = z.object({
208
208
  kind: z.literal("timeseries"),
209
209
  title: titleField,
210
- metric: resolvedMetricSchema.meta({
210
+ metric: computedMetricSchema.meta({
211
211
  label: "Metric",
212
- description: "Resolved metric definition."
212
+ description: "Computed metric definition."
213
213
  }),
214
214
  window: z.string().meta({ label: "Window", description: "Time window, e.g. '30d'." }),
215
215
  granularity: z.enum(["hour", "day", "week"]).default("day").meta({ label: "Granularity", description: "Time bucket size." })
@@ -217,9 +217,9 @@ var timeseriesWidgetSchema = z.object({
217
217
  var distributionWidgetSchema = z.object({
218
218
  kind: z.literal("distribution"),
219
219
  title: titleField,
220
- metric: resolvedMetricSchema.meta({
220
+ metric: computedMetricSchema.meta({
221
221
  label: "Metric",
222
- description: "Resolved metric definition."
222
+ description: "Computed metric definition."
223
223
  }),
224
224
  window: z.string().meta({ label: "Window", description: "Time window, e.g. '7d'." })
225
225
  });
@@ -930,6 +930,7 @@ export {
930
930
  aggFnSchema,
931
931
  computeMetric,
932
932
  computeRetention,
933
+ computedMetricSchema,
933
934
  defineConfig,
934
935
  defineConfigFields,
935
936
  defineConnector,
@@ -941,10 +942,9 @@ export {
941
942
  filterOperatorSchema,
942
943
  getWidgetSchema,
943
944
  groupBySchema,
944
- isSecretRef,
945
- resolveSecretRefs,
945
+ isSecret,
946
+ resolveSecrets,
946
947
  resolveWidget,
947
- resolvedMetricSchema,
948
948
  secret,
949
949
  selectForDeletion,
950
950
  shapeSchema,