@rawdash/adapter-libsql 0.22.0 → 0.24.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
@@ -1,6 +1,6 @@
1
1
  // src/libsql-storage.ts
2
- import { withAbortSignal } from "@rawdash/core";
3
- import { Kysely } from "kysely";
2
+ import { dimsKey, withAbortSignal } from "@rawdash/core";
3
+ import { Kysely, sql } from "kysely";
4
4
  import { LibsqlDialect } from "kysely-libsql";
5
5
 
6
6
  // src/migrations-bundle.ts
@@ -33,6 +33,14 @@ var MIGRATIONS = [
33
33
  "ALTER TABLE `sync_state` ADD `queued_at` text;",
34
34
  "ALTER TABLE `sync_state` ADD `started_at` text;"
35
35
  ]
36
+ },
37
+ {
38
+ tag: "0003_milky_morbius",
39
+ statements: [
40
+ "CREATE TABLE `rollup_watermarks` (\n `connector_id` text NOT NULL,\n `resource` text NOT NULL,\n `watermark` integer NOT NULL,\n PRIMARY KEY(`connector_id`, `resource`)\n);",
41
+ "CREATE TABLE `rollups` (\n `connector_id` text NOT NULL,\n `resource` text NOT NULL,\n `field` text DEFAULT '' NOT NULL,\n `granularity` text NOT NULL,\n `dims_key` text DEFAULT '' NOT NULL,\n `dims` text DEFAULT '{}' NOT NULL,\n `bucket_start` integer NOT NULL,\n `partials` text NOT NULL,\n PRIMARY KEY(`connector_id`, `resource`, `field`, `granularity`, `dims_key`, `bucket_start`)\n);",
42
+ "CREATE INDEX `rollups_conn_resource_field` ON `rollups` (`connector_id`,`resource`,`field`);"
43
+ ]
36
44
  }
37
45
  ];
38
46
 
@@ -209,6 +217,16 @@ var LibsqlStorage = class {
209
217
  data: JSON.stringify(d.data),
210
218
  attributes: JSON.stringify(d.attributes)
211
219
  });
220
+ const rollupRow = (b) => ({
221
+ connector_id: connectorId,
222
+ resource: b.resource,
223
+ field: b.field,
224
+ granularity: b.granularity,
225
+ dims_key: dimsKey(b.dims),
226
+ dims: JSON.stringify(b.dims),
227
+ bucket_start: b.bucketStart,
228
+ partials: JSON.stringify(b.partials)
229
+ });
212
230
  return {
213
231
  event: async (e) => {
214
232
  await ready;
@@ -543,6 +561,87 @@ var LibsqlStorage = class {
543
561
  throw new Error(
544
562
  `Unsupported shape for deleteOlderThan: ${String(shape)}`
545
563
  );
564
+ },
565
+ writeRollups: async (buckets) => {
566
+ await ready;
567
+ if (buckets.length === 0) {
568
+ return;
569
+ }
570
+ const stmts = buckets.map(
571
+ (b) => toBatchStmt(
572
+ db.insertInto("rollups").values(rollupRow(b)).onConflict(
573
+ (oc) => oc.columns([
574
+ "connector_id",
575
+ "resource",
576
+ "field",
577
+ "granularity",
578
+ "dims_key",
579
+ "bucket_start"
580
+ ]).doUpdateSet({
581
+ dims: (eb) => eb.ref("excluded.dims"),
582
+ partials: (eb) => eb.ref("excluded.partials")
583
+ })
584
+ ).compile()
585
+ )
586
+ );
587
+ await client.batch(stmts, "write");
588
+ },
589
+ queryRollups: async (q) => {
590
+ await ready;
591
+ let qb = db.selectFrom("rollups").select([
592
+ "resource",
593
+ "field",
594
+ "granularity",
595
+ "dims",
596
+ "bucket_start",
597
+ "partials"
598
+ ]).where("connector_id", "=", connectorId).where("resource", "=", q.resource);
599
+ if (q.field !== void 0) {
600
+ qb = qb.where("field", "=", q.field);
601
+ }
602
+ if (q.granularity !== void 0) {
603
+ qb = qb.where("granularity", "=", q.granularity);
604
+ }
605
+ if (q.start !== void 0) {
606
+ qb = qb.where("bucket_start", ">=", q.start);
607
+ }
608
+ if (q.end !== void 0) {
609
+ qb = qb.where("bucket_start", "<", q.end);
610
+ }
611
+ const rows = await qb.execute();
612
+ return rows.map(
613
+ (r) => ({
614
+ resource: r.resource,
615
+ field: r.field,
616
+ granularity: r.granularity,
617
+ dims: parseJson(r.dims, {}),
618
+ bucketStart: Number(r.bucket_start),
619
+ partials: parseJson(r.partials, {
620
+ count: 0,
621
+ numericCount: 0,
622
+ sum: 0,
623
+ min: null,
624
+ max: null,
625
+ firstTs: null,
626
+ firstValue: null,
627
+ latestTs: null,
628
+ latestValue: null
629
+ })
630
+ })
631
+ );
632
+ },
633
+ getRollupWatermark: async (resource) => {
634
+ await ready;
635
+ const r = await db.selectFrom("rollup_watermarks").select(["watermark"]).where("connector_id", "=", connectorId).where("resource", "=", resource).limit(1).executeTakeFirst();
636
+ return r ? Number(r.watermark) : null;
637
+ },
638
+ setRollupWatermark: async (resource, tsUnixMs) => {
639
+ await ready;
640
+ await db.insertInto("rollup_watermarks").values({ connector_id: connectorId, resource, watermark: tsUnixMs }).onConflict(
641
+ (oc) => oc.columns(["connector_id", "resource"]).doUpdateSet({
642
+ watermark: sql`max(rollup_watermarks.watermark, excluded.watermark)`
643
+ })
644
+ ).execute();
546
645
  }
547
646
  };
548
647
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/libsql-storage.ts","../src/migrations-bundle.ts","../src/migrate.ts"],"sourcesContent":["import type { Client, InValue } from '@libsql/client/web';\nimport type {\n Distribution,\n DistributionQuery,\n Edge,\n EdgeQuery,\n Entity,\n EntityQuery,\n Event,\n EventQuery,\n GetStorageHandleOptions,\n JSONValue,\n MetricQuery,\n MetricSample,\n ServerStorage,\n StorageHandle,\n SyncState,\n} from '@rawdash/core';\nimport { withAbortSignal } from '@rawdash/core';\nimport { type CompiledQuery, type Insertable, Kysely } from 'kysely';\nimport { LibsqlDialect } from 'kysely-libsql';\n\nimport type {\n Database,\n EdgesTable,\n EntitiesTable,\n EventsTable,\n MetricsTable,\n} from './db-schema';\nimport { applyMigrations } from './migrate';\n\ntype Attrs = Record<string, JSONValue>;\n\nconst SYNC_STATE_ID = 1;\n\nexport async function initLibsqlSchema(client: Client): Promise<void> {\n await applyMigrations(client, { assumeLegacyBaselineIfEventsExists: true });\n await client.execute({\n sql: \"INSERT OR IGNORE INTO sync_state (id, status, queued_at, started_at, last_sync_at, last_error) VALUES (?, 'idle', NULL, NULL, 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\nfunction createDb(client: Client): Kysely<Database> {\n return new Kysely<Database>({\n dialect: new LibsqlDialect({ client }),\n });\n}\n\nfunction toBatchStmt(q: CompiledQuery): { sql: string; args: InValue[] } {\n return { sql: q.sql, args: q.parameters as InValue[] };\n}\n\nexport interface LibsqlStorageOptions {\n client: Client;\n initSchema?: boolean;\n}\n\nexport class LibsqlStorage implements ServerStorage {\n private client: Client;\n private db: Kysely<Database>;\n private ready: Promise<void>;\n private initError: string | null = null;\n\n constructor(options: LibsqlStorageOptions) {\n this.client = options.client;\n this.db = createDb(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(\n connectorId: string,\n options?: GetStorageHandleOptions,\n ): StorageHandle {\n const handle = this.buildHandle(connectorId);\n return options?.signal ? withAbortSignal(handle, options.signal) : handle;\n }\n\n private buildHandle(connectorId: string): StorageHandle {\n const ready = this.ready;\n const db = this.db;\n const client = this.client;\n\n const eventRow = (e: Event): Insertable<EventsTable> => ({\n connector_id: connectorId,\n name: e.name,\n start_ts: e.start_ts,\n end_ts: e.end_ts,\n attributes: JSON.stringify(e.attributes),\n });\n\n const entityRow = (e: Entity): Insertable<EntitiesTable> => ({\n connector_id: connectorId,\n type: e.type,\n id: e.id,\n attributes: JSON.stringify(e.attributes),\n updated_at: e.updated_at,\n });\n\n const metricRow = (m: MetricSample): Insertable<MetricsTable> => ({\n connector_id: connectorId,\n name: m.name,\n ts: m.ts,\n value: m.value,\n attributes: JSON.stringify(m.attributes),\n });\n\n const edgeRow = (e: Edge): Insertable<EdgesTable> => ({\n connector_id: connectorId,\n from_type: e.from_type,\n from_id: e.from_id,\n kind: e.kind,\n to_type: e.to_type,\n to_id: e.to_id,\n attributes: JSON.stringify(e.attributes),\n updated_at: e.updated_at,\n });\n\n const distributionRow = (d: Distribution) => ({\n connector_id: connectorId,\n name: d.name,\n ts: d.ts,\n kind: d.kind,\n data: JSON.stringify(d.data),\n attributes: JSON.stringify(d.attributes),\n });\n\n return {\n event: async (e) => {\n await ready;\n await db.insertInto('events').values(eventRow(e)).execute();\n },\n\n entity: async (e) => {\n await ready;\n await db\n .insertInto('entities')\n .values(entityRow(e))\n .onConflict((oc) =>\n oc.columns(['connector_id', 'type', 'id']).doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .execute();\n },\n\n metric: async (m) => {\n await ready;\n await db.insertInto('metrics').values(metricRow(m)).execute();\n },\n\n edge: async (e) => {\n await ready;\n await db\n .insertInto('edges')\n .values(edgeRow(e))\n .onConflict((oc) =>\n oc\n .columns([\n 'connector_id',\n 'from_type',\n 'from_id',\n 'kind',\n 'to_type',\n 'to_id',\n ])\n .doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .execute();\n },\n\n distribution: async (d) => {\n await ready;\n await db\n .insertInto('distributions')\n .values(distributionRow(d))\n .execute();\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 toBatchStmt(\n db\n .deleteFrom('events')\n .where('connector_id', '=', connectorId)\n .where('name', 'in', names)\n .compile(),\n ),\n );\n }\n if (es.length > 0) {\n stmts.push(\n toBatchStmt(\n db.insertInto('events').values(es.map(eventRow)).compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('entities')\n .where('connector_id', '=', connectorId)\n .where('type', 'in', types)\n .compile(),\n ),\n );\n }\n if (es.length > 0) {\n stmts.push(\n toBatchStmt(\n db\n .insertInto('entities')\n .values(es.map(entityRow))\n .onConflict((oc) =>\n oc.columns(['connector_id', 'type', 'id']).doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('metrics')\n .where('connector_id', '=', connectorId)\n .where('name', 'in', names)\n .compile(),\n ),\n );\n }\n if (ms.length > 0) {\n stmts.push(\n toBatchStmt(\n db.insertInto('metrics').values(ms.map(metricRow)).compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('edges')\n .where('connector_id', '=', connectorId)\n .where('kind', 'in', kinds)\n .compile(),\n ),\n );\n }\n if (es.length > 0) {\n stmts.push(\n toBatchStmt(\n db\n .insertInto('edges')\n .values(es.map(edgeRow))\n .onConflict((oc) =>\n oc\n .columns([\n 'connector_id',\n 'from_type',\n 'from_id',\n 'kind',\n 'to_type',\n 'to_id',\n ])\n .doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('distributions')\n .where('connector_id', '=', connectorId)\n .where('name', 'in', names)\n .compile(),\n ),\n );\n }\n if (ds.length > 0) {\n stmts.push(\n toBatchStmt(\n db\n .insertInto('distributions')\n .values(ds.map(distributionRow))\n .compile(),\n ),\n );\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n queryEvents: async (q: EventQuery) => {\n await ready;\n let qb = db\n .selectFrom('events')\n .select(['name', 'start_ts', 'end_ts', 'attributes'])\n .where('connector_id', '=', connectorId);\n if (q.name !== undefined) {\n qb = qb.where('name', '=', q.name);\n }\n if (q.start !== undefined) {\n qb = qb.where('start_ts', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('start_ts', '<=', q.end);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): Event => ({\n name: r.name,\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 r = await db\n .selectFrom('entities')\n .select(['type', 'id', 'attributes', 'updated_at'])\n .where('connector_id', '=', connectorId)\n .where('type', '=', type)\n .where('id', '=', id)\n .limit(1)\n .executeTakeFirst();\n if (!r) {\n return null;\n }\n return {\n type: r.type,\n id: r.id,\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 rows = await db\n .selectFrom('entities')\n .select(['type', 'id', 'attributes', 'updated_at'])\n .where('connector_id', '=', connectorId)\n .where('type', '=', q.type)\n .execute();\n return rows.map(\n (r): Entity => ({\n type: r.type,\n id: r.id,\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 let qb = db\n .selectFrom('metrics')\n .select(['name', 'ts', 'value', 'attributes'])\n .where('connector_id', '=', connectorId);\n if (q.name !== undefined) {\n qb = qb.where('name', '=', q.name);\n }\n if (q.start !== undefined) {\n qb = qb.where('ts', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('ts', '<=', q.end);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): MetricSample => ({\n name: r.name,\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 let qb = db\n .selectFrom('edges')\n .select([\n 'from_type',\n 'from_id',\n 'kind',\n 'to_type',\n 'to_id',\n 'attributes',\n 'updated_at',\n ])\n .where('connector_id', '=', connectorId);\n if (q.fromType !== undefined) {\n qb = qb.where('from_type', '=', q.fromType);\n }\n if (q.fromId !== undefined) {\n qb = qb.where('from_id', '=', q.fromId);\n }\n if (q.kind !== undefined) {\n qb = qb.where('kind', '=', q.kind);\n }\n if (q.toType !== undefined) {\n qb = qb.where('to_type', '=', q.toType);\n }\n if (q.toId !== undefined) {\n qb = qb.where('to_id', '=', q.toId);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): Edge => ({\n from_type: r.from_type,\n from_id: r.from_id,\n kind: r.kind,\n to_type: r.to_type,\n to_id: r.to_id,\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 let qb = db\n .selectFrom('distributions')\n .select(['name', 'ts', 'kind', 'data', 'attributes'])\n .where('connector_id', '=', connectorId);\n if (q.name !== undefined) {\n qb = qb.where('name', '=', q.name);\n }\n if (q.start !== undefined) {\n qb = qb.where('ts', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('ts', '<=', q.end);\n }\n const rows = await qb.execute();\n return rows.map((r) => {\n const base = {\n name: r.name,\n ts: Number(r.ts),\n attributes: parseJson<Attrs>(r.attributes, {}),\n };\n const data = parseJson<Distribution['data']>(r.data, {\n count: 0,\n sum: 0,\n } as unknown as Distribution['data']);\n if (r.kind === 'histogram') {\n return { ...base, kind: 'histogram', data } as Distribution;\n }\n if (r.kind === 'summary') {\n return { ...base, kind: 'summary', data } as Distribution;\n }\n throw new Error(\n `Unknown distribution kind: ${r.kind} (name=${base.name})`,\n );\n });\n },\n\n deleteOlderThan: async (shape, tsUnixMs) => {\n await ready;\n if (shape === 'events') {\n const r = await db\n .deleteFrom('events')\n .where('connector_id', '=', connectorId)\n .where('start_ts', '<', tsUnixMs)\n .executeTakeFirst();\n return { rowsDeleted: Number(r.numDeletedRows) };\n }\n if (shape === 'metrics') {\n const r = await db\n .deleteFrom('metrics')\n .where('connector_id', '=', connectorId)\n .where('ts', '<', tsUnixMs)\n .executeTakeFirst();\n return { rowsDeleted: Number(r.numDeletedRows) };\n }\n if (shape === 'distributions') {\n const r = await db\n .deleteFrom('distributions')\n .where('connector_id', '=', connectorId)\n .where('ts', '<', tsUnixMs)\n .executeTakeFirst();\n return { rowsDeleted: Number(r.numDeletedRows) };\n }\n throw new Error(\n `Unsupported shape for deleteOlderThan: ${String(shape)}`,\n );\n },\n };\n }\n\n async getSyncState(): Promise<SyncState> {\n if (this.initError !== null) {\n return {\n status: 'failed',\n queuedAt: null,\n startedAt: null,\n lastSyncAt: null,\n lastError: this.initError,\n };\n }\n await this.ready;\n const r = await this.db\n .selectFrom('sync_state')\n .select([\n 'status',\n 'queued_at',\n 'started_at',\n 'last_sync_at',\n 'last_error',\n ])\n .where('id', '=', SYNC_STATE_ID)\n .limit(1)\n .executeTakeFirst();\n if (!r) {\n return {\n status: 'idle',\n queuedAt: null,\n startedAt: null,\n lastSyncAt: null,\n lastError: null,\n };\n }\n return {\n status: r.status as SyncState['status'],\n queuedAt: r.queued_at,\n startedAt: r.started_at,\n lastSyncAt: r.last_sync_at,\n lastError: r.last_error,\n };\n }\n\n async markSyncQueued(): Promise<boolean> {\n await this.ready;\n const r = await this.db\n .updateTable('sync_state')\n .set({\n status: 'queued',\n queued_at: new Date().toISOString(),\n started_at: null,\n })\n .where('id', '=', SYNC_STATE_ID)\n .where('status', 'not in', ['queued', 'running'])\n .executeTakeFirst();\n return Number(r.numUpdatedRows) > 0;\n }\n\n async markSyncRunning(): Promise<boolean> {\n await this.ready;\n const r = await this.db\n .updateTable('sync_state')\n .set({ status: 'running', started_at: new Date().toISOString() })\n .where('id', '=', SYNC_STATE_ID)\n .where('status', '=', 'queued')\n .executeTakeFirst();\n return Number(r.numUpdatedRows) > 0;\n }\n\n async markSyncSucceeded(): Promise<void> {\n await this.ready;\n await this.db\n .updateTable('sync_state')\n .set({\n status: 'succeeded',\n queued_at: null,\n started_at: null,\n last_sync_at: new Date().toISOString(),\n last_error: null,\n })\n .where('id', '=', SYNC_STATE_ID)\n .execute();\n }\n\n async markSyncFailed(error: string): Promise<void> {\n await this.ready;\n await this.db\n .updateTable('sync_state')\n .set({\n status: 'failed',\n queued_at: null,\n started_at: null,\n last_error: error,\n })\n .where('id', '=', SYNC_STATE_ID)\n .execute();\n }\n\n async close(): Promise<void> {\n await this.ready.catch(() => undefined);\n this.client.close();\n }\n}\n","// AUTO-GENERATED by scripts/bundle-migrations.ts — do not edit by hand.\n// Regenerate with: pnpm db:bundle (or pnpm db:generate).\n\nexport interface BundledMigration {\n tag: string;\n statements: string[];\n}\n\nexport const MIGRATIONS: readonly BundledMigration[] = [\n {\n tag: '0000_nosy_wendell_vaughn',\n statements: [\n \"CREATE TABLE `distributions` (\\n\\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\\n\\t`connector_id` text NOT NULL,\\n\\t`name` text NOT NULL,\\n\\t`ts` integer NOT NULL,\\n\\t`kind` text NOT NULL,\\n\\t`data` text NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL\\n);\",\n 'CREATE INDEX `distributions_conn_name_ts` ON `distributions` (`connector_id`,`name`,`ts`);',\n \"CREATE TABLE `edges` (\\n\\t`connector_id` text NOT NULL,\\n\\t`from_type` text NOT NULL,\\n\\t`from_id` text NOT NULL,\\n\\t`kind` text NOT NULL,\\n\\t`to_type` text NOT NULL,\\n\\t`to_id` text NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL,\\n\\t`updated_at` integer NOT NULL,\\n\\tPRIMARY KEY(`connector_id`, `from_type`, `from_id`, `kind`, `to_type`, `to_id`)\\n);\",\n 'CREATE INDEX `edges_conn_kind` ON `edges` (`connector_id`,`kind`);',\n 'CREATE INDEX `edges_conn_from` ON `edges` (`connector_id`,`from_type`,`from_id`);',\n \"CREATE TABLE `entities` (\\n\\t`connector_id` text NOT NULL,\\n\\t`type` text NOT NULL,\\n\\t`id` text NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL,\\n\\t`updated_at` integer NOT NULL,\\n\\tPRIMARY KEY(`connector_id`, `type`, `id`)\\n);\",\n 'CREATE INDEX `entities_conn_type` ON `entities` (`connector_id`,`type`);',\n \"CREATE TABLE `events` (\\n\\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\\n\\t`connector_id` text NOT NULL,\\n\\t`name` text NOT NULL,\\n\\t`start_ts` integer NOT NULL,\\n\\t`end_ts` integer,\\n\\t`attributes` text DEFAULT '{}' NOT NULL\\n);\",\n 'CREATE INDEX `events_conn_name_start` ON `events` (`connector_id`,`name`,`start_ts`);',\n \"CREATE TABLE `metrics` (\\n\\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\\n\\t`connector_id` text NOT NULL,\\n\\t`name` text NOT NULL,\\n\\t`ts` integer NOT NULL,\\n\\t`value` real NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL\\n);\",\n 'CREATE INDEX `metrics_conn_name_ts` ON `metrics` (`connector_id`,`name`,`ts`);',\n ],\n },\n {\n tag: '0001_clumsy_siren',\n statements: [\n 'CREATE TABLE `sync_state` (\\n\\t`id` integer PRIMARY KEY NOT NULL,\\n\\t`status` text NOT NULL,\\n\\t`last_sync_at` text,\\n\\t`last_error` text\\n);',\n ],\n },\n {\n tag: '0002_milky_echo',\n statements: [\n 'ALTER TABLE `sync_state` ADD `queued_at` text;',\n 'ALTER TABLE `sync_state` ADD `started_at` text;',\n ],\n },\n] as const;\n","import type { Client, InStatement } from '@libsql/client/web';\n\nimport { MIGRATIONS } from './migrations-bundle';\n\nconst SCHEMA_MIGRATIONS_TABLE = 'schema_migrations';\n\nconst LEGACY_BASELINE_TABLE = 'events';\n\nasync function tableExists(client: Client, name: string): Promise<boolean> {\n const result = await client.execute({\n sql: \"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1\",\n args: [name],\n });\n return result.rows.length > 0;\n}\n\nasync function readAppliedTags(client: Client): Promise<Set<string>> {\n const result = await client.execute(\n `SELECT tag FROM ${SCHEMA_MIGRATIONS_TABLE}`,\n );\n return new Set(result.rows.map((r) => String(r['tag'])));\n}\n\nexport interface ApplyMigrationsOptions {\n assumeLegacyBaselineIfEventsExists?: boolean;\n}\n\nexport async function migrateIfNeeded(\n client: Client,\n opts: ApplyMigrationsOptions = {},\n): Promise<void> {\n const latest = MIGRATIONS[MIGRATIONS.length - 1];\n if (latest === undefined) {\n return;\n }\n try {\n const result = await client.execute({\n sql: `SELECT 1 FROM ${SCHEMA_MIGRATIONS_TABLE} WHERE tag = ? LIMIT 1`,\n args: [latest.tag],\n });\n if (result.rows.length > 0) {\n return;\n }\n } catch {\n // schema_migrations table doesn't exist yet — fall through to apply.\n }\n await applyMigrations(client, opts);\n}\n\nexport async function applyMigrations(\n client: Client,\n opts: ApplyMigrationsOptions = {},\n): Promise<void> {\n const hadSchemaTable = await tableExists(client, SCHEMA_MIGRATIONS_TABLE);\n\n await client.execute(\n `CREATE TABLE IF NOT EXISTS ${SCHEMA_MIGRATIONS_TABLE} (\n tag TEXT PRIMARY KEY,\n applied_at INTEGER NOT NULL\n )`,\n );\n\n if (!hadSchemaTable && opts.assumeLegacyBaselineIfEventsExists === true) {\n const hasLegacySchema = await tableExists(client, LEGACY_BASELINE_TABLE);\n if (hasLegacySchema) {\n const now = Date.now();\n for (const migration of MIGRATIONS) {\n await client.execute({\n sql: `INSERT OR IGNORE INTO ${SCHEMA_MIGRATIONS_TABLE} (tag, applied_at) VALUES (?, ?)`,\n args: [migration.tag, now],\n });\n }\n return;\n }\n }\n\n let applied = await readAppliedTags(client);\n\n for (const migration of MIGRATIONS) {\n if (applied.has(migration.tag)) {\n continue;\n }\n const batch: InStatement[] = [\n {\n sql: `INSERT INTO ${SCHEMA_MIGRATIONS_TABLE} (tag, applied_at) VALUES (?, ?)`,\n args: [migration.tag, Date.now()],\n },\n ...migration.statements,\n ];\n try {\n await client.batch(batch, 'write');\n } catch (err) {\n applied = await readAppliedTags(client);\n if (!applied.has(migration.tag)) {\n throw err;\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/libsql-storage.ts","../src/migrations-bundle.ts","../src/migrate.ts"],"sourcesContent":["import type { Client, InValue } from '@libsql/client/web';\nimport type {\n Distribution,\n DistributionQuery,\n Edge,\n EdgeQuery,\n Entity,\n EntityQuery,\n Event,\n EventQuery,\n GetStorageHandleOptions,\n Granularity,\n JSONValue,\n MetricQuery,\n MetricSample,\n RollupBucket,\n RollupPartials,\n RollupQuery,\n ServerStorage,\n StorageHandle,\n SyncState,\n} from '@rawdash/core';\nimport { dimsKey, withAbortSignal } from '@rawdash/core';\nimport { type CompiledQuery, type Insertable, Kysely, sql } from 'kysely';\nimport { LibsqlDialect } from 'kysely-libsql';\n\nimport type {\n Database,\n EdgesTable,\n EntitiesTable,\n EventsTable,\n MetricsTable,\n RollupsTable,\n} from './db-schema';\nimport { applyMigrations } from './migrate';\n\ntype Attrs = Record<string, JSONValue>;\n\nconst SYNC_STATE_ID = 1;\n\nexport async function initLibsqlSchema(client: Client): Promise<void> {\n await applyMigrations(client, { assumeLegacyBaselineIfEventsExists: true });\n await client.execute({\n sql: \"INSERT OR IGNORE INTO sync_state (id, status, queued_at, started_at, last_sync_at, last_error) VALUES (?, 'idle', NULL, NULL, 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\nfunction createDb(client: Client): Kysely<Database> {\n return new Kysely<Database>({\n dialect: new LibsqlDialect({ client }),\n });\n}\n\nfunction toBatchStmt(q: CompiledQuery): { sql: string; args: InValue[] } {\n return { sql: q.sql, args: q.parameters as InValue[] };\n}\n\nexport interface LibsqlStorageOptions {\n client: Client;\n initSchema?: boolean;\n}\n\nexport class LibsqlStorage implements ServerStorage {\n private client: Client;\n private db: Kysely<Database>;\n private ready: Promise<void>;\n private initError: string | null = null;\n\n constructor(options: LibsqlStorageOptions) {\n this.client = options.client;\n this.db = createDb(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(\n connectorId: string,\n options?: GetStorageHandleOptions,\n ): StorageHandle {\n const handle = this.buildHandle(connectorId);\n return options?.signal ? withAbortSignal(handle, options.signal) : handle;\n }\n\n private buildHandle(connectorId: string): StorageHandle {\n const ready = this.ready;\n const db = this.db;\n const client = this.client;\n\n const eventRow = (e: Event): Insertable<EventsTable> => ({\n connector_id: connectorId,\n name: e.name,\n start_ts: e.start_ts,\n end_ts: e.end_ts,\n attributes: JSON.stringify(e.attributes),\n });\n\n const entityRow = (e: Entity): Insertable<EntitiesTable> => ({\n connector_id: connectorId,\n type: e.type,\n id: e.id,\n attributes: JSON.stringify(e.attributes),\n updated_at: e.updated_at,\n });\n\n const metricRow = (m: MetricSample): Insertable<MetricsTable> => ({\n connector_id: connectorId,\n name: m.name,\n ts: m.ts,\n value: m.value,\n attributes: JSON.stringify(m.attributes),\n });\n\n const edgeRow = (e: Edge): Insertable<EdgesTable> => ({\n connector_id: connectorId,\n from_type: e.from_type,\n from_id: e.from_id,\n kind: e.kind,\n to_type: e.to_type,\n to_id: e.to_id,\n attributes: JSON.stringify(e.attributes),\n updated_at: e.updated_at,\n });\n\n const distributionRow = (d: Distribution) => ({\n connector_id: connectorId,\n name: d.name,\n ts: d.ts,\n kind: d.kind,\n data: JSON.stringify(d.data),\n attributes: JSON.stringify(d.attributes),\n });\n\n const rollupRow = (b: RollupBucket): Insertable<RollupsTable> => ({\n connector_id: connectorId,\n resource: b.resource,\n field: b.field,\n granularity: b.granularity,\n dims_key: dimsKey(b.dims),\n dims: JSON.stringify(b.dims),\n bucket_start: b.bucketStart,\n partials: JSON.stringify(b.partials),\n });\n\n return {\n event: async (e) => {\n await ready;\n await db.insertInto('events').values(eventRow(e)).execute();\n },\n\n entity: async (e) => {\n await ready;\n await db\n .insertInto('entities')\n .values(entityRow(e))\n .onConflict((oc) =>\n oc.columns(['connector_id', 'type', 'id']).doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .execute();\n },\n\n metric: async (m) => {\n await ready;\n await db.insertInto('metrics').values(metricRow(m)).execute();\n },\n\n edge: async (e) => {\n await ready;\n await db\n .insertInto('edges')\n .values(edgeRow(e))\n .onConflict((oc) =>\n oc\n .columns([\n 'connector_id',\n 'from_type',\n 'from_id',\n 'kind',\n 'to_type',\n 'to_id',\n ])\n .doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .execute();\n },\n\n distribution: async (d) => {\n await ready;\n await db\n .insertInto('distributions')\n .values(distributionRow(d))\n .execute();\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 toBatchStmt(\n db\n .deleteFrom('events')\n .where('connector_id', '=', connectorId)\n .where('name', 'in', names)\n .compile(),\n ),\n );\n }\n if (es.length > 0) {\n stmts.push(\n toBatchStmt(\n db.insertInto('events').values(es.map(eventRow)).compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('entities')\n .where('connector_id', '=', connectorId)\n .where('type', 'in', types)\n .compile(),\n ),\n );\n }\n if (es.length > 0) {\n stmts.push(\n toBatchStmt(\n db\n .insertInto('entities')\n .values(es.map(entityRow))\n .onConflict((oc) =>\n oc.columns(['connector_id', 'type', 'id']).doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('metrics')\n .where('connector_id', '=', connectorId)\n .where('name', 'in', names)\n .compile(),\n ),\n );\n }\n if (ms.length > 0) {\n stmts.push(\n toBatchStmt(\n db.insertInto('metrics').values(ms.map(metricRow)).compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('edges')\n .where('connector_id', '=', connectorId)\n .where('kind', 'in', kinds)\n .compile(),\n ),\n );\n }\n if (es.length > 0) {\n stmts.push(\n toBatchStmt(\n db\n .insertInto('edges')\n .values(es.map(edgeRow))\n .onConflict((oc) =>\n oc\n .columns([\n 'connector_id',\n 'from_type',\n 'from_id',\n 'kind',\n 'to_type',\n 'to_id',\n ])\n .doUpdateSet({\n attributes: (eb) => eb.ref('excluded.attributes'),\n updated_at: (eb) => eb.ref('excluded.updated_at'),\n }),\n )\n .compile(),\n ),\n );\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 toBatchStmt(\n db\n .deleteFrom('distributions')\n .where('connector_id', '=', connectorId)\n .where('name', 'in', names)\n .compile(),\n ),\n );\n }\n if (ds.length > 0) {\n stmts.push(\n toBatchStmt(\n db\n .insertInto('distributions')\n .values(ds.map(distributionRow))\n .compile(),\n ),\n );\n }\n if (stmts.length > 0) {\n await client.batch(stmts, 'write');\n }\n },\n\n queryEvents: async (q: EventQuery) => {\n await ready;\n let qb = db\n .selectFrom('events')\n .select(['name', 'start_ts', 'end_ts', 'attributes'])\n .where('connector_id', '=', connectorId);\n if (q.name !== undefined) {\n qb = qb.where('name', '=', q.name);\n }\n if (q.start !== undefined) {\n qb = qb.where('start_ts', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('start_ts', '<=', q.end);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): Event => ({\n name: r.name,\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 r = await db\n .selectFrom('entities')\n .select(['type', 'id', 'attributes', 'updated_at'])\n .where('connector_id', '=', connectorId)\n .where('type', '=', type)\n .where('id', '=', id)\n .limit(1)\n .executeTakeFirst();\n if (!r) {\n return null;\n }\n return {\n type: r.type,\n id: r.id,\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 rows = await db\n .selectFrom('entities')\n .select(['type', 'id', 'attributes', 'updated_at'])\n .where('connector_id', '=', connectorId)\n .where('type', '=', q.type)\n .execute();\n return rows.map(\n (r): Entity => ({\n type: r.type,\n id: r.id,\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 let qb = db\n .selectFrom('metrics')\n .select(['name', 'ts', 'value', 'attributes'])\n .where('connector_id', '=', connectorId);\n if (q.name !== undefined) {\n qb = qb.where('name', '=', q.name);\n }\n if (q.start !== undefined) {\n qb = qb.where('ts', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('ts', '<=', q.end);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): MetricSample => ({\n name: r.name,\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 let qb = db\n .selectFrom('edges')\n .select([\n 'from_type',\n 'from_id',\n 'kind',\n 'to_type',\n 'to_id',\n 'attributes',\n 'updated_at',\n ])\n .where('connector_id', '=', connectorId);\n if (q.fromType !== undefined) {\n qb = qb.where('from_type', '=', q.fromType);\n }\n if (q.fromId !== undefined) {\n qb = qb.where('from_id', '=', q.fromId);\n }\n if (q.kind !== undefined) {\n qb = qb.where('kind', '=', q.kind);\n }\n if (q.toType !== undefined) {\n qb = qb.where('to_type', '=', q.toType);\n }\n if (q.toId !== undefined) {\n qb = qb.where('to_id', '=', q.toId);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): Edge => ({\n from_type: r.from_type,\n from_id: r.from_id,\n kind: r.kind,\n to_type: r.to_type,\n to_id: r.to_id,\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 let qb = db\n .selectFrom('distributions')\n .select(['name', 'ts', 'kind', 'data', 'attributes'])\n .where('connector_id', '=', connectorId);\n if (q.name !== undefined) {\n qb = qb.where('name', '=', q.name);\n }\n if (q.start !== undefined) {\n qb = qb.where('ts', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('ts', '<=', q.end);\n }\n const rows = await qb.execute();\n return rows.map((r) => {\n const base = {\n name: r.name,\n ts: Number(r.ts),\n attributes: parseJson<Attrs>(r.attributes, {}),\n };\n const data = parseJson<Distribution['data']>(r.data, {\n count: 0,\n sum: 0,\n } as unknown as Distribution['data']);\n if (r.kind === 'histogram') {\n return { ...base, kind: 'histogram', data } as Distribution;\n }\n if (r.kind === 'summary') {\n return { ...base, kind: 'summary', data } as Distribution;\n }\n throw new Error(\n `Unknown distribution kind: ${r.kind} (name=${base.name})`,\n );\n });\n },\n\n deleteOlderThan: async (shape, tsUnixMs) => {\n await ready;\n if (shape === 'events') {\n const r = await db\n .deleteFrom('events')\n .where('connector_id', '=', connectorId)\n .where('start_ts', '<', tsUnixMs)\n .executeTakeFirst();\n return { rowsDeleted: Number(r.numDeletedRows) };\n }\n if (shape === 'metrics') {\n const r = await db\n .deleteFrom('metrics')\n .where('connector_id', '=', connectorId)\n .where('ts', '<', tsUnixMs)\n .executeTakeFirst();\n return { rowsDeleted: Number(r.numDeletedRows) };\n }\n if (shape === 'distributions') {\n const r = await db\n .deleteFrom('distributions')\n .where('connector_id', '=', connectorId)\n .where('ts', '<', tsUnixMs)\n .executeTakeFirst();\n return { rowsDeleted: Number(r.numDeletedRows) };\n }\n throw new Error(\n `Unsupported shape for deleteOlderThan: ${String(shape)}`,\n );\n },\n\n writeRollups: async (buckets) => {\n await ready;\n if (buckets.length === 0) {\n return;\n }\n const stmts = buckets.map((b) =>\n toBatchStmt(\n db\n .insertInto('rollups')\n .values(rollupRow(b))\n .onConflict((oc) =>\n oc\n .columns([\n 'connector_id',\n 'resource',\n 'field',\n 'granularity',\n 'dims_key',\n 'bucket_start',\n ])\n .doUpdateSet({\n dims: (eb) => eb.ref('excluded.dims'),\n partials: (eb) => eb.ref('excluded.partials'),\n }),\n )\n .compile(),\n ),\n );\n await client.batch(stmts, 'write');\n },\n\n queryRollups: async (q: RollupQuery) => {\n await ready;\n let qb = db\n .selectFrom('rollups')\n .select([\n 'resource',\n 'field',\n 'granularity',\n 'dims',\n 'bucket_start',\n 'partials',\n ])\n .where('connector_id', '=', connectorId)\n .where('resource', '=', q.resource);\n if (q.field !== undefined) {\n qb = qb.where('field', '=', q.field);\n }\n if (q.granularity !== undefined) {\n qb = qb.where('granularity', '=', q.granularity);\n }\n if (q.start !== undefined) {\n qb = qb.where('bucket_start', '>=', q.start);\n }\n if (q.end !== undefined) {\n qb = qb.where('bucket_start', '<', q.end);\n }\n const rows = await qb.execute();\n return rows.map(\n (r): RollupBucket => ({\n resource: r.resource,\n field: r.field,\n granularity: r.granularity as Granularity,\n dims: parseJson<Record<string, JSONValue>>(r.dims, {}),\n bucketStart: Number(r.bucket_start),\n partials: parseJson<RollupPartials>(r.partials, {\n count: 0,\n numericCount: 0,\n sum: 0,\n min: null,\n max: null,\n firstTs: null,\n firstValue: null,\n latestTs: null,\n latestValue: null,\n }),\n }),\n );\n },\n\n getRollupWatermark: async (resource: string) => {\n await ready;\n const r = await db\n .selectFrom('rollup_watermarks')\n .select(['watermark'])\n .where('connector_id', '=', connectorId)\n .where('resource', '=', resource)\n .limit(1)\n .executeTakeFirst();\n return r ? Number(r.watermark) : null;\n },\n\n setRollupWatermark: async (resource: string, tsUnixMs: number) => {\n await ready;\n await db\n .insertInto('rollup_watermarks')\n .values({ connector_id: connectorId, resource, watermark: tsUnixMs })\n .onConflict((oc) =>\n oc.columns(['connector_id', 'resource']).doUpdateSet({\n watermark: sql<number>`max(rollup_watermarks.watermark, excluded.watermark)`,\n }),\n )\n .execute();\n },\n };\n }\n\n async getSyncState(): Promise<SyncState> {\n if (this.initError !== null) {\n return {\n status: 'failed',\n queuedAt: null,\n startedAt: null,\n lastSyncAt: null,\n lastError: this.initError,\n };\n }\n await this.ready;\n const r = await this.db\n .selectFrom('sync_state')\n .select([\n 'status',\n 'queued_at',\n 'started_at',\n 'last_sync_at',\n 'last_error',\n ])\n .where('id', '=', SYNC_STATE_ID)\n .limit(1)\n .executeTakeFirst();\n if (!r) {\n return {\n status: 'idle',\n queuedAt: null,\n startedAt: null,\n lastSyncAt: null,\n lastError: null,\n };\n }\n return {\n status: r.status as SyncState['status'],\n queuedAt: r.queued_at,\n startedAt: r.started_at,\n lastSyncAt: r.last_sync_at,\n lastError: r.last_error,\n };\n }\n\n async markSyncQueued(): Promise<boolean> {\n await this.ready;\n const r = await this.db\n .updateTable('sync_state')\n .set({\n status: 'queued',\n queued_at: new Date().toISOString(),\n started_at: null,\n })\n .where('id', '=', SYNC_STATE_ID)\n .where('status', 'not in', ['queued', 'running'])\n .executeTakeFirst();\n return Number(r.numUpdatedRows) > 0;\n }\n\n async markSyncRunning(): Promise<boolean> {\n await this.ready;\n const r = await this.db\n .updateTable('sync_state')\n .set({ status: 'running', started_at: new Date().toISOString() })\n .where('id', '=', SYNC_STATE_ID)\n .where('status', '=', 'queued')\n .executeTakeFirst();\n return Number(r.numUpdatedRows) > 0;\n }\n\n async markSyncSucceeded(): Promise<void> {\n await this.ready;\n await this.db\n .updateTable('sync_state')\n .set({\n status: 'succeeded',\n queued_at: null,\n started_at: null,\n last_sync_at: new Date().toISOString(),\n last_error: null,\n })\n .where('id', '=', SYNC_STATE_ID)\n .execute();\n }\n\n async markSyncFailed(error: string): Promise<void> {\n await this.ready;\n await this.db\n .updateTable('sync_state')\n .set({\n status: 'failed',\n queued_at: null,\n started_at: null,\n last_error: error,\n })\n .where('id', '=', SYNC_STATE_ID)\n .execute();\n }\n\n async close(): Promise<void> {\n await this.ready.catch(() => undefined);\n this.client.close();\n }\n}\n","// AUTO-GENERATED by scripts/bundle-migrations.ts — do not edit by hand.\n// Regenerate with: pnpm db:bundle (or pnpm db:generate).\n\nexport interface BundledMigration {\n tag: string;\n statements: string[];\n}\n\nexport const MIGRATIONS: readonly BundledMigration[] = [\n {\n tag: '0000_nosy_wendell_vaughn',\n statements: [\n \"CREATE TABLE `distributions` (\\n\\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\\n\\t`connector_id` text NOT NULL,\\n\\t`name` text NOT NULL,\\n\\t`ts` integer NOT NULL,\\n\\t`kind` text NOT NULL,\\n\\t`data` text NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL\\n);\",\n 'CREATE INDEX `distributions_conn_name_ts` ON `distributions` (`connector_id`,`name`,`ts`);',\n \"CREATE TABLE `edges` (\\n\\t`connector_id` text NOT NULL,\\n\\t`from_type` text NOT NULL,\\n\\t`from_id` text NOT NULL,\\n\\t`kind` text NOT NULL,\\n\\t`to_type` text NOT NULL,\\n\\t`to_id` text NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL,\\n\\t`updated_at` integer NOT NULL,\\n\\tPRIMARY KEY(`connector_id`, `from_type`, `from_id`, `kind`, `to_type`, `to_id`)\\n);\",\n 'CREATE INDEX `edges_conn_kind` ON `edges` (`connector_id`,`kind`);',\n 'CREATE INDEX `edges_conn_from` ON `edges` (`connector_id`,`from_type`,`from_id`);',\n \"CREATE TABLE `entities` (\\n\\t`connector_id` text NOT NULL,\\n\\t`type` text NOT NULL,\\n\\t`id` text NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL,\\n\\t`updated_at` integer NOT NULL,\\n\\tPRIMARY KEY(`connector_id`, `type`, `id`)\\n);\",\n 'CREATE INDEX `entities_conn_type` ON `entities` (`connector_id`,`type`);',\n \"CREATE TABLE `events` (\\n\\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\\n\\t`connector_id` text NOT NULL,\\n\\t`name` text NOT NULL,\\n\\t`start_ts` integer NOT NULL,\\n\\t`end_ts` integer,\\n\\t`attributes` text DEFAULT '{}' NOT NULL\\n);\",\n 'CREATE INDEX `events_conn_name_start` ON `events` (`connector_id`,`name`,`start_ts`);',\n \"CREATE TABLE `metrics` (\\n\\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\\n\\t`connector_id` text NOT NULL,\\n\\t`name` text NOT NULL,\\n\\t`ts` integer NOT NULL,\\n\\t`value` real NOT NULL,\\n\\t`attributes` text DEFAULT '{}' NOT NULL\\n);\",\n 'CREATE INDEX `metrics_conn_name_ts` ON `metrics` (`connector_id`,`name`,`ts`);',\n ],\n },\n {\n tag: '0001_clumsy_siren',\n statements: [\n 'CREATE TABLE `sync_state` (\\n\\t`id` integer PRIMARY KEY NOT NULL,\\n\\t`status` text NOT NULL,\\n\\t`last_sync_at` text,\\n\\t`last_error` text\\n);',\n ],\n },\n {\n tag: '0002_milky_echo',\n statements: [\n 'ALTER TABLE `sync_state` ADD `queued_at` text;',\n 'ALTER TABLE `sync_state` ADD `started_at` text;',\n ],\n },\n {\n tag: '0003_milky_morbius',\n statements: [\n 'CREATE TABLE `rollup_watermarks` (\\n\\t`connector_id` text NOT NULL,\\n\\t`resource` text NOT NULL,\\n\\t`watermark` integer NOT NULL,\\n\\tPRIMARY KEY(`connector_id`, `resource`)\\n);',\n \"CREATE TABLE `rollups` (\\n\\t`connector_id` text NOT NULL,\\n\\t`resource` text NOT NULL,\\n\\t`field` text DEFAULT '' NOT NULL,\\n\\t`granularity` text NOT NULL,\\n\\t`dims_key` text DEFAULT '' NOT NULL,\\n\\t`dims` text DEFAULT '{}' NOT NULL,\\n\\t`bucket_start` integer NOT NULL,\\n\\t`partials` text NOT NULL,\\n\\tPRIMARY KEY(`connector_id`, `resource`, `field`, `granularity`, `dims_key`, `bucket_start`)\\n);\",\n 'CREATE INDEX `rollups_conn_resource_field` ON `rollups` (`connector_id`,`resource`,`field`);',\n ],\n },\n] as const;\n","import type { Client, InStatement } from '@libsql/client/web';\n\nimport { MIGRATIONS } from './migrations-bundle';\n\nconst SCHEMA_MIGRATIONS_TABLE = 'schema_migrations';\n\nconst LEGACY_BASELINE_TABLE = 'events';\n\nasync function tableExists(client: Client, name: string): Promise<boolean> {\n const result = await client.execute({\n sql: \"SELECT name FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1\",\n args: [name],\n });\n return result.rows.length > 0;\n}\n\nasync function readAppliedTags(client: Client): Promise<Set<string>> {\n const result = await client.execute(\n `SELECT tag FROM ${SCHEMA_MIGRATIONS_TABLE}`,\n );\n return new Set(result.rows.map((r) => String(r['tag'])));\n}\n\nexport interface ApplyMigrationsOptions {\n assumeLegacyBaselineIfEventsExists?: boolean;\n}\n\nexport async function migrateIfNeeded(\n client: Client,\n opts: ApplyMigrationsOptions = {},\n): Promise<void> {\n const latest = MIGRATIONS[MIGRATIONS.length - 1];\n if (latest === undefined) {\n return;\n }\n try {\n const result = await client.execute({\n sql: `SELECT 1 FROM ${SCHEMA_MIGRATIONS_TABLE} WHERE tag = ? LIMIT 1`,\n args: [latest.tag],\n });\n if (result.rows.length > 0) {\n return;\n }\n } catch {\n // schema_migrations table doesn't exist yet — fall through to apply.\n }\n await applyMigrations(client, opts);\n}\n\nexport async function applyMigrations(\n client: Client,\n opts: ApplyMigrationsOptions = {},\n): Promise<void> {\n const hadSchemaTable = await tableExists(client, SCHEMA_MIGRATIONS_TABLE);\n\n await client.execute(\n `CREATE TABLE IF NOT EXISTS ${SCHEMA_MIGRATIONS_TABLE} (\n tag TEXT PRIMARY KEY,\n applied_at INTEGER NOT NULL\n )`,\n );\n\n if (!hadSchemaTable && opts.assumeLegacyBaselineIfEventsExists === true) {\n const hasLegacySchema = await tableExists(client, LEGACY_BASELINE_TABLE);\n if (hasLegacySchema) {\n const now = Date.now();\n for (const migration of MIGRATIONS) {\n await client.execute({\n sql: `INSERT OR IGNORE INTO ${SCHEMA_MIGRATIONS_TABLE} (tag, applied_at) VALUES (?, ?)`,\n args: [migration.tag, now],\n });\n }\n return;\n }\n }\n\n let applied = await readAppliedTags(client);\n\n for (const migration of MIGRATIONS) {\n if (applied.has(migration.tag)) {\n continue;\n }\n const batch: InStatement[] = [\n {\n sql: `INSERT INTO ${SCHEMA_MIGRATIONS_TABLE} (tag, applied_at) VALUES (?, ?)`,\n args: [migration.tag, Date.now()],\n },\n ...migration.statements,\n ];\n try {\n await client.batch(batch, 'write');\n } catch (err) {\n applied = await readAppliedTags(client);\n if (!applied.has(migration.tag)) {\n throw err;\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,20 @@
1
+ CREATE TABLE `rollup_watermarks` (
2
+ `connector_id` text NOT NULL,
3
+ `resource` text NOT NULL,
4
+ `watermark` integer NOT NULL,
5
+ PRIMARY KEY(`connector_id`, `resource`)
6
+ );
7
+ --> statement-breakpoint
8
+ CREATE TABLE `rollups` (
9
+ `connector_id` text NOT NULL,
10
+ `resource` text NOT NULL,
11
+ `field` text DEFAULT '' NOT NULL,
12
+ `granularity` text NOT NULL,
13
+ `dims_key` text DEFAULT '' NOT NULL,
14
+ `dims` text DEFAULT '{}' NOT NULL,
15
+ `bucket_start` integer NOT NULL,
16
+ `partials` text NOT NULL,
17
+ PRIMARY KEY(`connector_id`, `resource`, `field`, `granularity`, `dims_key`, `bucket_start`)
18
+ );
19
+ --> statement-breakpoint
20
+ CREATE INDEX `rollups_conn_resource_field` ON `rollups` (`connector_id`,`resource`,`field`);
@@ -0,0 +1,524 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "edb3272f-ace9-4f1d-8314-b68c06354d00",
5
+ "prevId": "3d07543f-90d0-49b2-9437-498446441f61",
6
+ "tables": {
7
+ "distributions": {
8
+ "name": "distributions",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "integer",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": true
16
+ },
17
+ "connector_id": {
18
+ "name": "connector_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "name": {
25
+ "name": "name",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "ts": {
32
+ "name": "ts",
33
+ "type": "integer",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ },
38
+ "kind": {
39
+ "name": "kind",
40
+ "type": "text",
41
+ "primaryKey": false,
42
+ "notNull": true,
43
+ "autoincrement": false
44
+ },
45
+ "data": {
46
+ "name": "data",
47
+ "type": "text",
48
+ "primaryKey": false,
49
+ "notNull": true,
50
+ "autoincrement": false
51
+ },
52
+ "attributes": {
53
+ "name": "attributes",
54
+ "type": "text",
55
+ "primaryKey": false,
56
+ "notNull": true,
57
+ "autoincrement": false,
58
+ "default": "'{}'"
59
+ }
60
+ },
61
+ "indexes": {
62
+ "distributions_conn_name_ts": {
63
+ "name": "distributions_conn_name_ts",
64
+ "columns": ["connector_id", "name", "ts"],
65
+ "isUnique": false
66
+ }
67
+ },
68
+ "foreignKeys": {},
69
+ "compositePrimaryKeys": {},
70
+ "uniqueConstraints": {},
71
+ "checkConstraints": {}
72
+ },
73
+ "edges": {
74
+ "name": "edges",
75
+ "columns": {
76
+ "connector_id": {
77
+ "name": "connector_id",
78
+ "type": "text",
79
+ "primaryKey": false,
80
+ "notNull": true,
81
+ "autoincrement": false
82
+ },
83
+ "from_type": {
84
+ "name": "from_type",
85
+ "type": "text",
86
+ "primaryKey": false,
87
+ "notNull": true,
88
+ "autoincrement": false
89
+ },
90
+ "from_id": {
91
+ "name": "from_id",
92
+ "type": "text",
93
+ "primaryKey": false,
94
+ "notNull": true,
95
+ "autoincrement": false
96
+ },
97
+ "kind": {
98
+ "name": "kind",
99
+ "type": "text",
100
+ "primaryKey": false,
101
+ "notNull": true,
102
+ "autoincrement": false
103
+ },
104
+ "to_type": {
105
+ "name": "to_type",
106
+ "type": "text",
107
+ "primaryKey": false,
108
+ "notNull": true,
109
+ "autoincrement": false
110
+ },
111
+ "to_id": {
112
+ "name": "to_id",
113
+ "type": "text",
114
+ "primaryKey": false,
115
+ "notNull": true,
116
+ "autoincrement": false
117
+ },
118
+ "attributes": {
119
+ "name": "attributes",
120
+ "type": "text",
121
+ "primaryKey": false,
122
+ "notNull": true,
123
+ "autoincrement": false,
124
+ "default": "'{}'"
125
+ },
126
+ "updated_at": {
127
+ "name": "updated_at",
128
+ "type": "integer",
129
+ "primaryKey": false,
130
+ "notNull": true,
131
+ "autoincrement": false
132
+ }
133
+ },
134
+ "indexes": {
135
+ "edges_conn_kind": {
136
+ "name": "edges_conn_kind",
137
+ "columns": ["connector_id", "kind"],
138
+ "isUnique": false
139
+ },
140
+ "edges_conn_from": {
141
+ "name": "edges_conn_from",
142
+ "columns": ["connector_id", "from_type", "from_id"],
143
+ "isUnique": false
144
+ }
145
+ },
146
+ "foreignKeys": {},
147
+ "compositePrimaryKeys": {
148
+ "edges_connector_id_from_type_from_id_kind_to_type_to_id_pk": {
149
+ "columns": [
150
+ "connector_id",
151
+ "from_type",
152
+ "from_id",
153
+ "kind",
154
+ "to_type",
155
+ "to_id"
156
+ ],
157
+ "name": "edges_connector_id_from_type_from_id_kind_to_type_to_id_pk"
158
+ }
159
+ },
160
+ "uniqueConstraints": {},
161
+ "checkConstraints": {}
162
+ },
163
+ "entities": {
164
+ "name": "entities",
165
+ "columns": {
166
+ "connector_id": {
167
+ "name": "connector_id",
168
+ "type": "text",
169
+ "primaryKey": false,
170
+ "notNull": true,
171
+ "autoincrement": false
172
+ },
173
+ "type": {
174
+ "name": "type",
175
+ "type": "text",
176
+ "primaryKey": false,
177
+ "notNull": true,
178
+ "autoincrement": false
179
+ },
180
+ "id": {
181
+ "name": "id",
182
+ "type": "text",
183
+ "primaryKey": false,
184
+ "notNull": true,
185
+ "autoincrement": false
186
+ },
187
+ "attributes": {
188
+ "name": "attributes",
189
+ "type": "text",
190
+ "primaryKey": false,
191
+ "notNull": true,
192
+ "autoincrement": false,
193
+ "default": "'{}'"
194
+ },
195
+ "updated_at": {
196
+ "name": "updated_at",
197
+ "type": "integer",
198
+ "primaryKey": false,
199
+ "notNull": true,
200
+ "autoincrement": false
201
+ }
202
+ },
203
+ "indexes": {
204
+ "entities_conn_type": {
205
+ "name": "entities_conn_type",
206
+ "columns": ["connector_id", "type"],
207
+ "isUnique": false
208
+ }
209
+ },
210
+ "foreignKeys": {},
211
+ "compositePrimaryKeys": {
212
+ "entities_connector_id_type_id_pk": {
213
+ "columns": ["connector_id", "type", "id"],
214
+ "name": "entities_connector_id_type_id_pk"
215
+ }
216
+ },
217
+ "uniqueConstraints": {},
218
+ "checkConstraints": {}
219
+ },
220
+ "events": {
221
+ "name": "events",
222
+ "columns": {
223
+ "id": {
224
+ "name": "id",
225
+ "type": "integer",
226
+ "primaryKey": true,
227
+ "notNull": true,
228
+ "autoincrement": true
229
+ },
230
+ "connector_id": {
231
+ "name": "connector_id",
232
+ "type": "text",
233
+ "primaryKey": false,
234
+ "notNull": true,
235
+ "autoincrement": false
236
+ },
237
+ "name": {
238
+ "name": "name",
239
+ "type": "text",
240
+ "primaryKey": false,
241
+ "notNull": true,
242
+ "autoincrement": false
243
+ },
244
+ "start_ts": {
245
+ "name": "start_ts",
246
+ "type": "integer",
247
+ "primaryKey": false,
248
+ "notNull": true,
249
+ "autoincrement": false
250
+ },
251
+ "end_ts": {
252
+ "name": "end_ts",
253
+ "type": "integer",
254
+ "primaryKey": false,
255
+ "notNull": false,
256
+ "autoincrement": false
257
+ },
258
+ "attributes": {
259
+ "name": "attributes",
260
+ "type": "text",
261
+ "primaryKey": false,
262
+ "notNull": true,
263
+ "autoincrement": false,
264
+ "default": "'{}'"
265
+ }
266
+ },
267
+ "indexes": {
268
+ "events_conn_name_start": {
269
+ "name": "events_conn_name_start",
270
+ "columns": ["connector_id", "name", "start_ts"],
271
+ "isUnique": false
272
+ }
273
+ },
274
+ "foreignKeys": {},
275
+ "compositePrimaryKeys": {},
276
+ "uniqueConstraints": {},
277
+ "checkConstraints": {}
278
+ },
279
+ "metrics": {
280
+ "name": "metrics",
281
+ "columns": {
282
+ "id": {
283
+ "name": "id",
284
+ "type": "integer",
285
+ "primaryKey": true,
286
+ "notNull": true,
287
+ "autoincrement": true
288
+ },
289
+ "connector_id": {
290
+ "name": "connector_id",
291
+ "type": "text",
292
+ "primaryKey": false,
293
+ "notNull": true,
294
+ "autoincrement": false
295
+ },
296
+ "name": {
297
+ "name": "name",
298
+ "type": "text",
299
+ "primaryKey": false,
300
+ "notNull": true,
301
+ "autoincrement": false
302
+ },
303
+ "ts": {
304
+ "name": "ts",
305
+ "type": "integer",
306
+ "primaryKey": false,
307
+ "notNull": true,
308
+ "autoincrement": false
309
+ },
310
+ "value": {
311
+ "name": "value",
312
+ "type": "real",
313
+ "primaryKey": false,
314
+ "notNull": true,
315
+ "autoincrement": false
316
+ },
317
+ "attributes": {
318
+ "name": "attributes",
319
+ "type": "text",
320
+ "primaryKey": false,
321
+ "notNull": true,
322
+ "autoincrement": false,
323
+ "default": "'{}'"
324
+ }
325
+ },
326
+ "indexes": {
327
+ "metrics_conn_name_ts": {
328
+ "name": "metrics_conn_name_ts",
329
+ "columns": ["connector_id", "name", "ts"],
330
+ "isUnique": false
331
+ }
332
+ },
333
+ "foreignKeys": {},
334
+ "compositePrimaryKeys": {},
335
+ "uniqueConstraints": {},
336
+ "checkConstraints": {}
337
+ },
338
+ "rollup_watermarks": {
339
+ "name": "rollup_watermarks",
340
+ "columns": {
341
+ "connector_id": {
342
+ "name": "connector_id",
343
+ "type": "text",
344
+ "primaryKey": false,
345
+ "notNull": true,
346
+ "autoincrement": false
347
+ },
348
+ "resource": {
349
+ "name": "resource",
350
+ "type": "text",
351
+ "primaryKey": false,
352
+ "notNull": true,
353
+ "autoincrement": false
354
+ },
355
+ "watermark": {
356
+ "name": "watermark",
357
+ "type": "integer",
358
+ "primaryKey": false,
359
+ "notNull": true,
360
+ "autoincrement": false
361
+ }
362
+ },
363
+ "indexes": {},
364
+ "foreignKeys": {},
365
+ "compositePrimaryKeys": {
366
+ "rollup_watermarks_connector_id_resource_pk": {
367
+ "columns": ["connector_id", "resource"],
368
+ "name": "rollup_watermarks_connector_id_resource_pk"
369
+ }
370
+ },
371
+ "uniqueConstraints": {},
372
+ "checkConstraints": {}
373
+ },
374
+ "rollups": {
375
+ "name": "rollups",
376
+ "columns": {
377
+ "connector_id": {
378
+ "name": "connector_id",
379
+ "type": "text",
380
+ "primaryKey": false,
381
+ "notNull": true,
382
+ "autoincrement": false
383
+ },
384
+ "resource": {
385
+ "name": "resource",
386
+ "type": "text",
387
+ "primaryKey": false,
388
+ "notNull": true,
389
+ "autoincrement": false
390
+ },
391
+ "field": {
392
+ "name": "field",
393
+ "type": "text",
394
+ "primaryKey": false,
395
+ "notNull": true,
396
+ "autoincrement": false,
397
+ "default": "''"
398
+ },
399
+ "granularity": {
400
+ "name": "granularity",
401
+ "type": "text",
402
+ "primaryKey": false,
403
+ "notNull": true,
404
+ "autoincrement": false
405
+ },
406
+ "dims_key": {
407
+ "name": "dims_key",
408
+ "type": "text",
409
+ "primaryKey": false,
410
+ "notNull": true,
411
+ "autoincrement": false,
412
+ "default": "''"
413
+ },
414
+ "dims": {
415
+ "name": "dims",
416
+ "type": "text",
417
+ "primaryKey": false,
418
+ "notNull": true,
419
+ "autoincrement": false,
420
+ "default": "'{}'"
421
+ },
422
+ "bucket_start": {
423
+ "name": "bucket_start",
424
+ "type": "integer",
425
+ "primaryKey": false,
426
+ "notNull": true,
427
+ "autoincrement": false
428
+ },
429
+ "partials": {
430
+ "name": "partials",
431
+ "type": "text",
432
+ "primaryKey": false,
433
+ "notNull": true,
434
+ "autoincrement": false
435
+ }
436
+ },
437
+ "indexes": {
438
+ "rollups_conn_resource_field": {
439
+ "name": "rollups_conn_resource_field",
440
+ "columns": ["connector_id", "resource", "field"],
441
+ "isUnique": false
442
+ }
443
+ },
444
+ "foreignKeys": {},
445
+ "compositePrimaryKeys": {
446
+ "rollups_connector_id_resource_field_granularity_dims_key_bucket_start_pk": {
447
+ "columns": [
448
+ "connector_id",
449
+ "resource",
450
+ "field",
451
+ "granularity",
452
+ "dims_key",
453
+ "bucket_start"
454
+ ],
455
+ "name": "rollups_connector_id_resource_field_granularity_dims_key_bucket_start_pk"
456
+ }
457
+ },
458
+ "uniqueConstraints": {},
459
+ "checkConstraints": {}
460
+ },
461
+ "sync_state": {
462
+ "name": "sync_state",
463
+ "columns": {
464
+ "id": {
465
+ "name": "id",
466
+ "type": "integer",
467
+ "primaryKey": true,
468
+ "notNull": true,
469
+ "autoincrement": false
470
+ },
471
+ "status": {
472
+ "name": "status",
473
+ "type": "text",
474
+ "primaryKey": false,
475
+ "notNull": true,
476
+ "autoincrement": false
477
+ },
478
+ "queued_at": {
479
+ "name": "queued_at",
480
+ "type": "text",
481
+ "primaryKey": false,
482
+ "notNull": false,
483
+ "autoincrement": false
484
+ },
485
+ "started_at": {
486
+ "name": "started_at",
487
+ "type": "text",
488
+ "primaryKey": false,
489
+ "notNull": false,
490
+ "autoincrement": false
491
+ },
492
+ "last_sync_at": {
493
+ "name": "last_sync_at",
494
+ "type": "text",
495
+ "primaryKey": false,
496
+ "notNull": false,
497
+ "autoincrement": false
498
+ },
499
+ "last_error": {
500
+ "name": "last_error",
501
+ "type": "text",
502
+ "primaryKey": false,
503
+ "notNull": false,
504
+ "autoincrement": false
505
+ }
506
+ },
507
+ "indexes": {},
508
+ "foreignKeys": {},
509
+ "compositePrimaryKeys": {},
510
+ "uniqueConstraints": {},
511
+ "checkConstraints": {}
512
+ }
513
+ },
514
+ "views": {},
515
+ "enums": {},
516
+ "_meta": {
517
+ "schemas": {},
518
+ "tables": {},
519
+ "columns": {}
520
+ },
521
+ "internal": {
522
+ "indexes": {}
523
+ }
524
+ }
@@ -22,6 +22,13 @@
22
22
  "when": 1779427904807,
23
23
  "tag": "0002_milky_echo",
24
24
  "breakpoints": true
25
+ },
26
+ {
27
+ "idx": 3,
28
+ "version": "6",
29
+ "when": 1781148513026,
30
+ "tag": "0003_milky_morbius",
31
+ "breakpoints": true
25
32
  }
26
33
  ]
27
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rawdash/adapter-libsql",
3
- "version": "0.22.0",
3
+ "version": "0.24.0",
4
4
  "description": "Rawdash libSQL/Turso storage adapter",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "kysely": "^0.29.0",
27
27
  "kysely-libsql": "^0.7.0",
28
- "@rawdash/core": "0.22.0"
28
+ "@rawdash/core": "0.24.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@libsql/client": ">=0.14.0 <1.0.0"