@nahisaho/yata-scale 1.8.5
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 +66 -0
- package/dist/CacheManager.d.ts +107 -0
- package/dist/CacheManager.d.ts.map +1 -0
- package/dist/CacheManager.js +343 -0
- package/dist/CacheManager.js.map +1 -0
- package/dist/IndexManager.d.ts +103 -0
- package/dist/IndexManager.d.ts.map +1 -0
- package/dist/IndexManager.js +385 -0
- package/dist/IndexManager.js.map +1 -0
- package/dist/MigrationHelper.d.ts +91 -0
- package/dist/MigrationHelper.d.ts.map +1 -0
- package/dist/MigrationHelper.js +220 -0
- package/dist/MigrationHelper.js.map +1 -0
- package/dist/QueryCoordinator.d.ts +76 -0
- package/dist/QueryCoordinator.d.ts.map +1 -0
- package/dist/QueryCoordinator.js +298 -0
- package/dist/QueryCoordinator.js.map +1 -0
- package/dist/ShardManager.d.ts +48 -0
- package/dist/ShardManager.d.ts.map +1 -0
- package/dist/ShardManager.js +193 -0
- package/dist/ShardManager.js.map +1 -0
- package/dist/SyncController.d.ts +102 -0
- package/dist/SyncController.d.ts.map +1 -0
- package/dist/SyncController.js +286 -0
- package/dist/SyncController.js.map +1 -0
- package/dist/YataScaleManager.d.ts +75 -0
- package/dist/YataScaleManager.d.ts.map +1 -0
- package/dist/YataScaleManager.js +265 -0
- package/dist/YataScaleManager.js.map +1 -0
- package/dist/cache/CacheManager.d.ts +116 -0
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +286 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/cache/InvalidationManager.d.ts +91 -0
- package/dist/cache/InvalidationManager.d.ts.map +1 -0
- package/dist/cache/InvalidationManager.js +155 -0
- package/dist/cache/InvalidationManager.js.map +1 -0
- package/dist/cache/L1Cache.d.ts +97 -0
- package/dist/cache/L1Cache.d.ts.map +1 -0
- package/dist/cache/L1Cache.js +225 -0
- package/dist/cache/L1Cache.js.map +1 -0
- package/dist/cache/L2Cache.d.ts +93 -0
- package/dist/cache/L2Cache.d.ts.map +1 -0
- package/dist/cache/L2Cache.js +248 -0
- package/dist/cache/L2Cache.js.map +1 -0
- package/dist/cache/L3Cache.d.ts +101 -0
- package/dist/cache/L3Cache.d.ts.map +1 -0
- package/dist/cache/L3Cache.js +229 -0
- package/dist/cache/L3Cache.js.map +1 -0
- package/dist/cache/index.d.ts +12 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +11 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/errors.d.ts +255 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +515 -0
- package/dist/errors.js.map +1 -0
- package/dist/index/BPlusTreeIndex.d.ts +101 -0
- package/dist/index/BPlusTreeIndex.d.ts.map +1 -0
- package/dist/index/BPlusTreeIndex.js +310 -0
- package/dist/index/BPlusTreeIndex.js.map +1 -0
- package/dist/index/BloomFilter.d.ts +85 -0
- package/dist/index/BloomFilter.d.ts.map +1 -0
- package/dist/index/BloomFilter.js +215 -0
- package/dist/index/BloomFilter.js.map +1 -0
- package/dist/index/FullTextIndex.d.ts +87 -0
- package/dist/index/FullTextIndex.d.ts.map +1 -0
- package/dist/index/FullTextIndex.js +213 -0
- package/dist/index/FullTextIndex.js.map +1 -0
- package/dist/index/GraphIndex.d.ts +116 -0
- package/dist/index/GraphIndex.d.ts.map +1 -0
- package/dist/index/GraphIndex.js +308 -0
- package/dist/index/GraphIndex.js.map +1 -0
- package/dist/index/IndexManager.d.ts +105 -0
- package/dist/index/IndexManager.d.ts.map +1 -0
- package/dist/index/IndexManager.js +287 -0
- package/dist/index/IndexManager.js.map +1 -0
- package/dist/index/index.d.ts +12 -0
- package/dist/index/index.d.ts.map +1 -0
- package/dist/index/index.js +11 -0
- package/dist/index/index.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/query/DistributedExecutor.d.ts +78 -0
- package/dist/query/DistributedExecutor.d.ts.map +1 -0
- package/dist/query/DistributedExecutor.js +232 -0
- package/dist/query/DistributedExecutor.js.map +1 -0
- package/dist/query/QueryCoordinator.d.ts +98 -0
- package/dist/query/QueryCoordinator.d.ts.map +1 -0
- package/dist/query/QueryCoordinator.js +246 -0
- package/dist/query/QueryCoordinator.js.map +1 -0
- package/dist/query/QueryPlanner.d.ts +88 -0
- package/dist/query/QueryPlanner.d.ts.map +1 -0
- package/dist/query/QueryPlanner.js +235 -0
- package/dist/query/QueryPlanner.js.map +1 -0
- package/dist/query/WorkerPool.d.ts +108 -0
- package/dist/query/WorkerPool.d.ts.map +1 -0
- package/dist/query/WorkerPool.js +195 -0
- package/dist/query/WorkerPool.js.map +1 -0
- package/dist/query/index.d.ts +11 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +10 -0
- package/dist/query/index.js.map +1 -0
- package/dist/shard/GraphPartitionStrategy.d.ts +65 -0
- package/dist/shard/GraphPartitionStrategy.d.ts.map +1 -0
- package/dist/shard/GraphPartitionStrategy.js +208 -0
- package/dist/shard/GraphPartitionStrategy.js.map +1 -0
- package/dist/shard/HashPartitionStrategy.d.ts +56 -0
- package/dist/shard/HashPartitionStrategy.d.ts.map +1 -0
- package/dist/shard/HashPartitionStrategy.js +169 -0
- package/dist/shard/HashPartitionStrategy.js.map +1 -0
- package/dist/shard/RangePartitionStrategy.d.ts +63 -0
- package/dist/shard/RangePartitionStrategy.d.ts.map +1 -0
- package/dist/shard/RangePartitionStrategy.js +157 -0
- package/dist/shard/RangePartitionStrategy.js.map +1 -0
- package/dist/shard/Rebalancer.d.ts +70 -0
- package/dist/shard/Rebalancer.d.ts.map +1 -0
- package/dist/shard/Rebalancer.js +184 -0
- package/dist/shard/Rebalancer.js.map +1 -0
- package/dist/shard/ShardManager.d.ts +123 -0
- package/dist/shard/ShardManager.d.ts.map +1 -0
- package/dist/shard/ShardManager.js +353 -0
- package/dist/shard/ShardManager.js.map +1 -0
- package/dist/shard/ShardRouter.d.ts +102 -0
- package/dist/shard/ShardRouter.d.ts.map +1 -0
- package/dist/shard/ShardRouter.js +181 -0
- package/dist/shard/ShardRouter.js.map +1 -0
- package/dist/shard/index.d.ts +13 -0
- package/dist/shard/index.d.ts.map +1 -0
- package/dist/shard/index.js +12 -0
- package/dist/shard/index.js.map +1 -0
- package/dist/sync/ConflictResolver.d.ts +71 -0
- package/dist/sync/ConflictResolver.d.ts.map +1 -0
- package/dist/sync/ConflictResolver.js +214 -0
- package/dist/sync/ConflictResolver.js.map +1 -0
- package/dist/sync/SyncController.d.ts +150 -0
- package/dist/sync/SyncController.d.ts.map +1 -0
- package/dist/sync/SyncController.js +304 -0
- package/dist/sync/SyncController.js.map +1 -0
- package/dist/sync/VectorClock.d.ts +102 -0
- package/dist/sync/VectorClock.d.ts.map +1 -0
- package/dist/sync/VectorClock.js +189 -0
- package/dist/sync/VectorClock.js.map +1 -0
- package/dist/sync/WALManager.d.ts +120 -0
- package/dist/sync/WALManager.d.ts.map +1 -0
- package/dist/sync/WALManager.js +240 -0
- package/dist/sync/WALManager.js.map +1 -0
- package/dist/sync/index.d.ts +11 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +10 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/types.d.ts +323 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Sync Controller
|
|
3
|
+
*
|
|
4
|
+
* Coordinates synchronization between nodes
|
|
5
|
+
*/
|
|
6
|
+
import { ok, err } from 'neverthrow';
|
|
7
|
+
import { SyncError, SyncConnectionError } from '../errors.js';
|
|
8
|
+
import { VectorClock } from './VectorClock.js';
|
|
9
|
+
import { ConflictResolver } from './ConflictResolver.js';
|
|
10
|
+
import { WALManager } from './WALManager.js';
|
|
11
|
+
/**
|
|
12
|
+
* Sync controller for managing distributed synchronization
|
|
13
|
+
*/
|
|
14
|
+
export class SyncController {
|
|
15
|
+
nodeId;
|
|
16
|
+
wal;
|
|
17
|
+
conflictResolver;
|
|
18
|
+
vectorClock;
|
|
19
|
+
state = 'idle';
|
|
20
|
+
activeSessions = new Map();
|
|
21
|
+
peers = new Map();
|
|
22
|
+
constructor(nodeId, resolutionStrategy = 'last-writer-wins') {
|
|
23
|
+
this.nodeId = nodeId;
|
|
24
|
+
this.wal = new WALManager();
|
|
25
|
+
this.conflictResolver = new ConflictResolver(resolutionStrategy);
|
|
26
|
+
this.vectorClock = new VectorClock();
|
|
27
|
+
this.vectorClock.increment(nodeId);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Register a peer
|
|
31
|
+
*/
|
|
32
|
+
registerPeer(peerId, endpoint) {
|
|
33
|
+
this.peers.set(peerId, {
|
|
34
|
+
peerId,
|
|
35
|
+
endpoint,
|
|
36
|
+
vectorClock: new VectorClock(),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Unregister a peer
|
|
41
|
+
*/
|
|
42
|
+
unregisterPeer(peerId) {
|
|
43
|
+
this.peers.delete(peerId);
|
|
44
|
+
this.activeSessions.delete(peerId);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Record entity create
|
|
48
|
+
*/
|
|
49
|
+
recordCreate(entity) {
|
|
50
|
+
this.vectorClock.increment(this.nodeId);
|
|
51
|
+
this.wal.appendCreate(entity);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Record entity update
|
|
55
|
+
*/
|
|
56
|
+
recordUpdate(entity, previous) {
|
|
57
|
+
this.vectorClock.increment(this.nodeId);
|
|
58
|
+
this.wal.appendUpdate(entity, previous);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Record entity delete
|
|
62
|
+
*/
|
|
63
|
+
recordDelete(entityId, previous) {
|
|
64
|
+
this.vectorClock.increment(this.nodeId);
|
|
65
|
+
this.wal.appendDelete(entityId, previous);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Record relationship create
|
|
69
|
+
*/
|
|
70
|
+
recordRelationshipCreate(relationship) {
|
|
71
|
+
this.vectorClock.increment(this.nodeId);
|
|
72
|
+
this.wal.appendRelationshipCreate(relationship);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Record relationship update
|
|
76
|
+
*/
|
|
77
|
+
recordRelationshipUpdate(relationship, previous) {
|
|
78
|
+
this.vectorClock.increment(this.nodeId);
|
|
79
|
+
this.wal.appendRelationshipUpdate(relationship, previous);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Record relationship delete
|
|
83
|
+
*/
|
|
84
|
+
recordRelationshipDelete(relationshipId, previous) {
|
|
85
|
+
this.vectorClock.increment(this.nodeId);
|
|
86
|
+
this.wal.appendRelationshipDelete(relationshipId, previous);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get local delta since a sequence number
|
|
90
|
+
*/
|
|
91
|
+
getLocalDelta(sinceSequence) {
|
|
92
|
+
const entries = this.wal.getEntriesSince(sinceSequence);
|
|
93
|
+
const entities = [];
|
|
94
|
+
const relationships = [];
|
|
95
|
+
const deletedEntityIds = [];
|
|
96
|
+
const deletedRelationshipIds = [];
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
if (entry.entityType === 'entity') {
|
|
99
|
+
if (entry.operation === 'delete') {
|
|
100
|
+
deletedEntityIds.push(entry.entityId);
|
|
101
|
+
}
|
|
102
|
+
else if (entry.data) {
|
|
103
|
+
entities.push(entry.data);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
if (entry.operation === 'delete') {
|
|
108
|
+
deletedRelationshipIds.push(entry.entityId);
|
|
109
|
+
}
|
|
110
|
+
else if (entry.data) {
|
|
111
|
+
relationships.push(entry.data);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
entities,
|
|
117
|
+
relationships,
|
|
118
|
+
deletedEntityIds,
|
|
119
|
+
deletedRelationshipIds,
|
|
120
|
+
vectorClock: this.vectorClock.toValue(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Apply remote delta
|
|
125
|
+
*/
|
|
126
|
+
applyRemoteDelta(delta, localEntities, localRelationships) {
|
|
127
|
+
const startTime = Date.now();
|
|
128
|
+
let entitiesSynced = 0;
|
|
129
|
+
let relationshipsSynced = 0;
|
|
130
|
+
let conflictsResolved = 0;
|
|
131
|
+
const errors = [];
|
|
132
|
+
try {
|
|
133
|
+
this.state = 'syncing';
|
|
134
|
+
// Apply entity changes
|
|
135
|
+
for (const remoteEntity of delta.entities) {
|
|
136
|
+
const localEntity = localEntities.get(remoteEntity.id);
|
|
137
|
+
if (localEntity) {
|
|
138
|
+
// Check for conflict
|
|
139
|
+
const conflict = this.conflictResolver.detectEntityConflict(localEntity, remoteEntity);
|
|
140
|
+
if (conflict) {
|
|
141
|
+
const resolution = this.conflictResolver.resolveEntityConflict(localEntity, remoteEntity, conflict);
|
|
142
|
+
localEntities.set(remoteEntity.id, resolution.winner);
|
|
143
|
+
conflictsResolved++;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// No conflict - check causality
|
|
147
|
+
const localClock = new VectorClock(localEntity.metadata.vectorClock);
|
|
148
|
+
const remoteClock = new VectorClock(remoteEntity.metadata.vectorClock);
|
|
149
|
+
if (remoteClock.happenedAfter(localClock)) {
|
|
150
|
+
localEntities.set(remoteEntity.id, remoteEntity);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// New entity
|
|
156
|
+
localEntities.set(remoteEntity.id, remoteEntity);
|
|
157
|
+
}
|
|
158
|
+
entitiesSynced++;
|
|
159
|
+
}
|
|
160
|
+
// Apply entity deletions
|
|
161
|
+
for (const entityId of delta.deletedEntityIds) {
|
|
162
|
+
localEntities.delete(entityId);
|
|
163
|
+
entitiesSynced++;
|
|
164
|
+
}
|
|
165
|
+
// Apply relationship changes
|
|
166
|
+
for (const remoteRel of delta.relationships) {
|
|
167
|
+
const localRel = localRelationships.get(remoteRel.id);
|
|
168
|
+
if (localRel) {
|
|
169
|
+
const resolution = this.conflictResolver.resolveRelationshipConflict(localRel, remoteRel);
|
|
170
|
+
localRelationships.set(remoteRel.id, resolution.winner);
|
|
171
|
+
if (resolution.resolution === 'merged') {
|
|
172
|
+
conflictsResolved++;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
localRelationships.set(remoteRel.id, remoteRel);
|
|
177
|
+
}
|
|
178
|
+
relationshipsSynced++;
|
|
179
|
+
}
|
|
180
|
+
// Apply relationship deletions
|
|
181
|
+
for (const relId of delta.deletedRelationshipIds) {
|
|
182
|
+
localRelationships.delete(relId);
|
|
183
|
+
relationshipsSynced++;
|
|
184
|
+
}
|
|
185
|
+
// Merge vector clocks
|
|
186
|
+
this.vectorClock.merge(new VectorClock(delta.vectorClock));
|
|
187
|
+
this.vectorClock.increment(this.nodeId);
|
|
188
|
+
this.state = 'idle';
|
|
189
|
+
return ok({
|
|
190
|
+
success: true,
|
|
191
|
+
entitiesSynced,
|
|
192
|
+
relationshipsSynced,
|
|
193
|
+
conflictsResolved,
|
|
194
|
+
errors,
|
|
195
|
+
duration: Date.now() - startTime,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
this.state = 'error';
|
|
200
|
+
return err(new SyncError(`Failed to apply remote delta: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Start sync session with peer
|
|
205
|
+
*/
|
|
206
|
+
startSession(peerId) {
|
|
207
|
+
const peer = this.peers.get(peerId);
|
|
208
|
+
if (!peer) {
|
|
209
|
+
return err(new SyncConnectionError(peerId, 'Peer not found'));
|
|
210
|
+
}
|
|
211
|
+
const session = {
|
|
212
|
+
sessionId: `sync_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
213
|
+
localNodeId: this.nodeId,
|
|
214
|
+
remoteNodeId: peerId,
|
|
215
|
+
startTime: new Date(),
|
|
216
|
+
state: 'negotiating',
|
|
217
|
+
localVectorClock: this.vectorClock.toValue(),
|
|
218
|
+
};
|
|
219
|
+
this.activeSessions.set(peerId, session);
|
|
220
|
+
return ok(session);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* End sync session
|
|
224
|
+
*/
|
|
225
|
+
endSession(peerId) {
|
|
226
|
+
const session = this.activeSessions.get(peerId);
|
|
227
|
+
if (session) {
|
|
228
|
+
session.state = 'completed';
|
|
229
|
+
session.endTime = new Date();
|
|
230
|
+
// Update peer's last sync time
|
|
231
|
+
const peer = this.peers.get(peerId);
|
|
232
|
+
if (peer) {
|
|
233
|
+
peer.lastSyncTime = new Date();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
this.activeSessions.delete(peerId);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Get current sync state
|
|
240
|
+
*/
|
|
241
|
+
getState() {
|
|
242
|
+
return this.state;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get vector clock
|
|
246
|
+
*/
|
|
247
|
+
getVectorClock() {
|
|
248
|
+
return this.vectorClock.clone();
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get WAL manager
|
|
252
|
+
*/
|
|
253
|
+
getWAL() {
|
|
254
|
+
return this.wal;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get conflict resolver
|
|
258
|
+
*/
|
|
259
|
+
getConflictResolver() {
|
|
260
|
+
return this.conflictResolver;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get active sessions
|
|
264
|
+
*/
|
|
265
|
+
getActiveSessions() {
|
|
266
|
+
return [...this.activeSessions.values()];
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Get registered peers
|
|
270
|
+
*/
|
|
271
|
+
getPeers() {
|
|
272
|
+
return [...this.peers.values()];
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get node ID
|
|
276
|
+
*/
|
|
277
|
+
getNodeId() {
|
|
278
|
+
return this.nodeId;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get sync statistics
|
|
282
|
+
*/
|
|
283
|
+
getStats() {
|
|
284
|
+
return {
|
|
285
|
+
nodeId: this.nodeId,
|
|
286
|
+
state: this.state,
|
|
287
|
+
activeSessions: this.activeSessions.size,
|
|
288
|
+
registeredPeers: this.peers.size,
|
|
289
|
+
walSequence: this.wal.getLatestSequence(),
|
|
290
|
+
vectorClock: this.vectorClock.toValue(),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Reset sync state
|
|
295
|
+
*/
|
|
296
|
+
reset() {
|
|
297
|
+
this.state = 'idle';
|
|
298
|
+
this.activeSessions.clear();
|
|
299
|
+
this.wal.clear();
|
|
300
|
+
this.vectorClock.clear();
|
|
301
|
+
this.vectorClock.increment(this.nodeId);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=SyncController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SyncController.js","sourceRoot":"","sources":["../../src/sync/SyncController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Vector Clock
|
|
3
|
+
*
|
|
4
|
+
* Logical clock for causality tracking
|
|
5
|
+
*/
|
|
6
|
+
import type { VectorClockValue } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Comparison result
|
|
9
|
+
*/
|
|
10
|
+
export type ClockComparison = 'before' | 'after' | 'concurrent' | 'equal';
|
|
11
|
+
/**
|
|
12
|
+
* Vector clock for distributed causality tracking
|
|
13
|
+
*/
|
|
14
|
+
export declare class VectorClock {
|
|
15
|
+
private clock;
|
|
16
|
+
constructor(initial?: VectorClockValue);
|
|
17
|
+
/**
|
|
18
|
+
* Increment clock for a node
|
|
19
|
+
*/
|
|
20
|
+
increment(nodeId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get clock value for a node
|
|
23
|
+
*/
|
|
24
|
+
get(nodeId: string): number;
|
|
25
|
+
/**
|
|
26
|
+
* Set clock value for a node
|
|
27
|
+
*/
|
|
28
|
+
set(nodeId: string, value: number): void;
|
|
29
|
+
/**
|
|
30
|
+
* Merge with another clock (point-wise maximum)
|
|
31
|
+
*/
|
|
32
|
+
merge(other: VectorClock): void;
|
|
33
|
+
/**
|
|
34
|
+
* Compare with another clock
|
|
35
|
+
*/
|
|
36
|
+
compare(other: VectorClock): ClockComparison;
|
|
37
|
+
/**
|
|
38
|
+
* Check if this clock happened before another
|
|
39
|
+
*/
|
|
40
|
+
happenedBefore(other: VectorClock): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Check if this clock happened after another
|
|
43
|
+
*/
|
|
44
|
+
happenedAfter(other: VectorClock): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if concurrent with another clock
|
|
47
|
+
*/
|
|
48
|
+
isConcurrentWith(other: VectorClock): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Check if equal to another clock
|
|
51
|
+
*/
|
|
52
|
+
isEqual(other: VectorClock): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Clone this clock
|
|
55
|
+
*/
|
|
56
|
+
clone(): VectorClock;
|
|
57
|
+
/**
|
|
58
|
+
* Convert to plain object
|
|
59
|
+
*/
|
|
60
|
+
toValue(): VectorClockValue;
|
|
61
|
+
/**
|
|
62
|
+
* Create from plain object
|
|
63
|
+
*/
|
|
64
|
+
static fromValue(value: VectorClockValue): VectorClock;
|
|
65
|
+
/**
|
|
66
|
+
* Serialize to string
|
|
67
|
+
*/
|
|
68
|
+
serialize(): string;
|
|
69
|
+
/**
|
|
70
|
+
* Deserialize from string
|
|
71
|
+
*/
|
|
72
|
+
static deserialize(data: string): VectorClock;
|
|
73
|
+
/**
|
|
74
|
+
* Get all node IDs
|
|
75
|
+
*/
|
|
76
|
+
getNodes(): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Get number of nodes
|
|
79
|
+
*/
|
|
80
|
+
get size(): number;
|
|
81
|
+
/**
|
|
82
|
+
* Check if empty
|
|
83
|
+
*/
|
|
84
|
+
get isEmpty(): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Get maximum timestamp across all nodes
|
|
87
|
+
*/
|
|
88
|
+
getMaxTimestamp(): number;
|
|
89
|
+
/**
|
|
90
|
+
* Get sum of all timestamps
|
|
91
|
+
*/
|
|
92
|
+
getSum(): number;
|
|
93
|
+
/**
|
|
94
|
+
* Clear the clock
|
|
95
|
+
*/
|
|
96
|
+
clear(): void;
|
|
97
|
+
/**
|
|
98
|
+
* String representation
|
|
99
|
+
*/
|
|
100
|
+
toString(): string;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=VectorClock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VectorClock.d.ts","sourceRoot":"","sources":["../../src/sync/VectorClock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,CAAC;AAE1E;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAsB;gBAEvB,OAAO,CAAC,EAAE,gBAAgB;IAItC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI3B;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxC;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAO/B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,eAAe;IAgC5C;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAI3C;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAI1C;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAI7C;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAIpC;;OAEG;IACH,KAAK,IAAI,WAAW;IAMpB;;OAEG;IACH,OAAO,IAAI,gBAAgB;IAI3B;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW;IAItD;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAI7C;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAIpB;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,eAAe,IAAI,MAAM;IAUzB;;OAEG;IACH,MAAM,IAAI,MAAM;IAQhB;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,QAAQ,IAAI,MAAM;CAMnB"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Vector Clock
|
|
3
|
+
*
|
|
4
|
+
* Logical clock for causality tracking
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Vector clock for distributed causality tracking
|
|
8
|
+
*/
|
|
9
|
+
export class VectorClock {
|
|
10
|
+
clock;
|
|
11
|
+
constructor(initial) {
|
|
12
|
+
this.clock = new Map(Object.entries(initial ?? {}));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Increment clock for a node
|
|
16
|
+
*/
|
|
17
|
+
increment(nodeId) {
|
|
18
|
+
const current = this.clock.get(nodeId) ?? 0;
|
|
19
|
+
this.clock.set(nodeId, current + 1);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get clock value for a node
|
|
23
|
+
*/
|
|
24
|
+
get(nodeId) {
|
|
25
|
+
return this.clock.get(nodeId) ?? 0;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Set clock value for a node
|
|
29
|
+
*/
|
|
30
|
+
set(nodeId, value) {
|
|
31
|
+
this.clock.set(nodeId, value);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Merge with another clock (point-wise maximum)
|
|
35
|
+
*/
|
|
36
|
+
merge(other) {
|
|
37
|
+
for (const [nodeId, value] of other.clock) {
|
|
38
|
+
const current = this.clock.get(nodeId) ?? 0;
|
|
39
|
+
this.clock.set(nodeId, Math.max(current, value));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compare with another clock
|
|
44
|
+
*/
|
|
45
|
+
compare(other) {
|
|
46
|
+
let hasGreater = false;
|
|
47
|
+
let hasLess = false;
|
|
48
|
+
// Check all nodes in this clock
|
|
49
|
+
for (const [nodeId, value] of this.clock) {
|
|
50
|
+
const otherValue = other.get(nodeId);
|
|
51
|
+
if (value > otherValue) {
|
|
52
|
+
hasGreater = true;
|
|
53
|
+
}
|
|
54
|
+
else if (value < otherValue) {
|
|
55
|
+
hasLess = true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Check nodes in other clock that we don't have
|
|
59
|
+
for (const [nodeId, otherValue] of other.clock) {
|
|
60
|
+
if (!this.clock.has(nodeId) && otherValue > 0) {
|
|
61
|
+
hasLess = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (hasGreater && hasLess) {
|
|
65
|
+
return 'concurrent';
|
|
66
|
+
}
|
|
67
|
+
else if (hasGreater) {
|
|
68
|
+
return 'after';
|
|
69
|
+
}
|
|
70
|
+
else if (hasLess) {
|
|
71
|
+
return 'before';
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return 'equal';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check if this clock happened before another
|
|
79
|
+
*/
|
|
80
|
+
happenedBefore(other) {
|
|
81
|
+
return this.compare(other) === 'before';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if this clock happened after another
|
|
85
|
+
*/
|
|
86
|
+
happenedAfter(other) {
|
|
87
|
+
return this.compare(other) === 'after';
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if concurrent with another clock
|
|
91
|
+
*/
|
|
92
|
+
isConcurrentWith(other) {
|
|
93
|
+
return this.compare(other) === 'concurrent';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Check if equal to another clock
|
|
97
|
+
*/
|
|
98
|
+
isEqual(other) {
|
|
99
|
+
return this.compare(other) === 'equal';
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Clone this clock
|
|
103
|
+
*/
|
|
104
|
+
clone() {
|
|
105
|
+
const cloned = new VectorClock();
|
|
106
|
+
cloned.clock = new Map(this.clock);
|
|
107
|
+
return cloned;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Convert to plain object
|
|
111
|
+
*/
|
|
112
|
+
toValue() {
|
|
113
|
+
return Object.fromEntries(this.clock);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create from plain object
|
|
117
|
+
*/
|
|
118
|
+
static fromValue(value) {
|
|
119
|
+
return new VectorClock(value);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Serialize to string
|
|
123
|
+
*/
|
|
124
|
+
serialize() {
|
|
125
|
+
return JSON.stringify(this.toValue());
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Deserialize from string
|
|
129
|
+
*/
|
|
130
|
+
static deserialize(data) {
|
|
131
|
+
return new VectorClock(JSON.parse(data));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get all node IDs
|
|
135
|
+
*/
|
|
136
|
+
getNodes() {
|
|
137
|
+
return [...this.clock.keys()];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get number of nodes
|
|
141
|
+
*/
|
|
142
|
+
get size() {
|
|
143
|
+
return this.clock.size;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check if empty
|
|
147
|
+
*/
|
|
148
|
+
get isEmpty() {
|
|
149
|
+
return this.clock.size === 0;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get maximum timestamp across all nodes
|
|
153
|
+
*/
|
|
154
|
+
getMaxTimestamp() {
|
|
155
|
+
let max = 0;
|
|
156
|
+
for (const value of this.clock.values()) {
|
|
157
|
+
if (value > max) {
|
|
158
|
+
max = value;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return max;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get sum of all timestamps
|
|
165
|
+
*/
|
|
166
|
+
getSum() {
|
|
167
|
+
let sum = 0;
|
|
168
|
+
for (const value of this.clock.values()) {
|
|
169
|
+
sum += value;
|
|
170
|
+
}
|
|
171
|
+
return sum;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Clear the clock
|
|
175
|
+
*/
|
|
176
|
+
clear() {
|
|
177
|
+
this.clock.clear();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* String representation
|
|
181
|
+
*/
|
|
182
|
+
toString() {
|
|
183
|
+
const parts = [...this.clock.entries()]
|
|
184
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
185
|
+
.map(([nodeId, value]) => `${nodeId}:${value}`);
|
|
186
|
+
return `VectorClock{${parts.join(', ')}}`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=VectorClock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VectorClock.js","sourceRoot":"","sources":["../../src/sync/VectorClock.ts"],"names":[],"mappings":"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"}
|