@delali/sirannon-db 0.2.0 → 0.2.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 (75) hide show
  1. package/dist/backup-scheduler/index.d.ts +15 -1
  2. package/dist/backup-scheduler/index.mjs +2 -2
  3. package/dist/baseline-D93hcIEE.d.ts +17 -0
  4. package/dist/{change-tracker-DKRVUC3l.d.ts → change-tracker-DDmXB754.d.ts} +56 -8
  5. package/dist/{chunk-5NOIGN5Y.mjs → chunk-2QLXDHAP.mjs} +1 -1
  6. package/dist/{chunk-LNY2VVHE.mjs → chunk-7C36BCSN.mjs} +1 -1
  7. package/dist/{chunk-NVQS53NT.mjs → chunk-7FQRQH5Z.mjs} +53 -64
  8. package/dist/{chunk-D7LAYTKN.mjs → chunk-7R4ER4FB.mjs} +1 -1
  9. package/dist/{chunk-FHWTZFI4.mjs → chunk-BQFQ65OL.mjs} +1 -1
  10. package/dist/{chunk-O7SLN3GI.mjs → chunk-BTTFW4Z4.mjs} +1 -1
  11. package/dist/{chunk-H6PIVVDN.mjs → chunk-CCZK6LCB.mjs} +38 -25
  12. package/dist/{chunk-JZGINXTN.mjs → chunk-HCCGEIZ2.mjs} +2 -2
  13. package/dist/{chunk-67M7KAH6.mjs → chunk-IWGIYDMZ.mjs} +1 -1
  14. package/dist/{chunk-LFZ37BSX.mjs → chunk-OUSWVNWT.mjs} +1 -1
  15. package/dist/{chunk-HR5CWTLC.mjs → chunk-P2VJYRVY.mjs} +60 -7
  16. package/dist/{chunk-UC3SCMIN.mjs → chunk-PBRXXISQ.mjs} +3 -0
  17. package/dist/{chunk-JU64Y7HM.mjs → chunk-SBL6GN43.mjs} +1 -1
  18. package/dist/{chunk-EBJXPQQO.mjs → chunk-UPKKSUPA.mjs} +2 -2
  19. package/dist/{chunk-TJF5GZSV.mjs → chunk-VOSJBZ6Q.mjs} +1 -1
  20. package/dist/{chunk-PIKHN33N.mjs → chunk-VOYGMAU7.mjs} +9 -1
  21. package/dist/{chunk-H237TXZW.mjs → chunk-WJ67DTD6.mjs} +48 -6
  22. package/dist/{chunk-OQVZBEBY.mjs → chunk-XF2HH5E6.mjs} +4 -61
  23. package/dist/client/index.d.ts +211 -12
  24. package/dist/client/index.mjs +155 -67
  25. package/dist/client/topology.d.ts +55 -7
  26. package/dist/client/topology.mjs +20 -1
  27. package/dist/{client-base-CLWmH5Ln.d.ts → client-base-CmZO0v3m.d.ts} +133 -24
  28. package/dist/codegen/cli.mjs +3 -3
  29. package/dist/codegen/index.d.ts +92 -2
  30. package/dist/codegen/index.mjs +3 -3
  31. package/dist/core/index.d.ts +177 -15
  32. package/dist/core/index.mjs +2481 -2226
  33. package/dist/core/writer-worker.mjs +3 -3
  34. package/dist/database-B5Qv1-cU.d.ts +380 -0
  35. package/dist/driver/better-sqlite3.d.ts +18 -1
  36. package/dist/driver/better-sqlite3.mjs +5 -5
  37. package/dist/driver/bun.d.ts +28 -0
  38. package/dist/driver/expo.d.ts +17 -0
  39. package/dist/driver/node.d.ts +18 -1
  40. package/dist/driver/node.mjs +5 -5
  41. package/dist/driver/wa-sqlite.d.ts +18 -1
  42. package/dist/{errors-Bw5MdNCu.d.ts → errors-Dei4GdBb.d.ts} +80 -7
  43. package/dist/file-migrations/index.d.ts +54 -2
  44. package/dist/file-migrations/index.mjs +3 -3
  45. package/dist/{operation-registry-9DcvxcE5.d.ts → operation-registry-hlbhqu7q.d.ts} +50 -1
  46. package/dist/{primary-wins-DPAm2AKG.d.ts → primary-wins-B0np8JS3.d.ts} +25 -1
  47. package/dist/protocol-rqANt-9Q.d.ts +152 -0
  48. package/dist/query-types-DL3LtPvY.d.ts +95 -0
  49. package/dist/react/index.d.ts +58 -3
  50. package/dist/replication/coordinator/etcd.d.ts +63 -3
  51. package/dist/replication/coordinator/etcd.mjs +82 -46
  52. package/dist/replication/index.d.ts +329 -95
  53. package/dist/replication/index.mjs +256 -141
  54. package/dist/server/index.d.ts +230 -12
  55. package/dist/server/index.mjs +63 -50
  56. package/dist/{server-options-1JHu8pid.d.ts → server-options-Dab_Jvd_.d.ts} +96 -12
  57. package/dist/sirannon-CMhiJa5Y.d.ts +111 -0
  58. package/dist/transport/grpc.d.ts +93 -9
  59. package/dist/transport/grpc.mjs +63 -20
  60. package/dist/transport/memory.d.ts +50 -20
  61. package/dist/transport/memory.mjs +25 -0
  62. package/dist/{types-CL6piSnD.d.ts → types-BCejqzNA.d.ts} +20 -0
  63. package/dist/types-CMBcFPhb.d.ts +336 -0
  64. package/dist/types-CjhxcjhA.d.ts +123 -0
  65. package/dist/types-DyrCiWuc.d.ts +499 -0
  66. package/dist/types-rVZKnKN-.d.ts +591 -0
  67. package/package.json +7 -1
  68. package/dist/baseline-Br77Fnhb.d.ts +0 -6
  69. package/dist/database-BY0L5Q2n.d.ts +0 -172
  70. package/dist/protocol-6KrSq2Hy.d.ts +0 -66
  71. package/dist/sirannon-DaQSyhbJ.d.ts +0 -36
  72. package/dist/types-B7gmEsZW.d.ts +0 -221
  73. package/dist/types-BsVabqSI.d.ts +0 -139
  74. package/dist/types-C_D8IhpO.d.ts +0 -60
  75. package/dist/types-zhnRXrsb.d.ts +0 -384
@@ -0,0 +1,336 @@
1
+ /**
2
+ * What a lease grants: the controller role, or one node's membership session.
3
+ *
4
+ * @public
5
+ */
6
+ type CoordinatorLeaseKind = 'controller' | 'node-session';
7
+ /**
8
+ * Stops a group watch when called.
9
+ *
10
+ * @public
11
+ */
12
+ type CoordinatorWatchDisposer = () => void | Promise<void>;
13
+ /**
14
+ * A time-limited claim one node holds, which lapses unless the node renews it.
15
+ *
16
+ * @public
17
+ */
18
+ interface CoordinatorLease {
19
+ /** Identifier of the lease, which the holder renews and releases it by. */
20
+ id: string;
21
+ /** What the lease grants. */
22
+ kind: CoordinatorLeaseKind;
23
+ /** Cluster the lease belongs to. */
24
+ clusterId: string;
25
+ /** Identifier of the node holding it. */
26
+ holderId: string;
27
+ /** Milliseconds the lease lasts from each renewal. */
28
+ ttlMs: number;
29
+ /** Milliseconds since the Unix epoch, taken when the lease was granted. */
30
+ grantedAtMs: number;
31
+ /** Milliseconds since the Unix epoch, after which the lease lapses. */
32
+ expiresAtMs: number;
33
+ /** Anything else the holder attached. */
34
+ metadata?: Record<string, unknown>;
35
+ }
36
+ /**
37
+ * A node's bid for the controller lease.
38
+ *
39
+ * @public
40
+ */
41
+ interface AcquireControllerLeaseInput {
42
+ /** Cluster the lease covers. */
43
+ clusterId: string;
44
+ /** Identifier the node claims the lease under. */
45
+ holderId: string;
46
+ /** Milliseconds the lease should last. */
47
+ ttlMs: number;
48
+ /** Anything else to record against the lease. */
49
+ metadata?: Record<string, unknown>;
50
+ }
51
+ /**
52
+ * Whether the bid won the controller lease, and who holds it either way.
53
+ *
54
+ * @public
55
+ */
56
+ type AcquireControllerLeaseResult = {
57
+ acquired: true;
58
+ lease: CoordinatorLease;
59
+ } | {
60
+ acquired: false;
61
+ lease: CoordinatorLease | null;
62
+ };
63
+ /**
64
+ * Versions a node publishes so that the group refuses a peer it cannot work with.
65
+ *
66
+ * @public
67
+ */
68
+ interface CoordinatorCompatibilityMetadata {
69
+ /** Version of the package the node runs. */
70
+ packageVersion?: string;
71
+ /** Version of the specification the node implements. */
72
+ specVersion?: string;
73
+ /** Version of the replication protocol the node speaks. */
74
+ protocolVersion?: string;
75
+ }
76
+ /**
77
+ * What a node tells the coordinator about itself when it joins.
78
+ *
79
+ * @public
80
+ */
81
+ interface RegisterNodeSessionInput {
82
+ /** Cluster the node joins. */
83
+ clusterId: string;
84
+ /** Identifier of the node. */
85
+ nodeId: string;
86
+ /** Milliseconds the session lasts from each renewal. */
87
+ ttlMs: number;
88
+ /** Address clients reach this node at. */
89
+ endpoint?: string;
90
+ /** Replication groups the node serves. */
91
+ groupIds?: string[];
92
+ /** Whether the node holds a copy of the data. */
93
+ dataBearing?: boolean;
94
+ /** Whether the node counts towards majority. */
95
+ voting?: boolean;
96
+ /** Versions the node publishes. */
97
+ compatibility?: CoordinatorCompatibilityMetadata;
98
+ /** Anything else to record against the session. */
99
+ metadata?: Record<string, unknown>;
100
+ }
101
+ /**
102
+ * One node's live membership of a cluster, which lapses when its lease does.
103
+ *
104
+ * @public
105
+ */
106
+ interface CoordinatorNodeSession {
107
+ /** Cluster the node belongs to. */
108
+ clusterId: string;
109
+ /** Identifier of the node. */
110
+ nodeId: string;
111
+ /** Lease keeping this session alive. */
112
+ lease: CoordinatorLease;
113
+ /** Address clients reach this node at. */
114
+ endpoint?: string;
115
+ /** Replication groups the node serves. */
116
+ groupIds: string[];
117
+ /** Whether the node holds a copy of the data. */
118
+ dataBearing: boolean;
119
+ /** Whether the node counts towards majority. */
120
+ voting: boolean;
121
+ /** Versions the node published. */
122
+ compatibility?: CoordinatorCompatibilityMetadata;
123
+ /** Anything else recorded against the session. */
124
+ metadata?: Record<string, unknown>;
125
+ }
126
+ /**
127
+ * The node a group currently names as its primary.
128
+ *
129
+ * @public
130
+ */
131
+ interface CoordinatorPrimary {
132
+ /** Identifier of the primary. */
133
+ nodeId: string;
134
+ /** Address clients reach it at. */
135
+ endpoint?: string;
136
+ }
137
+ /**
138
+ * The group's shared record of who writes, who is in sync, and how far the
139
+ * data is durable. Failover reads and advances it.
140
+ *
141
+ * @public
142
+ */
143
+ interface ReplicationGroupState {
144
+ /** Cluster the group belongs to. */
145
+ clusterId: string;
146
+ /** Identifier of the group. */
147
+ groupId: string;
148
+ /** Nodes that count towards majority. */
149
+ votingDataBearingNodeIds: string[];
150
+ /** The node currently named primary, or null when the group has none. */
151
+ currentPrimary: CoordinatorPrimary | null;
152
+ /** Term the current primary holds, which rises with each promotion. */
153
+ primaryTerm: bigint;
154
+ /** Change-log position a majority of voting nodes has durably stored. */
155
+ durabilityPointSeq: bigint;
156
+ /** Nodes the group counts as in sync. */
157
+ inSyncNodeIds: string[];
158
+ /** Nodes being taken out of service. */
159
+ drainingNodeIds: string[];
160
+ /** Nodes being rebuilt. */
161
+ repairingNodeIds: string[];
162
+ /** Nodes the group has quarantined. */
163
+ faultedNodeIds: string[];
164
+ /** Versions the group requires of its members. */
165
+ compatibility?: CoordinatorCompatibilityMetadata;
166
+ /** Milliseconds since the Unix epoch, taken at the last change to this state. */
167
+ updatedAtMs: number;
168
+ }
169
+ /**
170
+ * The group state to write, which seeds a new group or replaces an existing one.
171
+ *
172
+ * @public
173
+ */
174
+ interface SetReplicationGroupStateInput {
175
+ /** Cluster the group belongs to. */
176
+ clusterId: string;
177
+ /** Identifier of the group. */
178
+ groupId: string;
179
+ /** Nodes that count towards majority. */
180
+ votingDataBearingNodeIds: string[];
181
+ /** The node to name primary, or null to leave the group without one. */
182
+ currentPrimary?: CoordinatorPrimary | null;
183
+ /** Term to record for that primary. */
184
+ primaryTerm?: bigint;
185
+ /** Change-log position a majority has durably stored. */
186
+ durabilityPointSeq?: bigint;
187
+ /** Nodes to record as in sync. */
188
+ inSyncNodeIds?: string[];
189
+ /** Nodes to record as being taken out of service. */
190
+ drainingNodeIds?: string[];
191
+ /** Nodes to record as being rebuilt. */
192
+ repairingNodeIds?: string[];
193
+ /** Nodes to record as quarantined. */
194
+ faultedNodeIds?: string[];
195
+ /** Versions the group requires of its members. */
196
+ compatibility?: CoordinatorCompatibilityMetadata;
197
+ }
198
+ /**
199
+ * Promotes a node only while the group is still at the term the caller read,
200
+ * so two candidates cannot both promote themselves.
201
+ *
202
+ * @public
203
+ */
204
+ interface CompareAndAdvancePrimaryTermInput {
205
+ /** Cluster the group belongs to. */
206
+ clusterId: string;
207
+ /** Identifier of the group. */
208
+ groupId: string;
209
+ /** Term the caller last read. The promotion fails when the group has moved past it. */
210
+ expectedPrimaryTerm: bigint;
211
+ /** The node to promote. */
212
+ nextPrimary: CoordinatorPrimary;
213
+ }
214
+ /**
215
+ * Whether the promotion took effect, and the group state that resulted.
216
+ *
217
+ * @public
218
+ */
219
+ interface CompareAndAdvancePrimaryTermResult {
220
+ /** True when the group moved to the next term under the named primary. */
221
+ advanced: boolean;
222
+ /** The group state as it now stands, or null when the group is absent. */
223
+ state: ReplicationGroupState | null;
224
+ }
225
+ /**
226
+ * Replaces the group's in-sync set, and optionally moves its durability point.
227
+ *
228
+ * @public
229
+ */
230
+ interface UpdateInSyncSetInput {
231
+ /** Cluster the group belongs to. */
232
+ clusterId: string;
233
+ /** Identifier of the group. */
234
+ groupId: string;
235
+ /** Nodes to record as in sync. */
236
+ inSyncNodeIds: string[];
237
+ /** Change-log position a majority has durably stored. */
238
+ durabilityPointSeq?: bigint;
239
+ }
240
+ /**
241
+ * Adds one caught-up node to the in-sync set, naming the progress that earned it.
242
+ *
243
+ * @public
244
+ */
245
+ interface AdmitNodeToInSyncSetInput {
246
+ /** Cluster the group belongs to. */
247
+ clusterId: string;
248
+ /** Identifier of the group. */
249
+ groupId: string;
250
+ /** Node to admit. */
251
+ nodeId: string;
252
+ /** Node whose changes it has applied. */
253
+ sourceNodeId: string;
254
+ /** Change-log position it has applied up to. */
255
+ appliedSeq: bigint;
256
+ }
257
+ /**
258
+ * Marks one node as being taken out of service, rebuilt, or quarantined.
259
+ *
260
+ * @public
261
+ */
262
+ interface UpdateNodeMaintenanceInput {
263
+ /** Cluster the group belongs to. */
264
+ clusterId: string;
265
+ /** Identifier of the group. */
266
+ groupId: string;
267
+ /** Node whose state changes. */
268
+ nodeId: string;
269
+ /** Whether the node is being taken out of service. */
270
+ draining?: boolean;
271
+ /** Whether the node is being rebuilt. */
272
+ repairing?: boolean;
273
+ /** Whether the group quarantines the node. */
274
+ faulted?: boolean;
275
+ }
276
+ /**
277
+ * Asks the coordinator to promote whichever in-sync replica is safe to write.
278
+ *
279
+ * @public
280
+ */
281
+ interface PromoteEligibleReplicaInput {
282
+ /** Cluster the group belongs to. */
283
+ clusterId: string;
284
+ /** Identifier of the group. */
285
+ groupId: string;
286
+ /** Nodes to pass over, such as the primary that has just failed. */
287
+ excludeNodeIds?: string[];
288
+ }
289
+ /**
290
+ * Receives the group state each time it changes.
291
+ *
292
+ * @public
293
+ */
294
+ type ReplicationGroupWatcher = (state: ReplicationGroupState) => void;
295
+ /**
296
+ * Stores primary authority, node sessions, group state, and the in-sync set
297
+ * outside the database nodes so that failover has a source of truth no single node
298
+ * owns. The package includes an etcd adapter; build your own to store this
299
+ * elsewhere.
300
+ *
301
+ * @public
302
+ */
303
+ interface ClusterCoordinator {
304
+ /** Bids for the controller lease, and reports who holds it. */
305
+ tryAcquireControllerLease(input: AcquireControllerLeaseInput): Promise<AcquireControllerLeaseResult>;
306
+ /** Extends a lease, and reports false once it has already lapsed. */
307
+ renewLease(leaseId: string, ttlMs: number): Promise<boolean>;
308
+ /** Gives up a lease at once instead of waiting for it to lapse. */
309
+ releaseLease(leaseId: string): Promise<boolean>;
310
+ /** Records one node as a live member of the cluster. */
311
+ registerNodeSession(input: RegisterNodeSessionInput): Promise<CoordinatorNodeSession>;
312
+ /** Reads one node's session, and returns null once its lease has lapsed. */
313
+ getLiveNodeSession(clusterId: string, nodeId: string): Promise<CoordinatorNodeSession | null>;
314
+ /** Ends one node's membership at once. */
315
+ deregisterNodeSession(clusterId: string, nodeId: string): Promise<void>;
316
+ /** Writes the group's state, which seeds a new group or replaces an existing one. */
317
+ setReplicationGroupState(input: SetReplicationGroupStateInput): Promise<ReplicationGroupState>;
318
+ /** Reads the group's state, and returns null when the group is absent. */
319
+ getReplicationGroupState(clusterId: string, groupId: string): Promise<ReplicationGroupState | null>;
320
+ /** Calls back on each change to the group's state, and returns a function that stops the watch. */
321
+ watchReplicationGroup(clusterId: string, groupId: string, watcher: ReplicationGroupWatcher): CoordinatorWatchDisposer | Promise<CoordinatorWatchDisposer>;
322
+ /** Promotes a node only while the group is still at the term the caller read. */
323
+ compareAndAdvancePrimaryTerm(input: CompareAndAdvancePrimaryTermInput): Promise<CompareAndAdvancePrimaryTermResult>;
324
+ /** Replaces the group's in-sync set, and optionally moves its durability point. */
325
+ updateInSyncSet(input: UpdateInSyncSetInput): Promise<ReplicationGroupState | null>;
326
+ /** Adds one caught-up node to the in-sync set. */
327
+ admitNodeToInSyncSet(input: AdmitNodeToInSyncSetInput): Promise<ReplicationGroupState | null>;
328
+ /** Marks one node as being taken out of service, rebuilt, or quarantined. */
329
+ updateNodeMaintenance(input: UpdateNodeMaintenanceInput): Promise<ReplicationGroupState | null>;
330
+ /** Promotes whichever in-sync replica is safe to write. */
331
+ promoteEligibleReplica(input: PromoteEligibleReplicaInput): Promise<ReplicationGroupState>;
332
+ /** Releases whatever the coordinator holds open. */
333
+ close?(): Promise<void>;
334
+ }
335
+
336
+ export type { AcquireControllerLeaseInput as A, ClusterCoordinator as C, PromoteEligibleReplicaInput as P, RegisterNodeSessionInput as R, SetReplicationGroupStateInput as S, UpdateInSyncSetInput as U, AcquireControllerLeaseResult as a, CoordinatorNodeSession as b, ReplicationGroupState as c, ReplicationGroupWatcher as d, CoordinatorWatchDisposer as e, CompareAndAdvancePrimaryTermInput as f, CompareAndAdvancePrimaryTermResult as g, AdmitNodeToInSyncSetInput as h, UpdateNodeMaintenanceInput as i, CoordinatorCompatibilityMetadata as j, CoordinatorLease as k, CoordinatorPrimary as l };
@@ -0,0 +1,123 @@
1
+ /** A hybrid logical clock reading, decoded into its three parts.
2
+ * @public
3
+ */
4
+ interface HLCTimestamp {
5
+ /** Wall-clock milliseconds since the Unix epoch. */
6
+ wallMs: number;
7
+ /** Counter that orders events sharing one wall-clock millisecond. */
8
+ logical: number;
9
+ /** Identifier of the node that took the reading, which breaks remaining ties. */
10
+ nodeId: string;
11
+ }
12
+ /** One replicated row change, or one replicated schema statement.
13
+ * @public
14
+ */
15
+ interface ReplicationChange {
16
+ /** Table the change belongs to. */
17
+ table: string;
18
+ /** What the change does to the row, or 'ddl' for a schema statement. */
19
+ operation: 'insert' | 'update' | 'delete' | 'ddl';
20
+ /** Primary key of the changed row, encoded as a string. */
21
+ rowId: string;
22
+ /** Primary key of the changed row, by column. */
23
+ primaryKey: Record<string, unknown>;
24
+ /** Hybrid logical clock stamp the authoring node gave this change. */
25
+ hlc: string;
26
+ /** Identifier of the transaction that produced this change. */
27
+ txId: string;
28
+ /** Identifier of the node that authored the change. */
29
+ nodeId: string;
30
+ /** The row after the change, or null for a delete. */
31
+ newData: Record<string, unknown> | null;
32
+ /** The row before the change, or null for an insert. */
33
+ oldData: Record<string, unknown> | null;
34
+ /** The schema statement to replay, present only when the operation is 'ddl'. */
35
+ ddlStatement?: string;
36
+ }
37
+ /** A checksummed run of changes one node sends to another.
38
+ * @public
39
+ */
40
+ interface ReplicationBatch {
41
+ /** Identifier of the node that sent the batch. */
42
+ sourceNodeId: string;
43
+ /** Identifier of this batch, which the receiver acknowledges. */
44
+ batchId: string;
45
+ /** Change-log position of the first change in the batch. */
46
+ fromSeq: bigint;
47
+ /** Change-log position of the last change in the batch. */
48
+ toSeq: bigint;
49
+ /** Lowest and highest hybrid logical clock stamps the batch carries. */
50
+ hlcRange: {
51
+ min: string;
52
+ max: string;
53
+ };
54
+ /** The changes themselves, in ascending order. */
55
+ changes: ReplicationChange[];
56
+ /** Checksum of the changes, which the receiver verifies before it applies them. */
57
+ checksum: string;
58
+ /** Identifier of the replication group the sender belongs to. */
59
+ groupId?: string;
60
+ /** Primary term the sender held when it built the batch. */
61
+ primaryTerm?: bigint;
62
+ }
63
+ /** The local and incoming versions of one row, handed to a conflict resolver.
64
+ * @public
65
+ */
66
+ interface ConflictContext {
67
+ /** Table the row belongs to. */
68
+ table: string;
69
+ /** Primary key of the row, encoded as a string. */
70
+ rowId: string;
71
+ /** The change already applied locally, or null when the receiver recorded none. */
72
+ localChange: ReplicationChange | null;
73
+ /** The change that arrived from the sending node. */
74
+ remoteChange: ReplicationChange;
75
+ /** Hybrid logical clock stamp of the local version, or null when there is none. */
76
+ localHlc: string | null;
77
+ /** Hybrid logical clock stamp of the incoming version. */
78
+ remoteHlc: string;
79
+ }
80
+ /** What a conflict resolver decided to do with one row.
81
+ * @public
82
+ */
83
+ interface ConflictResolution {
84
+ /** Whether to take the incoming row, keep the local one, or write the merged row. */
85
+ action: 'accept_remote' | 'keep_local' | 'merge';
86
+ /** The row to write, required when the action is 'merge'. */
87
+ mergedData?: Record<string, unknown>;
88
+ }
89
+ /** Resolves which version of a row wins when a receiver already holds that row.
90
+ * @public
91
+ */
92
+ interface ConflictResolver {
93
+ /** Chooses between the local and the incoming version of one row. */
94
+ resolve(ctx: ConflictContext): ConflictResolution | Promise<ConflictResolution>;
95
+ }
96
+ /** What applying one batch of changes did.
97
+ * @public
98
+ */
99
+ interface ApplyResult {
100
+ /** Number of changes the receiver wrote. */
101
+ applied: number;
102
+ /** Number of changes the receiver had already seen. */
103
+ skipped: number;
104
+ /** Number of rows that went through a conflict resolver. */
105
+ conflicts: number;
106
+ /** Tables the batch dropped, named so callers can stop watching them. */
107
+ droppedTables: string[];
108
+ }
109
+ /** What a source node reports about one table at the end of first sync, so the joiner can verify it.
110
+ * @public
111
+ */
112
+ interface SyncTableManifest {
113
+ /** Name of the table. */
114
+ table: string;
115
+ /** Number of rows the source held in that table. */
116
+ rowCount: number;
117
+ /** Hash of every primary key in the table, in order. */
118
+ pkHash?: string;
119
+ /** Chained digest of the batches the source streamed for this table. */
120
+ batchDigest?: string;
121
+ }
122
+
123
+ export type { ApplyResult as A, ConflictResolver as C, HLCTimestamp as H, ReplicationBatch as R, SyncTableManifest as S, ConflictContext as a, ConflictResolution as b, ReplicationChange as c };