@spine-event-engine/storage-postgres 2.0.0-snapshot.13
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/LICENSE +201 -0
- package/README.md +102 -0
- package/REFERENCE.md +85 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/postgres/column-mapping.d.ts +33 -0
- package/dist/postgres/column-mapping.d.ts.map +1 -0
- package/dist/postgres/column-mapping.js +93 -0
- package/dist/postgres/column-mapping.js.map +1 -0
- package/dist/postgres/data-type.d.ts +25 -0
- package/dist/postgres/data-type.d.ts.map +1 -0
- package/dist/postgres/data-type.js +29 -0
- package/dist/postgres/data-type.js.map +1 -0
- package/dist/postgres/delivery-cleanup.d.ts +76 -0
- package/dist/postgres/delivery-cleanup.d.ts.map +1 -0
- package/dist/postgres/delivery-cleanup.js +224 -0
- package/dist/postgres/delivery-cleanup.js.map +1 -0
- package/dist/postgres/entity-commit.d.ts +114 -0
- package/dist/postgres/entity-commit.d.ts.map +1 -0
- package/dist/postgres/entity-commit.js +385 -0
- package/dist/postgres/entity-commit.js.map +1 -0
- package/dist/postgres/entity-history.d.ts +85 -0
- package/dist/postgres/entity-history.d.ts.map +1 -0
- package/dist/postgres/entity-history.js +840 -0
- package/dist/postgres/entity-history.js.map +1 -0
- package/dist/postgres/errors.d.ts +51 -0
- package/dist/postgres/errors.d.ts.map +1 -0
- package/dist/postgres/errors.js +113 -0
- package/dist/postgres/errors.js.map +1 -0
- package/dist/postgres/id-column.d.ts +61 -0
- package/dist/postgres/id-column.d.ts.map +1 -0
- package/dist/postgres/id-column.js +165 -0
- package/dist/postgres/id-column.js.map +1 -0
- package/dist/postgres/parameter.d.ts +5 -0
- package/dist/postgres/parameter.d.ts.map +1 -0
- package/dist/postgres/parameter.js +15 -0
- package/dist/postgres/parameter.js.map +1 -0
- package/dist/postgres/record-storage.d.ts +514 -0
- package/dist/postgres/record-storage.d.ts.map +1 -0
- package/dist/postgres/record-storage.js +849 -0
- package/dist/postgres/record-storage.js.map +1 -0
- package/dist/postgres/storage-factory.d.ts +321 -0
- package/dist/postgres/storage-factory.d.ts.map +1 -0
- package/dist/postgres/storage-factory.js +584 -0
- package/dist/postgres/storage-factory.js.map +1 -0
- package/dist/postgres/table-initializer.d.ts +66 -0
- package/dist/postgres/table-initializer.d.ts.map +1 -0
- package/dist/postgres/table-initializer.js +301 -0
- package/dist/postgres/table-initializer.js.map +1 -0
- package/dist/postgres/table-resolver.d.ts +41 -0
- package/dist/postgres/table-resolver.d.ts.map +1 -0
- package/dist/postgres/table-resolver.js +225 -0
- package/dist/postgres/table-resolver.js.map +1 -0
- package/dist/postgres/table-spec.d.ts +40 -0
- package/dist/postgres/table-spec.d.ts.map +1 -0
- package/dist/postgres/table-spec.js +126 -0
- package/dist/postgres/table-spec.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type Message } from "@bufbuild/protobuf";
|
|
2
|
+
import { type DeliveryCleanupInput, type DeliveryCleanupStorage } from "@spine-event-engine/storage/provider";
|
|
3
|
+
import type { RecordSpec, StorageContext } from "@spine-event-engine/storage";
|
|
4
|
+
import { PostgresRecordStorage, type PostgresRecordLifecycle } from "./record-storage.js";
|
|
5
|
+
/**
|
|
6
|
+
* Opens one tenant-bound PostgreSQL record family.
|
|
7
|
+
*
|
|
8
|
+
* @typeParam I Record identifier type.
|
|
9
|
+
* @typeParam R Stored Protobuf record type.
|
|
10
|
+
*/
|
|
11
|
+
type OpenRecords = <I, R extends Message>(context: StorageContext, spec: RecordSpec<I, R>) => PostgresRecordStorage<I, R>;
|
|
12
|
+
/**
|
|
13
|
+
* Deletes one delivered Inbox row only while its expected session record remains current.
|
|
14
|
+
*/
|
|
15
|
+
export declare class PostgresDeliveryCleanupStorage implements DeliveryCleanupStorage {
|
|
16
|
+
#private;
|
|
17
|
+
private readonly open;
|
|
18
|
+
private readonly lifecycle;
|
|
19
|
+
private readonly onClose;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a PostgreSQL cleanup handle.
|
|
22
|
+
*
|
|
23
|
+
* @param open Opens tenant-bound Inbox and session record families.
|
|
24
|
+
* @param lifecycle Resolves the exact tenant-bound transaction lifecycle.
|
|
25
|
+
* @param onClose Removes this handle from the factory's live-handle set.
|
|
26
|
+
*/
|
|
27
|
+
constructor(open: OpenRecords, lifecycle: (context: StorageContext) => PostgresRecordLifecycle, onClose: () => void);
|
|
28
|
+
/**
|
|
29
|
+
* Removes an exact Inbox row while its session snapshot remains current.
|
|
30
|
+
*
|
|
31
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
32
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
33
|
+
* @typeParam SessionId Session record identifier type.
|
|
34
|
+
* @typeParam SessionRecord Session record message type.
|
|
35
|
+
* @param input Describes the expected Inbox and session records.
|
|
36
|
+
* @returns Whether the exact Inbox row was deleted.
|
|
37
|
+
*/
|
|
38
|
+
remove<InboxId, InboxRecord extends Message, SessionId, SessionRecord extends Message>(input: DeliveryCleanupInput<InboxId, InboxRecord, SessionId, SessionRecord>): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Closes this handle to new cleanup operations.
|
|
41
|
+
*/
|
|
42
|
+
close(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Executes one cleanup transaction with one retry for a serialization conflict.
|
|
45
|
+
*
|
|
46
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
47
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
48
|
+
* @typeParam SessionId Session record identifier type.
|
|
49
|
+
* @typeParam SessionRecord Session record message type.
|
|
50
|
+
* @param input Describes the expected Inbox and session records.
|
|
51
|
+
* @param inbox Provides the delivered Inbox record family.
|
|
52
|
+
* @param sessions Provides the session record family.
|
|
53
|
+
* @returns Whether the transaction deleted the Inbox row.
|
|
54
|
+
*/
|
|
55
|
+
private coordinate;
|
|
56
|
+
/**
|
|
57
|
+
* Checks the expected records and deletes the Inbox row on one transaction client.
|
|
58
|
+
*
|
|
59
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
60
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
61
|
+
* @typeParam SessionId Session record identifier type.
|
|
62
|
+
* @typeParam SessionRecord Session record message type.
|
|
63
|
+
* @param client PostgreSQL transaction client.
|
|
64
|
+
* @param input Describes the expected Inbox and session records.
|
|
65
|
+
* @param inbox Provides the delivered Inbox record family.
|
|
66
|
+
* @param sessions Provides the session record family.
|
|
67
|
+
* @returns Whether the exact Inbox row was deleted.
|
|
68
|
+
*/
|
|
69
|
+
private removeOn;
|
|
70
|
+
/**
|
|
71
|
+
* Rejects cleanup after this handle has closed.
|
|
72
|
+
*/
|
|
73
|
+
private requireOpen;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=delivery-cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-cleanup.d.ts","sourceRoot":"","sources":["../../src/postgres/delivery-cleanup.ts"],"names":[],"mappings":"AAcA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAQ9E,OAAO,EAAE,qBAAqB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE1F;;;;;GAKG;AACH,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EACtC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KACnB,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEjC;;GAEG;AACH,qBAAa,8BAA+B,YAAW,sBAAsB;;IAWzE,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAV1B;;;;;;OAMG;gBAEgB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,uBAAuB,EAC/D,OAAO,EAAE,MAAM,IAAI;IAGtC;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,WAAW,SAAS,OAAO,EAAE,SAAS,EAAE,aAAa,SAAS,OAAO,EACzF,KAAK,EAAE,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,CAAC,GAC1E,OAAO,CAAC,OAAO,CAAC;IAmBnB;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;;;;;;OAWG;YACW,UAAU;IAkCxB;;;;;;;;;;;;OAYG;YACW,QAAQ;IA4BtB;;OAEG;IACH,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, CodeMatters. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
5
|
+
* in compliance with the License. You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
10
|
+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
11
|
+
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
|
+
* the License.
|
|
13
|
+
*/
|
|
14
|
+
import { toBinary } from "@bufbuild/protobuf";
|
|
15
|
+
import { cleanupOperationActive, } from "@spine-event-engine/storage/provider";
|
|
16
|
+
import { PostgresRollbackErrors, PostgresStorageOperationError, PostgresTransactionErrors, } from "./errors.js";
|
|
17
|
+
import { PostgresRecordStorage } from "./record-storage.js";
|
|
18
|
+
/**
|
|
19
|
+
* Deletes one delivered Inbox row only while its expected session record remains current.
|
|
20
|
+
*/
|
|
21
|
+
export class PostgresDeliveryCleanupStorage {
|
|
22
|
+
open;
|
|
23
|
+
lifecycle;
|
|
24
|
+
onClose;
|
|
25
|
+
#open = true;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a PostgreSQL cleanup handle.
|
|
28
|
+
*
|
|
29
|
+
* @param open Opens tenant-bound Inbox and session record families.
|
|
30
|
+
* @param lifecycle Resolves the exact tenant-bound transaction lifecycle.
|
|
31
|
+
* @param onClose Removes this handle from the factory's live-handle set.
|
|
32
|
+
*/
|
|
33
|
+
constructor(open, lifecycle, onClose) {
|
|
34
|
+
this.open = open;
|
|
35
|
+
this.lifecycle = lifecycle;
|
|
36
|
+
this.onClose = onClose;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Removes an exact Inbox row while its session snapshot remains current.
|
|
40
|
+
*
|
|
41
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
42
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
43
|
+
* @typeParam SessionId Session record identifier type.
|
|
44
|
+
* @typeParam SessionRecord Session record message type.
|
|
45
|
+
* @param input Describes the expected Inbox and session records.
|
|
46
|
+
* @returns Whether the exact Inbox row was deleted.
|
|
47
|
+
*/
|
|
48
|
+
async remove(input) {
|
|
49
|
+
this.requireOpen();
|
|
50
|
+
if (!PostgresCleanupValues.active(input))
|
|
51
|
+
return false;
|
|
52
|
+
const inbox = this.open(input.context, input.inbox.spec);
|
|
53
|
+
const sessions = this.open(input.context, input.session.spec);
|
|
54
|
+
try {
|
|
55
|
+
await inbox.prepare();
|
|
56
|
+
await sessions.prepare();
|
|
57
|
+
if (!PostgresCleanupValues.active(input))
|
|
58
|
+
return false;
|
|
59
|
+
return await this.coordinate(input, inbox, sessions);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof CleanupExpired)
|
|
63
|
+
return false;
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
inbox.close();
|
|
68
|
+
sessions.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Closes this handle to new cleanup operations.
|
|
73
|
+
*/
|
|
74
|
+
close() {
|
|
75
|
+
if (!this.#open)
|
|
76
|
+
return;
|
|
77
|
+
this.#open = false;
|
|
78
|
+
this.onClose();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Executes one cleanup transaction with one retry for a serialization conflict.
|
|
82
|
+
*
|
|
83
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
84
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
85
|
+
* @typeParam SessionId Session record identifier type.
|
|
86
|
+
* @typeParam SessionRecord Session record message type.
|
|
87
|
+
* @param input Describes the expected Inbox and session records.
|
|
88
|
+
* @param inbox Provides the delivered Inbox record family.
|
|
89
|
+
* @param sessions Provides the session record family.
|
|
90
|
+
* @returns Whether the transaction deleted the Inbox row.
|
|
91
|
+
*/
|
|
92
|
+
async coordinate(input, inbox, sessions) {
|
|
93
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
94
|
+
const client = await this.lifecycle(input.context).acquire();
|
|
95
|
+
let discard;
|
|
96
|
+
try {
|
|
97
|
+
await client.query("BEGIN");
|
|
98
|
+
const result = await this.removeOn(client, input, inbox, sessions);
|
|
99
|
+
await client.query("COMMIT");
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
try {
|
|
104
|
+
await client.query("ROLLBACK");
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
discard = PostgresRollbackErrors.discard(error);
|
|
108
|
+
}
|
|
109
|
+
if (error instanceof CleanupExpired)
|
|
110
|
+
throw error;
|
|
111
|
+
if (attempt === 0 && PostgresTransactionErrors.retryable(error))
|
|
112
|
+
continue;
|
|
113
|
+
throw PostgresCleanupErrors.operation(error);
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
client.release(discard);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
throw new Error("Unreachable PostgreSQL cleanup retry.");
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Checks the expected records and deletes the Inbox row on one transaction client.
|
|
123
|
+
*
|
|
124
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
125
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
126
|
+
* @typeParam SessionId Session record identifier type.
|
|
127
|
+
* @typeParam SessionRecord Session record message type.
|
|
128
|
+
* @param client PostgreSQL transaction client.
|
|
129
|
+
* @param input Describes the expected Inbox and session records.
|
|
130
|
+
* @param inbox Provides the delivered Inbox record family.
|
|
131
|
+
* @param sessions Provides the session record family.
|
|
132
|
+
* @returns Whether the exact Inbox row was deleted.
|
|
133
|
+
*/
|
|
134
|
+
async removeOn(client, input, inbox, sessions) {
|
|
135
|
+
if (!PostgresCleanupValues.active(input))
|
|
136
|
+
return false;
|
|
137
|
+
const session = sessions.historyExecutor();
|
|
138
|
+
const delivered = inbox.historyExecutor();
|
|
139
|
+
await client.query("SELECT pg_advisory_xact_lock($1)", [session.lockRecord(input.session.id)]);
|
|
140
|
+
if (!PostgresCleanupValues.active(input))
|
|
141
|
+
return false;
|
|
142
|
+
const currentSession = await session.read(client, input.session.id, "for-update");
|
|
143
|
+
if (!PostgresCleanupValues.active(input))
|
|
144
|
+
return false;
|
|
145
|
+
if (!PostgresCleanupValues.current(input, currentSession))
|
|
146
|
+
return false;
|
|
147
|
+
const currentInbox = await delivered.read(client, input.inbox.id, "for-update");
|
|
148
|
+
if (!PostgresCleanupValues.same(input.inbox.spec, currentInbox, input.inbox.expected))
|
|
149
|
+
return false;
|
|
150
|
+
if (!PostgresCleanupValues.active(input))
|
|
151
|
+
return false;
|
|
152
|
+
const removed = await delivered.delete(client, input.inbox.id);
|
|
153
|
+
if (!PostgresCleanupValues.active(input))
|
|
154
|
+
throw new CleanupExpired();
|
|
155
|
+
return removed;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Rejects cleanup after this handle has closed.
|
|
159
|
+
*/
|
|
160
|
+
requireOpen() {
|
|
161
|
+
if (!this.#open)
|
|
162
|
+
throw new PostgresStorageOperationError("Delivery cleanup storage is closed.");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const PostgresCleanupValues = Object.freeze({
|
|
166
|
+
/**
|
|
167
|
+
* Checks whether the caller still permits the cleanup operation.
|
|
168
|
+
*
|
|
169
|
+
* @param input Carries the optional operation lifetime.
|
|
170
|
+
* @returns Whether cleanup may continue.
|
|
171
|
+
*/
|
|
172
|
+
active(input) {
|
|
173
|
+
return cleanupOperationActive(input.operation);
|
|
174
|
+
},
|
|
175
|
+
/**
|
|
176
|
+
* Compares the current session with the expected cleanup session.
|
|
177
|
+
*
|
|
178
|
+
* @typeParam InboxId Inbox record identifier type.
|
|
179
|
+
* @typeParam InboxRecord Inbox record message type.
|
|
180
|
+
* @typeParam SessionId Session record identifier type.
|
|
181
|
+
* @typeParam SessionRecord Session record message type.
|
|
182
|
+
* @param input Describes the expected cleanup records.
|
|
183
|
+
* @param actual Session record read inside the transaction.
|
|
184
|
+
* @returns Whether the session is still current and unchanged.
|
|
185
|
+
*/
|
|
186
|
+
current(input, actual) {
|
|
187
|
+
return (actual !== undefined &&
|
|
188
|
+
input.session.isCurrent(actual) &&
|
|
189
|
+
this.same(input.session.spec, actual, input.session.expected));
|
|
190
|
+
},
|
|
191
|
+
/**
|
|
192
|
+
* Compares two records through their Protobuf wire representation.
|
|
193
|
+
*
|
|
194
|
+
* @typeParam I Record identifier type.
|
|
195
|
+
* @typeParam R Stored Protobuf record type.
|
|
196
|
+
* @param spec Describes the stored record schema.
|
|
197
|
+
* @param left Record read from PostgreSQL.
|
|
198
|
+
* @param right Expected record value.
|
|
199
|
+
* @returns Whether both records have identical wire bytes.
|
|
200
|
+
*/
|
|
201
|
+
same(spec, left, right) {
|
|
202
|
+
return (left !== undefined &&
|
|
203
|
+
Buffer.compare(toBinary(spec.recordType, left), toBinary(spec.recordType, right)) === 0);
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
const PostgresCleanupErrors = Object.freeze({
|
|
207
|
+
/**
|
|
208
|
+
* Converts an internal cleanup failure to the stable provider error.
|
|
209
|
+
*
|
|
210
|
+
* @param error Failure raised inside the cleanup transaction.
|
|
211
|
+
* @returns Stable public cleanup error.
|
|
212
|
+
*/
|
|
213
|
+
operation(error) {
|
|
214
|
+
return error instanceof PostgresStorageOperationError
|
|
215
|
+
? error
|
|
216
|
+
: new PostgresStorageOperationError("PostgreSQL delivery cleanup failed.");
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
/**
|
|
220
|
+
* Signals that the cleanup lifetime ended after deletion but before commit.
|
|
221
|
+
*/
|
|
222
|
+
class CleanupExpired extends Error {
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=delivery-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-cleanup.js","sourceRoot":"","sources":["../../src/postgres/delivery-cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type Message } from "@bufbuild/protobuf";
|
|
2
|
+
import { type RecordSpec, type StorageGroup } from "@spine-event-engine/storage";
|
|
3
|
+
import { type EntityCommitInput, type EntityCommitResult, type EntityCommitStorage, type EntityStorageInput } from "@spine-event-engine/storage/provider";
|
|
4
|
+
import { PostgresRecordStorage, type PostgresRecordLifecycle } from "./record-storage.js";
|
|
5
|
+
/**
|
|
6
|
+
* Opens one PostgreSQL record family used by an Entity commit.
|
|
7
|
+
*
|
|
8
|
+
* @typeParam I Record identifier type.
|
|
9
|
+
* @typeParam R Stored Protobuf record type.
|
|
10
|
+
*/
|
|
11
|
+
type OpenRecords = <I, R extends Message>(spec: RecordSpec<I, R>, group?: StorageGroup) => PostgresRecordStorage<I, R>;
|
|
12
|
+
/**
|
|
13
|
+
* Represents a factory-tracked PostgreSQL Entity commit handle.
|
|
14
|
+
*
|
|
15
|
+
* @typeParam I Entity identifier type captured by this handle.
|
|
16
|
+
* @typeParam S Entity state message type captured by this handle.
|
|
17
|
+
*/
|
|
18
|
+
export declare class PostgresEntityCommitStorage<I, S extends Message> implements EntityCommitStorage {
|
|
19
|
+
#private;
|
|
20
|
+
private readonly entity;
|
|
21
|
+
private readonly open;
|
|
22
|
+
private readonly onClose;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a PostgreSQL Entity commit handle for one Entity storage boundary.
|
|
25
|
+
*
|
|
26
|
+
* @param entity Defines the captured Entity source, state, and tenant scope.
|
|
27
|
+
* @param open Opens temporary current and history record-family handles.
|
|
28
|
+
* @param lifecycle Acquires transaction clients for the captured database.
|
|
29
|
+
* @param onClose Removes this handle from the factory's live-handle set.
|
|
30
|
+
*/
|
|
31
|
+
constructor(entity: EntityStorageInput<I, S>, open: OpenRecords, lifecycle: PostgresRecordLifecycle, onClose: () => void);
|
|
32
|
+
/**
|
|
33
|
+
* Commits one current Entity record and its optional immutable records.
|
|
34
|
+
*
|
|
35
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
36
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
37
|
+
* @param input Defines the expected and next current records plus histories.
|
|
38
|
+
* @returns Whether PostgreSQL committed the mutation or found a conflict.
|
|
39
|
+
*/
|
|
40
|
+
commit<Id, State extends Message>(input: EntityCommitInput<Id, State>): Promise<EntityCommitResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Closes this handle to new commits while allowing started work to settle.
|
|
43
|
+
*/
|
|
44
|
+
close(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Applies one validated Entity commit on an active transaction.
|
|
47
|
+
*
|
|
48
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
49
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
50
|
+
* @param client PostgreSQL transaction client.
|
|
51
|
+
* @param input Defines the Entity records to commit.
|
|
52
|
+
* @param records Provides the prepared record families.
|
|
53
|
+
* @returns Whether records were committed or conflicted.
|
|
54
|
+
*/
|
|
55
|
+
private apply;
|
|
56
|
+
/**
|
|
57
|
+
* Acquires locks for each mutable or append-only family in the commit.
|
|
58
|
+
*
|
|
59
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
60
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
61
|
+
* @param client PostgreSQL transaction client.
|
|
62
|
+
* @param input Defines the Entity records to commit.
|
|
63
|
+
* @param records Provides the prepared record families.
|
|
64
|
+
* @returns Completion after all transaction locks are acquired.
|
|
65
|
+
*/
|
|
66
|
+
private locks;
|
|
67
|
+
/**
|
|
68
|
+
* Verifies that every immutable record can be appended.
|
|
69
|
+
*
|
|
70
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
71
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
72
|
+
* @param client PostgreSQL transaction client.
|
|
73
|
+
* @param input Defines the immutable records to verify.
|
|
74
|
+
* @param records Provides the prepared record families.
|
|
75
|
+
* @returns Completion after all immutable checks pass.
|
|
76
|
+
*/
|
|
77
|
+
private preflight;
|
|
78
|
+
/**
|
|
79
|
+
* Stores every immutable history and event-store record.
|
|
80
|
+
*
|
|
81
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
82
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
83
|
+
* @param client PostgreSQL transaction client.
|
|
84
|
+
* @param input Defines the immutable records to append.
|
|
85
|
+
* @param records Provides the prepared record families.
|
|
86
|
+
* @returns Completion after all records are appended.
|
|
87
|
+
*/
|
|
88
|
+
private append;
|
|
89
|
+
/**
|
|
90
|
+
* Validates the commit against the Entity boundary captured by this handle.
|
|
91
|
+
*
|
|
92
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
93
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
94
|
+
* @param input Defines the Entity records to validate.
|
|
95
|
+
*/
|
|
96
|
+
private validate;
|
|
97
|
+
/**
|
|
98
|
+
* Validates record identifiers inside one Entity commit.
|
|
99
|
+
*
|
|
100
|
+
* @typeParam Id Entity identifier type supplied by the commit.
|
|
101
|
+
* @typeParam State Entity state message type supplied by the commit.
|
|
102
|
+
* @param input Defines current and historical records to validate.
|
|
103
|
+
*/
|
|
104
|
+
private validateRows;
|
|
105
|
+
/**
|
|
106
|
+
* Validates event identifiers for one immutable event family.
|
|
107
|
+
*
|
|
108
|
+
* @param events Events to validate when the family is enabled.
|
|
109
|
+
* @param family Names the event family in validation errors.
|
|
110
|
+
*/
|
|
111
|
+
private validateEventIds;
|
|
112
|
+
}
|
|
113
|
+
export {};
|
|
114
|
+
//# sourceMappingURL=entity-commit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-commit.d.ts","sourceRoot":"","sources":["../../src/postgres/entity-commit.ts"],"names":[],"mappings":"AAcA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAO5D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACxB,MAAM,sCAAsC,CAAC;AAQ9C,OAAO,EACL,qBAAqB,EAErB,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AA6C7B;;;;;GAKG;AACH,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EACtC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,KAAK,CAAC,EAAE,YAAY,KACjB,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AA4GjC;;;;;GAKG;AACH,qBAAa,2BAA2B,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,CAAE,YAAW,mBAAmB;;IAczF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZ1B;;;;;;;OAOG;gBAEgB,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,EAChC,IAAI,EAAE,WAAW,EAClC,SAAS,EAAE,uBAAuB,EACjB,OAAO,EAAE,MAAM,IAAI;IAKtC;;;;;;;OAOG;IACG,MAAM,CAAC,EAAE,EAAE,KAAK,SAAS,OAAO,EACpC,KAAK,EAAE,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,GAClC,OAAO,CAAC,kBAAkB,CAAC;IAW9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;;;;;;;;OASG;YACW,KAAK;IAmBnB;;;;;;;;;OASG;YACW,KAAK;IAsBnB;;;;;;;;;OASG;YACW,SAAS;IAWvB;;;;;;;;;OASG;YACW,MAAM;IAWpB;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;IAkBhB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAgBpB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;CAWzB"}
|