@quereus/sync 4.4.1 → 4.6.0

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 (52) hide show
  1. package/README.md +2 -2
  2. package/dist/src/index.d.ts +1 -1
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/index.js +1 -1
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/metadata/column-version.d.ts.map +1 -1
  7. package/dist/src/metadata/column-version.js +8 -9
  8. package/dist/src/metadata/column-version.js.map +1 -1
  9. package/dist/src/metadata/keys.d.ts +71 -39
  10. package/dist/src/metadata/keys.d.ts.map +1 -1
  11. package/dist/src/metadata/keys.js +181 -158
  12. package/dist/src/metadata/keys.js.map +1 -1
  13. package/dist/src/metadata/pk-identity.d.ts +19 -14
  14. package/dist/src/metadata/pk-identity.d.ts.map +1 -1
  15. package/dist/src/metadata/pk-identity.js +21 -28
  16. package/dist/src/metadata/pk-identity.js.map +1 -1
  17. package/dist/src/metadata/schema-migration.d.ts +25 -9
  18. package/dist/src/metadata/schema-migration.d.ts.map +1 -1
  19. package/dist/src/metadata/schema-migration.js +49 -15
  20. package/dist/src/metadata/schema-migration.js.map +1 -1
  21. package/dist/src/sync/change-applicator.d.ts +19 -3
  22. package/dist/src/sync/change-applicator.d.ts.map +1 -1
  23. package/dist/src/sync/change-applicator.js +194 -60
  24. package/dist/src/sync/change-applicator.js.map +1 -1
  25. package/dist/src/sync/maintenance.d.ts +8 -5
  26. package/dist/src/sync/maintenance.d.ts.map +1 -1
  27. package/dist/src/sync/maintenance.js +7 -4
  28. package/dist/src/sync/maintenance.js.map +1 -1
  29. package/dist/src/sync/manager.d.ts +23 -1
  30. package/dist/src/sync/manager.d.ts.map +1 -1
  31. package/dist/src/sync/protocol.d.ts +30 -1
  32. package/dist/src/sync/protocol.d.ts.map +1 -1
  33. package/dist/src/sync/protocol.js +38 -0
  34. package/dist/src/sync/protocol.js.map +1 -1
  35. package/dist/src/sync/snapshot-identity.d.ts.map +1 -1
  36. package/dist/src/sync/snapshot-identity.js +1 -9
  37. package/dist/src/sync/snapshot-identity.js.map +1 -1
  38. package/dist/src/sync/snapshot-stream.d.ts.map +1 -1
  39. package/dist/src/sync/snapshot-stream.js +41 -39
  40. package/dist/src/sync/snapshot-stream.js.map +1 -1
  41. package/dist/src/sync/snapshot.d.ts.map +1 -1
  42. package/dist/src/sync/snapshot.js +12 -30
  43. package/dist/src/sync/snapshot.js.map +1 -1
  44. package/dist/src/sync/store-adapter.d.ts +5 -4
  45. package/dist/src/sync/store-adapter.d.ts.map +1 -1
  46. package/dist/src/sync/store-adapter.js +27 -46
  47. package/dist/src/sync/store-adapter.js.map +1 -1
  48. package/dist/src/sync/sync-manager-impl.d.ts +35 -4
  49. package/dist/src/sync/sync-manager-impl.d.ts.map +1 -1
  50. package/dist/src/sync/sync-manager-impl.js +72 -40
  51. package/dist/src/sync/sync-manager-impl.js.map +1 -1
  52. package/package.json +7 -7
@@ -4,10 +4,11 @@
4
4
  * The sync layer files every per-row record (`cv:`/`tb:`/`cl:`) under the row's
5
5
  * IDENTITY — the same "same row?" answer the rest of the engine gives: each pk
6
6
  * column normalized under its KEY COLLATION ('apple' ≡ 'APPLE' under nocase) and
7
- * its logical type's semantic key transform ('PT1H' ≡ 'PT60M' for TIMESPAN).
8
- * This module resolves that keying from a table's schema, mirroring
9
- * `makePkKeySerializer` in `@quereus/isolation` (the overlay's row-alignment
10
- * key) so the two layers can never disagree on row identity.
7
+ * its logical type's semantic key transform ('PT1H' ≡ 'PT60M' for TIMESPAN). This
8
+ * module resolves that keying from a table's schema by calling into
9
+ * `@quereus/quereus`'s `resolvePkIdentityKeying` — the ONE implementation of that
10
+ * recipe, also used by `makePkKeySerializer` in `@quereus/isolation` (the overlay's
11
+ * row-alignment key) — so the two layers can never disagree on row identity.
11
12
  *
12
13
  * Identity is derived and lossy; the row's ADDRESS (a real, type-valid
13
14
  * `SqlValue[]` — any spelling from the equivalence class) lives in the record
@@ -22,16 +23,20 @@ import { type PkKeying } from './keys.js';
22
23
  */
23
24
  export type PkKeyingResolver = (schemaName: string, tableName: string) => PkKeying;
24
25
  /**
25
- * Resolve a table's {@link PkKeying} from its schema:
26
- * - normalizers: each pk column's key collation via {@link pkKeyCollationName}
27
- * (its own declared collation for a textual column — the store reconciles an
28
- * undecorated text pk to the table key collation at CREATE, so the registered
29
- * schema always carries it; BINARY for text-capable-but-not-textual columns;
30
- * identity for never-text columns via `resolver(undefined)`).
31
- * - transforms: the engine's {@link semanticKeyTransform} (the logical type's
32
- * `groupKey` — today TIMESPAN → total seconds). Deliberately the ENGINE
33
- * transform, not the store's byte-order variant: identity strings need
34
- * equality, not memcmp order, so JSON's canonical text is already faithful.
26
+ * Resolve a table's {@link PkKeying} from its schema. Delegates entirely to
27
+ * `@quereus/quereus`'s {@link resolvePkIdentityKeying} (per pk column: key collation
28
+ * via `pkKeyCollationName` — its own declared collation for a collation-aware column
29
+ * (`text`, `any`; for text the store reconciles an undecorated pk to the table key
30
+ * collation at CREATE, so the registered schema always carries it); BINARY for
31
+ * collation-blind text-capable columns (`json`, the temporal types); identity for
32
+ * never-text columns — plus the engine's `semanticKeyTransform`,
33
+ * the logical type's `groupKey`, today TIMESPAN → total seconds. Deliberately the
34
+ * ENGINE transform, not the store's byte-order variant: identity strings need
35
+ * equality, not memcmp order, so JSON's canonical text is already faithful), whose
36
+ * shape is exactly {@link PkKeying}'s. That shared function is also defensive about a
37
+ * missing `primaryKeyDefinition` or column `logicalType` (test oracles stub minimal
38
+ * schemas — `{ columns: [{ name }] }` only), degrading a missing piece to the identity
39
+ * normalizer (raw value identity) instead of crashing.
35
40
  */
36
41
  export declare function resolvePkKeying(schema: TableSchema, resolver: KeyNormalizerResolver): PkKeying;
37
42
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pk-identity.d.ts","sourceRoot":"","sources":["../../../src/metadata/pk-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAGN,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAmC,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3E;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,QAAQ,CAAC;AAEnF;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,qBAAqB,GAAG,QAAQ,CAc9F;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACrC,cAAc,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC,GAAG,SAAS,EAChG,qBAAqB,EAAE,qBAAqB,GAAG,SAAS,GACtD,gBAAgB,CAwBlB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,qBAAqB,GAC7B,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,MAAM,CAG5B"}
1
+ {"version":3,"file":"pk-identity.d.ts","sourceRoot":"","sources":["../../../src/metadata/pk-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAmC,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3E;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,QAAQ,CAAC;AAEnF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,qBAAqB,GAAG,QAAQ,CAE9F;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACrC,cAAc,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC,GAAG,SAAS,EAChG,qBAAqB,EAAE,qBAAqB,GAAG,SAAS,GACtD,gBAAgB,CAwBlB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,qBAAqB,GAC7B,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,MAAM,CAG5B"}
@@ -4,44 +4,37 @@
4
4
  * The sync layer files every per-row record (`cv:`/`tb:`/`cl:`) under the row's
5
5
  * IDENTITY — the same "same row?" answer the rest of the engine gives: each pk
6
6
  * column normalized under its KEY COLLATION ('apple' ≡ 'APPLE' under nocase) and
7
- * its logical type's semantic key transform ('PT1H' ≡ 'PT60M' for TIMESPAN).
8
- * This module resolves that keying from a table's schema, mirroring
9
- * `makePkKeySerializer` in `@quereus/isolation` (the overlay's row-alignment
10
- * key) so the two layers can never disagree on row identity.
7
+ * its logical type's semantic key transform ('PT1H' ≡ 'PT60M' for TIMESPAN). This
8
+ * module resolves that keying from a table's schema by calling into
9
+ * `@quereus/quereus`'s `resolvePkIdentityKeying` — the ONE implementation of that
10
+ * recipe, also used by `makePkKeySerializer` in `@quereus/isolation` (the overlay's
11
+ * row-alignment key) — so the two layers can never disagree on row identity.
11
12
  *
12
13
  * Identity is derived and lossy; the row's ADDRESS (a real, type-valid
13
14
  * `SqlValue[]` — any spelling from the equivalence class) lives in the record
14
15
  * value and on the wire. See docs/sync.md § Row identity vs. address.
15
16
  */
16
- import { pkKeyCollationName, semanticKeyTransform, } from '@quereus/quereus';
17
+ import { resolvePkIdentityKeying, } from '@quereus/quereus';
17
18
  import { BUILTIN_KEY_NORMALIZER_RESOLVER } from '@quereus/store';
18
19
  import { encodePkIdentity, RAW_PK_KEYING } from './keys.js';
19
20
  /**
20
- * Resolve a table's {@link PkKeying} from its schema:
21
- * - normalizers: each pk column's key collation via {@link pkKeyCollationName}
22
- * (its own declared collation for a textual column — the store reconciles an
23
- * undecorated text pk to the table key collation at CREATE, so the registered
24
- * schema always carries it; BINARY for text-capable-but-not-textual columns;
25
- * identity for never-text columns via `resolver(undefined)`).
26
- * - transforms: the engine's {@link semanticKeyTransform} (the logical type's
27
- * `groupKey` — today TIMESPAN → total seconds). Deliberately the ENGINE
28
- * transform, not the store's byte-order variant: identity strings need
29
- * equality, not memcmp order, so JSON's canonical text is already faithful.
21
+ * Resolve a table's {@link PkKeying} from its schema. Delegates entirely to
22
+ * `@quereus/quereus`'s {@link resolvePkIdentityKeying} (per pk column: key collation
23
+ * via `pkKeyCollationName` — its own declared collation for a collation-aware column
24
+ * (`text`, `any`; for text the store reconciles an undecorated pk to the table key
25
+ * collation at CREATE, so the registered schema always carries it); BINARY for
26
+ * collation-blind text-capable columns (`json`, the temporal types); identity for
27
+ * never-text columns — plus the engine's `semanticKeyTransform`,
28
+ * the logical type's `groupKey`, today TIMESPAN → total seconds. Deliberately the
29
+ * ENGINE transform, not the store's byte-order variant: identity strings need
30
+ * equality, not memcmp order, so JSON's canonical text is already faithful), whose
31
+ * shape is exactly {@link PkKeying}'s. That shared function is also defensive about a
32
+ * missing `primaryKeyDefinition` or column `logicalType` (test oracles stub minimal
33
+ * schemas — `{ columns: [{ name }] }` only), degrading a missing piece to the identity
34
+ * normalizer (raw value identity) instead of crashing.
30
35
  */
31
36
  export function resolvePkKeying(schema, resolver) {
32
- // Defensive `?? []` / logicalType guard: a real TableSchema always carries
33
- // primaryKeyDefinition and typed columns, but test oracles stub minimal
34
- // schemas ({ columns: [{ name }] } only). A missing piece degrades that
35
- // position to the identity normalizer (raw value identity) — the same
36
- // treatment a keyless stub got before — instead of crashing.
37
- const pkDef = schema.primaryKeyDefinition ?? [];
38
- return {
39
- normalizers: pkDef.map(def => {
40
- const column = schema.columns[def.index];
41
- return resolver(column?.logicalType ? pkKeyCollationName(column) : undefined);
42
- }),
43
- transforms: pkDef.map(def => semanticKeyTransform(schema.columns[def.index]?.logicalType)),
44
- };
37
+ return resolvePkIdentityKeying(schema, resolver);
45
38
  }
46
39
  /**
47
40
  * Build the {@link PkKeyingResolver} a `SyncManagerImpl` threads through its
@@ -1 +1 @@
1
- {"version":3,"file":"pk-identity.js","sourceRoot":"","sources":["../../../src/metadata/pk-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACN,kBAAkB,EAClB,oBAAoB,GAIpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAiB,MAAM,WAAW,CAAC;AAS3E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,MAAmB,EAAE,QAA+B;IACnF,2EAA2E;IAC3E,wEAAwE;IACxE,wEAAwE;IACxE,sEAAsE;IACtE,6DAA6D;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,oBAAoB,IAAI,EAAE,CAAC;IAChD,OAAO;QACN,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/E,CAAC,CAAC;QACF,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,CAAC;KAC1F,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CACrC,cAAgG,EAChG,qBAAwD;IAExD,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,8EAA8E;IAC9E,8EAA8E;IAC9E,gDAAgD;IAChD,MAAM,QAAQ,GAAG,qBAAqB,IAAI,+BAA+B,CAAC;IAC1E,MAAM,KAAK,GAAG,IAAI,OAAO,EAAyB,CAAC;IACnD,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACd,uBAAuB,UAAU,IAAI,SAAS,sCAAsC;kBACjF,kFAAkF,CACrF,CAAC;QACH,CAAC;QACD,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC3C,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACpC,MAAmB,EACnB,QAA+B;IAE/B,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjD,OAAO,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"pk-identity.js","sourceRoot":"","sources":["../../../src/metadata/pk-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACN,uBAAuB,GAIvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAiB,MAAM,WAAW,CAAC;AAS3E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,MAAmB,EAAE,QAA+B;IACnF,OAAO,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CACrC,cAAgG,EAChG,qBAAwD;IAExD,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,8EAA8E;IAC9E,8EAA8E;IAC9E,gDAAgD;IAChD,MAAM,QAAQ,GAAG,qBAAqB,IAAI,+BAA+B,CAAC;IAC1E,MAAM,KAAK,GAAG,IAAI,OAAO,EAAyB,CAAC;IACnD,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACrD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACd,uBAAuB,UAAU,IAAI,SAAS,sCAAsC;kBACjF,kFAAkF,CACrF,CAAC;QACH,CAAC;QACD,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC3C,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACpC,MAAmB,EACnB,QAA+B;IAE/B,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjD,OAAO,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC"}
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import type { KVStore, WriteBatch } from '@quereus/store';
8
8
  import { type HLC } from '../clock/hlc.js';
9
- import type { SchemaMigrationType } from '../sync/protocol.js';
9
+ import { type SchemaMigration, type SchemaMigrationType, type SchemaObjectKind } from '../sync/protocol.js';
10
10
  /**
11
11
  * Stored schema migration record.
12
12
  */
@@ -27,6 +27,11 @@ export declare function serializeMigration(migration: StoredMigration): Uint8Arr
27
27
  export declare function deserializeMigration(buffer: Uint8Array): StoredMigration;
28
28
  /**
29
29
  * Schema migration store operations.
30
+ *
31
+ * Every method is keyed by `(schemaName, kind, objectName)`: the object name
32
+ * alone is ambiguous, since an index migration names an INDEX while every other
33
+ * migration type names a TABLE. Callers derive `kind` from the migration type
34
+ * with {@link import('../sync/protocol.js').migrationObjectKind}.
30
35
  */
31
36
  export declare class SchemaMigrationStore {
32
37
  private readonly kv;
@@ -34,27 +39,38 @@ export declare class SchemaMigrationStore {
34
39
  /**
35
40
  * Get a specific migration by version.
36
41
  */
37
- getMigration(schemaName: string, tableName: string, version: number): Promise<StoredMigration | undefined>;
42
+ getMigration(schemaName: string, kind: SchemaObjectKind, objectName: string, version: number): Promise<StoredMigration | undefined>;
38
43
  /**
39
44
  * Record a new migration.
40
45
  */
41
- recordMigration(schemaName: string, tableName: string, migration: StoredMigration): Promise<void>;
46
+ recordMigration(schemaName: string, kind: SchemaObjectKind, objectName: string, migration: StoredMigration): Promise<void>;
42
47
  /**
43
48
  * Record migration in a batch.
44
49
  */
45
- recordMigrationBatch(batch: WriteBatch, schemaName: string, tableName: string, migration: StoredMigration): void;
50
+ recordMigrationBatch(batch: WriteBatch, schemaName: string, kind: SchemaObjectKind, objectName: string, migration: StoredMigration): void;
51
+ /**
52
+ * Get the current schema version for one object (a table's, or an index's).
53
+ */
54
+ getCurrentVersion(schemaName: string, kind: SchemaObjectKind, objectName: string): Promise<number>;
46
55
  /**
47
- * Get the current schema version for a table.
56
+ * Get all migrations for one object.
48
57
  */
49
- getCurrentVersion(schemaName: string, tableName: string): Promise<number>;
58
+ getAllMigrations(schemaName: string, kind: SchemaObjectKind, objectName: string): AsyncIterable<StoredMigration>;
50
59
  /**
51
- * Get all migrations for a table.
60
+ * Every migration on this replica as a wire record, in causal (HLC) order.
61
+ *
62
+ * The producers that ship DDL — both snapshot paths and the delta collector —
63
+ * all need the whole set, and all need it causally ordered: DDL replays in list
64
+ * order, so a `create index` ahead of its table's `create table` fails outright.
65
+ * `sm:` key order is (schema, object kind, object name), which puts every index
66
+ * migration ahead of every table migration in a schema, so the scan order can
67
+ * never be used directly.
52
68
  */
53
- getAllMigrations(schemaName: string, tableName: string): AsyncIterable<StoredMigration>;
69
+ listAllMigrations(): Promise<SchemaMigration[]>;
54
70
  /**
55
71
  * Check if a migration conflicts with an existing one.
56
72
  * Returns the existing migration if there's a conflict, undefined otherwise.
57
73
  */
58
- checkConflict(schemaName: string, tableName: string, version: number, incomingHLC: HLC): Promise<StoredMigration | undefined>;
74
+ checkConflict(schemaName: string, kind: SchemaObjectKind, objectName: string, version: number, incomingHLC: HLC): Promise<StoredMigration | undefined>;
59
75
  }
60
76
  //# sourceMappingURL=schema-migration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-migration.d.ts","sourceRoot":"","sources":["../../../src/metadata/schema-migration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,KAAK,GAAG,EAA4C,MAAM,iBAAiB,CAAC;AAErF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,GAAG,CAAC;IACT,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,UAAU,CA4BzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,CAuBxE;AAED;;GAEG;AACH,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,OAAO;IAExC;;OAEG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAOvC;;OAEG;IACG,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACH,oBAAoB,CAClB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe,GACzB,IAAI;IAKP;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAY/E;;OAEG;IACI,gBAAgB,CACrB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,aAAa,CAAC,eAAe,CAAC;IAQjC;;;OAGG;IACG,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,GAAG,GACf,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;CAWxC"}
1
+ {"version":3,"file":"schema-migration.d.ts","sourceRoot":"","sources":["../../../src/metadata/schema-migration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,KAAK,GAAG,EAA4C,MAAM,iBAAiB,CAAC;AAOrF,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,GAAG,CAAC;IACT,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,eAAe,GAAG,UAAU,CA4BzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,CAuBxE;AAED;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,OAAO;IAExC;;OAEG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAOvC;;OAEG;IACG,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,eAAe,GACzB,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACH,oBAAoB,CAClB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,eAAe,GACzB,IAAI;IAKP;;OAEG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;IAYlB;;OAEG;IACI,gBAAgB,CACrB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,GACjB,aAAa,CAAC,eAAe,CAAC;IAQjC;;;;;;;;;OASG;IACG,iBAAiB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAqBrD;;;OAGG;IACG,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,GAAG,GACf,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;CAWxC"}
@@ -5,7 +5,8 @@
5
5
  * Uses first-writer-wins for conflict resolution on schema changes.
6
6
  */
7
7
  import { serializeHLC, deserializeHLC, compareHLC } from '../clock/hlc.js';
8
- import { buildSchemaMigrationKey, buildSchemaMigrationScanBounds } from './keys.js';
8
+ import { buildAllSchemaMigrationsScanBounds, buildSchemaMigrationKey, buildSchemaMigrationScanBounds, parseSchemaMigrationKey, } from './keys.js';
9
+ import { sortMigrationsByHLC, } from '../sync/protocol.js';
9
10
  /**
10
11
  * Serialize a migration for storage.
11
12
  * Format: 30 bytes HLC + 4 bytes version + 1 byte type length + type + ddl
@@ -57,6 +58,11 @@ export function deserializeMigration(buffer) {
57
58
  }
58
59
  /**
59
60
  * Schema migration store operations.
61
+ *
62
+ * Every method is keyed by `(schemaName, kind, objectName)`: the object name
63
+ * alone is ambiguous, since an index migration names an INDEX while every other
64
+ * migration type names a TABLE. Callers derive `kind` from the migration type
65
+ * with {@link import('../sync/protocol.js').migrationObjectKind}.
60
66
  */
61
67
  export class SchemaMigrationStore {
62
68
  kv;
@@ -66,8 +72,8 @@ export class SchemaMigrationStore {
66
72
  /**
67
73
  * Get a specific migration by version.
68
74
  */
69
- async getMigration(schemaName, tableName, version) {
70
- const key = buildSchemaMigrationKey(schemaName, tableName, version);
75
+ async getMigration(schemaName, kind, objectName, version) {
76
+ const key = buildSchemaMigrationKey(schemaName, kind, objectName, version);
71
77
  const data = await this.kv.get(key);
72
78
  if (!data)
73
79
  return undefined;
@@ -76,22 +82,22 @@ export class SchemaMigrationStore {
76
82
  /**
77
83
  * Record a new migration.
78
84
  */
79
- async recordMigration(schemaName, tableName, migration) {
80
- const key = buildSchemaMigrationKey(schemaName, tableName, migration.schemaVersion);
85
+ async recordMigration(schemaName, kind, objectName, migration) {
86
+ const key = buildSchemaMigrationKey(schemaName, kind, objectName, migration.schemaVersion);
81
87
  await this.kv.put(key, serializeMigration(migration));
82
88
  }
83
89
  /**
84
90
  * Record migration in a batch.
85
91
  */
86
- recordMigrationBatch(batch, schemaName, tableName, migration) {
87
- const key = buildSchemaMigrationKey(schemaName, tableName, migration.schemaVersion);
92
+ recordMigrationBatch(batch, schemaName, kind, objectName, migration) {
93
+ const key = buildSchemaMigrationKey(schemaName, kind, objectName, migration.schemaVersion);
88
94
  batch.put(key, serializeMigration(migration));
89
95
  }
90
96
  /**
91
- * Get the current schema version for a table.
97
+ * Get the current schema version for one object (a table's, or an index's).
92
98
  */
93
- async getCurrentVersion(schemaName, tableName) {
94
- const bounds = buildSchemaMigrationScanBounds(schemaName, tableName);
99
+ async getCurrentVersion(schemaName, kind, objectName) {
100
+ const bounds = buildSchemaMigrationScanBounds(schemaName, kind, objectName);
95
101
  let maxVersion = 0;
96
102
  for await (const entry of this.kv.iterate({ ...bounds, reverse: true, limit: 1 })) {
97
103
  const migration = deserializeMigration(entry.value);
@@ -100,20 +106,48 @@ export class SchemaMigrationStore {
100
106
  return maxVersion;
101
107
  }
102
108
  /**
103
- * Get all migrations for a table.
109
+ * Get all migrations for one object.
104
110
  */
105
- async *getAllMigrations(schemaName, tableName) {
106
- const bounds = buildSchemaMigrationScanBounds(schemaName, tableName);
111
+ async *getAllMigrations(schemaName, kind, objectName) {
112
+ const bounds = buildSchemaMigrationScanBounds(schemaName, kind, objectName);
107
113
  for await (const entry of this.kv.iterate(bounds)) {
108
114
  yield deserializeMigration(entry.value);
109
115
  }
110
116
  }
117
+ /**
118
+ * Every migration on this replica as a wire record, in causal (HLC) order.
119
+ *
120
+ * The producers that ship DDL — both snapshot paths and the delta collector —
121
+ * all need the whole set, and all need it causally ordered: DDL replays in list
122
+ * order, so a `create index` ahead of its table's `create table` fails outright.
123
+ * `sm:` key order is (schema, object kind, object name), which puts every index
124
+ * migration ahead of every table migration in a schema, so the scan order can
125
+ * never be used directly.
126
+ */
127
+ async listAllMigrations() {
128
+ const migrations = [];
129
+ for await (const entry of this.kv.iterate(buildAllSchemaMigrationsScanBounds())) {
130
+ const parsed = parseSchemaMigrationKey(entry.key);
131
+ if (!parsed)
132
+ continue;
133
+ const stored = deserializeMigration(entry.value);
134
+ migrations.push({
135
+ type: stored.type,
136
+ schema: parsed.schema,
137
+ table: parsed.table,
138
+ ddl: stored.ddl,
139
+ hlc: stored.hlc,
140
+ schemaVersion: stored.schemaVersion,
141
+ });
142
+ }
143
+ return sortMigrationsByHLC(migrations);
144
+ }
111
145
  /**
112
146
  * Check if a migration conflicts with an existing one.
113
147
  * Returns the existing migration if there's a conflict, undefined otherwise.
114
148
  */
115
- async checkConflict(schemaName, tableName, version, incomingHLC) {
116
- const existing = await this.getMigration(schemaName, tableName, version);
149
+ async checkConflict(schemaName, kind, objectName, version, incomingHLC) {
150
+ const existing = await this.getMigration(schemaName, kind, objectName, version);
117
151
  if (!existing)
118
152
  return undefined;
119
153
  // First-writer-wins: if existing has lower HLC, it wins
@@ -1 +1 @@
1
- {"version":3,"file":"schema-migration.js","sourceRoot":"","sources":["../../../src/metadata/schema-migration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema-migration.js","sourceRoot":"","sources":["../../../src/metadata/schema-migration.ts"],"names":[],"mappings":"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"}
@@ -50,9 +50,25 @@ export interface ResolvedChange {
50
50
  * 2. Apply data to store via callback
51
51
  * 3. Commit CRDT metadata (+ durable quarantine of diverted changes)
52
52
  *
53
- * Unknown-table disposition: a change referencing a table outside the local basis
54
- * (a retired-table straggler delta — see `docs/migration.md` § 4 Contract) is
55
- * **diverted** during resolution — never resolved, applied, or recorded as CRDT
53
+ * ORDER-INDEPENDENT: `changes` may arrive in any order and produces the same
54
+ * committed state as the HLC-ordered array. Callers need not (and do not) preserve
55
+ * timestamp order — the coordinator's `onBeforeApplyChanges` approval hook returns a
56
+ * caller-supplied array, and the REST/WebSocket ingress accepts an arbitrary array
57
+ * from any client. Everything whose outcome depends on order is re-derived from the
58
+ * HLCs here rather than from arrival position: resolution and
59
+ * {@link reconcileInBatchDeletes} already compare HLCs, the store apply list is sorted
60
+ * by {@link orderDataChangesByHLC}, the DDL list by {@link orderMigrationsByHLC}, and
61
+ * the emitted payload by {@link emitRemoteChanges}. Everything else (the counters, the
62
+ * quarantine holds, the watermark max) is order-insensitive by construction. The
63
+ * guarantee covers committed STATE, not the event stream: `onConflictResolved` fires
64
+ * from the resolve loop in arrival order, and an `onUnknownTable` event reports the
65
+ * FIRST changeset that referenced the table as the straggler origin, so a reordered
66
+ * batch can name a different relayer — telemetry only, never a stored fact.
67
+ *
68
+ * Unknown-table disposition: a change referencing a table the batch leaves absent — not
69
+ * in the local basis and not created by this batch's schema steps (a retired-table
70
+ * straggler delta — see `docs/migration.md` § 4 Contract) — is **diverted** during
71
+ * resolution — never resolved, applied, or recorded as CRDT
56
72
  * metadata, so the change log stays clean (no survivor-HLC pollution). Diverted
57
73
  * changes are held (durably, idempotently — `quarantine`, or `store-and-forward`
58
74
  * which additionally marks them forwardable) or ignored per
@@ -1 +1 @@
1
- {"version":3,"file":"change-applicator.d.ts","sourceRoot":"","sources":["../../../src/sync/change-applicator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,KAAK,EACX,SAAS,EACT,MAAM,EAGN,WAAW,EACX,iBAAiB,EAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,sGAAsG;IACtG,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;;OAMG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AA2CD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,SAAS,EAAE,GAClB,OAAO,CAAC,WAAW,CAAC,CAiPtB;AAsCD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAsBjB;AA6FD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAC1C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACtD,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAClC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,UAAQ,GACrB,OAAO,CAAC,cAAc,CAAC,CAkHzB;AAyDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,oBAAoB,CACzC,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,cAAc,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC,CAiDf"}
1
+ {"version":3,"file":"change-applicator.d.ts","sourceRoot":"","sources":["../../../src/sync/change-applicator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,KAAK,EACX,SAAS,EACT,MAAM,EAGN,WAAW,EACX,iBAAiB,EAGjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,sGAAsG;IACtG,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;;OAMG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAqFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,SAAS,EAAE,GAClB,OAAO,CAAC,WAAW,CAAC,CA4RtB;AA6FD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAsBjB;AAgGD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAC1C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACtD,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAClC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,UAAQ,GACrB,OAAO,CAAC,cAAc,CAAC,CAkHzB;AAyDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,oBAAoB,CACzC,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,cAAc,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC,CAiDf"}