@sixb/sqlite 0.1.10 → 0.1.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAkG3B,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD,eAAO,MAAM,uBAAuB,wBA8ElC,CAAA;AAEF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAQ9E;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC1C,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,QAAQ,CAAC,CAEzB;AAED,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAS3D;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CAOzF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;CAC5C,GAAG,eAAe,CAoBlB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1E"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAqG3B,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAC5D,eAAO,MAAM,mBAAmB,mBAAmB,CAAA;AAEnD,eAAO,MAAM,uBAAuB,wBA+ElC,CAAA;AAEF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAQ9E;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC1C,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,QAAQ,CAAC,CAEzB;AAED,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAS3D;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,eAAe,EAAE,CAOzF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;CAC5C,GAAG,eAAe,CAoBlB;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAM1C,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,qBAAqB,EACrB,qBAAqB,EACrB,iCAAiC,EACjC,kCAAkC,EAClC,4BAA4B,EAC7B,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAML,KAAK,mBAAmB,EACzB,MAAM,UAAU,CAAA;AAEjB,qBAAa,2BAA4B,YAAW,qBAAqB;IAErE,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,mBAAmB;IAGlD,KAAK,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;IAyDpF,aAAa,CAAC,KAAK,EAAE,gCAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCrE,UAAU,CAAC,KAAK,EAAE,kCAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;IA2CpE,cAAc,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBzE,SAAS,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,qBAAqB,CAAC;CA4BrF"}
1
+ {"version":3,"file":"outbox.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/outbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAM1C,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,qBAAqB,EACrB,qBAAqB,EACrB,iCAAiC,EACjC,kCAAkC,EAClC,4BAA4B,EAC7B,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAML,KAAK,mBAAmB,EACzB,MAAM,UAAU,CAAA;AAEjB,qBAAa,2BAA4B,YAAW,qBAAqB;IAErE,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,EAAE,EAAE,QAAQ,EACZ,gBAAgB,EAAE,mBAAmB;IAGlD,KAAK,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,SAAS,wBAAwB,EAAE,CAAC;IAwEpF,aAAa,CAAC,KAAK,EAAE,gCAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCrE,UAAU,CAAC,KAAK,EAAE,kCAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CpE,cAAc,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBzE,SAAS,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,qBAAqB,CAAC;CA4BrF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sixb/sqlite",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "SQLite storage provider for Sixb",
5
5
  "keywords": [
6
6
  "sixb",
@@ -36,10 +36,10 @@
36
36
  "prepack": "bun run build"
37
37
  },
38
38
  "peerDependencies": {
39
- "@sixb/core": "0.1.10"
39
+ "@sixb/core": "0.1.11"
40
40
  },
41
41
  "devDependencies": {
42
- "@sixb/core": "0.1.10",
42
+ "@sixb/core": "0.1.11",
43
43
  "@types/bun": "latest",
44
44
  "typescript": "^5.7.0"
45
45
  },
@@ -143,6 +143,16 @@ class SqliteConnectorConnectionPersistence implements ConnectorConnectionPersist
143
143
  }
144
144
  }
145
145
 
146
+ async listPendingConnectionRuns(): Promise<readonly ConnectorConnectionRunRecord[]> {
147
+ if (!this.scope.connectorId) return []
148
+ const rows = this.db
149
+ .query(`SELECT * FROM connector_connection_runs
150
+ WHERE project_id = ? AND connector_id = ?
151
+ AND (status = 'running' OR (status = 'waiting' AND waiting_for = 'account_selection'))`)
152
+ .all(this.scope.projectId, this.scope.connectorId) as SqliteConnectionRunRow[]
153
+ return rows.map(connectionRunFromRow)
154
+ }
155
+
146
156
  async getConnectionRun(id: string): Promise<ConnectorConnectionRunRecord | null> {
147
157
  const row = this.getById<SqliteConnectionRunRow>("connector_connection_runs", id)
148
158
  return row ? connectionRunFromRow(row) : null
@@ -0,0 +1,8 @@
1
+ -- Match the bounded claim order without sorting the entire unpublished backlog.
2
+ -- Cover every selection predicate so new databases also benefit before ANALYZE.
3
+ CREATE INDEX idx_ontology_outbox_publication_order
4
+ ON ontology_outbox(
5
+ project_id, published_at, created_at, commit_id, commit_ordinal,
6
+ available_at, lease_expires_at
7
+ )
8
+ WHERE published_at IS NULL;
package/src/migrations.ts CHANGED
@@ -93,6 +93,9 @@ import shareSessionsSql from "./migrations/036-share-sessions.sql" with { type:
93
93
  import projectionSourceRootsSql from "./migrations/038-projection-source-roots.sql" with {
94
94
  type: "text",
95
95
  }
96
+ import outboxPublicationOrderSql from "./migrations/040-outbox-publication-order.sql" with {
97
+ type: "text",
98
+ }
96
99
 
97
100
  const MIGRATIONS_TABLE_SQL = `
98
101
  CREATE TABLE IF NOT EXISTS sixb_migrations (
@@ -187,6 +190,7 @@ export const sqliteStorageMigrations = defineMigrations({
187
190
  sqliteSql("037-execution-requester-groups", executionRequesterGroupsSql),
188
191
  sqliteSql("038-projection-source-roots", projectionSourceRootsSql),
189
192
  sqliteSql("039-connector-optional-pkce", connectorOptionalPkceSql),
193
+ sqliteSql("040-outbox-publication-order", outboxPublicationOrderSql),
190
194
  ],
191
195
  })
192
196
 
@@ -43,19 +43,37 @@ export class SqliteOntologyOutboxStorage implements OntologyOutboxStorage {
43
43
  )
44
44
  }
45
45
 
46
+ // Probe at most one page plus a sentinel through the eligibility index. Sparse retries
47
+ // avoid scanning delayed rows; overflowing backlogs use publication order without a sort.
48
+ const eligible = this.db
49
+ .query(
50
+ `SELECT CAST(rowid AS TEXT) AS rowId
51
+ FROM ontology_outbox INDEXED BY idx_ontology_outbox_claim
52
+ WHERE project_id = ? AND published_at IS NULL AND available_at <= ?
53
+ AND (lease_expires_at IS NULL OR lease_expires_at <= ?)
54
+ LIMIT ?`
55
+ )
56
+ .all(input.projectId, input.now, input.now, input.limit + 1) as { rowId: string }[]
57
+ if (eligible.length === 0) return []
58
+ const selected =
59
+ eligible.length <= input.limit
60
+ ? eligible
61
+ : (this.db
62
+ .query(
63
+ `SELECT CAST(rowid AS TEXT) AS rowId
64
+ FROM ontology_outbox INDEXED BY idx_ontology_outbox_publication_order
65
+ WHERE project_id = ? AND published_at IS NULL AND available_at <= ?
66
+ AND (lease_expires_at IS NULL OR lease_expires_at <= ?)
67
+ ORDER BY created_at, commit_id, commit_ordinal
68
+ LIMIT ?`
69
+ )
70
+ .all(input.projectId, input.now, input.now, input.limit) as { rowId: string }[])
46
71
  const rows = this.db
47
72
  .query(
48
73
  `
49
74
  UPDATE ontology_outbox
50
75
  SET attempts = attempts + 1, lease_id = ?, lease_expires_at = ?
51
- WHERE rowid IN (
52
- SELECT rowid
53
- FROM ontology_outbox
54
- WHERE project_id = ? AND published_at IS NULL AND available_at <= ?
55
- AND (lease_expires_at IS NULL OR lease_expires_at <= ?)
56
- ORDER BY created_at, commit_id, commit_ordinal
57
- LIMIT ?
58
- )
76
+ WHERE rowid IN (SELECT CAST(value AS INTEGER) FROM json_each(?))
59
77
  RETURNING envelope, available_at, attempts, lease_id, lease_expires_at,
60
78
  published_at, last_failure, created_at
61
79
  `
@@ -63,10 +81,7 @@ export class SqliteOntologyOutboxStorage implements OntologyOutboxStorage {
63
81
  .all(
64
82
  input.leaseId,
65
83
  input.leaseExpiresAt,
66
- input.projectId,
67
- input.now,
68
- input.now,
69
- input.limit
84
+ JSON.stringify(selected.map((row) => row.rowId))
70
85
  ) as SqliteOntologyOutboxRow[]
71
86
  return rows
72
87
  .map((row) => outboxRecord(row))
@@ -98,8 +113,9 @@ export class SqliteOntologyOutboxStorage implements OntologyOutboxStorage {
98
113
  WITH requested(id) AS MATERIALIZED (
99
114
  SELECT CAST(value AS TEXT) FROM json_each(?)
100
115
  ), leased(id) AS MATERIALIZED (
101
- SELECT outbox.id FROM ontology_outbox AS outbox
102
- JOIN requested USING (id)
116
+ -- Drive validation from the bounded ID list even before ANALYZE.
117
+ SELECT outbox.id FROM requested
118
+ CROSS JOIN ontology_outbox AS outbox USING (id)
103
119
  WHERE outbox.project_id = ? AND outbox.lease_id = ?
104
120
  AND outbox.lease_expires_at IS NOT NULL
105
121
  ), eligible(id) AS (
@@ -139,8 +155,9 @@ export class SqliteOntologyOutboxStorage implements OntologyOutboxStorage {
139
155
  WITH requested(id) AS MATERIALIZED (
140
156
  SELECT CAST(value AS TEXT) FROM json_each(?)
141
157
  ), leased(id) AS MATERIALIZED (
142
- SELECT outbox.id FROM ontology_outbox AS outbox
143
- JOIN requested USING (id)
158
+ -- Drive validation from the bounded ID list even before ANALYZE.
159
+ SELECT outbox.id FROM requested
160
+ CROSS JOIN ontology_outbox AS outbox USING (id)
144
161
  WHERE outbox.project_id = ? AND outbox.lease_id = ?
145
162
  AND outbox.lease_expires_at IS NOT NULL
146
163
  ), eligible(id) AS (