@quereus/sync 4.4.0 → 4.4.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.
- package/README.md +19 -1
- package/dist/src/create-sync-module.d.ts +11 -1
- package/dist/src/create-sync-module.d.ts.map +1 -1
- package/dist/src/create-sync-module.js +2 -2
- package/dist/src/create-sync-module.js.map +1 -1
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/metadata/change-log.d.ts +39 -3
- package/dist/src/metadata/change-log.d.ts.map +1 -1
- package/dist/src/metadata/change-log.js +43 -8
- package/dist/src/metadata/change-log.js.map +1 -1
- package/dist/src/metadata/column-version.d.ts +62 -9
- package/dist/src/metadata/column-version.d.ts.map +1 -1
- package/dist/src/metadata/column-version.js +79 -25
- package/dist/src/metadata/column-version.js.map +1 -1
- package/dist/src/metadata/index.d.ts +1 -0
- package/dist/src/metadata/index.d.ts.map +1 -1
- package/dist/src/metadata/index.js +1 -0
- package/dist/src/metadata/index.js.map +1 -1
- package/dist/src/metadata/keys.d.ts +88 -22
- package/dist/src/metadata/keys.d.ts.map +1 -1
- package/dist/src/metadata/keys.js +134 -77
- package/dist/src/metadata/keys.js.map +1 -1
- package/dist/src/metadata/pk-identity.d.ts +60 -0
- package/dist/src/metadata/pk-identity.d.ts.map +1 -0
- package/dist/src/metadata/pk-identity.js +94 -0
- package/dist/src/metadata/pk-identity.js.map +1 -0
- package/dist/src/metadata/tombstones.d.ts +41 -11
- package/dist/src/metadata/tombstones.d.ts.map +1 -1
- package/dist/src/metadata/tombstones.js +58 -33
- package/dist/src/metadata/tombstones.js.map +1 -1
- package/dist/src/sync/change-applicator.d.ts +30 -1
- package/dist/src/sync/change-applicator.d.ts.map +1 -1
- package/dist/src/sync/change-applicator.js +161 -40
- package/dist/src/sync/change-applicator.js.map +1 -1
- package/dist/src/sync/maintenance.d.ts +70 -0
- package/dist/src/sync/maintenance.d.ts.map +1 -0
- package/dist/src/sync/maintenance.js +84 -0
- package/dist/src/sync/maintenance.js.map +1 -0
- package/dist/src/sync/protocol.d.ts +61 -10
- package/dist/src/sync/protocol.d.ts.map +1 -1
- package/dist/src/sync/protocol.js +15 -0
- package/dist/src/sync/protocol.js.map +1 -1
- package/dist/src/sync/snapshot-identity.d.ts +62 -0
- package/dist/src/sync/snapshot-identity.d.ts.map +1 -0
- package/dist/src/sync/snapshot-identity.js +88 -0
- package/dist/src/sync/snapshot-identity.js.map +1 -0
- package/dist/src/sync/snapshot-stream.d.ts +8 -1
- package/dist/src/sync/snapshot-stream.d.ts.map +1 -1
- package/dist/src/sync/snapshot-stream.js +166 -67
- package/dist/src/sync/snapshot-stream.js.map +1 -1
- package/dist/src/sync/snapshot.d.ts +1 -1
- package/dist/src/sync/snapshot.d.ts.map +1 -1
- package/dist/src/sync/snapshot.js +75 -44
- package/dist/src/sync/snapshot.js.map +1 -1
- package/dist/src/sync/staged-transaction-metadata.d.ts +75 -0
- package/dist/src/sync/staged-transaction-metadata.d.ts.map +1 -0
- package/dist/src/sync/staged-transaction-metadata.js +100 -0
- package/dist/src/sync/staged-transaction-metadata.js.map +1 -0
- package/dist/src/sync/store-adapter.d.ts +10 -4
- package/dist/src/sync/store-adapter.d.ts.map +1 -1
- package/dist/src/sync/store-adapter.js +244 -21
- package/dist/src/sync/store-adapter.js.map +1 -1
- package/dist/src/sync/sync-context.d.ts +54 -2
- package/dist/src/sync/sync-context.d.ts.map +1 -1
- package/dist/src/sync/sync-context.js +66 -0
- package/dist/src/sync/sync-context.js.map +1 -1
- package/dist/src/sync/sync-manager-impl.d.ts +70 -4
- package/dist/src/sync/sync-manager-impl.d.ts.map +1 -1
- package/dist/src/sync/sync-manager-impl.js +206 -36
- package/dist/src/sync/sync-manager-impl.js.map +1 -1
- package/dist/src/sync/wire.d.ts +47 -6
- package/dist/src/sync/wire.d.ts.map +1 -1
- package/dist/src/sync/wire.js +62 -11
- package/dist/src/sync/wire.js.map +1 -1
- package/package.json +6 -6
|
@@ -10,11 +10,17 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Per `applyToStore(dataChanges, schemaChanges, options)` invocation:
|
|
12
12
|
* 1. Schema changes execute first via `db.exec` (DDL before DML), with the
|
|
13
|
-
* resulting module schema events pre-marked remote.
|
|
13
|
+
* resulting module schema events pre-marked remote. Replicated DDL is
|
|
14
|
+
* applied IDEMPOTENTLY: an object already in the migration's wanted state
|
|
15
|
+
* with a matching definition is counted applied without re-exec'ing, so two
|
|
16
|
+
* peers that independently created the same table converge instead of the
|
|
17
|
+
* receiver failing "already exists" on every sync (see
|
|
18
|
+
* {@link decideSchemaChange}).
|
|
14
19
|
* 2. Data changes are grouped per table, then per row; each row group
|
|
15
|
-
* collapses to ONE `ExternalRowOp`
|
|
16
|
-
*
|
|
17
|
-
*
|
|
20
|
+
* collapses to ONE `ExternalRowOp` — the group's NET effect in arrival
|
|
21
|
+
* order (a delete resets the row to absent and later column updates
|
|
22
|
+
* rebuild it from PK+nulls; updates with no later delete merge onto the
|
|
23
|
+
* pre-read existing row — UPSERT semantics; see {@link buildRowOp}).
|
|
18
24
|
* 3. `StoreTable.applyExternalRowChanges(ops)` applies the table's ops to
|
|
19
25
|
* committed storage and returns the EFFECTIVE changes (no-ops — absent
|
|
20
26
|
* delete, value-identical upsert — are suppressed: no storage write, no
|
|
@@ -98,7 +104,8 @@
|
|
|
98
104
|
* MV/capture state from the already-committed storage rows; recoverable via
|
|
99
105
|
* MV refresh).
|
|
100
106
|
*/
|
|
101
|
-
import { compareSqlValues } from '@quereus/quereus';
|
|
107
|
+
import { compareSqlValues, generateIndexDDL, generateTableDDL } from '@quereus/quereus';
|
|
108
|
+
import { makePkIdentityEncoder } from '../metadata/pk-identity.js';
|
|
102
109
|
import { toError } from './sync-context.js';
|
|
103
110
|
/**
|
|
104
111
|
* Creates an ApplyToStoreCallback for applying remote sync changes.
|
|
@@ -158,8 +165,15 @@ export function createStoreAdapter(options) {
|
|
|
158
165
|
// One ExternalRowOp per row group: multiple same-row changes collapse
|
|
159
166
|
// to a single effective op, so the seam's same-row before-image
|
|
160
167
|
// chaining rule is satisfied trivially (oldRow = true pre-batch image).
|
|
168
|
+
// Rows group by pk IDENTITY (key collation + semantic transform), so two
|
|
169
|
+
// spellings of one row ('apple'/'APPLE' under nocase) collapse to ONE op
|
|
170
|
+
// — matching how the store itself keys them.
|
|
171
|
+
// NOTE: resolves the keying fresh per table per apply invocation; if apply
|
|
172
|
+
// batches ever get hot enough for this to show up, cache per TableSchema
|
|
173
|
+
// object like metadata/pk-identity.ts's resolver does.
|
|
174
|
+
const pkIdentity = makePkIdentityEncoder(table.getSchema(), db.getKeyNormalizerResolver());
|
|
161
175
|
const ops = [];
|
|
162
|
-
for (const rowChanges of groupChangesByRow(tableChanges).values()) {
|
|
176
|
+
for (const rowChanges of groupChangesByRow(tableChanges, pkIdentity).values()) {
|
|
163
177
|
ops.push(await buildRowOp(table, rowChanges));
|
|
164
178
|
}
|
|
165
179
|
const effective = await table.applyExternalRowChanges(ops);
|
|
@@ -241,7 +255,7 @@ async function finalizeBootstrap(db, options) {
|
|
|
241
255
|
* grouped change (never re-split the key), so today the only cost is a
|
|
242
256
|
* misgrouped write when both dotted-schema tables exist. If dotted schema names
|
|
243
257
|
* ever become reachable, key on a delimiter that identifiers cannot contain
|
|
244
|
-
* (e.g. length-prefixed, or
|
|
258
|
+
* (e.g. length-prefixed, or a NUL byte).
|
|
245
259
|
*/
|
|
246
260
|
function groupChangesByTable(changes) {
|
|
247
261
|
const grouped = new Map();
|
|
@@ -258,12 +272,15 @@ function groupChangesByTable(changes) {
|
|
|
258
272
|
return grouped;
|
|
259
273
|
}
|
|
260
274
|
/**
|
|
261
|
-
* Group data changes by row (
|
|
275
|
+
* Group one table's data changes by row, keyed on the pk IDENTITY (the caller's
|
|
276
|
+
* `pkIdentity` encoder — key collation + semantic transform), so all spellings
|
|
277
|
+
* of one row land in one group. Only ever called with a single table's changes,
|
|
278
|
+
* so the identity alone is a sufficient key.
|
|
262
279
|
*/
|
|
263
|
-
function groupChangesByRow(changes) {
|
|
280
|
+
function groupChangesByRow(changes, pkIdentity) {
|
|
264
281
|
const grouped = new Map();
|
|
265
282
|
for (const change of changes) {
|
|
266
|
-
const rowKey =
|
|
283
|
+
const rowKey = pkIdentity(change.pk);
|
|
267
284
|
const existing = grouped.get(rowKey);
|
|
268
285
|
if (existing) {
|
|
269
286
|
existing.push(change);
|
|
@@ -275,12 +292,190 @@ function groupChangesByRow(changes) {
|
|
|
275
292
|
return grouped;
|
|
276
293
|
}
|
|
277
294
|
/**
|
|
278
|
-
*
|
|
295
|
+
* Normalize a DDL string for definition comparison: trim, drop a trailing `;`,
|
|
296
|
+
* collapse whitespace runs to a single space, lowercase.
|
|
297
|
+
*
|
|
298
|
+
* Case-insensitive is deliberate — Quereus identifiers are already
|
|
299
|
+
* case-insensitive (`SchemaManager.getTable` lowercases), and a peer whose table
|
|
300
|
+
* was created through a different module may emit different keyword casing.
|
|
301
|
+
*
|
|
302
|
+
* NOTE: the whitespace collapse and the lowercase both reach inside string
|
|
303
|
+
* literals, so two definitions differing ONLY inside a literal (e.g.
|
|
304
|
+
* `default 'a b'` vs `default 'a b'`, or `default 'X'` vs `default 'x'`) compare
|
|
305
|
+
* equal and the duplicate create is treated as converged. Harmless for the shapes
|
|
306
|
+
* canonical DDL emits today; if literal-sensitive column defaults ever matter
|
|
307
|
+
* here, compare the parsed schemas instead of their rendered strings.
|
|
308
|
+
*/
|
|
309
|
+
function normalizeDDL(ddl) {
|
|
310
|
+
// Strip the trailing `;` (with any whitespace after it) BEFORE collapsing, then
|
|
311
|
+
// trim again — collapsing first would leave the `;`-adjacent space behind.
|
|
312
|
+
return ddl.replace(/;\s*$/, '').replace(/\s+/g, ' ').trim().toLowerCase();
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Locate the table owning `indexName` in `schemaName`, case-insensitively.
|
|
316
|
+
*
|
|
317
|
+
* There is no direct index accessor on the schema manager, so this mirrors the
|
|
318
|
+
* owner scan `SchemaManager.dropIndex` performs.
|
|
319
|
+
*
|
|
320
|
+
* NOTE: first-match is unambiguous only because `SchemaManager.createIndex`
|
|
321
|
+
* rejects an index name already taken by a user index elsewhere in the same
|
|
322
|
+
* schema. A replicated `drop index "main"."idx"` carries no table name (the
|
|
323
|
+
* DROP INDEX grammar has no slot for one), so without that invariant each
|
|
324
|
+
* receiver would resolve the owner by its own table-registration order and two
|
|
325
|
+
* devices could drop different indexes while both believing they converged.
|
|
326
|
+
*/
|
|
327
|
+
function findIndexOwner(db, schemaName, indexName) {
|
|
328
|
+
const schema = db.schemaManager.getSchema(schemaName);
|
|
329
|
+
if (!schema)
|
|
330
|
+
return undefined;
|
|
331
|
+
const lowerIndexName = indexName.toLowerCase();
|
|
332
|
+
for (const table of schema.getAllTables()) {
|
|
333
|
+
const index = table.indexes?.find(idx => idx.name.toLowerCase() === lowerIndexName);
|
|
334
|
+
if (index)
|
|
335
|
+
return { table, index };
|
|
336
|
+
}
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* The object named by the migration already exists locally: converge silently if
|
|
341
|
+
* its definition matches the replicated one, otherwise throw a conflict naming
|
|
342
|
+
* both definitions.
|
|
343
|
+
*
|
|
344
|
+
* NOTE: a genuinely DIVERGENT concurrent `create_table` (same name, different
|
|
345
|
+
* shape on two peers) has no automatic convergence path — this throw aborts the
|
|
346
|
+
* batch's metadata commit, so the batch re-resolves and re-fails until an
|
|
347
|
+
* operator intervenes. Resolving it automatically would need last-writer-wins
|
|
348
|
+
* over schema definitions (apply the higher-HLC shape as a migration, rewriting
|
|
349
|
+
* the local table), which is a much larger change. If divergent concurrent
|
|
350
|
+
* creates start showing up in practice, that is the work to do.
|
|
351
|
+
*/
|
|
352
|
+
function assertDefinitionMatches(change, localDDL) {
|
|
353
|
+
if (normalizeDDL(localDDL) === normalizeDDL(change.ddl))
|
|
354
|
+
return;
|
|
355
|
+
throw new Error(`Schema conflict applying remote ${change.type} for ${change.schema}.${change.table}: ` +
|
|
356
|
+
`a different definition already exists locally.\n` +
|
|
357
|
+
` local: ${localDDL}\n` +
|
|
358
|
+
` remote: ${change.ddl}`);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Decide whether a replicated DDL statement still needs to run. Never called
|
|
362
|
+
* with a blank `ddl` — {@link applySchemaChange} short-circuits that first.
|
|
363
|
+
*
|
|
364
|
+
* Replication delivers a migration to peers that may already be in its wanted
|
|
365
|
+
* state — two offline peers can each `create table orders`, and whichever
|
|
366
|
+
* migration wins the HLC comparison is then admitted at a peer that already has
|
|
367
|
+
* the table. Re-exec'ing raw DDL there throws ("Table main.orders already
|
|
368
|
+
* exists"), which aborts the whole admission unit and permanently blocks that
|
|
369
|
+
* peer's metadata commit. So decide first, and only execute when the object is
|
|
370
|
+
* NOT already in the wanted state.
|
|
371
|
+
*
|
|
372
|
+
* Throws on a same-name/different-definition collision — silently keeping the
|
|
373
|
+
* local shape and committing the metadata would record "converged" for a
|
|
374
|
+
* divergence that is not converged (see {@link assertDefinitionMatches}).
|
|
375
|
+
*
|
|
376
|
+
* NOTE: presence is read from the in-memory catalog (`db.schemaManager`), which
|
|
377
|
+
* is assumed to reflect what is persisted — true once a database has finished
|
|
378
|
+
* `rehydrateCatalog`. If a peer ever drives sync against a half-rehydrated
|
|
379
|
+
* catalog, a table present in storage but absent from the catalog decides
|
|
380
|
+
* `execute` and the underlying "already exists" throw returns.
|
|
381
|
+
*/
|
|
382
|
+
function decideSchemaChange(db, change) {
|
|
383
|
+
switch (change.type) {
|
|
384
|
+
case 'create_table': {
|
|
385
|
+
const local = db.schemaManager.getTable(change.schema, change.table);
|
|
386
|
+
if (!local)
|
|
387
|
+
return 'execute';
|
|
388
|
+
// Both sides render through `generateTableDDL` with no `db` argument, so
|
|
389
|
+
// the strings are fully qualified and session-independent — directly
|
|
390
|
+
// comparable against the DDL the origin put on the wire.
|
|
391
|
+
// NOTE: that symmetry is a property of the store module (it is the only
|
|
392
|
+
// module that puts DDL on the wire today). A second DDL-emitting module
|
|
393
|
+
// rendering the same table some other way would be reported as a conflict
|
|
394
|
+
// rather than converging; the comparison would then need to be over parsed
|
|
395
|
+
// schemas, not rendered strings.
|
|
396
|
+
assertDefinitionMatches(change, generateTableDDL(local));
|
|
397
|
+
return 'already-applied';
|
|
398
|
+
}
|
|
399
|
+
case 'drop_table':
|
|
400
|
+
return db.schemaManager.getTable(change.schema, change.table) ? 'execute' : 'already-applied';
|
|
401
|
+
case 'add_index': {
|
|
402
|
+
// For an index migration `change.table` holds the INDEX name, not the
|
|
403
|
+
// table name (see `mapSchemaMigrationType` / `recordSchemaMigration`).
|
|
404
|
+
const owner = findIndexOwner(db, change.schema, change.table);
|
|
405
|
+
if (!owner)
|
|
406
|
+
return 'execute';
|
|
407
|
+
assertDefinitionMatches(change, generateIndexDDL(owner.index, owner.table));
|
|
408
|
+
return 'already-applied';
|
|
409
|
+
}
|
|
410
|
+
case 'drop_index':
|
|
411
|
+
return findIndexOwner(db, change.schema, change.table) ? 'execute' : 'already-applied';
|
|
412
|
+
default:
|
|
413
|
+
// Column-level migrations (add_column / drop_column / alter_column) carry
|
|
414
|
+
// no object-lifecycle state to compare; run them as before.
|
|
415
|
+
return 'execute';
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* The module schema-event signature the migration's DDL will produce — the exact
|
|
420
|
+
* inverse of `mapSchemaMigrationType` (sync-manager-impl.ts), which is what
|
|
421
|
+
* recorded the migration on the origin in the first place.
|
|
422
|
+
*
|
|
423
|
+
* Keeping the two inverse is load-bearing: the signature is what pre-marks the
|
|
424
|
+
* emitted event remote, and a signature that never matches means the receiver
|
|
425
|
+
* records the replicated DDL as its OWN local migration and broadcasts it back
|
|
426
|
+
* out. Deriving it from the migration type by string-shape (`startsWith('drop')`,
|
|
427
|
+
* `includes('table')`) does not survive the `add_index` / `*_column` names, so
|
|
428
|
+
* map explicitly.
|
|
429
|
+
*/
|
|
430
|
+
function schemaEventSignature(type) {
|
|
431
|
+
switch (type) {
|
|
432
|
+
case 'create_table': return { type: 'create', objectType: 'table' };
|
|
433
|
+
case 'drop_table': return { type: 'drop', objectType: 'table' };
|
|
434
|
+
case 'add_index': return { type: 'create', objectType: 'index' };
|
|
435
|
+
case 'drop_index': return { type: 'drop', objectType: 'index' };
|
|
436
|
+
// Column-level migrations replay as an ALTER of the owning table — matching
|
|
437
|
+
// the `'table' alter → alter_column` direction of mapSchemaMigrationType.
|
|
438
|
+
case 'add_column':
|
|
439
|
+
case 'drop_column':
|
|
440
|
+
case 'alter_column':
|
|
441
|
+
return { type: 'alter', objectType: 'table' };
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Apply one schema change (DDL) to the database, idempotently.
|
|
279
446
|
*/
|
|
280
447
|
async function applySchemaChange(db, events, change, _options) {
|
|
281
|
-
//
|
|
282
|
-
|
|
283
|
-
|
|
448
|
+
// A blank `ddl` still reaches here: the four object-lifecycle migrations
|
|
449
|
+
// (create/drop table, add/drop index) now carry canonical text, but the
|
|
450
|
+
// `*_column` migrations do not, and a peer on an older build still sends blank
|
|
451
|
+
// drop/index migrations. Such a migration runs nothing, so it also EMITS
|
|
452
|
+
// nothing — registering a remote-event expectation for it would leave that
|
|
453
|
+
// expectation pending forever (the emitter refcounts expectations and never
|
|
454
|
+
// expires them), and the next genuine LOCAL DDL of the same signature would be
|
|
455
|
+
// consumed by it, marked remote, and dropped from the SyncManager's local-fact
|
|
456
|
+
// capture — silently never replicated.
|
|
457
|
+
if (change.ddl.trim() === '') {
|
|
458
|
+
// Deliberately NOT scoped to `alter_column`, unlike the origin-side warning in
|
|
459
|
+
// `recordSchemaMigration` (sync-manager-impl.ts): a peer on an older build can
|
|
460
|
+
// still send a blank drop/index migration, and that is equally worth hearing.
|
|
461
|
+
// The migration still counts applied — it just runs nothing — so an operator
|
|
462
|
+
// watching this peer needs to see that a schema change arrived and did nothing.
|
|
463
|
+
// NOTE: this returns before the `already-applied` check below, so a peer
|
|
464
|
+
// re-bootstrapping from zero re-warns for every blank migration it replays.
|
|
465
|
+
// Fine while alterations are rare; if it ever floods a log, dedupe per
|
|
466
|
+
// (schema, table, type) for the duration of one apply.
|
|
467
|
+
console.warn(`[Sync] Received ${change.type} for ${change.schema}.${change.table} with no DDL — `
|
|
468
|
+
+ `not applied; this peer's schema is unchanged`);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
// Decide BEFORE registering the remote-event expectation, for the same reason:
|
|
472
|
+
// an expectation for DDL that is then not executed would linger and mis-mark a
|
|
473
|
+
// later genuine LOCAL DDL of the same signature as remote.
|
|
474
|
+
if (decideSchemaChange(db, change) === 'already-applied') {
|
|
475
|
+
console.debug(`[Sync] Remote ${change.type} for ${change.schema}.${change.table} already applied locally — converging without re-executing DDL`);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const { type: eventType, objectType } = schemaEventSignature(change.type);
|
|
284
479
|
// Register this as an expected remote event BEFORE executing DDL.
|
|
285
480
|
// When the module emits the event, it will be automatically marked as
|
|
286
481
|
// remote, so SyncManager won't re-record it.
|
|
@@ -310,24 +505,52 @@ async function applySchemaChange(db, events, change, _options) {
|
|
|
310
505
|
// The module's event is automatically marked as remote.
|
|
311
506
|
}
|
|
312
507
|
/**
|
|
313
|
-
* Collapse one row group's changes into a single ExternalRowOp
|
|
314
|
-
* A delete
|
|
508
|
+
* Collapse one row group's changes into a single ExternalRowOp — the group's NET
|
|
509
|
+
* effect in arrival (batch) order. A delete resets the row to absent: column
|
|
510
|
+
* updates BEFORE it are discarded (the delete already erased their effect) and
|
|
511
|
+
* updates AFTER it rebuild the row from a PK+nulls base — the same state the
|
|
512
|
+
* changes would leave applied one at a time (a re-creation after a same-batch
|
|
513
|
+
* delete must not resurrect the pre-delete image of columns it does not set).
|
|
514
|
+
* A group whose net effect is the delete collapses to a delete op; updates with
|
|
515
|
+
* no later delete merge onto the pre-read existing row (UPSERT semantics).
|
|
516
|
+
*
|
|
517
|
+
* NOTE: "net effect in order" assumes the batch arrives in HLC order, which
|
|
518
|
+
* `getChangesSince` guarantees (`DataChangeToApply` carries no HLC to re-sort
|
|
519
|
+
* by). The change-applicator's in-batch delete reconciliation decides the SAME
|
|
520
|
+
* question by HLC instead, so on a batch whose changesets were reordered the two
|
|
521
|
+
* disagree: under `allowResurrection` a resurrected row keeps its cell records
|
|
522
|
+
* and change-log entries while this collapse deletes it from the table, leaving
|
|
523
|
+
* the replica relaying a row it does not have. Tracked as
|
|
524
|
+
* `bug-sync-apply-order-splits-data-from-metadata`.
|
|
315
525
|
*/
|
|
316
526
|
async function buildRowOp(table, changes) {
|
|
317
527
|
const { pk } = changes[0];
|
|
318
|
-
|
|
528
|
+
let deleted = false;
|
|
529
|
+
let updates = [];
|
|
530
|
+
for (const change of changes) {
|
|
531
|
+
if (change.type === 'delete') {
|
|
532
|
+
deleted = true;
|
|
533
|
+
updates = [];
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
updates.push(change);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (deleted && updates.length === 0) {
|
|
319
540
|
return { op: 'delete', pk };
|
|
320
541
|
}
|
|
321
|
-
return { op: 'upsert', row: await mergeColumnUpdates(table, pk,
|
|
542
|
+
return { op: 'upsert', row: await mergeColumnUpdates(table, pk, updates, deleted) };
|
|
322
543
|
}
|
|
323
544
|
/**
|
|
324
545
|
* Merge column updates onto the row's current image (UPSERT semantics):
|
|
325
546
|
* pre-read the existing row by PK, or build a PK+nulls partial row when
|
|
326
|
-
* absent (column changes may arrive before the rest of the row).
|
|
547
|
+
* absent (column changes may arrive before the rest of the row). When
|
|
548
|
+
* `rowDeletedInGroup` is set, a delete earlier in the same row group already
|
|
549
|
+
* erased the stored image — the merge base is PK+nulls, never the pre-read row.
|
|
327
550
|
*/
|
|
328
|
-
async function mergeColumnUpdates(table, pk, changes) {
|
|
551
|
+
async function mergeColumnUpdates(table, pk, changes, rowDeletedInGroup = false) {
|
|
329
552
|
const tableSchema = table.getSchema();
|
|
330
|
-
const existing = await table.readRowByPk(pk);
|
|
553
|
+
const existing = rowDeletedInGroup ? undefined : await table.readRowByPk(pk);
|
|
331
554
|
let row;
|
|
332
555
|
if (existing) {
|
|
333
556
|
row = [...existing];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-adapter.js","sourceRoot":"","sources":["../../../src/sync/store-adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store-adapter.js","sourceRoot":"","sources":["../../../src/sync/store-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Extracted modules (snapshot-stream, change-applicator, snapshot) receive
|
|
5
5
|
* this context instead of accessing SyncManagerImpl internals directly.
|
|
6
6
|
*/
|
|
7
|
-
import type { KVStore } from '@quereus/store';
|
|
7
|
+
import type { KVStore, WriteBatch } from '@quereus/store';
|
|
8
|
+
import type { SqlValue } from '@quereus/quereus';
|
|
8
9
|
import type { HLCManager, HLC } from '../clock/hlc.js';
|
|
9
10
|
import type { SiteId } from '../clock/site.js';
|
|
10
11
|
import type { ColumnVersionStore } from '../metadata/column-version.js';
|
|
@@ -15,6 +16,8 @@ import type { QuarantineStore } from '../metadata/quarantine.js';
|
|
|
15
16
|
import type { BasisLifecycleStore } from '../metadata/basis-lifecycle.js';
|
|
16
17
|
import type { SyncConfig, ApplyToStoreCallback, ApplyToStoreResult, UnknownTableDisposition } from './protocol.js';
|
|
17
18
|
import type { SyncEventEmitterImpl } from './events.js';
|
|
19
|
+
import type { StagedRowState } from './staged-transaction-metadata.js';
|
|
20
|
+
import { type PkKeying } from '../metadata/keys.js';
|
|
18
21
|
/**
|
|
19
22
|
* Context shared across sync sub-modules.
|
|
20
23
|
*
|
|
@@ -35,6 +38,14 @@ export interface SyncContext {
|
|
|
35
38
|
readonly applyToStore?: ApplyToStoreCallback;
|
|
36
39
|
getSiteId(): SiteId;
|
|
37
40
|
getCurrentHLC(): HLC;
|
|
41
|
+
/**
|
|
42
|
+
* Per-table pk-identity keying (key collation normalizers + semantic key
|
|
43
|
+
* transforms) for building in-memory row-grouping keys that agree with the
|
|
44
|
+
* `cv:`/`tb:`/`cl:` storage keys. Throws when the table's schema is
|
|
45
|
+
* unavailable and a schema oracle is wired; resolves to the raw keying on a
|
|
46
|
+
* relay-only deployment with no oracle (see `metadata/pk-identity.ts`).
|
|
47
|
+
*/
|
|
48
|
+
getPkKeying(schema: string, table: string): PkKeying;
|
|
38
49
|
/**
|
|
39
50
|
* Whether `(schema, table)` is in the local basis. Backed by the
|
|
40
51
|
* `getTableSchema` oracle; when no oracle was provided detection is inert and
|
|
@@ -62,6 +73,47 @@ export interface SyncContext {
|
|
|
62
73
|
* Persist HLC state to the KV store (standalone put).
|
|
63
74
|
*/
|
|
64
75
|
export declare function persistHLCState(ctx: SyncContext): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Stage the deletion of every column version of a row, together with the
|
|
78
|
+
* change-log entries that index them, into the caller's `batch`. The caller
|
|
79
|
+
* owns the write — nothing is committed here.
|
|
80
|
+
*
|
|
81
|
+
* The `cl:` change log is a derived HLC-ordered index over live `cv:`/`tb:`
|
|
82
|
+
* records: `collectChangesSince` resolves each entry back to its record and drops
|
|
83
|
+
* the entry when that record is gone. So once a row's column versions are deleted,
|
|
84
|
+
* their `cl:` entries can never produce output again — they are pure garbage that
|
|
85
|
+
* still costs a KV lookup per delta scan. Deleting them with their target is what
|
|
86
|
+
* keeps the change log proportional to LIVE data instead of to the replica's
|
|
87
|
+
* lifetime delete volume.
|
|
88
|
+
*
|
|
89
|
+
* Both stores' deletions share the one `WriteBatch`, so no crash can leave the
|
|
90
|
+
* index and the data disagreeing.
|
|
91
|
+
*
|
|
92
|
+
* Used by both delete paths — local DML capture (`recordDataEvent`) and inbound
|
|
93
|
+
* apply (`commitChangeMetadata`) — which must stay symmetric: a relay runs almost
|
|
94
|
+
* exclusively the latter.
|
|
95
|
+
*
|
|
96
|
+
* `keepColumns` names columns whose cell record must SURVIVE this cleanup: on the
|
|
97
|
+
* inbound path, a column write in the same apply batch that beat the delete under
|
|
98
|
+
* `allowResurrection` (see change-applicator's `reconcileInBatchDeletes`). The scan
|
|
99
|
+
* reads committed storage, which by cleanup time already includes those records —
|
|
100
|
+
* both the `cv:` delete and its paired `cl:` delete skip them. Empty/absent for
|
|
101
|
+
* every caller unless resurrection is on.
|
|
102
|
+
*
|
|
103
|
+
* `staged` is the local-capture path's read-your-own-writes overlay state for
|
|
104
|
+
* the row (see `staged-transaction-metadata.ts`): the committed scan cannot see
|
|
105
|
+
* cell records the transaction has only STAGED into `batch`, so the column set
|
|
106
|
+
* here is (committed scan) ∪ (staged live columns), each `cl:` removal keyed by
|
|
107
|
+
* the staged HLC where one exists (the committed entry's removal was already
|
|
108
|
+
* staged when the cell was rewritten). A cleared row's committed columns not
|
|
109
|
+
* re-staged since are skipped — the clear that set `rowCleared` staged their
|
|
110
|
+
* removals already. Absent on the inbound path, whose batch is committed before
|
|
111
|
+
* cleanup runs.
|
|
112
|
+
*/
|
|
113
|
+
export declare function deleteRowVersionsAndLogEntries(ctx: SyncContext, batch: WriteBatch, schema: string, table: string, pk: SqlValue[], options?: {
|
|
114
|
+
keepColumns?: ReadonlySet<string>;
|
|
115
|
+
staged?: StagedRowState;
|
|
116
|
+
}): Promise<void>;
|
|
65
117
|
/**
|
|
66
118
|
* Normalize an unknown caught value into an Error instance.
|
|
67
119
|
*/
|
|
@@ -86,5 +138,5 @@ export declare function throwIfApplyErrors(ctx: SyncContext, result: ApplyToStor
|
|
|
86
138
|
/**
|
|
87
139
|
* Write HLC state into an existing WriteBatch.
|
|
88
140
|
*/
|
|
89
|
-
export declare function persistHLCStateBatch(ctx: SyncContext, batch:
|
|
141
|
+
export declare function persistHLCStateBatch(ctx: SyncContext, batch: WriteBatch): void;
|
|
90
142
|
//# sourceMappingURL=sync-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-context.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-context.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,72 @@ export async function persistHLCState(ctx) {
|
|
|
16
16
|
view.setUint16(8, state.counter, false);
|
|
17
17
|
await ctx.kv.put(SYNC_KEY_PREFIX.HLC_STATE, buffer);
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Stage the deletion of every column version of a row, together with the
|
|
21
|
+
* change-log entries that index them, into the caller's `batch`. The caller
|
|
22
|
+
* owns the write — nothing is committed here.
|
|
23
|
+
*
|
|
24
|
+
* The `cl:` change log is a derived HLC-ordered index over live `cv:`/`tb:`
|
|
25
|
+
* records: `collectChangesSince` resolves each entry back to its record and drops
|
|
26
|
+
* the entry when that record is gone. So once a row's column versions are deleted,
|
|
27
|
+
* their `cl:` entries can never produce output again — they are pure garbage that
|
|
28
|
+
* still costs a KV lookup per delta scan. Deleting them with their target is what
|
|
29
|
+
* keeps the change log proportional to LIVE data instead of to the replica's
|
|
30
|
+
* lifetime delete volume.
|
|
31
|
+
*
|
|
32
|
+
* Both stores' deletions share the one `WriteBatch`, so no crash can leave the
|
|
33
|
+
* index and the data disagreeing.
|
|
34
|
+
*
|
|
35
|
+
* Used by both delete paths — local DML capture (`recordDataEvent`) and inbound
|
|
36
|
+
* apply (`commitChangeMetadata`) — which must stay symmetric: a relay runs almost
|
|
37
|
+
* exclusively the latter.
|
|
38
|
+
*
|
|
39
|
+
* `keepColumns` names columns whose cell record must SURVIVE this cleanup: on the
|
|
40
|
+
* inbound path, a column write in the same apply batch that beat the delete under
|
|
41
|
+
* `allowResurrection` (see change-applicator's `reconcileInBatchDeletes`). The scan
|
|
42
|
+
* reads committed storage, which by cleanup time already includes those records —
|
|
43
|
+
* both the `cv:` delete and its paired `cl:` delete skip them. Empty/absent for
|
|
44
|
+
* every caller unless resurrection is on.
|
|
45
|
+
*
|
|
46
|
+
* `staged` is the local-capture path's read-your-own-writes overlay state for
|
|
47
|
+
* the row (see `staged-transaction-metadata.ts`): the committed scan cannot see
|
|
48
|
+
* cell records the transaction has only STAGED into `batch`, so the column set
|
|
49
|
+
* here is (committed scan) ∪ (staged live columns), each `cl:` removal keyed by
|
|
50
|
+
* the staged HLC where one exists (the committed entry's removal was already
|
|
51
|
+
* staged when the cell was rewritten). A cleared row's committed columns not
|
|
52
|
+
* re-staged since are skipped — the clear that set `rowCleared` staged their
|
|
53
|
+
* removals already. Absent on the inbound path, whose batch is committed before
|
|
54
|
+
* cleanup runs.
|
|
55
|
+
*/
|
|
56
|
+
export async function deleteRowVersionsAndLogEntries(ctx, batch, schema, table, pk, options) {
|
|
57
|
+
const keepColumns = options?.keepColumns;
|
|
58
|
+
const staged = options?.staged;
|
|
59
|
+
const removed = await ctx.columnVersions.deleteRowVersionsBatch(batch, schema, table, pk, keepColumns);
|
|
60
|
+
// `cl:` entry HLC per column: committed HLCs, overridden by the staged HLC
|
|
61
|
+
// where this transaction rewrote the cell.
|
|
62
|
+
const entryHlcByColumn = new Map();
|
|
63
|
+
for (const [column, version] of removed) {
|
|
64
|
+
if (staged?.rowCleared && !staged.stagedColumns.has(column))
|
|
65
|
+
continue;
|
|
66
|
+
entryHlcByColumn.set(column, version.hlc);
|
|
67
|
+
}
|
|
68
|
+
if (staged) {
|
|
69
|
+
for (const [column, hlc] of staged.stagedColumns) {
|
|
70
|
+
if (keepColumns?.has(column))
|
|
71
|
+
continue;
|
|
72
|
+
entryHlcByColumn.set(column, hlc);
|
|
73
|
+
if (!removed.has(column)) {
|
|
74
|
+
// Staged-only cell (this transaction created it): no committed record
|
|
75
|
+
// for the scan to find, so stage its removal explicitly. Batch ordering
|
|
76
|
+
// makes this later delete win over the earlier staged put.
|
|
77
|
+
ctx.columnVersions.deleteColumnVersionBatch(batch, schema, table, pk, column);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const [column, hlc] of entryHlcByColumn) {
|
|
82
|
+
ctx.changeLog.deleteEntryBatch(batch, hlc, 'column', schema, table, pk, column);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
19
85
|
/**
|
|
20
86
|
* Normalize an unknown caught value into an Error instance.
|
|
21
87
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-context.js","sourceRoot":"","sources":["../../../src/sync/sync-context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"sync-context.js","sourceRoot":"","sources":["../../../src/sync/sync-context.ts"],"names":[],"mappings":"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"}
|