@sixb/sqlite 0.1.16 → 0.1.17

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
@@ -49,12 +49,10 @@ import {
49
49
  activeSourceRows,
50
50
  LIVE_SOURCE_ROWS_JOIN,
51
51
  replacementAssertionRows,
52
- replacementSourceRows,
53
52
  SOURCE_ASSERTION_COLUMNS,
54
53
  } from "./source-roots"
55
54
 
56
55
  export const SQLITE_MATERIALIZATION_WORK_TABLE = "ontology_materialization_work"
57
- export const SQLITE_REPLACEMENT_WORK_TABLE = "ontology_replacement_work"
58
56
 
59
57
  interface EffectiveObjectRow {
60
58
  readonly object_type_id: string
@@ -135,40 +133,11 @@ interface ReplacementSources {
135
133
  readonly byMaterialization: ReadonlyMap<string, ReadonlyMap<string, StoredSourceAssertion>>
136
134
  }
137
135
 
138
- export type ReplacementIdentity =
139
- | {
140
- readonly kind: "object"
141
- readonly ref: OntologyObjectRef
142
- readonly sortKey: string
143
- readonly diffRequired: true
144
- }
145
- | {
146
- readonly kind: "link"
147
- readonly ref: OntologyLinkRef
148
- readonly sortKey: string
149
- readonly diffRequired: boolean
150
- }
151
-
152
- interface ReplacementIdentityInput {
153
- readonly incremental?: boolean
154
- readonly sessionId: string
155
- readonly sourceId: string
156
- readonly candidateMaterializationId: string
157
- readonly previousMaterializationId: string | null
158
- readonly kind: "object" | "link"
159
- readonly pageRows: number
160
- }
161
-
162
- interface ReplacementWorkRow {
163
- readonly entity_kind: "object" | "link"
164
- readonly identity_key: string
165
- readonly sort_key: string
166
- readonly diff_required: number
167
- }
168
-
169
- interface ReplacementCursor {
136
+ /** A link a replacement plan decides, and whether its plan needs a diff. */
137
+ export interface ReplacementLinkIdentity {
138
+ readonly ref: OntologyLinkRef
170
139
  readonly sortKey: string
171
- readonly identityKey: string
140
+ readonly diffRequired: boolean
172
141
  }
173
142
 
174
143
  export class SqliteMaterializationStateReader {
@@ -606,19 +575,6 @@ export class SqliteMaterializationStateReader {
606
575
  }
607
576
  }
608
577
 
609
- *replacementIdentities(input: ReplacementIdentityInput): Iterable<ReplacementIdentity[]> {
610
- this.prepareReplacementIdentities(input)
611
- let cursor: ReplacementCursor | null = null
612
- while (true) {
613
- const rows = this.replacementRows(input, cursor)
614
- if (rows.length === 0) break
615
- yield rows.map(replacementIdentity)
616
- if (rows.length < input.pageRows) break
617
- const last = rows[rows.length - 1]!
618
- cursor = { sortKey: last.sort_key, identityKey: last.identity_key }
619
- }
620
- }
621
-
622
578
  replacementObjectStates(
623
579
  sourceId: string,
624
580
  candidateMaterializationId: string,
@@ -647,7 +603,7 @@ export class SqliteMaterializationStateReader {
647
603
  sourceId: string,
648
604
  candidateMaterializationId: string,
649
605
  materializationIds: readonly string[],
650
- identities: readonly Extract<ReplacementIdentity, { readonly kind: "link" }>[],
606
+ identities: readonly ReplacementLinkIdentity[],
651
607
  incremental = false
652
608
  ): readonly SourceReplacementLinkState[] {
653
609
  const refs = identities.map((identity) => identity.ref)
@@ -739,213 +695,6 @@ export class SqliteMaterializationStateReader {
739
695
  }
740
696
  return { owned, byMaterialization }
741
697
  }
742
-
743
- private prepareReplacementIdentities(input: ReplacementIdentityInput): void {
744
- if (input.kind === "object") {
745
- this.prepareReplacementObjects(input)
746
- return
747
- }
748
- this.prepareReplacementLinks(input)
749
- }
750
-
751
- private prepareReplacementObjects(input: ReplacementIdentityInput): void {
752
- const rows = replacementSourceRows(this.db, {
753
- projectId: this.projectId,
754
- sourceId: input.sourceId,
755
- materializationId: input.candidateMaterializationId,
756
- incremental: input.incremental ?? false,
757
- })
758
- this.db
759
- .query(
760
- `
761
- INSERT INTO ${SQLITE_REPLACEMENT_WORK_TABLE} (
762
- session_id, entity_kind, identity_key, sort_key, diff_required
763
- )
764
- SELECT ?, 'object', json_array(object_type_id, primary_id),
765
- ${objectSortExpression()}, 1
766
- FROM (${rows.sql}) AS rows
767
- WHERE entity_kind = 'object'
768
- GROUP BY object_type_id, primary_id
769
- `
770
- )
771
- .run(input.sessionId, ...rows.values)
772
- }
773
-
774
- private prepareReplacementLinks(input: ReplacementIdentityInput): void {
775
- const rows = replacementSourceRows(this.db, {
776
- projectId: this.projectId,
777
- sourceId: input.sourceId,
778
- materializationId: input.candidateMaterializationId,
779
- incremental: input.incremental ?? false,
780
- })
781
- this.db
782
- .query(
783
- `
784
- WITH incident_objects AS (
785
- SELECT DISTINCT
786
- json_extract(payload, '$.ref.objectTypeId') AS object_type_id,
787
- json_extract(payload, '$.ref.primaryId') AS primary_id
788
- FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}
789
- WHERE session_id = ? AND kind = 'incident-object'
790
- ), replacement_links AS (
791
- SELECT source_type_id, source_primary_id AS source_id, link_id,
792
- target_type_id, target_primary_id AS target_id
793
- FROM (${rows.sql}) AS rows
794
- WHERE entity_kind = 'link'
795
- ), incident_links AS (
796
- SELECT links.source_type_id, links.source_id, links.link_id,
797
- links.target_type_id, links.target_id
798
- FROM links
799
- JOIN incident_objects
800
- ON incident_objects.object_type_id = links.source_type_id
801
- AND incident_objects.primary_id = links.source_id
802
- WHERE links.project_id = ?
803
- UNION
804
- SELECT links.source_type_id, links.source_id, links.link_id,
805
- links.target_type_id, links.target_id
806
- FROM links
807
- JOIN incident_objects
808
- ON incident_objects.object_type_id = links.target_type_id
809
- AND incident_objects.primary_id = links.target_id
810
- WHERE links.project_id = ?
811
- UNION
812
- SELECT overrides.source_type_id,
813
- overrides.source_primary_id AS source_id,
814
- overrides.link_id, overrides.target_type_id,
815
- overrides.target_primary_id AS target_id
816
- FROM ontology_link_overrides AS overrides
817
- JOIN incident_objects
818
- ON incident_objects.object_type_id = overrides.source_type_id
819
- AND incident_objects.primary_id = overrides.source_primary_id
820
- WHERE overrides.project_id = ?
821
- UNION
822
- SELECT overrides.source_type_id,
823
- overrides.source_primary_id AS source_id,
824
- overrides.link_id, overrides.target_type_id,
825
- overrides.target_primary_id AS target_id
826
- FROM ontology_link_overrides AS overrides
827
- JOIN incident_objects
828
- ON incident_objects.object_type_id = overrides.target_type_id
829
- AND incident_objects.primary_id = overrides.target_primary_id
830
- WHERE overrides.project_id = ?
831
- UNION
832
- SELECT rows.source_type_id, rows.source_primary_id AS source_id,
833
- rows.link_id, rows.target_type_id, rows.target_primary_id AS target_id
834
- FROM incident_objects
835
- CROSS JOIN ontology_source_rows AS rows
836
- ON rows.entity_kind = 'link'
837
- AND rows.source_type_id = incident_objects.object_type_id
838
- AND rows.source_primary_id = incident_objects.primary_id
839
- ${LIVE_SOURCE_ROWS_JOIN}
840
- UNION
841
- SELECT rows.source_type_id, rows.source_primary_id AS source_id,
842
- rows.link_id, rows.target_type_id, rows.target_primary_id AS target_id
843
- FROM incident_objects
844
- CROSS JOIN ontology_source_rows AS rows
845
- ON rows.entity_kind = 'link'
846
- AND rows.target_type_id = incident_objects.object_type_id
847
- AND rows.target_primary_id = incident_objects.primary_id
848
- ${LIVE_SOURCE_ROWS_JOIN}
849
- ), diff_links AS (
850
- SELECT * FROM replacement_links
851
- UNION SELECT * FROM incident_links
852
- ), affected_scopes AS (
853
- SELECT DISTINCT source_type_id, source_id, link_id FROM diff_links
854
- ), all_links AS (
855
- SELECT *, 1 AS diff_required FROM diff_links
856
- UNION ALL
857
- SELECT links.source_type_id, links.source_id, links.link_id,
858
- links.target_type_id, links.target_id, 0 AS diff_required
859
- FROM links
860
- JOIN affected_scopes USING (source_type_id, source_id, link_id)
861
- WHERE links.project_id = ?
862
- UNION ALL
863
- SELECT overrides.source_type_id, overrides.source_primary_id AS source_id,
864
- overrides.link_id, overrides.target_type_id,
865
- overrides.target_primary_id AS target_id, 0 AS diff_required
866
- FROM ontology_link_overrides AS overrides
867
- JOIN affected_scopes
868
- ON affected_scopes.source_type_id = overrides.source_type_id
869
- AND affected_scopes.source_id = overrides.source_primary_id
870
- AND affected_scopes.link_id = overrides.link_id
871
- WHERE overrides.project_id = ? AND overrides.identity_kind = 'slot'
872
- ), selected AS (
873
- SELECT source_type_id, source_id, link_id, target_type_id, target_id,
874
- ${linkSortExpression("all_links")} AS sort_key,
875
- MAX(diff_required) AS diff_required
876
- FROM all_links
877
- GROUP BY source_type_id, source_id, link_id, target_type_id, target_id
878
- )
879
- INSERT INTO ${SQLITE_REPLACEMENT_WORK_TABLE} (
880
- session_id, entity_kind, identity_key, sort_key, diff_required
881
- )
882
- SELECT ?, 'link',
883
- json_array(source_type_id, source_id, link_id, target_type_id, target_id),
884
- sort_key, diff_required
885
- FROM selected
886
- `
887
- )
888
- .run(
889
- input.sessionId,
890
- ...rows.values,
891
- this.projectId,
892
- this.projectId,
893
- this.projectId,
894
- this.projectId,
895
- this.projectId,
896
- this.projectId,
897
- this.projectId,
898
- this.projectId,
899
- input.sessionId
900
- )
901
- }
902
-
903
- private replacementRows(
904
- input: ReplacementIdentityInput,
905
- cursor: ReplacementCursor | null
906
- ): ReplacementWorkRow[] {
907
- return this.db
908
- .query(
909
- `
910
- SELECT entity_kind, identity_key, sort_key, diff_required
911
- FROM ${SQLITE_REPLACEMENT_WORK_TABLE}
912
- WHERE session_id = ? AND entity_kind = ?
913
- AND (? IS NULL OR (sort_key, identity_key) > (?, ?))
914
- ORDER BY sort_key, identity_key
915
- LIMIT ?
916
- `
917
- )
918
- .all(
919
- input.sessionId,
920
- input.kind,
921
- cursor?.sortKey ?? null,
922
- cursor?.sortKey ?? null,
923
- cursor?.identityKey ?? null,
924
- input.pageRows
925
- ) as ReplacementWorkRow[]
926
- }
927
- }
928
-
929
- function replacementIdentity(row: ReplacementWorkRow): ReplacementIdentity {
930
- const parts = parseJson<string[]>(row.identity_key)
931
- if (row.entity_kind === "object") {
932
- return {
933
- kind: "object",
934
- ref: { objectTypeId: parts[0]!, primaryId: parts[1]! },
935
- sortKey: row.sort_key,
936
- diffRequired: true,
937
- }
938
- }
939
- return {
940
- kind: "link",
941
- ref: {
942
- source: { objectTypeId: parts[0]!, primaryId: parts[1]! },
943
- linkId: parts[2]!,
944
- target: { objectTypeId: parts[3]!, primaryId: parts[4]! },
945
- },
946
- sortKey: row.sort_key,
947
- diffRequired: row.diff_required === 1,
948
- }
949
698
  }
950
699
 
951
700
  function activeSourceMap(
@@ -1115,11 +864,6 @@ function storedPoint(row: TelemetryRow): StoredTelemetryPoint {
1115
864
  }
1116
865
  }
1117
866
 
1118
- function objectSortExpression(alias?: string): string {
1119
- const prefix = alias ? `${alias}.` : ""
1120
- return `LOWER(HEX(CAST(json_array(${prefix}object_type_id, ${prefix}primary_id) AS BLOB)))`
1121
- }
1122
-
1123
867
  export function linkSortExpression(alias?: string): string {
1124
868
  const prefix = alias ? `${alias}.` : ""
1125
869
  return `LOWER(HEX(CAST(json_array(${prefix}source_type_id, ${prefix}source_id, ${prefix}link_id, ${prefix}target_type_id, ${prefix}target_id) AS BLOB)))`
@@ -5,12 +5,11 @@ import {
5
5
  objectRefKey,
6
6
  telemetryPointKey,
7
7
  } from "@sixb/core/internal/materialization"
8
- import { effectiveConflict } from "@sixb/core/internal/ontology-storage-provider"
9
- import type {
10
- ExactEffectiveLinkWrite,
11
- ExactEffectiveObjectWrite,
12
- MaterializationPlanChunk,
13
- } from "@sixb/core/storage"
8
+ import {
9
+ effectiveConflict,
10
+ type MaterializationPlanChunk,
11
+ } from "@sixb/core/internal/ontology-storage-provider"
12
+ import type { ExactEffectiveLinkWrite, ExactEffectiveObjectWrite } from "@sixb/core/storage"
14
13
  import { assertTimestamp, canonicalJson, isSqliteConstraintError, requireChanges } from "./shared"
15
14
 
16
15
  function linkOverrideConflictMessage(identityKind: "edge" | "slot"): string {
@@ -442,28 +441,27 @@ export class SqliteMaterializationWriter {
442
441
  const insert = this.db.query(
443
442
  `
444
443
  INSERT INTO ontology_outbox (
445
- project_id, id, commit_id, commit_ordinal, envelope,
444
+ project_id, id, commit_id, commit_ordinal, event,
446
445
  available_at, attempts, lease_id, lease_expires_at,
447
446
  published_at, last_failure, created_at
448
447
  ) VALUES (?, ?, ?, ?, json(?), ?, 0, NULL, NULL, NULL, NULL, ?)
449
448
  `
450
449
  )
451
450
  for (const item of chunk.outbox) {
452
- assertTimestamp(item.availableAt, "Outbox availableAt")
453
451
  assertTimestamp(item.createdAt, "Outbox createdAt")
454
452
  try {
455
453
  insert.run(
456
454
  projectId,
457
- item.envelope.id,
455
+ item.id,
458
456
  commitId,
459
- item.envelope.commitOrdinal,
460
- canonicalJson(item.envelope),
461
- item.availableAt,
457
+ item.commitOrdinal,
458
+ canonicalJson(item.event),
459
+ item.createdAt,
462
460
  item.createdAt
463
461
  )
464
462
  } catch (error) {
465
463
  if (isSqliteConstraintError(error)) {
466
- throw effectiveConflict(`Duplicate outbox event '${item.envelope.id}'.`)
464
+ throw effectiveConflict(`Duplicate outbox event '${item.id}'.`)
467
465
  }
468
466
  throw error
469
467
  }