@sixb/sqlite 0.0.1

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 (152) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/dist/action-run-storage.d.ts +29 -0
  4. package/dist/action-run-storage.d.ts.map +1 -0
  5. package/dist/agents/agent-storage.d.ts +25 -0
  6. package/dist/agents/agent-storage.d.ts.map +1 -0
  7. package/dist/agents/index.d.ts +6 -0
  8. package/dist/agents/index.d.ts.map +1 -0
  9. package/dist/agents/messages.d.ts +14 -0
  10. package/dist/agents/messages.d.ts.map +1 -0
  11. package/dist/agents/rows.d.ts +77 -0
  12. package/dist/agents/rows.d.ts.map +1 -0
  13. package/dist/agents/runs.d.ts +26 -0
  14. package/dist/agents/runs.d.ts.map +1 -0
  15. package/dist/agents/threads.d.ts +14 -0
  16. package/dist/agents/threads.d.ts.map +1 -0
  17. package/dist/auth-storage/access-tokens.d.ts +33 -0
  18. package/dist/auth-storage/access-tokens.d.ts.map +1 -0
  19. package/dist/auth-storage/auth-storage.d.ts +46 -0
  20. package/dist/auth-storage/auth-storage.d.ts.map +1 -0
  21. package/dist/auth-storage/group-memberships.d.ts +21 -0
  22. package/dist/auth-storage/group-memberships.d.ts.map +1 -0
  23. package/dist/auth-storage/identities.d.ts +17 -0
  24. package/dist/auth-storage/identities.d.ts.map +1 -0
  25. package/dist/auth-storage/index.d.ts +3 -0
  26. package/dist/auth-storage/index.d.ts.map +1 -0
  27. package/dist/auth-storage/invitations.d.ts +28 -0
  28. package/dist/auth-storage/invitations.d.ts.map +1 -0
  29. package/dist/auth-storage/magic-links.d.ts +28 -0
  30. package/dist/auth-storage/magic-links.d.ts.map +1 -0
  31. package/dist/auth-storage/oidc-attempts.d.ts +18 -0
  32. package/dist/auth-storage/oidc-attempts.d.ts.map +1 -0
  33. package/dist/auth-storage/rows.d.ts +134 -0
  34. package/dist/auth-storage/rows.d.ts.map +1 -0
  35. package/dist/auth-storage/service-account-group-memberships.d.ts +17 -0
  36. package/dist/auth-storage/service-account-group-memberships.d.ts.map +1 -0
  37. package/dist/auth-storage/service-accounts.d.ts +14 -0
  38. package/dist/auth-storage/service-accounts.d.ts.map +1 -0
  39. package/dist/auth-storage/sessions.d.ts +55 -0
  40. package/dist/auth-storage/sessions.d.ts.map +1 -0
  41. package/dist/auth-storage/shared.d.ts +131 -0
  42. package/dist/auth-storage/shared.d.ts.map +1 -0
  43. package/dist/auth-storage/users.d.ts +19 -0
  44. package/dist/auth-storage/users.d.ts.map +1 -0
  45. package/dist/index.d.ts +71 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +10204 -0
  48. package/dist/index.js.map +54 -0
  49. package/dist/latest-run-query.d.ts +22 -0
  50. package/dist/latest-run-query.d.ts.map +1 -0
  51. package/dist/migrations.d.ts +18 -0
  52. package/dist/migrations.d.ts.map +1 -0
  53. package/dist/object-query-compiler.d.ts +44 -0
  54. package/dist/object-query-compiler.d.ts.map +1 -0
  55. package/dist/object-storage.d.ts +93 -0
  56. package/dist/object-storage.d.ts.map +1 -0
  57. package/dist/ontology-storage/commits.d.ts +14 -0
  58. package/dist/ontology-storage/commits.d.ts.map +1 -0
  59. package/dist/ontology-storage/index.d.ts +22 -0
  60. package/dist/ontology-storage/index.d.ts.map +1 -0
  61. package/dist/ontology-storage/materialization-session.d.ts +49 -0
  62. package/dist/ontology-storage/materialization-session.d.ts.map +1 -0
  63. package/dist/ontology-storage/materialization-state.d.ts +63 -0
  64. package/dist/ontology-storage/materialization-state.d.ts.map +1 -0
  65. package/dist/ontology-storage/materialization-writer.d.ts +15 -0
  66. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -0
  67. package/dist/ontology-storage/materializations.d.ts +32 -0
  68. package/dist/ontology-storage/materializations.d.ts.map +1 -0
  69. package/dist/ontology-storage/outbox.d.ts +14 -0
  70. package/dist/ontology-storage/outbox.d.ts.map +1 -0
  71. package/dist/ontology-storage/shared.d.ts +91 -0
  72. package/dist/ontology-storage/shared.d.ts.map +1 -0
  73. package/dist/ontology-storage/sources.d.ts +26 -0
  74. package/dist/ontology-storage/sources.d.ts.map +1 -0
  75. package/dist/pipeline-run-storage.d.ts +26 -0
  76. package/dist/pipeline-run-storage.d.ts.map +1 -0
  77. package/dist/projection-run-storage.d.ts +32 -0
  78. package/dist/projection-run-storage.d.ts.map +1 -0
  79. package/dist/rules-storage.d.ts +33 -0
  80. package/dist/rules-storage.d.ts.map +1 -0
  81. package/dist/run-list-query.d.ts +27 -0
  82. package/dist/run-list-query.d.ts.map +1 -0
  83. package/dist/storage-errors.d.ts +2 -0
  84. package/dist/storage-errors.d.ts.map +1 -0
  85. package/dist/sync-run-storage.d.ts +23 -0
  86. package/dist/sync-run-storage.d.ts.map +1 -0
  87. package/dist/timeseries-storage.d.ts +41 -0
  88. package/dist/timeseries-storage.d.ts.map +1 -0
  89. package/dist/transactions.d.ts +15 -0
  90. package/dist/transactions.d.ts.map +1 -0
  91. package/dist/tsconfig.json +5 -0
  92. package/dist/validation.d.ts +5 -0
  93. package/dist/validation.d.ts.map +1 -0
  94. package/dist/webhook-delivery-storage.d.ts +27 -0
  95. package/dist/webhook-delivery-storage.d.ts.map +1 -0
  96. package/dist/webhook-run-storage.d.ts +22 -0
  97. package/dist/webhook-run-storage.d.ts.map +1 -0
  98. package/dist/workflow-intervention-storage.d.ts +26 -0
  99. package/dist/workflow-intervention-storage.d.ts.map +1 -0
  100. package/dist/workflow-run-storage.d.ts +63 -0
  101. package/dist/workflow-run-storage.d.ts.map +1 -0
  102. package/package.json +58 -0
  103. package/src/action-run-storage.ts +761 -0
  104. package/src/agents/agent-storage.ts +46 -0
  105. package/src/agents/index.ts +5 -0
  106. package/src/agents/messages.ts +162 -0
  107. package/src/agents/rows.ts +205 -0
  108. package/src/agents/runs.ts +389 -0
  109. package/src/agents/threads.ts +133 -0
  110. package/src/auth-storage/access-tokens.ts +289 -0
  111. package/src/auth-storage/auth-storage.ts +784 -0
  112. package/src/auth-storage/group-memberships.ts +52 -0
  113. package/src/auth-storage/identities.ts +98 -0
  114. package/src/auth-storage/index.ts +2 -0
  115. package/src/auth-storage/invitations.ts +258 -0
  116. package/src/auth-storage/magic-links.ts +149 -0
  117. package/src/auth-storage/oidc-attempts.ts +109 -0
  118. package/src/auth-storage/rows.ts +338 -0
  119. package/src/auth-storage/service-account-group-memberships.ts +161 -0
  120. package/src/auth-storage/service-accounts.ts +168 -0
  121. package/src/auth-storage/sessions.ts +230 -0
  122. package/src/auth-storage/shared.ts +707 -0
  123. package/src/auth-storage/users.ts +226 -0
  124. package/src/index.ts +292 -0
  125. package/src/latest-run-query.ts +49 -0
  126. package/src/migrations/001-initial-schema.sql +1068 -0
  127. package/src/migrations.ts +245 -0
  128. package/src/object-query-compiler.ts +1198 -0
  129. package/src/object-storage.ts +605 -0
  130. package/src/ontology-storage/commits.ts +127 -0
  131. package/src/ontology-storage/index.ts +35 -0
  132. package/src/ontology-storage/materialization-session.ts +393 -0
  133. package/src/ontology-storage/materialization-state.ts +901 -0
  134. package/src/ontology-storage/materialization-writer.ts +394 -0
  135. package/src/ontology-storage/materializations.ts +838 -0
  136. package/src/ontology-storage/outbox.ts +237 -0
  137. package/src/ontology-storage/shared.ts +269 -0
  138. package/src/ontology-storage/sources.ts +653 -0
  139. package/src/pipeline-run-storage.ts +506 -0
  140. package/src/projection-run-storage.ts +592 -0
  141. package/src/rules-storage.ts +375 -0
  142. package/src/run-list-query.ts +98 -0
  143. package/src/sql.d.ts +4 -0
  144. package/src/storage-errors.ts +3 -0
  145. package/src/sync-run-storage.ts +299 -0
  146. package/src/timeseries-storage.ts +212 -0
  147. package/src/transactions.ts +96 -0
  148. package/src/validation.ts +30 -0
  149. package/src/webhook-delivery-storage.ts +272 -0
  150. package/src/webhook-run-storage.ts +240 -0
  151. package/src/workflow-intervention-storage.ts +398 -0
  152. package/src/workflow-run-storage.ts +1148 -0
@@ -0,0 +1,394 @@
1
+ import type { Database } from "bun:sqlite"
2
+ import {
3
+ linkRefKey,
4
+ MaterializationConflictError,
5
+ objectRefKey,
6
+ telemetryPointKey,
7
+ } from "@sixb/core/internal/materialization"
8
+ import {
9
+ effectiveConflict,
10
+ type OverrideEntity,
11
+ overrideEntityColumns as overrideColumns,
12
+ } from "@sixb/core/internal/ontology-storage-provider"
13
+ import type {
14
+ ExactEffectiveLinkWrite,
15
+ ExactEffectiveObjectWrite,
16
+ MaterializationPlanChunk,
17
+ } from "@sixb/core/storage"
18
+ import { assertTimestamp, canonicalJson, isSqliteConstraintError, requireChanges } from "./shared"
19
+
20
+ /** Applies one already-validated exact plan chunk to SQLite authority tables. */
21
+ export class SqliteMaterializationWriter {
22
+ constructor(private readonly db: Database) {}
23
+
24
+ apply(projectId: string, commitId: string, chunk: MaterializationPlanChunk): void {
25
+ this.applyOverrides(projectId, chunk)
26
+ this.applyEffective(projectId, chunk)
27
+ this.applyTimeseries(projectId, chunk)
28
+ this.applyOutbox(projectId, commitId, chunk)
29
+ }
30
+
31
+ private applyOverrides(projectId: string, chunk: MaterializationPlanChunk): void {
32
+ const upsert = (
33
+ entity: OverrideEntity,
34
+ item:
35
+ | (typeof chunk.overrides.objectUpserts)[number]
36
+ | (typeof chunk.overrides.linkUpserts)[number]
37
+ ): void => {
38
+ const kind = entity.kind
39
+ const key = kind === "object" ? objectRefKey(entity.ref) : linkRefKey(entity.ref)
40
+ const columns = overrideColumns(entity)
41
+ if (item.expectedLastCommitId === null) {
42
+ try {
43
+ this.db
44
+ .query(
45
+ `
46
+ INSERT INTO ontology_overrides (
47
+ project_id, entity_kind, entity_key, entity_sort_key,
48
+ object_type_id, primary_id, source_type_id, source_primary_id,
49
+ link_id, target_type_id, target_primary_id,
50
+ value, last_commit_id, updated_at
51
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, json(?), ?, ?)
52
+ `
53
+ )
54
+ .run(
55
+ projectId,
56
+ kind,
57
+ key,
58
+ columns.sortKey,
59
+ columns.objectTypeId,
60
+ columns.primaryId,
61
+ columns.sourceTypeId,
62
+ columns.sourcePrimaryId,
63
+ columns.linkId,
64
+ columns.targetTypeId,
65
+ columns.targetPrimaryId,
66
+ canonicalJson(item.value),
67
+ item.lastCommitId,
68
+ item.updatedAt
69
+ )
70
+ } catch (error) {
71
+ if (isSqliteConstraintError(error)) {
72
+ throw effectiveConflict(`Expected ${kind} override changed.`)
73
+ }
74
+ throw error
75
+ }
76
+ } else {
77
+ requireChanges(
78
+ this.db
79
+ .query(
80
+ `
81
+ UPDATE ontology_overrides
82
+ SET value = json(?), last_commit_id = ?, updated_at = ?
83
+ WHERE project_id = ? AND entity_kind = ? AND entity_key = ?
84
+ AND last_commit_id = ?
85
+ `
86
+ )
87
+ .run(
88
+ canonicalJson(item.value),
89
+ item.lastCommitId,
90
+ item.updatedAt,
91
+ projectId,
92
+ kind,
93
+ key,
94
+ item.expectedLastCommitId
95
+ ).changes,
96
+ "effective-state",
97
+ `Expected ${kind} override changed.`
98
+ )
99
+ }
100
+ }
101
+ for (const item of chunk.overrides.objectUpserts) {
102
+ upsert({ kind: "object", ref: item.ref }, item)
103
+ }
104
+ for (const item of chunk.overrides.objectDeletes) {
105
+ requireChanges(
106
+ this.db
107
+ .query(
108
+ `DELETE FROM ontology_overrides
109
+ WHERE project_id = ? AND entity_kind = 'object' AND entity_key = ? AND last_commit_id = ?`
110
+ )
111
+ .run(projectId, objectRefKey(item.ref), item.expectedLastCommitId).changes,
112
+ "effective-state",
113
+ "Expected object override changed."
114
+ )
115
+ }
116
+ for (const item of chunk.overrides.linkUpserts) {
117
+ upsert({ kind: "link", ref: item.ref }, item)
118
+ }
119
+ for (const item of chunk.overrides.linkDeletes) {
120
+ requireChanges(
121
+ this.db
122
+ .query(
123
+ `DELETE FROM ontology_overrides
124
+ WHERE project_id = ? AND entity_kind = 'link' AND entity_key = ? AND last_commit_id = ?`
125
+ )
126
+ .run(projectId, linkRefKey(item.ref), item.expectedLastCommitId).changes,
127
+ "effective-state",
128
+ "Expected link override changed."
129
+ )
130
+ }
131
+ }
132
+
133
+ private applyEffective(projectId: string, chunk: MaterializationPlanChunk): void {
134
+ for (const item of chunk.effective.linkDeletes) {
135
+ requireChanges(
136
+ this.db
137
+ .query(
138
+ `
139
+ DELETE FROM links
140
+ WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?
141
+ AND target_type_id = ? AND target_id = ? AND last_commit_id = ?
142
+ `
143
+ )
144
+ .run(
145
+ projectId,
146
+ item.ref.source.objectTypeId,
147
+ item.ref.source.primaryId,
148
+ item.ref.linkId,
149
+ item.ref.target.objectTypeId,
150
+ item.ref.target.primaryId,
151
+ item.expected.lastCommitId
152
+ ).changes,
153
+ "effective-state",
154
+ `Expected link ${linkRefKey(item.ref)} changed.`
155
+ )
156
+ }
157
+ for (const item of chunk.effective.objectDeletes) {
158
+ requireChanges(
159
+ this.db
160
+ .query(
161
+ `DELETE FROM objects
162
+ WHERE project_id = ? AND object_type_id = ? AND primary_id = ?
163
+ AND version = ? AND last_commit_id = ?`
164
+ )
165
+ .run(
166
+ projectId,
167
+ item.ref.objectTypeId,
168
+ item.ref.primaryId,
169
+ item.expected.version,
170
+ item.expected.lastCommitId
171
+ ).changes,
172
+ "effective-state",
173
+ `Expected object ${objectRefKey(item.ref)} changed.`
174
+ )
175
+ }
176
+ for (const item of chunk.effective.objectUpserts) this.applyObject(projectId, item)
177
+ for (const item of chunk.effective.linkUpserts) this.applyLink(projectId, item)
178
+ }
179
+
180
+ private applyObject(projectId: string, item: ExactEffectiveObjectWrite): void {
181
+ const { row, expected } = item
182
+ if (!expected.exists) {
183
+ try {
184
+ this.db
185
+ .query(
186
+ `
187
+ INSERT INTO objects (
188
+ project_id, object_type_id, primary_id, properties, created_at,
189
+ updated_at, version, last_commit_id
190
+ ) VALUES (?, ?, ?, json(?), ?, ?, ?, ?)
191
+ `
192
+ )
193
+ .run(
194
+ projectId,
195
+ row.ref.objectTypeId,
196
+ row.ref.primaryId,
197
+ canonicalJson(row.properties),
198
+ row.createdAt,
199
+ row.updatedAt,
200
+ row.version,
201
+ row.lastCommitId
202
+ )
203
+ } catch (error) {
204
+ if (isSqliteConstraintError(error)) {
205
+ throw effectiveConflict(`Expected object ${objectRefKey(row.ref)} to be absent.`)
206
+ }
207
+ throw error
208
+ }
209
+ return
210
+ }
211
+ requireChanges(
212
+ this.db
213
+ .query(
214
+ `
215
+ UPDATE objects
216
+ SET properties = json(?), created_at = ?, updated_at = ?, version = ?,
217
+ last_commit_id = ?
218
+ WHERE project_id = ? AND object_type_id = ? AND primary_id = ?
219
+ AND version = ? AND last_commit_id = ?
220
+ `
221
+ )
222
+ .run(
223
+ canonicalJson(row.properties),
224
+ row.createdAt,
225
+ row.updatedAt,
226
+ row.version,
227
+ row.lastCommitId,
228
+ projectId,
229
+ row.ref.objectTypeId,
230
+ row.ref.primaryId,
231
+ expected.version,
232
+ expected.lastCommitId
233
+ ).changes,
234
+ "effective-state",
235
+ `Expected object ${objectRefKey(row.ref)} changed.`
236
+ )
237
+ }
238
+
239
+ private applyLink(projectId: string, item: ExactEffectiveLinkWrite): void {
240
+ const { row, expected } = item
241
+ if (!expected.exists) {
242
+ try {
243
+ this.db
244
+ .query(
245
+ `
246
+ INSERT INTO links (
247
+ project_id, source_type_id, source_id, link_id, target_type_id, target_id,
248
+ properties, created_at, updated_at, last_commit_id
249
+ ) VALUES (?, ?, ?, ?, ?, ?, json(?), ?, ?, ?)
250
+ `
251
+ )
252
+ .run(
253
+ projectId,
254
+ row.ref.source.objectTypeId,
255
+ row.ref.source.primaryId,
256
+ row.ref.linkId,
257
+ row.ref.target.objectTypeId,
258
+ row.ref.target.primaryId,
259
+ row.properties === undefined ? null : canonicalJson(row.properties),
260
+ row.createdAt,
261
+ row.updatedAt,
262
+ row.lastCommitId
263
+ )
264
+ } catch (error) {
265
+ if (isSqliteConstraintError(error)) {
266
+ throw effectiveConflict(`Expected link ${linkRefKey(row.ref)} to be absent.`)
267
+ }
268
+ throw error
269
+ }
270
+ return
271
+ }
272
+ requireChanges(
273
+ this.db
274
+ .query(
275
+ `
276
+ UPDATE links
277
+ SET properties = json(?), created_at = ?, updated_at = ?,
278
+ last_commit_id = ?
279
+ WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?
280
+ AND target_type_id = ? AND target_id = ? AND last_commit_id = ?
281
+ `
282
+ )
283
+ .run(
284
+ row.properties === undefined ? null : canonicalJson(row.properties),
285
+ row.createdAt,
286
+ row.updatedAt,
287
+ row.lastCommitId,
288
+ projectId,
289
+ row.ref.source.objectTypeId,
290
+ row.ref.source.primaryId,
291
+ row.ref.linkId,
292
+ row.ref.target.objectTypeId,
293
+ row.ref.target.primaryId,
294
+ expected.lastCommitId
295
+ ).changes,
296
+ "effective-state",
297
+ `Expected link ${linkRefKey(row.ref)} changed.`
298
+ )
299
+ }
300
+
301
+ private applyTimeseries(projectId: string, chunk: MaterializationPlanChunk): void {
302
+ for (const item of chunk.timeseries.pointUpserts) {
303
+ const { point, expected } = item
304
+ if (expected.lastCommitId === null) {
305
+ try {
306
+ this.db
307
+ .query(
308
+ `
309
+ INSERT INTO timeseries (
310
+ project_id, object_type_id, object_id, property_id,
311
+ value, unit, at, last_commit_id
312
+ ) VALUES (?, ?, ?, ?, json(?), ?, ?, ?)
313
+ `
314
+ )
315
+ .run(
316
+ projectId,
317
+ point.series.object.objectTypeId,
318
+ point.series.object.primaryId,
319
+ point.series.propertyId,
320
+ canonicalJson(point.value),
321
+ point.unit ?? null,
322
+ point.at,
323
+ point.lastCommitId
324
+ )
325
+ } catch (error) {
326
+ if (isSqliteConstraintError(error)) {
327
+ throw new MaterializationConflictError(
328
+ "timeseries-point",
329
+ `Telemetry point ${telemetryPointKey(point.series, point.at)} changed.`
330
+ )
331
+ }
332
+ throw error
333
+ }
334
+ } else {
335
+ requireChanges(
336
+ this.db
337
+ .query(
338
+ `
339
+ UPDATE timeseries
340
+ SET value = json(?), unit = ?, last_commit_id = ?
341
+ WHERE project_id = ? AND object_type_id = ? AND object_id = ?
342
+ AND property_id = ? AND at = ? AND last_commit_id = ?
343
+ `
344
+ )
345
+ .run(
346
+ canonicalJson(point.value),
347
+ point.unit ?? null,
348
+ point.lastCommitId,
349
+ projectId,
350
+ point.series.object.objectTypeId,
351
+ point.series.object.primaryId,
352
+ point.series.propertyId,
353
+ point.at,
354
+ expected.lastCommitId
355
+ ).changes,
356
+ "timeseries-point",
357
+ `Telemetry point ${telemetryPointKey(point.series, point.at)} changed.`
358
+ )
359
+ }
360
+ }
361
+ }
362
+
363
+ private applyOutbox(projectId: string, commitId: string, chunk: MaterializationPlanChunk): void {
364
+ const insert = this.db.query(
365
+ `
366
+ INSERT INTO ontology_outbox (
367
+ project_id, id, commit_id, commit_ordinal, envelope,
368
+ available_at, attempts, lease_id, lease_expires_at,
369
+ published_at, last_error, created_at
370
+ ) VALUES (?, ?, ?, ?, json(?), ?, 0, NULL, NULL, NULL, NULL, ?)
371
+ `
372
+ )
373
+ for (const item of chunk.outbox) {
374
+ assertTimestamp(item.availableAt, "Outbox availableAt")
375
+ assertTimestamp(item.createdAt, "Outbox createdAt")
376
+ try {
377
+ insert.run(
378
+ projectId,
379
+ item.envelope.id,
380
+ commitId,
381
+ item.envelope.commitOrdinal,
382
+ canonicalJson(item.envelope),
383
+ item.availableAt,
384
+ item.createdAt
385
+ )
386
+ } catch (error) {
387
+ if (isSqliteConstraintError(error)) {
388
+ throw effectiveConflict(`Duplicate outbox event '${item.envelope.id}'.`)
389
+ }
390
+ throw error
391
+ }
392
+ }
393
+ }
394
+ }