@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.
- package/dist/ai-limit-storage.d.ts.map +1 -1
- package/dist/ai-usage-storage.d.ts.map +1 -1
- package/dist/execution-storage.d.ts +28 -0
- package/dist/execution-storage.d.ts.map +1 -1
- package/dist/file-download-grant-storage.d.ts +11 -0
- package/dist/file-download-grant-storage.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1362 -579
- package/dist/index.js.map +27 -25
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/query-compiler.d.ts.map +1 -1
- package/dist/objects/reader.d.ts.map +1 -1
- package/dist/objects/storage.d.ts.map +1 -1
- package/dist/ontology-storage/index.d.ts +2 -0
- package/dist/ontology-storage/index.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-session.d.ts +17 -37
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-state.d.ts +3 -26
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-writer.d.ts +1 -1
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts +3 -6
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/dist/ontology-storage/outbox.d.ts.map +1 -1
- package/dist/ontology-storage/replacement-plans.d.ts +88 -0
- package/dist/ontology-storage/replacement-plans.d.ts.map +1 -0
- package/dist/ontology-storage/shared.d.ts +8 -5
- package/dist/ontology-storage/shared.d.ts.map +1 -1
- package/dist/ontology-storage/source-cleanup.d.ts.map +1 -1
- package/dist/ontology-storage/source-roots.d.ts +15 -2
- package/dist/ontology-storage/source-roots.d.ts.map +1 -1
- package/dist/ontology-storage/sources.d.ts +1 -2
- package/dist/ontology-storage/sources.d.ts.map +1 -1
- package/dist/projection-run-storage.d.ts.map +1 -1
- package/dist/rules-storage.d.ts.map +1 -1
- package/dist/testing.d.ts +4 -1
- package/dist/testing.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/ai-cost-storage.ts +10 -0
- package/src/ai-limit-storage.ts +13 -2
- package/src/ai-usage-storage.ts +9 -1
- package/src/execution-storage.ts +7 -2
- package/src/file-download-grant-storage.ts +76 -0
- package/src/index.ts +10 -3
- package/src/migrations/053-replacement-plans.sql +73 -0
- package/src/migrations/054-slim-ontology-outbox.sql +21 -0
- package/src/migrations/055-commit-touches.sql +31 -0
- package/src/migrations/056-audio-transcription.sql +10 -0
- package/src/migrations/057-reranking-model-kind.sql +16 -0
- package/src/migrations/058-file-download-grants.sql +21 -0
- package/src/migrations/059-drained-source-versions.sql +11 -0
- package/src/migrations.ts +115 -0
- package/src/objects/query-compiler.ts +5 -0
- package/src/objects/reader.ts +1 -0
- package/src/objects/storage.ts +5 -11
- package/src/ontology-storage/index.ts +6 -1
- package/src/ontology-storage/materialization-session.ts +120 -211
- package/src/ontology-storage/materialization-state.ts +5 -261
- package/src/ontology-storage/materialization-writer.ts +11 -13
- package/src/ontology-storage/materializations.ts +133 -210
- package/src/ontology-storage/outbox.ts +50 -16
- package/src/ontology-storage/replacement-plans.ts +1064 -0
- package/src/ontology-storage/shared.ts +17 -12
- package/src/ontology-storage/source-cleanup.ts +24 -9
- package/src/ontology-storage/source-roots.ts +38 -14
- package/src/ontology-storage/sources.ts +0 -26
- package/src/projection-run-storage.ts +7 -1
- package/src/rules-storage.ts +9 -14
- 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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
|
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
|
|
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 {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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,
|
|
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.
|
|
455
|
+
item.id,
|
|
458
456
|
commitId,
|
|
459
|
-
item.
|
|
460
|
-
canonicalJson(item.
|
|
461
|
-
item.
|
|
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.
|
|
464
|
+
throw effectiveConflict(`Duplicate outbox event '${item.id}'.`)
|
|
467
465
|
}
|
|
468
466
|
throw error
|
|
469
467
|
}
|