@quereus/plugin-sync 0.3.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 +154 -0
- package/dist/src/clock/hlc.d.ts +105 -0
- package/dist/src/clock/hlc.d.ts.map +1 -0
- package/dist/src/clock/hlc.js +251 -0
- package/dist/src/clock/hlc.js.map +1 -0
- package/dist/src/clock/index.d.ts +6 -0
- package/dist/src/clock/index.d.ts.map +1 -0
- package/dist/src/clock/index.js +6 -0
- package/dist/src/clock/index.js.map +1 -0
- package/dist/src/clock/site.d.ts +58 -0
- package/dist/src/clock/site.d.ts.map +1 -0
- package/dist/src/clock/site.js +137 -0
- package/dist/src/clock/site.js.map +1 -0
- package/dist/src/create-sync-module.d.ts +85 -0
- package/dist/src/create-sync-module.d.ts.map +1 -0
- package/dist/src/create-sync-module.js +54 -0
- package/dist/src/create-sync-module.js.map +1 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +42 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/metadata/change-log.d.ts +67 -0
- package/dist/src/metadata/change-log.d.ts.map +1 -0
- package/dist/src/metadata/change-log.js +107 -0
- package/dist/src/metadata/change-log.js.map +1 -0
- package/dist/src/metadata/column-version.d.ts +58 -0
- package/dist/src/metadata/column-version.d.ts.map +1 -0
- package/dist/src/metadata/column-version.js +100 -0
- package/dist/src/metadata/column-version.js.map +1 -0
- package/dist/src/metadata/index.d.ts +11 -0
- package/dist/src/metadata/index.d.ts.map +1 -0
- package/dist/src/metadata/index.js +11 -0
- package/dist/src/metadata/index.js.map +1 -0
- package/dist/src/metadata/keys.d.ts +180 -0
- package/dist/src/metadata/keys.d.ts.map +1 -0
- package/dist/src/metadata/keys.js +390 -0
- package/dist/src/metadata/keys.js.map +1 -0
- package/dist/src/metadata/peer-state.d.ts +52 -0
- package/dist/src/metadata/peer-state.d.ts.map +1 -0
- package/dist/src/metadata/peer-state.js +87 -0
- package/dist/src/metadata/peer-state.js.map +1 -0
- package/dist/src/metadata/schema-migration.d.ts +60 -0
- package/dist/src/metadata/schema-migration.d.ts.map +1 -0
- package/dist/src/metadata/schema-migration.js +126 -0
- package/dist/src/metadata/schema-migration.js.map +1 -0
- package/dist/src/metadata/schema-version.d.ts +163 -0
- package/dist/src/metadata/schema-version.d.ts.map +1 -0
- package/dist/src/metadata/schema-version.js +307 -0
- package/dist/src/metadata/schema-version.js.map +1 -0
- package/dist/src/metadata/tombstones.d.ts +67 -0
- package/dist/src/metadata/tombstones.d.ts.map +1 -0
- package/dist/src/metadata/tombstones.js +125 -0
- package/dist/src/metadata/tombstones.js.map +1 -0
- package/dist/src/sync/events.d.ts +117 -0
- package/dist/src/sync/events.d.ts.map +1 -0
- package/dist/src/sync/events.js +56 -0
- package/dist/src/sync/events.js.map +1 -0
- package/dist/src/sync/index.d.ts +8 -0
- package/dist/src/sync/index.d.ts.map +1 -0
- package/dist/src/sync/index.js +8 -0
- package/dist/src/sync/index.js.map +1 -0
- package/dist/src/sync/manager.d.ts +146 -0
- package/dist/src/sync/manager.d.ts.map +1 -0
- package/dist/src/sync/manager.js +8 -0
- package/dist/src/sync/manager.js.map +1 -0
- package/dist/src/sync/protocol.d.ts +282 -0
- package/dist/src/sync/protocol.d.ts.map +1 -0
- package/dist/src/sync/protocol.js +16 -0
- package/dist/src/sync/protocol.js.map +1 -0
- package/dist/src/sync/store-adapter.d.ts +42 -0
- package/dist/src/sync/store-adapter.d.ts.map +1 -0
- package/dist/src/sync/store-adapter.js +232 -0
- package/dist/src/sync/store-adapter.js.map +1 -0
- package/dist/src/sync/sync-manager-impl.d.ts +91 -0
- package/dist/src/sync/sync-manager-impl.d.ts.map +1 -0
- package/dist/src/sync/sync-manager-impl.js +1123 -0
- package/dist/src/sync/sync-manager-impl.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site ID management - unique identifier for each replica.
|
|
3
|
+
*
|
|
4
|
+
* Site IDs are 16-byte UUIDs that uniquely identify a replica in the
|
|
5
|
+
* distributed system. They are used for:
|
|
6
|
+
* - Breaking ties in HLC comparison
|
|
7
|
+
* - Tracking which changes came from which replica
|
|
8
|
+
* - Peer-to-peer sync state tracking
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Generate a new random site ID (UUID v4).
|
|
12
|
+
*/
|
|
13
|
+
export function generateSiteId() {
|
|
14
|
+
const id = new Uint8Array(16);
|
|
15
|
+
// Use crypto.getRandomValues if available (browser and Node 19+)
|
|
16
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
17
|
+
crypto.getRandomValues(id);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
// Fallback for older Node.js
|
|
21
|
+
for (let i = 0; i < 16; i++) {
|
|
22
|
+
id[i] = Math.floor(Math.random() * 256);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Set version to 4 (random UUID)
|
|
26
|
+
id[6] = (id[6] & 0x0f) | 0x40;
|
|
27
|
+
// Set variant to RFC 4122
|
|
28
|
+
id[8] = (id[8] & 0x3f) | 0x80;
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
// Base64url alphabet (RFC 4648 Section 5)
|
|
32
|
+
const BASE64URL_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
33
|
+
/**
|
|
34
|
+
* Convert a Uint8Array to base64url encoding (no padding).
|
|
35
|
+
*/
|
|
36
|
+
export function toBase64Url(bytes) {
|
|
37
|
+
let result = '';
|
|
38
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
39
|
+
const byte1 = bytes[i];
|
|
40
|
+
const byte2 = i + 1 < bytes.length ? bytes[i + 1] : 0;
|
|
41
|
+
const byte3 = i + 2 < bytes.length ? bytes[i + 2] : 0;
|
|
42
|
+
const triplet = (byte1 << 16) | (byte2 << 8) | byte3;
|
|
43
|
+
result += BASE64URL_CHARS[(triplet >>> 18) & 0x3f];
|
|
44
|
+
result += BASE64URL_CHARS[(triplet >>> 12) & 0x3f];
|
|
45
|
+
if (i + 1 < bytes.length) {
|
|
46
|
+
result += BASE64URL_CHARS[(triplet >>> 6) & 0x3f];
|
|
47
|
+
}
|
|
48
|
+
if (i + 2 < bytes.length) {
|
|
49
|
+
result += BASE64URL_CHARS[triplet & 0x3f];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Convert a base64url string to Uint8Array.
|
|
56
|
+
*/
|
|
57
|
+
export function fromBase64Url(str) {
|
|
58
|
+
// Build reverse lookup table
|
|
59
|
+
const lookup = {};
|
|
60
|
+
for (let i = 0; i < BASE64URL_CHARS.length; i++) {
|
|
61
|
+
lookup[BASE64URL_CHARS[i]] = i;
|
|
62
|
+
}
|
|
63
|
+
// Calculate output length (no padding in base64url)
|
|
64
|
+
const len = str.length;
|
|
65
|
+
const outputLen = Math.floor((len * 3) / 4);
|
|
66
|
+
const result = new Uint8Array(outputLen);
|
|
67
|
+
let writePos = 0;
|
|
68
|
+
for (let i = 0; i < len; i += 4) {
|
|
69
|
+
const c1 = lookup[str[i]] ?? 0;
|
|
70
|
+
const c2 = lookup[str[i + 1]] ?? 0;
|
|
71
|
+
const c3 = i + 2 < len ? lookup[str[i + 2]] ?? 0 : 0;
|
|
72
|
+
const c4 = i + 3 < len ? lookup[str[i + 3]] ?? 0 : 0;
|
|
73
|
+
const triplet = (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
|
|
74
|
+
if (writePos < outputLen)
|
|
75
|
+
result[writePos++] = (triplet >>> 16) & 0xff;
|
|
76
|
+
if (writePos < outputLen)
|
|
77
|
+
result[writePos++] = (triplet >>> 8) & 0xff;
|
|
78
|
+
if (writePos < outputLen)
|
|
79
|
+
result[writePos++] = triplet & 0xff;
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convert site ID to base64url string for serialization.
|
|
85
|
+
* 16 bytes → 22 characters (no padding).
|
|
86
|
+
*/
|
|
87
|
+
export function siteIdToBase64(siteId) {
|
|
88
|
+
return toBase64Url(siteId);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Parse site ID from base64url string.
|
|
92
|
+
*/
|
|
93
|
+
export function siteIdFromBase64(base64) {
|
|
94
|
+
if (base64.length !== 22) {
|
|
95
|
+
throw new Error(`Invalid site ID base64 length: ${base64.length}, expected 22`);
|
|
96
|
+
}
|
|
97
|
+
return fromBase64Url(base64);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Compare two site IDs for equality.
|
|
101
|
+
*/
|
|
102
|
+
export function siteIdEquals(a, b) {
|
|
103
|
+
if (a.length !== b.length)
|
|
104
|
+
return false;
|
|
105
|
+
for (let i = 0; i < a.length; i++) {
|
|
106
|
+
if (a[i] !== b[i])
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Storage key for site identity.
|
|
113
|
+
*/
|
|
114
|
+
export const SITE_ID_KEY = 'si:';
|
|
115
|
+
/**
|
|
116
|
+
* Serialize site identity for storage.
|
|
117
|
+
*/
|
|
118
|
+
export function serializeSiteIdentity(identity) {
|
|
119
|
+
const buffer = new Uint8Array(24); // 16 bytes siteId + 8 bytes timestamp
|
|
120
|
+
buffer.set(identity.siteId, 0);
|
|
121
|
+
const view = new DataView(buffer.buffer);
|
|
122
|
+
view.setBigUint64(16, BigInt(identity.createdAt), false);
|
|
123
|
+
return buffer;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Deserialize site identity from storage.
|
|
127
|
+
*/
|
|
128
|
+
export function deserializeSiteIdentity(buffer) {
|
|
129
|
+
if (buffer.length !== 24) {
|
|
130
|
+
throw new Error(`Invalid site identity buffer length: ${buffer.length}, expected 24`);
|
|
131
|
+
}
|
|
132
|
+
const siteId = new Uint8Array(buffer.slice(0, 16));
|
|
133
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
134
|
+
const createdAt = Number(view.getBigUint64(16, false));
|
|
135
|
+
return { siteId, createdAt };
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=site.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../../src/clock/site.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory function to create a sync-enabled store module.
|
|
3
|
+
*
|
|
4
|
+
* This wraps an existing store module (LevelDB or IndexedDB) with
|
|
5
|
+
* CRDT sync capabilities.
|
|
6
|
+
*/
|
|
7
|
+
import type { KVStore, StoreEventEmitter } from '@quereus/plugin-store';
|
|
8
|
+
import type { TableSchema } from '@quereus/quereus';
|
|
9
|
+
import { SyncEventEmitterImpl } from './sync/events.js';
|
|
10
|
+
import { type SyncConfig, type ApplyToStoreCallback } from './sync/protocol.js';
|
|
11
|
+
import type { SyncManager } from './sync/manager.js';
|
|
12
|
+
/**
|
|
13
|
+
* Function to get table schema by name.
|
|
14
|
+
* Used to map column indices to column names for sync.
|
|
15
|
+
*/
|
|
16
|
+
export type GetTableSchemaCallback = (schemaName: string, tableName: string) => TableSchema | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Result of creating a sync module.
|
|
19
|
+
*/
|
|
20
|
+
export interface CreateSyncModuleResult {
|
|
21
|
+
/** The sync manager for sync operations */
|
|
22
|
+
syncManager: SyncManager;
|
|
23
|
+
/** Event emitter for reactive UI integration */
|
|
24
|
+
syncEvents: SyncEventEmitterImpl;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Options for creating a sync module.
|
|
28
|
+
*/
|
|
29
|
+
export interface CreateSyncModuleOptions extends Partial<SyncConfig> {
|
|
30
|
+
/**
|
|
31
|
+
* Callback for applying remote changes to the store.
|
|
32
|
+
*
|
|
33
|
+
* When provided, the SyncManager will call this to apply data and schema
|
|
34
|
+
* changes from remote replicas. The store should emit events with
|
|
35
|
+
* `remote: true` when this is called.
|
|
36
|
+
*
|
|
37
|
+
* If not provided, the SyncManager will only update CRDT metadata
|
|
38
|
+
* and emit sync events, but will not modify actual data. The application
|
|
39
|
+
* is responsible for applying changes separately.
|
|
40
|
+
*/
|
|
41
|
+
applyToStore?: ApplyToStoreCallback;
|
|
42
|
+
/**
|
|
43
|
+
* Callback for getting table schema by name.
|
|
44
|
+
*
|
|
45
|
+
* When provided, the SyncManager uses this to get actual column names
|
|
46
|
+
* for sync. This is required for proper column-level CRDT tracking.
|
|
47
|
+
*
|
|
48
|
+
* If not provided, column names will be derived from row indices (col_0,
|
|
49
|
+
* col_1, etc.), which may not match across replicas if table schemas differ.
|
|
50
|
+
*/
|
|
51
|
+
getTableSchema?: GetTableSchemaCallback;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a sync-enabled module.
|
|
55
|
+
*
|
|
56
|
+
* This function:
|
|
57
|
+
* 1. Creates a SyncManager that tracks CRDT metadata
|
|
58
|
+
* 2. Subscribes to store events to record changes
|
|
59
|
+
* 3. Returns the sync manager and event emitter for UI integration
|
|
60
|
+
*
|
|
61
|
+
* @param kv - The KV store to use for metadata storage
|
|
62
|
+
* @param storeEvents - The store's event emitter
|
|
63
|
+
* @param config - Optional sync configuration
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { LevelDBStore, StoreEventEmitter } from '@quereus/plugin-store';
|
|
68
|
+
* import { createSyncModule } from '@quereus/plugin-sync';
|
|
69
|
+
*
|
|
70
|
+
* const storeEvents = new StoreEventEmitter();
|
|
71
|
+
* const kv = await LevelDBStore.open({ path: './data' });
|
|
72
|
+
*
|
|
73
|
+
* const { syncManager, syncEvents } = await createSyncModule(kv, storeEvents);
|
|
74
|
+
*
|
|
75
|
+
* // Subscribe to sync events for UI
|
|
76
|
+
* syncEvents.onRemoteChange((event) => {
|
|
77
|
+
* console.log('Remote changes:', event.changes.length);
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* // Use syncManager for sync operations
|
|
81
|
+
* const changes = await syncManager.getChangesSince(peerSiteId, lastHLC);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare function createSyncModule(kv: KVStore, storeEvents: StoreEventEmitter, options?: CreateSyncModuleOptions): Promise<CreateSyncModuleResult>;
|
|
85
|
+
//# sourceMappingURL=create-sync-module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-sync-module.d.ts","sourceRoot":"","sources":["../../src/create-sync-module.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAuB,KAAK,UAAU,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;AAExG;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,2CAA2C;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,gDAAgD;IAChD,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,OAAO,CAAC,UAAU,CAAC;IAClE;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;IAEpC;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,OAAO,EACX,WAAW,EAAE,iBAAiB,EAC9B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAuBjC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory function to create a sync-enabled store module.
|
|
3
|
+
*
|
|
4
|
+
* This wraps an existing store module (LevelDB or IndexedDB) with
|
|
5
|
+
* CRDT sync capabilities.
|
|
6
|
+
*/
|
|
7
|
+
import { SyncManagerImpl } from './sync/sync-manager-impl.js';
|
|
8
|
+
import { SyncEventEmitterImpl } from './sync/events.js';
|
|
9
|
+
import { DEFAULT_SYNC_CONFIG } from './sync/protocol.js';
|
|
10
|
+
/**
|
|
11
|
+
* Create a sync-enabled module.
|
|
12
|
+
*
|
|
13
|
+
* This function:
|
|
14
|
+
* 1. Creates a SyncManager that tracks CRDT metadata
|
|
15
|
+
* 2. Subscribes to store events to record changes
|
|
16
|
+
* 3. Returns the sync manager and event emitter for UI integration
|
|
17
|
+
*
|
|
18
|
+
* @param kv - The KV store to use for metadata storage
|
|
19
|
+
* @param storeEvents - The store's event emitter
|
|
20
|
+
* @param config - Optional sync configuration
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { LevelDBStore, StoreEventEmitter } from '@quereus/plugin-store';
|
|
25
|
+
* import { createSyncModule } from '@quereus/plugin-sync';
|
|
26
|
+
*
|
|
27
|
+
* const storeEvents = new StoreEventEmitter();
|
|
28
|
+
* const kv = await LevelDBStore.open({ path: './data' });
|
|
29
|
+
*
|
|
30
|
+
* const { syncManager, syncEvents } = await createSyncModule(kv, storeEvents);
|
|
31
|
+
*
|
|
32
|
+
* // Subscribe to sync events for UI
|
|
33
|
+
* syncEvents.onRemoteChange((event) => {
|
|
34
|
+
* console.log('Remote changes:', event.changes.length);
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Use syncManager for sync operations
|
|
38
|
+
* const changes = await syncManager.getChangesSince(peerSiteId, lastHLC);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export async function createSyncModule(kv, storeEvents, options = {}) {
|
|
42
|
+
const { applyToStore, getTableSchema, ...configOverrides } = options;
|
|
43
|
+
const fullConfig = {
|
|
44
|
+
...DEFAULT_SYNC_CONFIG,
|
|
45
|
+
...configOverrides,
|
|
46
|
+
};
|
|
47
|
+
const syncEvents = new SyncEventEmitterImpl();
|
|
48
|
+
const syncManager = await SyncManagerImpl.create(kv, storeEvents, fullConfig, syncEvents, applyToStore, getTableSchema);
|
|
49
|
+
return {
|
|
50
|
+
syncManager,
|
|
51
|
+
syncEvents,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=create-sync-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-sync-module.js","sourceRoot":"","sources":["../../src/create-sync-module.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAA8C,MAAM,oBAAoB,CAAC;AAgDrG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAW,EACX,WAA8B,EAC9B,UAAmC,EAAE;IAErC,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IAErE,MAAM,UAAU,GAAe;QAC7B,GAAG,mBAAmB;QACtB,GAAG,eAAe;KACnB,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE9C,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,MAAM,CAC9C,EAAE,EACF,WAAW,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,CACf,CAAC;IAEF,OAAO;QACL,WAAW;QACX,UAAU;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync Plugin for Quereus
|
|
3
|
+
*
|
|
4
|
+
* Provides multi-master CRDT replication with automatic conflict resolution.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Fully automatic: All tables are CRDT-enabled without opt-in
|
|
8
|
+
* - Column-level LWW: Fine-grained conflict resolution
|
|
9
|
+
* - Transport agnostic: Bring your own WebSocket/HTTP/WebRTC
|
|
10
|
+
* - Reactive hooks: UI integration for real-time updates
|
|
11
|
+
* - Offline-first: Works with local changes that sync later
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* import { createSyncModule } from '@quereus/plugin-sync';
|
|
15
|
+
* import { LevelDBModule, StoreEventEmitter } from '@quereus/plugin-store';
|
|
16
|
+
*
|
|
17
|
+
* const storeEvents = new StoreEventEmitter();
|
|
18
|
+
* const store = new LevelDBModule(storeEvents);
|
|
19
|
+
* const { syncModule, syncManager, syncEvents } = createSyncModule(store, storeEvents);
|
|
20
|
+
*
|
|
21
|
+
* db.registerVtabModule('store', syncModule);
|
|
22
|
+
*/
|
|
23
|
+
export { type HLC, HLCManager, compareHLC, hlcEquals, createHLC, serializeHLC, deserializeHLC, type SerializedHLC, hlcToJson, hlcFromJson, type SiteId, generateSiteId, siteIdToBase64, siteIdFromBase64, toBase64Url, fromBase64Url, siteIdEquals, type SiteIdentity, serializeSiteIdentity, deserializeSiteIdentity, SITE_ID_KEY, } from './clock/index.js';
|
|
24
|
+
export { type ColumnChange, type RowDeletion, type Change, type SchemaMigrationType, type SchemaMigration, type ChangeSet, type ApplyResult, type ColumnVersionEntry, type TableSnapshot, type Snapshot, type PeerSyncState, type SnapshotChunkType, type SnapshotHeaderChunk, type SnapshotTableStartChunk, type SnapshotColumnVersionsChunk, type SnapshotTableEndChunk, type SnapshotSchemaMigrationChunk, type SnapshotFooterChunk, type SnapshotChunk, type SnapshotProgress, type ApplyToStoreOptions, type DataChangeToApply, type SchemaChangeToApply, type ApplyToStoreResult, type ApplyToStoreCallback, type SyncConfig, DEFAULT_SYNC_CONFIG, } from './sync/protocol.js';
|
|
25
|
+
export { type SyncManager, type SnapshotCheckpoint } from './sync/manager.js';
|
|
26
|
+
export { SyncManagerImpl } from './sync/sync-manager-impl.js';
|
|
27
|
+
export { createStoreAdapter, type SyncStoreAdapterOptions } from './sync/store-adapter.js';
|
|
28
|
+
export { createSyncModule, type CreateSyncModuleResult, type CreateSyncModuleOptions, type GetTableSchemaCallback, } from './create-sync-module.js';
|
|
29
|
+
export { type RemoteChangeEvent, type LocalChangeEvent, type ConflictEvent, type SyncState, type Unsubscribe, type SyncEventEmitter, SyncEventEmitterImpl, } from './sync/events.js';
|
|
30
|
+
export { SYNC_KEY_PREFIX, buildColumnVersionKey, buildTombstoneKey, buildTransactionKey, buildPeerStateKey, buildSchemaMigrationKey, buildColumnVersionScanBounds, buildTombstoneScanBounds, buildSchemaMigrationScanBounds, encodePK, decodePK, type ColumnVersion, ColumnVersionStore, serializeColumnVersion, deserializeColumnVersion, type Tombstone, TombstoneStore, serializeTombstone, deserializeTombstone, type PeerState, PeerStateStore, serializePeerState, deserializePeerState, type SchemaVersion, type SchemaVersionType, type SchemaChangeOperation, SchemaVersionStore, buildSchemaVersionKey, buildSchemaVersionScanBounds, buildAllSchemaVersionsScanBounds, serializeSchemaVersion, deserializeSchemaVersion, parseSchemaVersionKey, getDestructiveness, getOperationDestructiveness, shouldApplySchemaChangeByOperation, } from './metadata/index.js';
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAEL,KAAK,GAAG,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,cAAc,EAEd,KAAK,aAAa,EAClB,SAAS,EACT,WAAW,EAEX,KAAK,MAAM,EACX,cAAc,EAEd,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,KAAK,YAAY,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,MAAM,EAEX,KAAK,mBAAmB,EACxB,KAAK,eAAe,EAEpB,KAAK,SAAS,EAEd,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,aAAa,EAElB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EAErB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAEzB,KAAK,UAAU,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAG3F,OAAO,EACL,gBAAgB,EAChB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAEL,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,wBAAwB,EACxB,8BAA8B,EAC9B,QAAQ,EACR,QAAQ,EAER,KAAK,aAAa,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EAExB,KAAK,SAAS,EACd,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EAEpB,KAAK,SAAS,EACd,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EAEpB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,4BAA4B,EAC5B,gCAAgC,EAChC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EAErB,kBAAkB,EAClB,2BAA2B,EAC3B,kCAAkC,GACnC,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync Plugin for Quereus
|
|
3
|
+
*
|
|
4
|
+
* Provides multi-master CRDT replication with automatic conflict resolution.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Fully automatic: All tables are CRDT-enabled without opt-in
|
|
8
|
+
* - Column-level LWW: Fine-grained conflict resolution
|
|
9
|
+
* - Transport agnostic: Bring your own WebSocket/HTTP/WebRTC
|
|
10
|
+
* - Reactive hooks: UI integration for real-time updates
|
|
11
|
+
* - Offline-first: Works with local changes that sync later
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* import { createSyncModule } from '@quereus/plugin-sync';
|
|
15
|
+
* import { LevelDBModule, StoreEventEmitter } from '@quereus/plugin-store';
|
|
16
|
+
*
|
|
17
|
+
* const storeEvents = new StoreEventEmitter();
|
|
18
|
+
* const store = new LevelDBModule(storeEvents);
|
|
19
|
+
* const { syncModule, syncManager, syncEvents } = createSyncModule(store, storeEvents);
|
|
20
|
+
*
|
|
21
|
+
* db.registerVtabModule('store', syncModule);
|
|
22
|
+
*/
|
|
23
|
+
// Clock module
|
|
24
|
+
export { HLCManager, compareHLC, hlcEquals, createHLC, serializeHLC, deserializeHLC, hlcToJson, hlcFromJson, generateSiteId,
|
|
25
|
+
// Base64url encoding
|
|
26
|
+
siteIdToBase64, siteIdFromBase64, toBase64Url, fromBase64Url, siteIdEquals, serializeSiteIdentity, deserializeSiteIdentity, SITE_ID_KEY, } from './clock/index.js';
|
|
27
|
+
// Sync protocol types
|
|
28
|
+
export { DEFAULT_SYNC_CONFIG, } from './sync/protocol.js';
|
|
29
|
+
export { SyncManagerImpl } from './sync/sync-manager-impl.js';
|
|
30
|
+
// Store adapter for applying remote changes
|
|
31
|
+
export { createStoreAdapter } from './sync/store-adapter.js';
|
|
32
|
+
// Factory function
|
|
33
|
+
export { createSyncModule, } from './create-sync-module.js';
|
|
34
|
+
// Reactive events
|
|
35
|
+
export { SyncEventEmitterImpl, } from './sync/events.js';
|
|
36
|
+
// Metadata storage
|
|
37
|
+
export {
|
|
38
|
+
// Key builders
|
|
39
|
+
SYNC_KEY_PREFIX, buildColumnVersionKey, buildTombstoneKey, buildTransactionKey, buildPeerStateKey, buildSchemaMigrationKey, buildColumnVersionScanBounds, buildTombstoneScanBounds, buildSchemaMigrationScanBounds, encodePK, decodePK, ColumnVersionStore, serializeColumnVersion, deserializeColumnVersion, TombstoneStore, serializeTombstone, deserializeTombstone, PeerStateStore, serializePeerState, deserializePeerState, SchemaVersionStore, buildSchemaVersionKey, buildSchemaVersionScanBounds, buildAllSchemaVersionsScanBounds, serializeSchemaVersion, deserializeSchemaVersion, parseSchemaVersionKey,
|
|
40
|
+
// Most destructive wins
|
|
41
|
+
getDestructiveness, getOperationDestructiveness, shouldApplySchemaChangeByOperation, } from './metadata/index.js';
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAe;AACf,OAAO,EAGL,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,cAAc,EAGd,SAAS,EACT,WAAW,EAGX,cAAc;AACd,qBAAqB;AACrB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,YAAY,EAEZ,qBAAqB,EACrB,uBAAuB,EACvB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,sBAAsB;AACtB,OAAO,EAkCL,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,4CAA4C;AAC5C,OAAO,EAAE,kBAAkB,EAAgC,MAAM,yBAAyB,CAAC;AAE3F,mBAAmB;AACnB,OAAO,EACL,gBAAgB,GAIjB,MAAM,yBAAyB,CAAC;AAEjC,kBAAkB;AAClB,OAAO,EAOL,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,mBAAmB;AACnB,OAAO;AACL,eAAe;AACf,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,4BAA4B,EAC5B,wBAAwB,EACxB,8BAA8B,EAC9B,QAAQ,EACR,QAAQ,EAGR,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EAGxB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EAGpB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EAKpB,kBAAkB,EAClB,qBAAqB,EACrB,4BAA4B,EAC5B,gCAAgC,EAChC,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB;AACrB,wBAAwB;AACxB,kBAAkB,EAClB,2BAA2B,EAC3B,kCAAkC,GACnC,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HLC-indexed change log for efficient delta sync.
|
|
3
|
+
*
|
|
4
|
+
* The change log stores references to changes indexed by HLC timestamp,
|
|
5
|
+
* enabling efficient getChangesSince() queries without scanning all data.
|
|
6
|
+
*/
|
|
7
|
+
import type { KVStore, WriteBatch } from '@quereus/plugin-store';
|
|
8
|
+
import type { SqlValue } from '@quereus/quereus';
|
|
9
|
+
import type { HLC } from '../clock/hlc.js';
|
|
10
|
+
import { type ChangeLogEntryType } from './keys.js';
|
|
11
|
+
/**
|
|
12
|
+
* Change log entry stored in KV.
|
|
13
|
+
*/
|
|
14
|
+
export interface ChangeLogEntry {
|
|
15
|
+
readonly hlc: HLC;
|
|
16
|
+
readonly entryType: ChangeLogEntryType;
|
|
17
|
+
readonly schema: string;
|
|
18
|
+
readonly table: string;
|
|
19
|
+
readonly pk: SqlValue[];
|
|
20
|
+
readonly column?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Change log store for HLC-indexed change tracking.
|
|
24
|
+
*
|
|
25
|
+
* Each mutation (column update or row deletion) creates an entry in the
|
|
26
|
+
* change log, keyed by HLC. This allows efficient range scans to find
|
|
27
|
+
* all changes since a given timestamp.
|
|
28
|
+
*/
|
|
29
|
+
export declare class ChangeLogStore {
|
|
30
|
+
private readonly kv;
|
|
31
|
+
constructor(kv: KVStore);
|
|
32
|
+
/**
|
|
33
|
+
* Record a column change in the change log.
|
|
34
|
+
*/
|
|
35
|
+
recordColumnChange(hlc: HLC, schema: string, table: string, pk: SqlValue[], column: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Record a column change in a batch.
|
|
38
|
+
*/
|
|
39
|
+
recordColumnChangeBatch(batch: WriteBatch, hlc: HLC, schema: string, table: string, pk: SqlValue[], column: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Record a row deletion in the change log.
|
|
42
|
+
*/
|
|
43
|
+
recordDeletion(hlc: HLC, schema: string, table: string, pk: SqlValue[]): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Record a row deletion in a batch.
|
|
46
|
+
*/
|
|
47
|
+
recordDeletionBatch(batch: WriteBatch, hlc: HLC, schema: string, table: string, pk: SqlValue[]): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get all change log entries after a given HLC.
|
|
50
|
+
* Returns entries in HLC order (oldest first).
|
|
51
|
+
*/
|
|
52
|
+
getChangesSince(sinceHLC: HLC): AsyncIterable<ChangeLogEntry>;
|
|
53
|
+
/**
|
|
54
|
+
* Get all change log entries.
|
|
55
|
+
*/
|
|
56
|
+
getAllChanges(): AsyncIterable<ChangeLogEntry>;
|
|
57
|
+
/**
|
|
58
|
+
* Delete change log entries up to a given HLC.
|
|
59
|
+
* Used for pruning old entries after they've been synced to all peers.
|
|
60
|
+
*/
|
|
61
|
+
pruneEntriesBefore(beforeHLC: HLC): Promise<number>;
|
|
62
|
+
/**
|
|
63
|
+
* Delete a specific change log entry (used during snapshot application).
|
|
64
|
+
*/
|
|
65
|
+
deleteEntryBatch(batch: WriteBatch, hlc: HLC, entryType: ChangeLogEntryType, schema: string, table: string, pk: SqlValue[], column?: string): void;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=change-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-log.d.ts","sourceRoot":"","sources":["../../../src/metadata/change-log.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,OAAO;IAExC;;OAEG;IACG,kBAAkB,CACtB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAMhB;;OAEG;IACH,uBAAuB,CACrB,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,EAAE,MAAM,GACb,IAAI;IAKP;;OAEG;IACG,cAAc,CAClB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,QAAQ,EAAE,GACb,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACH,mBAAmB,CACjB,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,QAAQ,EAAE,GACb,IAAI;IAKP;;;OAGG;IACI,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,aAAa,CAAC,cAAc,CAAC;IAUpE;;OAEG;IACI,aAAa,IAAI,aAAa,CAAC,cAAc,CAAC;IAUrD;;;OAGG;IACG,kBAAkB,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBzD;;OAEG;IACH,gBAAgB,CACd,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,CAAC,EAAE,MAAM,GACd,IAAI;CAIR"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HLC-indexed change log for efficient delta sync.
|
|
3
|
+
*
|
|
4
|
+
* The change log stores references to changes indexed by HLC timestamp,
|
|
5
|
+
* enabling efficient getChangesSince() queries without scanning all data.
|
|
6
|
+
*/
|
|
7
|
+
import { buildChangeLogKey, buildChangeLogScanBoundsAfter, buildAllChangeLogScanBounds, parseChangeLogKey, } from './keys.js';
|
|
8
|
+
/**
|
|
9
|
+
* Change log store for HLC-indexed change tracking.
|
|
10
|
+
*
|
|
11
|
+
* Each mutation (column update or row deletion) creates an entry in the
|
|
12
|
+
* change log, keyed by HLC. This allows efficient range scans to find
|
|
13
|
+
* all changes since a given timestamp.
|
|
14
|
+
*/
|
|
15
|
+
export class ChangeLogStore {
|
|
16
|
+
kv;
|
|
17
|
+
constructor(kv) {
|
|
18
|
+
this.kv = kv;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Record a column change in the change log.
|
|
22
|
+
*/
|
|
23
|
+
async recordColumnChange(hlc, schema, table, pk, column) {
|
|
24
|
+
const key = buildChangeLogKey(hlc, 'column', schema, table, pk, column);
|
|
25
|
+
// Value is empty - all info is in the key
|
|
26
|
+
await this.kv.put(key, new Uint8Array(0));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Record a column change in a batch.
|
|
30
|
+
*/
|
|
31
|
+
recordColumnChangeBatch(batch, hlc, schema, table, pk, column) {
|
|
32
|
+
const key = buildChangeLogKey(hlc, 'column', schema, table, pk, column);
|
|
33
|
+
batch.put(key, new Uint8Array(0));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Record a row deletion in the change log.
|
|
37
|
+
*/
|
|
38
|
+
async recordDeletion(hlc, schema, table, pk) {
|
|
39
|
+
const key = buildChangeLogKey(hlc, 'delete', schema, table, pk);
|
|
40
|
+
await this.kv.put(key, new Uint8Array(0));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Record a row deletion in a batch.
|
|
44
|
+
*/
|
|
45
|
+
recordDeletionBatch(batch, hlc, schema, table, pk) {
|
|
46
|
+
const key = buildChangeLogKey(hlc, 'delete', schema, table, pk);
|
|
47
|
+
batch.put(key, new Uint8Array(0));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get all change log entries after a given HLC.
|
|
51
|
+
* Returns entries in HLC order (oldest first).
|
|
52
|
+
*/
|
|
53
|
+
async *getChangesSince(sinceHLC) {
|
|
54
|
+
const bounds = buildChangeLogScanBoundsAfter(sinceHLC);
|
|
55
|
+
for await (const entry of this.kv.iterate(bounds)) {
|
|
56
|
+
const parsed = parseChangeLogKey(entry.key);
|
|
57
|
+
if (parsed) {
|
|
58
|
+
yield parsed;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get all change log entries.
|
|
64
|
+
*/
|
|
65
|
+
async *getAllChanges() {
|
|
66
|
+
const bounds = buildAllChangeLogScanBounds();
|
|
67
|
+
for await (const entry of this.kv.iterate(bounds)) {
|
|
68
|
+
const parsed = parseChangeLogKey(entry.key);
|
|
69
|
+
if (parsed) {
|
|
70
|
+
yield parsed;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Delete change log entries up to a given HLC.
|
|
76
|
+
* Used for pruning old entries after they've been synced to all peers.
|
|
77
|
+
*/
|
|
78
|
+
async pruneEntriesBefore(beforeHLC) {
|
|
79
|
+
const bounds = buildAllChangeLogScanBounds();
|
|
80
|
+
const batch = this.kv.batch();
|
|
81
|
+
let count = 0;
|
|
82
|
+
for await (const entry of this.kv.iterate(bounds)) {
|
|
83
|
+
const parsed = parseChangeLogKey(entry.key);
|
|
84
|
+
if (!parsed)
|
|
85
|
+
continue;
|
|
86
|
+
// Compare HLCs - stop when we reach entries >= beforeHLC
|
|
87
|
+
if (parsed.hlc.wallTime > beforeHLC.wallTime)
|
|
88
|
+
break;
|
|
89
|
+
if (parsed.hlc.wallTime === beforeHLC.wallTime) {
|
|
90
|
+
if (parsed.hlc.counter >= beforeHLC.counter)
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
batch.delete(entry.key);
|
|
94
|
+
count++;
|
|
95
|
+
}
|
|
96
|
+
await batch.write();
|
|
97
|
+
return count;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Delete a specific change log entry (used during snapshot application).
|
|
101
|
+
*/
|
|
102
|
+
deleteEntryBatch(batch, hlc, entryType, schema, table, pk, column) {
|
|
103
|
+
const key = buildChangeLogKey(hlc, entryType, schema, table, pk, column);
|
|
104
|
+
batch.delete(key);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=change-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-log.js","sourceRoot":"","sources":["../../../src/metadata/change-log.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,2BAA2B,EAC3B,iBAAiB,GAElB,MAAM,WAAW,CAAC;AAcnB;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,EAAW;QAAX,OAAE,GAAF,EAAE,CAAS;IAAG,CAAC;IAE5C;;OAEG;IACH,KAAK,CAAC,kBAAkB,CACtB,GAAQ,EACR,MAAc,EACd,KAAa,EACb,EAAc,EACd,MAAc;QAEd,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACxE,0CAA0C;QAC1C,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,uBAAuB,CACrB,KAAiB,EACjB,GAAQ,EACR,MAAc,EACd,KAAa,EACb,EAAc,EACd,MAAc;QAEd,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACxE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAClB,GAAQ,EACR,MAAc,EACd,KAAa,EACb,EAAc;QAEd,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,mBAAmB,CACjB,KAAiB,EACjB,GAAQ,EACR,MAAc,EACd,KAAa,EACb,EAAc;QAEd,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAChE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAC,eAAe,CAAC,QAAa;QAClC,MAAM,MAAM,GAAG,6BAA6B,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAC,aAAa;QAClB,MAAM,MAAM,GAAG,2BAA2B,EAAE,CAAC;QAC7C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,MAAM,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,kBAAkB,CAAC,SAAc;QACrC,MAAM,MAAM,GAAG,2BAA2B,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM;gBAAE,SAAS;YAEtB,yDAAyD;YACzD,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ;gBAAE,MAAM;YACpD,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC/C,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;oBAAE,MAAM;YACrD,CAAC;YAED,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxB,KAAK,EAAE,CAAC;QACV,CAAC;QAED,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,gBAAgB,CACd,KAAiB,EACjB,GAAQ,EACR,SAA6B,EAC7B,MAAc,EACd,KAAa,EACb,EAAc,EACd,MAAe;QAEf,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACzE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column version tracking for LWW conflict resolution.
|
|
3
|
+
*
|
|
4
|
+
* Each column of each row has an associated HLC timestamp.
|
|
5
|
+
* When merging changes, the column with the higher HLC wins.
|
|
6
|
+
*/
|
|
7
|
+
import type { SqlValue } from '@quereus/quereus';
|
|
8
|
+
import type { KVStore, WriteBatch } from '@quereus/plugin-store';
|
|
9
|
+
import { type HLC } from '../clock/hlc.js';
|
|
10
|
+
/**
|
|
11
|
+
* Column version record stored in the KV store.
|
|
12
|
+
*/
|
|
13
|
+
export interface ColumnVersion {
|
|
14
|
+
hlc: HLC;
|
|
15
|
+
value: SqlValue;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Serialize a column version for storage.
|
|
19
|
+
* Format: 26 bytes HLC + JSON value
|
|
20
|
+
*/
|
|
21
|
+
export declare function serializeColumnVersion(cv: ColumnVersion): Uint8Array;
|
|
22
|
+
/**
|
|
23
|
+
* Deserialize a column version from storage.
|
|
24
|
+
*/
|
|
25
|
+
export declare function deserializeColumnVersion(buffer: Uint8Array): ColumnVersion;
|
|
26
|
+
/**
|
|
27
|
+
* Column version store operations.
|
|
28
|
+
*/
|
|
29
|
+
export declare class ColumnVersionStore {
|
|
30
|
+
private readonly kv;
|
|
31
|
+
constructor(kv: KVStore);
|
|
32
|
+
/**
|
|
33
|
+
* Get the version of a specific column.
|
|
34
|
+
*/
|
|
35
|
+
getColumnVersion(schemaName: string, tableName: string, pk: SqlValue[], column: string): Promise<ColumnVersion | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Set the version of a specific column.
|
|
38
|
+
*/
|
|
39
|
+
setColumnVersion(schemaName: string, tableName: string, pk: SqlValue[], column: string, version: ColumnVersion): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Set column version in a batch.
|
|
42
|
+
*/
|
|
43
|
+
setColumnVersionBatch(batch: WriteBatch, schemaName: string, tableName: string, pk: SqlValue[], column: string, version: ColumnVersion): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get all column versions for a row.
|
|
46
|
+
*/
|
|
47
|
+
getRowVersions(schemaName: string, tableName: string, pk: SqlValue[]): Promise<Map<string, ColumnVersion>>;
|
|
48
|
+
/**
|
|
49
|
+
* Delete all column versions for a row.
|
|
50
|
+
*/
|
|
51
|
+
deleteRowVersions(schemaName: string, tableName: string, pk: SqlValue[]): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a column write should be applied (LWW comparison).
|
|
54
|
+
* Returns true if the incoming HLC is newer than the current version.
|
|
55
|
+
*/
|
|
56
|
+
shouldApplyWrite(schemaName: string, tableName: string, pk: SqlValue[], column: string, incomingHLC: HLC): Promise<boolean>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=column-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column-version.d.ts","sourceRoot":"","sources":["../../../src/metadata/column-version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,KAAK,GAAG,EAA4C,MAAM,iBAAiB,CAAC;AAGrF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,aAAa,GAAG,UAAU,CASpE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAK1E;AAED;;GAEG;AACH,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,OAAO;IAExC;;OAEG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAOrC;;OAEG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACH,qBAAqB,CACnB,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,GACrB,IAAI;IAKP;;OAEG;IACG,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,QAAQ,EAAE,GACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAgBtC;;OAEG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,QAAQ,EAAE,GACb,OAAO,CAAC,IAAI,CAAC;IAWhB;;;OAGG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,QAAQ,EAAE,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,GAAG,GACf,OAAO,CAAC,OAAO,CAAC;CAKpB"}
|