@sixb/sqlite 0.1.16 → 0.1.18

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.
Files changed (70) hide show
  1. package/dist/ai-limit-storage.d.ts.map +1 -1
  2. package/dist/ai-usage-storage.d.ts.map +1 -1
  3. package/dist/execution-storage.d.ts +28 -0
  4. package/dist/execution-storage.d.ts.map +1 -1
  5. package/dist/file-download-grant-storage.d.ts +11 -0
  6. package/dist/file-download-grant-storage.d.ts.map +1 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1362 -579
  10. package/dist/index.js.map +27 -25
  11. package/dist/migrations.d.ts.map +1 -1
  12. package/dist/objects/query-compiler.d.ts.map +1 -1
  13. package/dist/objects/reader.d.ts.map +1 -1
  14. package/dist/objects/storage.d.ts.map +1 -1
  15. package/dist/ontology-storage/index.d.ts +2 -0
  16. package/dist/ontology-storage/index.d.ts.map +1 -1
  17. package/dist/ontology-storage/materialization-session.d.ts +17 -37
  18. package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
  19. package/dist/ontology-storage/materialization-state.d.ts +3 -26
  20. package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
  21. package/dist/ontology-storage/materialization-writer.d.ts +1 -1
  22. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
  23. package/dist/ontology-storage/materializations.d.ts +3 -6
  24. package/dist/ontology-storage/materializations.d.ts.map +1 -1
  25. package/dist/ontology-storage/outbox.d.ts.map +1 -1
  26. package/dist/ontology-storage/replacement-plans.d.ts +88 -0
  27. package/dist/ontology-storage/replacement-plans.d.ts.map +1 -0
  28. package/dist/ontology-storage/shared.d.ts +8 -5
  29. package/dist/ontology-storage/shared.d.ts.map +1 -1
  30. package/dist/ontology-storage/source-cleanup.d.ts.map +1 -1
  31. package/dist/ontology-storage/source-roots.d.ts +15 -2
  32. package/dist/ontology-storage/source-roots.d.ts.map +1 -1
  33. package/dist/ontology-storage/sources.d.ts +1 -2
  34. package/dist/ontology-storage/sources.d.ts.map +1 -1
  35. package/dist/projection-run-storage.d.ts.map +1 -1
  36. package/dist/rules-storage.d.ts.map +1 -1
  37. package/dist/testing.d.ts +4 -1
  38. package/dist/testing.d.ts.map +1 -1
  39. package/package.json +3 -3
  40. package/src/ai-cost-storage.ts +10 -0
  41. package/src/ai-limit-storage.ts +13 -2
  42. package/src/ai-usage-storage.ts +9 -1
  43. package/src/execution-storage.ts +7 -2
  44. package/src/file-download-grant-storage.ts +76 -0
  45. package/src/index.ts +10 -3
  46. package/src/migrations/053-replacement-plans.sql +73 -0
  47. package/src/migrations/054-slim-ontology-outbox.sql +21 -0
  48. package/src/migrations/055-commit-touches.sql +31 -0
  49. package/src/migrations/056-audio-transcription.sql +10 -0
  50. package/src/migrations/057-reranking-model-kind.sql +16 -0
  51. package/src/migrations/058-file-download-grants.sql +21 -0
  52. package/src/migrations/059-drained-source-versions.sql +11 -0
  53. package/src/migrations.ts +115 -0
  54. package/src/objects/query-compiler.ts +5 -0
  55. package/src/objects/reader.ts +1 -0
  56. package/src/objects/storage.ts +5 -11
  57. package/src/ontology-storage/index.ts +6 -1
  58. package/src/ontology-storage/materialization-session.ts +120 -211
  59. package/src/ontology-storage/materialization-state.ts +5 -261
  60. package/src/ontology-storage/materialization-writer.ts +11 -13
  61. package/src/ontology-storage/materializations.ts +133 -210
  62. package/src/ontology-storage/outbox.ts +50 -16
  63. package/src/ontology-storage/replacement-plans.ts +1064 -0
  64. package/src/ontology-storage/shared.ts +17 -12
  65. package/src/ontology-storage/source-cleanup.ts +24 -9
  66. package/src/ontology-storage/source-roots.ts +38 -14
  67. package/src/ontology-storage/sources.ts +0 -26
  68. package/src/projection-run-storage.ts +7 -1
  69. package/src/rules-storage.ts +9 -14
  70. package/src/testing.ts +6 -4
package/src/migrations.ts CHANGED
@@ -121,6 +121,11 @@ import projectionRunSupersessionSql from "./migrations/051-projection-run-supers
121
121
  import compactSourceStorageSql from "./migrations/052-compact-source-storage.sql" with {
122
122
  type: "text",
123
123
  }
124
+ import replacementPlansSql from "./migrations/053-replacement-plans.sql" with { type: "text" }
125
+ import slimOntologyOutboxSql from "./migrations/054-slim-ontology-outbox.sql" with { type: "text" }
126
+ import commitTouchesSql from "./migrations/055-commit-touches.sql" with { type: "text" }
127
+ import audioTranscriptionSql from "./migrations/056-audio-transcription.sql" with { type: "text" }
128
+ import rerankingModelKindSql from "./migrations/057-reranking-model-kind.sql" with { type: "text" }
124
129
 
125
130
  const MIGRATIONS_TABLE_SQL = `
126
131
  CREATE TABLE IF NOT EXISTS sixb_migrations (
@@ -246,6 +251,26 @@ export const sqliteStorageMigrations = defineMigrations({
246
251
  },
247
252
  { checksum: checksum(compactSourceStorageSql) }
248
253
  ),
254
+ sqliteSql("053-replacement-plans", replacementPlansSql),
255
+ sqliteStep(
256
+ "054-slim-ontology-outbox",
257
+ (db) => {
258
+ // SQLite has no procedural block to refuse the conversion in SQL: check before it.
259
+ const mismatched = unrebuildableOutboxEvents(db)
260
+ if (mismatched > 0) {
261
+ throw new Error(
262
+ `[SixbSqliteStorage] ${mismatched} outbox events would not rebuild from their commit.`
263
+ )
264
+ }
265
+ db.run(slimOntologyOutboxSql)
266
+ },
267
+ { checksum: checksum(slimOntologyOutboxSql) }
268
+ ),
269
+ sqliteSql("055-commit-touches", commitTouchesSql),
270
+ sqliteSql("056-audio-transcription", audioTranscriptionSql),
271
+ sqliteSql("057-reranking-model-kind", rerankingModelKindSql),
272
+ sqliteSql("058-file-download-grants", fileDownloadGrantsSql),
273
+ sqliteSql("059-drained-source-versions", drainedSourceVersionsSql),
249
274
  ],
250
275
  })
251
276
 
@@ -416,6 +441,92 @@ function sourceStorageCounts(db: Database): {
416
441
  .get() as { readonly versions: number; readonly roots: number; readonly rows: number }
417
442
  }
418
443
 
444
+ /**
445
+ * Stored events that would not rebuild exactly from their commit and execution. Who asked and what
446
+ * wrote are derived from the execution exactly as 047 derived the commit's copies; both sides were
447
+ * written as canonical JSON, so equal JSON compares as equal text.
448
+ */
449
+ function unrebuildableOutboxEvents(db: Database): number {
450
+ const row = db
451
+ .query(
452
+ `SELECT COUNT(*) AS mismatched
453
+ FROM ontology_outbox AS outbox
454
+ LEFT JOIN ontology_commits AS commits
455
+ ON commits.project_id = outbox.project_id AND commits.id = outbox.commit_id
456
+ LEFT JOIN executions
457
+ ON executions.project_id = commits.project_id AND executions.id = commits.execution_id
458
+ WHERE executions.id IS NULL
459
+ OR outbox.envelope ->> '$.id' IS NOT outbox.id
460
+ OR outbox.envelope ->> '$.commitOrdinal' IS NOT outbox.commit_ordinal
461
+ OR outbox.envelope ->> '$.commitId' IS NOT commits.id
462
+ OR outbox.envelope ->> '$.projectId' IS NOT commits.project_id
463
+ OR outbox.envelope ->> '$.schemaVersion' IS NOT 1
464
+ OR outbox.envelope ->> '$.occurredAt' IS NOT commits.committed_at
465
+ OR outbox.envelope -> '$.origin' IS NOT json(commits.origin)
466
+ OR outbox.envelope ->> '$.correlationId' IS NOT executions.correlation_id
467
+ OR outbox.envelope -> '$.requestedBy' IS NOT CASE
468
+ WHEN executions.requested_by_user_id IS NOT NULL
469
+ THEN json_object('id', executions.requested_by_user_id, 'type', 'user')
470
+ WHEN executions.requested_by_service_account_id IS NOT NULL
471
+ THEN json_object('id', executions.requested_by_service_account_id, 'type', 'serviceAccount')
472
+ END
473
+ OR outbox.envelope -> '$.executor' IS NOT CASE executions.executor_kind
474
+ WHEN 'request' THEN json_object('requestId', executions.executor_id, 'type', 'request')
475
+ WHEN 'agent' THEN json_object('runId', executions.executor_id, 'type', 'agent')
476
+ WHEN 'kernel' THEN json_object(
477
+ 'operation',
478
+ CASE executions.authority_kernel_operation
479
+ WHEN 'ontology.recover'
480
+ THEN json_object('recoveryId', executions.executor_id, 'type', 'ontology.recover')
481
+ ELSE json_object('indexingId', executions.executor_id, 'type', 'ontology.indexVectors')
482
+ END,
483
+ 'type', 'kernel'
484
+ )
485
+ ELSE json_object(
486
+ 'id', executions.authority_primitive_id,
487
+ 'kind', executions.executor_kind,
488
+ 'runId', executions.executor_id,
489
+ 'type', 'primitive'
490
+ )
491
+ END
492
+ OR outbox.envelope ->> '$.topic' IS NOT CASE substr(outbox.envelope ->> '$.type', 1, 4)
493
+ WHEN 'obje' THEN 'objects'
494
+ WHEN 'link' THEN 'links'
495
+ WHEN 'tele' THEN 'telemetry'
496
+ END
497
+ OR outbox.envelope ->> '$.partitionKey' IS NOT CASE outbox.envelope ->> '$.topic'
498
+ WHEN 'objects' THEN (outbox.envelope ->> '$.payload.objectTypeId') || ':' ||
499
+ (outbox.envelope ->> '$.payload.primaryId')
500
+ WHEN 'links' THEN (outbox.envelope ->> '$.payload.sourceTypeId') || ':' ||
501
+ (outbox.envelope ->> '$.payload.sourceId') || ':' ||
502
+ (outbox.envelope ->> '$.payload.linkId')
503
+ WHEN 'telemetry' THEN (outbox.envelope ->> '$.payload.objectTypeId') || ':' ||
504
+ (outbox.envelope ->> '$.payload.objectId') || ':' ||
505
+ (outbox.envelope ->> '$.payload.propertyId')
506
+ END
507
+ OR (
508
+ outbox.envelope ->> '$.type' IN ('object.created', 'link.created')
509
+ AND (
510
+ (SELECT COUNT(*) FROM json_each(outbox.envelope, '$.payload.propertyChanges'))
511
+ IS NOT (SELECT COUNT(*) FROM json_each(outbox.envelope, '$.payload.properties'))
512
+ OR EXISTS (
513
+ SELECT 1
514
+ FROM json_each(outbox.envelope, '$.payload.propertyChanges') AS change
515
+ LEFT JOIN json_each(outbox.envelope, '$.payload.properties') AS property
516
+ ON property.key = change.key
517
+ WHERE property.key IS NULL
518
+ OR change.value ->> '$.operation' IS NOT 'created'
519
+ OR json_type(change.value, '$.after') IS NOT property.type
520
+ OR change.value ->> '$.after' IS NOT property.value
521
+ OR (SELECT COUNT(*) FROM json_each(change.value)) IS NOT 2
522
+ )
523
+ )
524
+ )`
525
+ )
526
+ .get() as { readonly mismatched: number }
527
+ return row.mismatched
528
+ }
529
+
419
530
  function checksum(value: string): string {
420
531
  return createHash("sha256").update(value).digest("hex")
421
532
  }
@@ -482,3 +593,7 @@ import connectorOptionalPkceSql from "./migrations/039-connector-optional-pkce.s
482
593
  type: "text",
483
594
  }
484
595
  import fileUploadSessionsSql from "./migrations/048-file-upload-sessions.sql" with { type: "text" }
596
+ import fileDownloadGrantsSql from "./migrations/058-file-download-grants.sql" with { type: "text" }
597
+ import drainedSourceVersionsSql from "./migrations/059-drained-source-versions.sql" with {
598
+ type: "text",
599
+ }
@@ -146,6 +146,11 @@ function compileObjectQueryInternal(
146
146
  ctx: CompileContext
147
147
  ): CompiledObjectQuery {
148
148
  switch (query.kind) {
149
+ case "rerank":
150
+ throw new ObjectQueryExecutionError(
151
+ "reranking_requires_runtime",
152
+ "Reranking must execute in the model runtime, not storage."
153
+ )
149
154
  case "start":
150
155
  return compileStart(projectId, query, ctx)
151
156
  case "refs":
@@ -136,6 +136,7 @@ export class SqliteObjectReader {
136
136
  source,
137
137
  })
138
138
  return {
139
+ total: readTotal(this.db, compiled),
139
140
  facets: params.facets.map((facet) => ({
140
141
  propertyId: facet.propertyId,
141
142
  buckets: readFacetBuckets(this.db, compiled, facet),
@@ -161,9 +161,7 @@ export class SqliteObjectStorage implements ObjectStorage {
161
161
  }
162
162
 
163
163
  async facetObjects(params: FacetObjectsInput): Promise<FacetObjectsResult> {
164
- if (hasVectorProfile(params.query))
165
- return runDeferredReadTransaction(this.db, () => this.reader.facetObjects(params))
166
- return this.reader.facetObjects(params)
164
+ return runDeferredReadTransaction(this.db, () => this.reader.facetObjects(params))
167
165
  }
168
166
 
169
167
  async getByPrimaryId(params: {
@@ -252,23 +250,19 @@ export class SqliteObjectStorage implements ObjectStorage {
252
250
  limit: number
253
251
  }): Promise<{ objects: readonly ObjectRow[]; nextPrimaryId?: string }> {
254
252
  assertReconciliationPageLimit(params.limit)
253
+ // A cursor written as `? IS NULL OR …` cannot seek, so every page would rescan from the start.
254
+ const cursor = params.afterPrimaryId === undefined ? [] : [params.afterPrimaryId]
255
255
  const rows = this.db
256
256
  .query(
257
257
  `
258
258
  SELECT * FROM objects
259
259
  WHERE project_id = ? AND object_type_id = ?
260
- AND (? IS NULL OR primary_id > ?)
260
+ ${cursor.length > 0 ? "AND primary_id > ?" : ""}
261
261
  ORDER BY primary_id ASC
262
262
  LIMIT ?
263
263
  `
264
264
  )
265
- .all(
266
- params.projectId,
267
- params.objectTypeId,
268
- params.afterPrimaryId ?? null,
269
- params.afterPrimaryId ?? null,
270
- params.limit + 1
271
- ) as DatabaseRow[]
265
+ .all(params.projectId, params.objectTypeId, ...cursor, params.limit + 1) as DatabaseRow[]
272
266
  const hasMore = rows.length > params.limit
273
267
  const objects = rows.slice(0, params.limit).map((row) => rowToObject(row))
274
268
  const last = objects.at(-1)
@@ -4,9 +4,9 @@ import { SqliteOntologyCommitStorage } from "./commits"
4
4
  import type { SqliteOntologyTransactionContext } from "./materialization-session"
5
5
  import { SqliteOntologyMaterializationStorage } from "./materializations"
6
6
  import { SqliteOntologyOutboxStorage } from "./outbox"
7
+ import { SqliteOntologyReplacementPlanStorage } from "./replacement-plans"
7
8
  import type { SqliteRootOperation } from "./shared"
8
9
  import { SqliteOntologySourceStorage } from "./sources"
9
-
10
10
  import { SqliteVectorIndexingStorage } from "./vector-indexing"
11
11
  import { SqliteOntologyVectorStorage } from "./vectors"
12
12
 
@@ -14,6 +14,7 @@ export class SqliteOntologyStorage implements OntologyStorage {
14
14
  readonly commits: SqliteOntologyCommitStorage
15
15
  readonly sources: SqliteOntologySourceStorage
16
16
  readonly materializations: SqliteOntologyMaterializationStorage
17
+ readonly replacementPlans: SqliteOntologyReplacementPlanStorage
17
18
  readonly vectorIndexing: SqliteVectorIndexingStorage
18
19
  readonly vectors: SqliteOntologyVectorStorage
19
20
  readonly outbox: SqliteOntologyOutboxStorage
@@ -29,6 +30,10 @@ export class SqliteOntologyStorage implements OntologyStorage {
29
30
  input.db,
30
31
  input.transactionContext
31
32
  )
33
+ this.replacementPlans = new SqliteOntologyReplacementPlanStorage(
34
+ input.db,
35
+ input.runRootOperation
36
+ )
32
37
  this.vectorIndexing = new SqliteVectorIndexingStorage(
33
38
  input.db,
34
39
  input.runRootOperation,