@rawdash/adapter-libsql 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,16 +14,17 @@ Internals: [Kysely](https://kysely.dev) for type-safe queries on top of `@libsql
14
14
  ## Install
15
15
 
16
16
  ```sh
17
- npm install @rawdash/adapter-libsql @libsql/client
17
+ npm install @rawdash/adapter-libsql @libsql/client @rawdash/hono @hono/node-server
18
18
  ```
19
19
 
20
20
  ## Quick example
21
21
 
22
22
  ```ts
23
+ import { serve as honoServe } from '@hono/node-server';
23
24
  import { createClient } from '@libsql/client';
24
25
  import { LibsqlStorage } from '@rawdash/adapter-libsql';
25
26
  import { defineConfig } from '@rawdash/core';
26
- import { serve } from '@rawdash/server';
27
+ import { mountEngine } from '@rawdash/hono';
27
28
 
28
29
  const storage = new LibsqlStorage({
29
30
  client: createClient({
@@ -37,7 +38,8 @@ const config = defineConfig({
37
38
  dashboards: {},
38
39
  });
39
40
 
40
- serve(config, { storage });
41
+ const { app } = mountEngine(config, { storage });
42
+ honoServe({ fetch: app.fetch, port: 8080 });
41
43
  ```
42
44
 
43
45
  On Cloudflare Workers, import from `@libsql/client/web` and pass the resulting client in the same way.
@@ -46,8 +48,9 @@ On Cloudflare Workers, import from `@libsql/client/web` and pass the resulting c
46
48
 
47
49
  The Drizzle schema in `src/drizzle-schema.ts` is the source of truth.
48
50
 
49
- - `pnpm db:generate` runs `drizzle-kit generate` to emit a new `drizzle/NNNN_*.sql` file, then re-inlines the SQL into `src/migrations.ts`.
50
- - At runtime, `LibsqlStorage` applies pending migrations from `MIGRATIONS` on first use and records applied versions in a `schema_migrations` table. The runtime applier reads from the inlined arrayno filesystem access so it works on Workers.
51
+ - `pnpm db:generate` runs `drizzle-kit generate` to emit a new `migrations/NNNN_*.sql` file, then inlines the SQL into `src/migrations-bundle.ts` (formatted to match the repo's Prettier config so the regeneration is byte-stable).
52
+ - The bundle is **committed** so the package can ship to npm without a build step. CI runs `pnpm --filter @rawdash/adapter-libsql db:bundle` and fails if the result differs from what's checked inthis catches `.sql` migrations added without regenerating the bundle.
53
+ - At runtime, `LibsqlStorage` applies pending migrations from `MIGRATIONS` on first use and records applied versions in a `schema_migrations` table. The runtime applier reads from the inlined array — no filesystem access — so it works on Cloudflare Workers and other edge runtimes.
51
54
 
52
55
  ## License
53
56
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Client } from '@libsql/client/web';
2
- import { ServerStorage, StorageHandle, SyncState } from '@rawdash/core';
2
+ import { ServerStorage, GetStorageHandleOptions, StorageHandle, SyncState } from '@rawdash/core';
3
3
 
4
4
  declare function initLibsqlSchema(client: Client): Promise<void>;
5
5
  interface LibsqlStorageOptions {
@@ -14,11 +14,13 @@ declare class LibsqlStorage implements ServerStorage {
14
14
  constructor(options: LibsqlStorageOptions);
15
15
  private init;
16
16
  waitUntilReady(): Promise<void>;
17
- getStorageHandle(connectorId: string): StorageHandle;
17
+ getStorageHandle(connectorId: string, options?: GetStorageHandleOptions): StorageHandle;
18
+ private buildHandle;
18
19
  getSyncState(): Promise<SyncState>;
19
- setSyncing(): Promise<boolean>;
20
- setSyncSuccess(): Promise<void>;
21
- setSyncError(error: string): Promise<void>;
20
+ markSyncQueued(): Promise<boolean>;
21
+ markSyncRunning(): Promise<boolean>;
22
+ markSyncSucceeded(): Promise<void>;
23
+ markSyncFailed(error: string): Promise<void>;
22
24
  close(): Promise<void>;
23
25
  }
24
26
 
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/libsql-storage.ts
2
+ import { withAbortSignal } from "@rawdash/core";
2
3
  import { Kysely } from "kysely";
3
4
  import { LibsqlDialect } from "kysely-libsql";
4
5
 
@@ -25,6 +26,13 @@ var MIGRATIONS = [
25
26
  statements: [
26
27
  "CREATE TABLE `sync_state` (\n `id` integer PRIMARY KEY NOT NULL,\n `status` text NOT NULL,\n `last_sync_at` text,\n `last_error` text\n);"
27
28
  ]
29
+ },
30
+ {
31
+ tag: "0002_milky_echo",
32
+ statements: [
33
+ "ALTER TABLE `sync_state` ADD `queued_at` text;",
34
+ "ALTER TABLE `sync_state` ADD `started_at` text;"
35
+ ]
28
36
  }
29
37
  ];
30
38
 
@@ -110,7 +118,7 @@ var SYNC_STATE_ID = 1;
110
118
  async function initLibsqlSchema(client) {
111
119
  await applyMigrations(client, { assumeLegacyBaselineIfEventsExists: true });
112
120
  await client.execute({
113
- sql: "INSERT OR IGNORE INTO sync_state (id, status, last_sync_at, last_error) VALUES (?, 'idle', NULL, NULL)",
121
+ sql: "INSERT OR IGNORE INTO sync_state (id, status, queued_at, started_at, last_sync_at, last_error) VALUES (?, 'idle', NULL, NULL, NULL, NULL)",
114
122
  args: [SYNC_STATE_ID]
115
123
  });
116
124
  }
@@ -154,7 +162,11 @@ var LibsqlStorage = class {
154
162
  async waitUntilReady() {
155
163
  return this.ready;
156
164
  }
157
- getStorageHandle(connectorId) {
165
+ getStorageHandle(connectorId, options) {
166
+ const handle = this.buildHandle(connectorId);
167
+ return options?.signal ? withAbortSignal(handle, options.signal) : handle;
168
+ }
169
+ buildHandle(connectorId) {
158
170
  const ready = this.ready;
159
171
  const db = this.db;
160
172
  const client = this.client;
@@ -536,35 +548,71 @@ var LibsqlStorage = class {
536
548
  }
537
549
  async getSyncState() {
538
550
  if (this.initError !== null) {
539
- return { status: "error", lastSyncAt: null, lastError: this.initError };
551
+ return {
552
+ status: "failed",
553
+ queuedAt: null,
554
+ startedAt: null,
555
+ lastSyncAt: null,
556
+ lastError: this.initError
557
+ };
540
558
  }
541
559
  await this.ready;
542
- const r = await this.db.selectFrom("sync_state").select(["status", "last_sync_at", "last_error"]).where("id", "=", SYNC_STATE_ID).limit(1).executeTakeFirst();
560
+ const r = await this.db.selectFrom("sync_state").select([
561
+ "status",
562
+ "queued_at",
563
+ "started_at",
564
+ "last_sync_at",
565
+ "last_error"
566
+ ]).where("id", "=", SYNC_STATE_ID).limit(1).executeTakeFirst();
543
567
  if (!r) {
544
- return { status: "idle", lastSyncAt: null, lastError: null };
568
+ return {
569
+ status: "idle",
570
+ queuedAt: null,
571
+ startedAt: null,
572
+ lastSyncAt: null,
573
+ lastError: null
574
+ };
545
575
  }
546
576
  return {
547
577
  status: r.status,
578
+ queuedAt: r.queued_at,
579
+ startedAt: r.started_at,
548
580
  lastSyncAt: r.last_sync_at,
549
581
  lastError: r.last_error
550
582
  };
551
583
  }
552
- async setSyncing() {
584
+ async markSyncQueued() {
553
585
  await this.ready;
554
- const r = await this.db.updateTable("sync_state").set({ status: "syncing" }).where("id", "=", SYNC_STATE_ID).where("status", "!=", "syncing").executeTakeFirst();
586
+ const r = await this.db.updateTable("sync_state").set({
587
+ status: "queued",
588
+ queued_at: (/* @__PURE__ */ new Date()).toISOString(),
589
+ started_at: null
590
+ }).where("id", "=", SYNC_STATE_ID).where("status", "not in", ["queued", "running"]).executeTakeFirst();
555
591
  return Number(r.numUpdatedRows) > 0;
556
592
  }
557
- async setSyncSuccess() {
593
+ async markSyncRunning() {
594
+ await this.ready;
595
+ const r = await this.db.updateTable("sync_state").set({ status: "running", started_at: (/* @__PURE__ */ new Date()).toISOString() }).where("id", "=", SYNC_STATE_ID).where("status", "=", "queued").executeTakeFirst();
596
+ return Number(r.numUpdatedRows) > 0;
597
+ }
598
+ async markSyncSucceeded() {
558
599
  await this.ready;
559
600
  await this.db.updateTable("sync_state").set({
560
- status: "idle",
601
+ status: "succeeded",
602
+ queued_at: null,
603
+ started_at: null,
561
604
  last_sync_at: (/* @__PURE__ */ new Date()).toISOString(),
562
605
  last_error: null
563
606
  }).where("id", "=", SYNC_STATE_ID).execute();
564
607
  }
565
- async setSyncError(error) {
608
+ async markSyncFailed(error) {
566
609
  await this.ready;
567
- await this.db.updateTable("sync_state").set({ status: "error", last_error: error }).where("id", "=", SYNC_STATE_ID).execute();
610
+ await this.db.updateTable("sync_state").set({
611
+ status: "failed",
612
+ queued_at: null,
613
+ started_at: null,
614
+ last_error: error
615
+ }).where("id", "=", SYNC_STATE_ID).execute();
568
616
  }
569
617
  async close() {
570
618
  await this.ready.catch(() => void 0);
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 JSONValue,\n MetricQuery,\n MetricSample,\n ServerStorage,\n StorageHandle,\n SyncState,\n} 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, 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\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(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 { status: 'error', lastSyncAt: null, lastError: this.initError };\n }\n await this.ready;\n const r = await this.db\n .selectFrom('sync_state')\n .select(['status', 'last_sync_at', 'last_error'])\n .where('id', '=', SYNC_STATE_ID)\n .limit(1)\n .executeTakeFirst();\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,\n lastError: r.last_error,\n };\n }\n\n async setSyncing(): Promise<boolean> {\n await this.ready;\n const r = await this.db\n .updateTable('sync_state')\n .set({ status: 'syncing' })\n .where('id', '=', SYNC_STATE_ID)\n .where('status', '!=', 'syncing')\n .executeTakeFirst();\n return Number(r.numUpdatedRows) > 0;\n }\n\n async setSyncSuccess(): Promise<void> {\n await this.ready;\n await this.db\n .updateTable('sync_state')\n .set({\n status: 'idle',\n last_sync_at: new Date().toISOString(),\n last_error: null,\n })\n .where('id', '=', SYNC_STATE_ID)\n .execute();\n }\n\n async setSyncError(error: string): Promise<void> {\n await this.ready;\n await this.db\n .updateTable('sync_state')\n .set({ status: 'error', last_error: error })\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] 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 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":[]}
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `sync_state` ADD `queued_at` text;--> statement-breakpoint
2
+ ALTER TABLE `sync_state` ADD `started_at` text;
@@ -0,0 +1,401 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "3d07543f-90d0-49b2-9437-498446441f61",
5
+ "prevId": "ef2445c8-d1b8-4cc2-9c2b-cb7426886fb4",
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
+ "sync_state": {
339
+ "name": "sync_state",
340
+ "columns": {
341
+ "id": {
342
+ "name": "id",
343
+ "type": "integer",
344
+ "primaryKey": true,
345
+ "notNull": true,
346
+ "autoincrement": false
347
+ },
348
+ "status": {
349
+ "name": "status",
350
+ "type": "text",
351
+ "primaryKey": false,
352
+ "notNull": true,
353
+ "autoincrement": false
354
+ },
355
+ "queued_at": {
356
+ "name": "queued_at",
357
+ "type": "text",
358
+ "primaryKey": false,
359
+ "notNull": false,
360
+ "autoincrement": false
361
+ },
362
+ "started_at": {
363
+ "name": "started_at",
364
+ "type": "text",
365
+ "primaryKey": false,
366
+ "notNull": false,
367
+ "autoincrement": false
368
+ },
369
+ "last_sync_at": {
370
+ "name": "last_sync_at",
371
+ "type": "text",
372
+ "primaryKey": false,
373
+ "notNull": false,
374
+ "autoincrement": false
375
+ },
376
+ "last_error": {
377
+ "name": "last_error",
378
+ "type": "text",
379
+ "primaryKey": false,
380
+ "notNull": false,
381
+ "autoincrement": false
382
+ }
383
+ },
384
+ "indexes": {},
385
+ "foreignKeys": {},
386
+ "compositePrimaryKeys": {},
387
+ "uniqueConstraints": {},
388
+ "checkConstraints": {}
389
+ }
390
+ },
391
+ "views": {},
392
+ "enums": {},
393
+ "_meta": {
394
+ "schemas": {},
395
+ "tables": {},
396
+ "columns": {}
397
+ },
398
+ "internal": {
399
+ "indexes": {}
400
+ }
401
+ }
@@ -15,6 +15,13 @@
15
15
  "when": 1776691516753,
16
16
  "tag": "0001_clumsy_siren",
17
17
  "breakpoints": true
18
+ },
19
+ {
20
+ "idx": 2,
21
+ "version": "6",
22
+ "when": 1779427904807,
23
+ "tag": "0002_milky_echo",
24
+ "breakpoints": true
18
25
  }
19
26
  ]
20
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rawdash/adapter-libsql",
3
- "version": "0.12.0",
3
+ "version": "0.14.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.12.0"
28
+ "@rawdash/core": "0.14.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@libsql/client": ">=0.14.0 <1.0.0"