@rawdash/core 0.1.1 → 0.3.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/libsql.js ADDED
@@ -0,0 +1,509 @@
1
+ // src/libsql.ts
2
+ var SYNC_STATE_ID = 1;
3
+ var CREATE_TABLES_SQL = [
4
+ `CREATE TABLE IF NOT EXISTS events (
5
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6
+ connector_id TEXT NOT NULL,
7
+ name TEXT NOT NULL,
8
+ start_ts INTEGER NOT NULL,
9
+ end_ts INTEGER,
10
+ attributes TEXT NOT NULL DEFAULT '{}'
11
+ )`,
12
+ `CREATE INDEX IF NOT EXISTS events_conn_name_start ON events (connector_id, name, start_ts)`,
13
+ `CREATE TABLE IF NOT EXISTS entities (
14
+ connector_id TEXT NOT NULL,
15
+ type TEXT NOT NULL,
16
+ id TEXT NOT NULL,
17
+ attributes TEXT NOT NULL DEFAULT '{}',
18
+ updated_at INTEGER NOT NULL,
19
+ PRIMARY KEY (connector_id, type, id)
20
+ )`,
21
+ `CREATE INDEX IF NOT EXISTS entities_conn_type ON entities (connector_id, type)`,
22
+ `CREATE TABLE IF NOT EXISTS metrics (
23
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
24
+ connector_id TEXT NOT NULL,
25
+ name TEXT NOT NULL,
26
+ ts INTEGER NOT NULL,
27
+ value REAL NOT NULL,
28
+ attributes TEXT NOT NULL DEFAULT '{}'
29
+ )`,
30
+ `CREATE INDEX IF NOT EXISTS metrics_conn_name_ts ON metrics (connector_id, name, ts)`,
31
+ `CREATE TABLE IF NOT EXISTS edges (
32
+ connector_id TEXT NOT NULL,
33
+ from_type TEXT NOT NULL,
34
+ from_id TEXT NOT NULL,
35
+ kind TEXT NOT NULL,
36
+ to_type TEXT NOT NULL,
37
+ to_id TEXT NOT NULL,
38
+ attributes TEXT NOT NULL DEFAULT '{}',
39
+ updated_at INTEGER NOT NULL,
40
+ PRIMARY KEY (connector_id, from_type, from_id, kind, to_type, to_id)
41
+ )`,
42
+ `CREATE INDEX IF NOT EXISTS edges_conn_kind ON edges (connector_id, kind)`,
43
+ `CREATE INDEX IF NOT EXISTS edges_conn_from ON edges (connector_id, from_type, from_id)`,
44
+ `CREATE INDEX IF NOT EXISTS edges_conn_to ON edges (connector_id, to_type, to_id)`,
45
+ `CREATE TABLE IF NOT EXISTS distributions (
46
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
47
+ connector_id TEXT NOT NULL,
48
+ name TEXT NOT NULL,
49
+ ts INTEGER NOT NULL,
50
+ kind TEXT NOT NULL,
51
+ data TEXT NOT NULL,
52
+ attributes TEXT NOT NULL DEFAULT '{}'
53
+ )`,
54
+ `CREATE INDEX IF NOT EXISTS distributions_conn_name_ts ON distributions (connector_id, name, ts)`,
55
+ `CREATE TABLE IF NOT EXISTS sync_state (
56
+ id INTEGER PRIMARY KEY,
57
+ status TEXT NOT NULL,
58
+ last_sync_at TEXT,
59
+ last_error TEXT
60
+ )`
61
+ ];
62
+ async function initLibsqlSchema(client) {
63
+ for (const sql of CREATE_TABLES_SQL) {
64
+ await client.execute(sql);
65
+ }
66
+ await client.execute({
67
+ sql: "INSERT OR IGNORE INTO sync_state (id, status, last_sync_at, last_error) VALUES (?, 'idle', NULL, NULL)",
68
+ args: [SYNC_STATE_ID]
69
+ });
70
+ }
71
+ function parseJson(value, fallback) {
72
+ if (typeof value !== "string") {
73
+ return fallback;
74
+ }
75
+ try {
76
+ return JSON.parse(value);
77
+ } catch {
78
+ return fallback;
79
+ }
80
+ }
81
+ var LibsqlStorage = class {
82
+ client;
83
+ ready;
84
+ initError = null;
85
+ constructor(options) {
86
+ this.client = options.client;
87
+ this.ready = options.initSchema === false ? Promise.resolve() : this.init();
88
+ }
89
+ async init() {
90
+ try {
91
+ await initLibsqlSchema(this.client);
92
+ } catch (err) {
93
+ const message = err instanceof Error ? err.message : String(err);
94
+ this.initError = `init failed: ${message}`;
95
+ throw err;
96
+ }
97
+ }
98
+ async waitUntilReady() {
99
+ return this.ready;
100
+ }
101
+ getStorageHandle(connectorId) {
102
+ const ready = this.ready;
103
+ const client = this.client;
104
+ const insertEvent = (e) => ({
105
+ sql: "INSERT INTO events (connector_id, name, start_ts, end_ts, attributes) VALUES (?, ?, ?, ?, ?)",
106
+ args: [
107
+ connectorId,
108
+ e.name,
109
+ e.start_ts,
110
+ e.end_ts,
111
+ JSON.stringify(e.attributes)
112
+ ]
113
+ });
114
+ const upsertEntity = (e) => ({
115
+ sql: `INSERT INTO entities (connector_id, type, id, attributes, updated_at)
116
+ VALUES (?, ?, ?, ?, ?)
117
+ ON CONFLICT (connector_id, type, id)
118
+ DO UPDATE SET attributes = excluded.attributes, updated_at = excluded.updated_at`,
119
+ args: [
120
+ connectorId,
121
+ e.type,
122
+ e.id,
123
+ JSON.stringify(e.attributes),
124
+ e.updated_at
125
+ ]
126
+ });
127
+ const insertMetric = (m) => ({
128
+ sql: "INSERT INTO metrics (connector_id, name, ts, value, attributes) VALUES (?, ?, ?, ?, ?)",
129
+ args: [connectorId, m.name, m.ts, m.value, JSON.stringify(m.attributes)]
130
+ });
131
+ const upsertEdge = (e) => ({
132
+ sql: `INSERT INTO edges (connector_id, from_type, from_id, kind, to_type, to_id, attributes, updated_at)
133
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
134
+ ON CONFLICT (connector_id, from_type, from_id, kind, to_type, to_id)
135
+ DO UPDATE SET attributes = excluded.attributes, updated_at = excluded.updated_at`,
136
+ args: [
137
+ connectorId,
138
+ e.from_type,
139
+ e.from_id,
140
+ e.kind,
141
+ e.to_type,
142
+ e.to_id,
143
+ JSON.stringify(e.attributes),
144
+ e.updated_at
145
+ ]
146
+ });
147
+ const insertDistribution = (d) => ({
148
+ sql: "INSERT INTO distributions (connector_id, name, ts, kind, data, attributes) VALUES (?, ?, ?, ?, ?, ?)",
149
+ args: [
150
+ connectorId,
151
+ d.name,
152
+ d.ts,
153
+ d.kind,
154
+ JSON.stringify(d.data),
155
+ JSON.stringify(d.attributes)
156
+ ]
157
+ });
158
+ const inPlaceholders = (n) => Array.from({ length: n }, () => "?").join(", ");
159
+ return {
160
+ event: async (e) => {
161
+ await ready;
162
+ await client.execute(insertEvent(e));
163
+ },
164
+ entity: async (e) => {
165
+ await ready;
166
+ await client.execute(upsertEntity(e));
167
+ },
168
+ metric: async (m) => {
169
+ await ready;
170
+ await client.execute(insertMetric(m));
171
+ },
172
+ edge: async (e) => {
173
+ await ready;
174
+ await client.execute(upsertEdge(e));
175
+ },
176
+ distribution: async (d) => {
177
+ await ready;
178
+ await client.execute(insertDistribution(d));
179
+ },
180
+ events: async (es, scope) => {
181
+ await ready;
182
+ const names = Array.from(
183
+ new Set(scope?.names ?? es.map((e) => e.name))
184
+ );
185
+ const stmts = [];
186
+ if (names.length > 0) {
187
+ stmts.push({
188
+ sql: `DELETE FROM events WHERE connector_id = ? AND name IN (${inPlaceholders(names.length)})`,
189
+ args: [connectorId, ...names]
190
+ });
191
+ }
192
+ for (const e of es) {
193
+ stmts.push(insertEvent(e));
194
+ }
195
+ if (stmts.length > 0) {
196
+ await client.batch(stmts, "write");
197
+ }
198
+ },
199
+ entities: async (es, scope) => {
200
+ await ready;
201
+ const types = Array.from(
202
+ new Set(scope?.types ?? es.map((e) => e.type))
203
+ );
204
+ const stmts = [];
205
+ if (types.length > 0) {
206
+ stmts.push({
207
+ sql: `DELETE FROM entities WHERE connector_id = ? AND type IN (${inPlaceholders(types.length)})`,
208
+ args: [connectorId, ...types]
209
+ });
210
+ }
211
+ for (const e of es) {
212
+ stmts.push(upsertEntity(e));
213
+ }
214
+ if (stmts.length > 0) {
215
+ await client.batch(stmts, "write");
216
+ }
217
+ },
218
+ metrics: async (ms, scope) => {
219
+ await ready;
220
+ const names = Array.from(
221
+ new Set(scope?.names ?? ms.map((m) => m.name))
222
+ );
223
+ const stmts = [];
224
+ if (names.length > 0) {
225
+ stmts.push({
226
+ sql: `DELETE FROM metrics WHERE connector_id = ? AND name IN (${inPlaceholders(names.length)})`,
227
+ args: [connectorId, ...names]
228
+ });
229
+ }
230
+ for (const m of ms) {
231
+ stmts.push(insertMetric(m));
232
+ }
233
+ if (stmts.length > 0) {
234
+ await client.batch(stmts, "write");
235
+ }
236
+ },
237
+ edges: async (es, scope) => {
238
+ await ready;
239
+ const kinds = Array.from(
240
+ new Set(scope?.kinds ?? es.map((e) => e.kind))
241
+ );
242
+ const stmts = [];
243
+ if (kinds.length > 0) {
244
+ stmts.push({
245
+ sql: `DELETE FROM edges WHERE connector_id = ? AND kind IN (${inPlaceholders(kinds.length)})`,
246
+ args: [connectorId, ...kinds]
247
+ });
248
+ }
249
+ for (const e of es) {
250
+ stmts.push(upsertEdge(e));
251
+ }
252
+ if (stmts.length > 0) {
253
+ await client.batch(stmts, "write");
254
+ }
255
+ },
256
+ distributions: async (ds, scope) => {
257
+ await ready;
258
+ const names = Array.from(
259
+ new Set(scope?.names ?? ds.map((d) => d.name))
260
+ );
261
+ const stmts = [];
262
+ if (names.length > 0) {
263
+ stmts.push({
264
+ sql: `DELETE FROM distributions WHERE connector_id = ? AND name IN (${inPlaceholders(names.length)})`,
265
+ args: [connectorId, ...names]
266
+ });
267
+ }
268
+ for (const d of ds) {
269
+ stmts.push(insertDistribution(d));
270
+ }
271
+ if (stmts.length > 0) {
272
+ await client.batch(stmts, "write");
273
+ }
274
+ },
275
+ queryEvents: async (q) => {
276
+ await ready;
277
+ const conds = ["connector_id = ?"];
278
+ const args = [connectorId];
279
+ if (q.name !== void 0) {
280
+ conds.push("name = ?");
281
+ args.push(q.name);
282
+ }
283
+ if (q.start !== void 0) {
284
+ conds.push("start_ts >= ?");
285
+ args.push(q.start);
286
+ }
287
+ if (q.end !== void 0) {
288
+ conds.push("start_ts <= ?");
289
+ args.push(q.end);
290
+ }
291
+ const result = await client.execute({
292
+ sql: `SELECT name, start_ts, end_ts, attributes FROM events WHERE ${conds.join(" AND ")}`,
293
+ args
294
+ });
295
+ return result.rows.map(
296
+ (r) => ({
297
+ name: r.name,
298
+ start_ts: Number(r.start_ts),
299
+ end_ts: r.end_ts === null ? null : Number(r.end_ts),
300
+ attributes: parseJson(r.attributes, {})
301
+ })
302
+ );
303
+ },
304
+ getEntity: async (type, id) => {
305
+ await ready;
306
+ const result = await client.execute({
307
+ sql: "SELECT type, id, attributes, updated_at FROM entities WHERE connector_id = ? AND type = ? AND id = ? LIMIT 1",
308
+ args: [connectorId, type, id]
309
+ });
310
+ const r = result.rows[0];
311
+ if (!r) {
312
+ return null;
313
+ }
314
+ return {
315
+ type: r.type,
316
+ id: r.id,
317
+ attributes: parseJson(r.attributes, {}),
318
+ updated_at: Number(r.updated_at)
319
+ };
320
+ },
321
+ queryEntities: async (q) => {
322
+ await ready;
323
+ const result = await client.execute({
324
+ sql: "SELECT type, id, attributes, updated_at FROM entities WHERE connector_id = ? AND type = ?",
325
+ args: [connectorId, q.type]
326
+ });
327
+ return result.rows.map(
328
+ (r) => ({
329
+ type: r.type,
330
+ id: r.id,
331
+ attributes: parseJson(r.attributes, {}),
332
+ updated_at: Number(r.updated_at)
333
+ })
334
+ );
335
+ },
336
+ queryMetrics: async (q) => {
337
+ await ready;
338
+ const conds = ["connector_id = ?"];
339
+ const args = [connectorId];
340
+ if (q.name !== void 0) {
341
+ conds.push("name = ?");
342
+ args.push(q.name);
343
+ }
344
+ if (q.start !== void 0) {
345
+ conds.push("ts >= ?");
346
+ args.push(q.start);
347
+ }
348
+ if (q.end !== void 0) {
349
+ conds.push("ts <= ?");
350
+ args.push(q.end);
351
+ }
352
+ const result = await client.execute({
353
+ sql: `SELECT name, ts, value, attributes FROM metrics WHERE ${conds.join(" AND ")}`,
354
+ args
355
+ });
356
+ return result.rows.map(
357
+ (r) => ({
358
+ name: r.name,
359
+ ts: Number(r.ts),
360
+ value: Number(r.value),
361
+ attributes: parseJson(r.attributes, {})
362
+ })
363
+ );
364
+ },
365
+ traverse: async (q) => {
366
+ await ready;
367
+ const conds = ["connector_id = ?"];
368
+ const args = [connectorId];
369
+ if (q.fromType !== void 0) {
370
+ conds.push("from_type = ?");
371
+ args.push(q.fromType);
372
+ }
373
+ if (q.fromId !== void 0) {
374
+ conds.push("from_id = ?");
375
+ args.push(q.fromId);
376
+ }
377
+ if (q.kind !== void 0) {
378
+ conds.push("kind = ?");
379
+ args.push(q.kind);
380
+ }
381
+ if (q.toType !== void 0) {
382
+ conds.push("to_type = ?");
383
+ args.push(q.toType);
384
+ }
385
+ if (q.toId !== void 0) {
386
+ conds.push("to_id = ?");
387
+ args.push(q.toId);
388
+ }
389
+ const result = await client.execute({
390
+ sql: `SELECT from_type, from_id, kind, to_type, to_id, attributes, updated_at FROM edges WHERE ${conds.join(" AND ")}`,
391
+ args
392
+ });
393
+ return result.rows.map(
394
+ (r) => ({
395
+ from_type: r.from_type,
396
+ from_id: r.from_id,
397
+ kind: r.kind,
398
+ to_type: r.to_type,
399
+ to_id: r.to_id,
400
+ attributes: parseJson(r.attributes, {}),
401
+ updated_at: Number(r.updated_at)
402
+ })
403
+ );
404
+ },
405
+ queryDistributions: async (q) => {
406
+ await ready;
407
+ const conds = ["connector_id = ?"];
408
+ const args = [connectorId];
409
+ if (q.name !== void 0) {
410
+ conds.push("name = ?");
411
+ args.push(q.name);
412
+ }
413
+ if (q.start !== void 0) {
414
+ conds.push("ts >= ?");
415
+ args.push(q.start);
416
+ }
417
+ if (q.end !== void 0) {
418
+ conds.push("ts <= ?");
419
+ args.push(q.end);
420
+ }
421
+ const result = await client.execute({
422
+ sql: `SELECT name, ts, kind, data, attributes FROM distributions WHERE ${conds.join(" AND ")}`,
423
+ args
424
+ });
425
+ return result.rows.map((r) => {
426
+ const base = {
427
+ name: r.name,
428
+ ts: Number(r.ts),
429
+ attributes: parseJson(r.attributes, {})
430
+ };
431
+ const kind = r.kind;
432
+ const data = parseJson(r.data, {
433
+ count: 0,
434
+ sum: 0
435
+ });
436
+ if (kind === "histogram") {
437
+ return { ...base, kind: "histogram", data };
438
+ }
439
+ if (kind === "summary") {
440
+ return { ...base, kind: "summary", data };
441
+ }
442
+ throw new Error(
443
+ `Unknown distribution kind: ${kind} (name=${base.name})`
444
+ );
445
+ });
446
+ },
447
+ deleteOlderThan: async (shape, tsUnixMs) => {
448
+ await ready;
449
+ const tsCol = shape === "events" ? "start_ts" : "ts";
450
+ if (shape !== "events" && shape !== "metrics" && shape !== "distributions") {
451
+ throw new Error(
452
+ `Unsupported shape for deleteOlderThan: ${String(shape)}`
453
+ );
454
+ }
455
+ const result = await client.execute({
456
+ sql: `DELETE FROM ${shape} WHERE connector_id = ? AND ${tsCol} < ?`,
457
+ args: [connectorId, tsUnixMs]
458
+ });
459
+ return { rowsDeleted: result.rowsAffected };
460
+ }
461
+ };
462
+ }
463
+ async getSyncState() {
464
+ if (this.initError !== null) {
465
+ return { status: "error", lastSyncAt: null, lastError: this.initError };
466
+ }
467
+ await this.ready;
468
+ const result = await this.client.execute({
469
+ sql: "SELECT status, last_sync_at, last_error FROM sync_state WHERE id = ? LIMIT 1",
470
+ args: [SYNC_STATE_ID]
471
+ });
472
+ const r = result.rows[0];
473
+ if (!r) {
474
+ return { status: "idle", lastSyncAt: null, lastError: null };
475
+ }
476
+ return {
477
+ status: r.status,
478
+ lastSyncAt: r.last_sync_at,
479
+ lastError: r.last_error
480
+ };
481
+ }
482
+ async setSyncing() {
483
+ await this.ready;
484
+ const result = await this.client.execute({
485
+ sql: "UPDATE sync_state SET status = 'syncing' WHERE id = ? AND status != 'syncing'",
486
+ args: [SYNC_STATE_ID]
487
+ });
488
+ return result.rowsAffected > 0;
489
+ }
490
+ async setSyncSuccess() {
491
+ await this.ready;
492
+ await this.client.execute({
493
+ sql: "UPDATE sync_state SET status = 'idle', last_sync_at = ?, last_error = NULL WHERE id = ?",
494
+ args: [(/* @__PURE__ */ new Date()).toISOString(), SYNC_STATE_ID]
495
+ });
496
+ }
497
+ async setSyncError(error) {
498
+ await this.ready;
499
+ await this.client.execute({
500
+ sql: "UPDATE sync_state SET status = 'error', last_error = ? WHERE id = ?",
501
+ args: [error, SYNC_STATE_ID]
502
+ });
503
+ }
504
+ };
505
+ export {
506
+ LibsqlStorage,
507
+ initLibsqlSchema
508
+ };
509
+ //# sourceMappingURL=libsql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/libsql.ts"],"sourcesContent":["import type { Client, InValue } from '@libsql/client/web';\n\nimport type {\n Distribution,\n DistributionQuery,\n Edge,\n EdgeQuery,\n Entity,\n EntityQuery,\n Event,\n EventQuery,\n JSONValue,\n Metric,\n MetricQuery,\n StorageHandle,\n} from './connector';\nimport type { SyncState } from './engine';\nimport type { ServerStorage } from './server-storage';\n\ntype Attrs = Record<string, JSONValue>;\n\nconst SYNC_STATE_ID = 1;\n\nconst CREATE_TABLES_SQL = [\n `CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n connector_id TEXT NOT NULL,\n name TEXT NOT NULL,\n start_ts INTEGER NOT NULL,\n end_ts INTEGER,\n attributes TEXT NOT NULL DEFAULT '{}'\n )`,\n `CREATE INDEX IF NOT EXISTS events_conn_name_start ON events (connector_id, name, start_ts)`,\n `CREATE TABLE IF NOT EXISTS entities (\n connector_id TEXT NOT NULL,\n type TEXT NOT NULL,\n id TEXT NOT NULL,\n attributes TEXT NOT NULL DEFAULT '{}',\n updated_at INTEGER NOT NULL,\n PRIMARY KEY (connector_id, type, id)\n )`,\n `CREATE INDEX IF NOT EXISTS entities_conn_type ON entities (connector_id, type)`,\n `CREATE TABLE IF NOT EXISTS metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n connector_id TEXT NOT NULL,\n name TEXT NOT NULL,\n ts INTEGER NOT NULL,\n value REAL NOT NULL,\n attributes TEXT NOT NULL DEFAULT '{}'\n )`,\n `CREATE INDEX IF NOT EXISTS metrics_conn_name_ts ON metrics (connector_id, name, ts)`,\n `CREATE TABLE IF NOT EXISTS edges (\n connector_id TEXT NOT NULL,\n from_type TEXT NOT NULL,\n from_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n to_type TEXT NOT NULL,\n to_id TEXT NOT NULL,\n attributes TEXT NOT NULL DEFAULT '{}',\n updated_at INTEGER NOT NULL,\n PRIMARY KEY (connector_id, from_type, from_id, kind, to_type, to_id)\n )`,\n `CREATE INDEX IF NOT EXISTS edges_conn_kind ON edges (connector_id, kind)`,\n `CREATE INDEX IF NOT EXISTS edges_conn_from ON edges (connector_id, from_type, from_id)`,\n `CREATE INDEX IF NOT EXISTS edges_conn_to ON edges (connector_id, to_type, to_id)`,\n `CREATE TABLE IF NOT EXISTS distributions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n connector_id TEXT NOT NULL,\n name TEXT NOT NULL,\n ts INTEGER NOT NULL,\n kind TEXT NOT NULL,\n data TEXT NOT NULL,\n attributes TEXT NOT NULL DEFAULT '{}'\n )`,\n `CREATE INDEX IF NOT EXISTS distributions_conn_name_ts ON distributions (connector_id, name, ts)`,\n `CREATE TABLE IF NOT EXISTS sync_state (\n id INTEGER PRIMARY KEY,\n status TEXT NOT NULL,\n last_sync_at TEXT,\n last_error TEXT\n )`,\n];\n\nexport async function initLibsqlSchema(client: Client): Promise<void> {\n for (const sql of CREATE_TABLES_SQL) {\n await client.execute(sql);\n }\n await client.execute({\n sql: \"INSERT OR IGNORE INTO sync_state (id, status, last_sync_at, last_error) VALUES (?, 'idle', NULL, NULL)\",\n args: [SYNC_STATE_ID],\n });\n}\n\nfunction parseJson<T>(value: unknown, fallback: T): T {\n if (typeof value !== 'string') {\n return fallback;\n }\n try {\n return JSON.parse(value) as T;\n } catch {\n return fallback;\n }\n}\n\nexport interface LibsqlStorageOptions {\n client: Client;\n initSchema?: boolean;\n}\n\nexport class LibsqlStorage implements ServerStorage {\n private client: Client;\n private ready: Promise<void>;\n private initError: string | null = null;\n\n constructor(options: LibsqlStorageOptions) {\n this.client = options.client;\n this.ready = options.initSchema === false ? Promise.resolve() : this.init();\n }\n\n private async init(): Promise<void> {\n try {\n await initLibsqlSchema(this.client);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.initError = `init failed: ${message}`;\n throw err;\n }\n }\n\n async waitUntilReady(): Promise<void> {\n return this.ready;\n }\n\n getStorageHandle(connectorId: string): StorageHandle {\n const ready = this.ready;\n const client = this.client;\n\n const insertEvent = (e: Event): { sql: string; args: InValue[] } => ({\n sql: 'INSERT INTO events (connector_id, name, start_ts, end_ts, attributes) VALUES (?, ?, ?, ?, ?)',\n args: [\n connectorId,\n e.name,\n e.start_ts,\n e.end_ts,\n JSON.stringify(e.attributes),\n ],\n });\n\n const upsertEntity = (e: Entity): { sql: string; args: InValue[] } => ({\n sql: `INSERT INTO entities (connector_id, type, id, attributes, updated_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT (connector_id, type, id)\n DO UPDATE SET attributes = excluded.attributes, updated_at = excluded.updated_at`,\n args: [\n connectorId,\n e.type,\n e.id,\n JSON.stringify(e.attributes),\n e.updated_at,\n ],\n });\n\n const insertMetric = (m: Metric): { sql: string; args: InValue[] } => ({\n sql: 'INSERT INTO metrics (connector_id, name, ts, value, attributes) VALUES (?, ?, ?, ?, ?)',\n args: [connectorId, m.name, m.ts, m.value, JSON.stringify(m.attributes)],\n });\n\n const upsertEdge = (e: Edge): { sql: string; args: InValue[] } => ({\n sql: `INSERT INTO edges (connector_id, from_type, from_id, kind, to_type, to_id, attributes, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (connector_id, from_type, from_id, kind, to_type, to_id)\n DO UPDATE SET attributes = excluded.attributes, updated_at = excluded.updated_at`,\n args: [\n connectorId,\n e.from_type,\n e.from_id,\n e.kind,\n e.to_type,\n e.to_id,\n JSON.stringify(e.attributes),\n e.updated_at,\n ],\n });\n\n const insertDistribution = (\n d: Distribution,\n ): { sql: string; args: InValue[] } => ({\n sql: 'INSERT INTO distributions (connector_id, name, ts, kind, data, attributes) VALUES (?, ?, ?, ?, ?, ?)',\n args: [\n connectorId,\n d.name,\n d.ts,\n d.kind,\n JSON.stringify(d.data),\n JSON.stringify(d.attributes),\n ],\n });\n\n const inPlaceholders = (n: number): string =>\n Array.from({ length: n }, () => '?').join(', ');\n\n return {\n event: async (e) => {\n await ready;\n await client.execute(insertEvent(e));\n },\n\n entity: async (e) => {\n await ready;\n await client.execute(upsertEntity(e));\n },\n\n metric: async (m) => {\n await ready;\n await client.execute(insertMetric(m));\n },\n\n edge: async (e) => {\n await ready;\n await client.execute(upsertEdge(e));\n },\n\n distribution: async (d) => {\n await ready;\n await client.execute(insertDistribution(d));\n },\n\n events: async (es, scope) => {\n await ready;\n const names = Array.from(\n new Set(scope?.names ?? es.map((e) => e.name)),\n );\n const stmts: { sql: string; args: InValue[] }[] = [];\n if (names.length > 0) {\n stmts.push({\n sql: `DELETE FROM events WHERE connector_id = ? AND name IN (${inPlaceholders(names.length)})`,\n args: [connectorId, ...names],\n });\n }\n for (const e of es) {\n stmts.push(insertEvent(e));\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n entities: async (es, scope) => {\n await ready;\n const types = Array.from(\n new Set(scope?.types ?? es.map((e) => e.type)),\n );\n const stmts: { sql: string; args: InValue[] }[] = [];\n if (types.length > 0) {\n stmts.push({\n sql: `DELETE FROM entities WHERE connector_id = ? AND type IN (${inPlaceholders(types.length)})`,\n args: [connectorId, ...types],\n });\n }\n for (const e of es) {\n stmts.push(upsertEntity(e));\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n metrics: async (ms, scope) => {\n await ready;\n const names = Array.from(\n new Set(scope?.names ?? ms.map((m) => m.name)),\n );\n const stmts: { sql: string; args: InValue[] }[] = [];\n if (names.length > 0) {\n stmts.push({\n sql: `DELETE FROM metrics WHERE connector_id = ? AND name IN (${inPlaceholders(names.length)})`,\n args: [connectorId, ...names],\n });\n }\n for (const m of ms) {\n stmts.push(insertMetric(m));\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n edges: async (es, scope) => {\n await ready;\n const kinds = Array.from(\n new Set(scope?.kinds ?? es.map((e) => e.kind)),\n );\n const stmts: { sql: string; args: InValue[] }[] = [];\n if (kinds.length > 0) {\n stmts.push({\n sql: `DELETE FROM edges WHERE connector_id = ? AND kind IN (${inPlaceholders(kinds.length)})`,\n args: [connectorId, ...kinds],\n });\n }\n for (const e of es) {\n stmts.push(upsertEdge(e));\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n distributions: async (ds, scope) => {\n await ready;\n const names = Array.from(\n new Set(scope?.names ?? ds.map((d) => d.name)),\n );\n const stmts: { sql: string; args: InValue[] }[] = [];\n if (names.length > 0) {\n stmts.push({\n sql: `DELETE FROM distributions WHERE connector_id = ? AND name IN (${inPlaceholders(names.length)})`,\n args: [connectorId, ...names],\n });\n }\n for (const d of ds) {\n stmts.push(insertDistribution(d));\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n queryEvents: async (q: EventQuery) => {\n await ready;\n const conds = ['connector_id = ?'];\n const args: InValue[] = [connectorId];\n if (q.name !== undefined) {\n conds.push('name = ?');\n args.push(q.name);\n }\n if (q.start !== undefined) {\n conds.push('start_ts >= ?');\n args.push(q.start);\n }\n if (q.end !== undefined) {\n conds.push('start_ts <= ?');\n args.push(q.end);\n }\n const result = await client.execute({\n sql: `SELECT name, start_ts, end_ts, attributes FROM events WHERE ${conds.join(' AND ')}`,\n args,\n });\n return result.rows.map(\n (r): Event => ({\n name: r.name as string,\n start_ts: Number(r.start_ts),\n end_ts: r.end_ts === null ? null : Number(r.end_ts),\n attributes: parseJson<Attrs>(r.attributes, {}),\n }),\n );\n },\n\n getEntity: async (type, id) => {\n await ready;\n const result = await client.execute({\n sql: 'SELECT type, id, attributes, updated_at FROM entities WHERE connector_id = ? AND type = ? AND id = ? LIMIT 1',\n args: [connectorId, type, id],\n });\n const r = result.rows[0];\n if (!r) {\n return null;\n }\n return {\n type: r.type as string,\n id: r.id as string,\n attributes: parseJson<Attrs>(r.attributes, {}),\n updated_at: Number(r.updated_at),\n };\n },\n\n queryEntities: async (q: EntityQuery) => {\n await ready;\n const result = await client.execute({\n sql: 'SELECT type, id, attributes, updated_at FROM entities WHERE connector_id = ? AND type = ?',\n args: [connectorId, q.type],\n });\n return result.rows.map(\n (r): Entity => ({\n type: r.type as string,\n id: r.id as string,\n attributes: parseJson<Attrs>(r.attributes, {}),\n updated_at: Number(r.updated_at),\n }),\n );\n },\n\n queryMetrics: async (q: MetricQuery) => {\n await ready;\n const conds = ['connector_id = ?'];\n const args: InValue[] = [connectorId];\n if (q.name !== undefined) {\n conds.push('name = ?');\n args.push(q.name);\n }\n if (q.start !== undefined) {\n conds.push('ts >= ?');\n args.push(q.start);\n }\n if (q.end !== undefined) {\n conds.push('ts <= ?');\n args.push(q.end);\n }\n const result = await client.execute({\n sql: `SELECT name, ts, value, attributes FROM metrics WHERE ${conds.join(' AND ')}`,\n args,\n });\n return result.rows.map(\n (r): Metric => ({\n name: r.name as string,\n ts: Number(r.ts),\n value: Number(r.value),\n attributes: parseJson<Attrs>(r.attributes, {}),\n }),\n );\n },\n\n traverse: async (q: EdgeQuery) => {\n await ready;\n const conds = ['connector_id = ?'];\n const args: InValue[] = [connectorId];\n if (q.fromType !== undefined) {\n conds.push('from_type = ?');\n args.push(q.fromType);\n }\n if (q.fromId !== undefined) {\n conds.push('from_id = ?');\n args.push(q.fromId);\n }\n if (q.kind !== undefined) {\n conds.push('kind = ?');\n args.push(q.kind);\n }\n if (q.toType !== undefined) {\n conds.push('to_type = ?');\n args.push(q.toType);\n }\n if (q.toId !== undefined) {\n conds.push('to_id = ?');\n args.push(q.toId);\n }\n const result = await client.execute({\n sql: `SELECT from_type, from_id, kind, to_type, to_id, attributes, updated_at FROM edges WHERE ${conds.join(' AND ')}`,\n args,\n });\n return result.rows.map(\n (r): Edge => ({\n from_type: r.from_type as string,\n from_id: r.from_id as string,\n kind: r.kind as string,\n to_type: r.to_type as string,\n to_id: r.to_id as string,\n attributes: parseJson<Attrs>(r.attributes, {}),\n updated_at: Number(r.updated_at),\n }),\n );\n },\n\n queryDistributions: async (q: DistributionQuery) => {\n await ready;\n const conds = ['connector_id = ?'];\n const args: InValue[] = [connectorId];\n if (q.name !== undefined) {\n conds.push('name = ?');\n args.push(q.name);\n }\n if (q.start !== undefined) {\n conds.push('ts >= ?');\n args.push(q.start);\n }\n if (q.end !== undefined) {\n conds.push('ts <= ?');\n args.push(q.end);\n }\n const result = await client.execute({\n sql: `SELECT name, ts, kind, data, attributes FROM distributions WHERE ${conds.join(' AND ')}`,\n args,\n });\n return result.rows.map((r) => {\n const base = {\n name: r.name as string,\n ts: Number(r.ts),\n attributes: parseJson<Attrs>(r.attributes, {}),\n };\n const kind = r.kind as string;\n const data = parseJson<Distribution['data']>(r.data, {\n count: 0,\n sum: 0,\n } as unknown as Distribution['data']);\n if (kind === 'histogram') {\n return { ...base, kind: 'histogram', data } as Distribution;\n }\n if (kind === 'summary') {\n return { ...base, kind: 'summary', data } as Distribution;\n }\n throw new Error(\n `Unknown distribution kind: ${kind} (name=${base.name})`,\n );\n });\n },\n\n deleteOlderThan: async (shape, tsUnixMs) => {\n await ready;\n const tsCol = shape === 'events' ? 'start_ts' : 'ts';\n if (\n shape !== 'events' &&\n shape !== 'metrics' &&\n shape !== 'distributions'\n ) {\n throw new Error(\n `Unsupported shape for deleteOlderThan: ${String(shape)}`,\n );\n }\n const result = await client.execute({\n sql: `DELETE FROM ${shape} WHERE connector_id = ? AND ${tsCol} < ?`,\n args: [connectorId, tsUnixMs],\n });\n return { rowsDeleted: result.rowsAffected };\n },\n };\n }\n\n async getSyncState(): Promise<SyncState> {\n if (this.initError !== null) {\n return { status: 'error', lastSyncAt: null, lastError: this.initError };\n }\n await this.ready;\n const result = await this.client.execute({\n sql: 'SELECT status, last_sync_at, last_error FROM sync_state WHERE id = ? LIMIT 1',\n args: [SYNC_STATE_ID],\n });\n const r = result.rows[0];\n if (!r) {\n return { status: 'idle', lastSyncAt: null, lastError: null };\n }\n return {\n status: r.status as SyncState['status'],\n lastSyncAt: r.last_sync_at as string | null,\n lastError: r.last_error as string | null,\n };\n }\n\n async setSyncing(): Promise<boolean> {\n await this.ready;\n const result = await this.client.execute({\n sql: \"UPDATE sync_state SET status = 'syncing' WHERE id = ? AND status != 'syncing'\",\n args: [SYNC_STATE_ID],\n });\n return result.rowsAffected > 0;\n }\n\n async setSyncSuccess(): Promise<void> {\n await this.ready;\n await this.client.execute({\n sql: \"UPDATE sync_state SET status = 'idle', last_sync_at = ?, last_error = NULL WHERE id = ?\",\n args: [new Date().toISOString(), SYNC_STATE_ID],\n });\n }\n\n async setSyncError(error: string): Promise<void> {\n await this.ready;\n await this.client.execute({\n sql: \"UPDATE sync_state SET status = 'error', last_error = ? WHERE id = ?\",\n args: [error, SYNC_STATE_ID],\n });\n }\n}\n"],"mappings":"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","names":[]}