@affectively/aeon 1.2.0 → 1.3.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.
- package/dist/compression/index.cjs.map +1 -1
- package/dist/compression/index.js.map +1 -1
- package/dist/core/index.d.cts +105 -100
- package/dist/core/index.d.ts +105 -100
- package/dist/crypto/index.cjs.map +1 -1
- package/dist/crypto/index.d.cts +310 -271
- package/dist/crypto/index.d.ts +310 -271
- package/dist/crypto/index.js.map +1 -1
- package/dist/distributed/index.cjs +8 -2
- package/dist/distributed/index.cjs.map +1 -1
- package/dist/distributed/index.d.cts +871 -756
- package/dist/distributed/index.d.ts +871 -756
- package/dist/distributed/index.js +8 -2
- package/dist/distributed/index.js.map +1 -1
- package/dist/index.cjs +26 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +26 -10
- package/dist/index.js.map +1 -1
- package/dist/offline/index.cjs.map +1 -1
- package/dist/offline/index.d.cts +128 -122
- package/dist/offline/index.d.ts +128 -122
- package/dist/offline/index.js.map +1 -1
- package/dist/optimization/index.cjs.map +1 -1
- package/dist/optimization/index.js.map +1 -1
- package/dist/persistence/index.cjs.map +1 -1
- package/dist/persistence/index.d.cts +38 -38
- package/dist/persistence/index.d.ts +38 -38
- package/dist/persistence/index.js.map +1 -1
- package/dist/presence/index.cjs.map +1 -1
- package/dist/presence/index.js.map +1 -1
- package/dist/{types-CMxO7QF0.d.cts → types-B7gCpNX9.d.cts} +6 -6
- package/dist/{types-CMxO7QF0.d.ts → types-B7gCpNX9.d.ts} +6 -6
- package/dist/utils/index.d.cts +4 -4
- package/dist/utils/index.d.ts +4 -4
- package/dist/versioning/index.cjs +18 -8
- package/dist/versioning/index.cjs.map +1 -1
- package/dist/versioning/index.d.cts +1 -1
- package/dist/versioning/index.d.ts +1 -1
- package/dist/versioning/index.js +18 -8
- package/dist/versioning/index.js.map +1 -1
- package/package.json +6 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from 'eventemitter3';
|
|
2
2
|
import { ICryptoProvider, AeonEncryptionMode, AuthenticatedMessageFields } from '../crypto/index.cjs';
|
|
3
|
-
import { S as StorageAdapter, b as PersistenceSerializer, a as PersistenceDeserializer } from '../types-
|
|
3
|
+
import { S as StorageAdapter, b as PersistenceSerializer, a as PersistenceDeserializer } from '../types-B7gCpNX9.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Sync Coordinator
|
|
@@ -19,199 +19,224 @@ import { S as StorageAdapter, b as PersistenceSerializer, a as PersistenceDeseri
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
interface SyncNode {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
id: string;
|
|
23
|
+
address: string;
|
|
24
|
+
port: number;
|
|
25
|
+
status: 'online' | 'offline' | 'syncing';
|
|
26
|
+
lastHeartbeat: string;
|
|
27
|
+
version: string;
|
|
28
|
+
capabilities: string[];
|
|
29
|
+
did?: string;
|
|
30
|
+
publicSigningKey?: JsonWebKey;
|
|
31
|
+
publicEncryptionKey?: JsonWebKey;
|
|
32
|
+
grantedCapabilities?: string[];
|
|
33
33
|
}
|
|
34
34
|
interface SyncSession {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
id: string;
|
|
36
|
+
initiatorId: string;
|
|
37
|
+
participantIds: string[];
|
|
38
|
+
status: 'pending' | 'active' | 'completed' | 'failed';
|
|
39
|
+
startTime: string;
|
|
40
|
+
endTime?: string;
|
|
41
|
+
itemsSynced: number;
|
|
42
|
+
itemsFailed: number;
|
|
43
|
+
conflictsDetected: number;
|
|
44
|
+
initiatorDID?: string;
|
|
45
|
+
participantDIDs?: string[];
|
|
46
|
+
encryptionMode?: AeonEncryptionMode;
|
|
47
|
+
requiredCapabilities?: string[];
|
|
48
|
+
sessionToken?: string;
|
|
49
49
|
}
|
|
50
50
|
interface SyncEvent {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
type:
|
|
52
|
+
| 'node-joined'
|
|
53
|
+
| 'node-left'
|
|
54
|
+
| 'sync-started'
|
|
55
|
+
| 'sync-completed'
|
|
56
|
+
| 'conflict-detected';
|
|
57
|
+
sessionId?: string;
|
|
58
|
+
nodeId: string;
|
|
59
|
+
timestamp: string;
|
|
60
|
+
data?: unknown;
|
|
56
61
|
}
|
|
57
62
|
/**
|
|
58
63
|
* Sync Coordinator
|
|
59
64
|
* Coordinates synchronization across distributed nodes
|
|
60
65
|
*/
|
|
61
66
|
declare class SyncCoordinator extends EventEmitter {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
67
|
+
private nodes;
|
|
68
|
+
private sessions;
|
|
69
|
+
private syncEvents;
|
|
70
|
+
private nodeHeartbeats;
|
|
71
|
+
private heartbeatInterval;
|
|
72
|
+
private cryptoProvider;
|
|
73
|
+
private nodesByDID;
|
|
74
|
+
constructor();
|
|
75
|
+
/**
|
|
76
|
+
* Configure cryptographic provider for authenticated sync
|
|
77
|
+
*/
|
|
78
|
+
configureCrypto(provider: ICryptoProvider): void;
|
|
79
|
+
/**
|
|
80
|
+
* Check if crypto is configured
|
|
81
|
+
*/
|
|
82
|
+
isCryptoEnabled(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Register a node with DID-based identity
|
|
85
|
+
*/
|
|
86
|
+
registerAuthenticatedNode(
|
|
87
|
+
nodeInfo: Omit<
|
|
88
|
+
SyncNode,
|
|
89
|
+
'did' | 'publicSigningKey' | 'publicEncryptionKey'
|
|
90
|
+
> & {
|
|
91
|
+
did: string;
|
|
92
|
+
publicSigningKey: JsonWebKey;
|
|
93
|
+
publicEncryptionKey?: JsonWebKey;
|
|
94
|
+
}
|
|
95
|
+
): Promise<SyncNode>;
|
|
96
|
+
/**
|
|
97
|
+
* Get node by DID
|
|
98
|
+
*/
|
|
99
|
+
getNodeByDID(did: string): SyncNode | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Get all authenticated nodes (nodes with DIDs)
|
|
102
|
+
*/
|
|
103
|
+
getAuthenticatedNodes(): SyncNode[];
|
|
104
|
+
/**
|
|
105
|
+
* Create an authenticated sync session with UCAN-based authorization
|
|
106
|
+
*/
|
|
107
|
+
createAuthenticatedSyncSession(
|
|
108
|
+
initiatorDID: string,
|
|
109
|
+
participantDIDs: string[],
|
|
110
|
+
options?: {
|
|
111
|
+
encryptionMode?: AeonEncryptionMode;
|
|
112
|
+
requiredCapabilities?: string[];
|
|
113
|
+
}
|
|
114
|
+
): Promise<SyncSession>;
|
|
115
|
+
/**
|
|
116
|
+
* Verify a node's UCAN capabilities for a session
|
|
117
|
+
*/
|
|
118
|
+
verifyNodeCapabilities(
|
|
119
|
+
sessionId: string,
|
|
120
|
+
nodeDID: string,
|
|
121
|
+
token: string
|
|
122
|
+
): Promise<{
|
|
123
|
+
authorized: boolean;
|
|
124
|
+
error?: string;
|
|
125
|
+
}>;
|
|
126
|
+
/**
|
|
127
|
+
* Register a node in the cluster
|
|
128
|
+
*/
|
|
129
|
+
registerNode(node: SyncNode): void;
|
|
130
|
+
/**
|
|
131
|
+
* Deregister a node from the cluster
|
|
132
|
+
*/
|
|
133
|
+
deregisterNode(nodeId: string): void;
|
|
134
|
+
/**
|
|
135
|
+
* Create a new sync session
|
|
136
|
+
*/
|
|
137
|
+
createSyncSession(initiatorId: string, participantIds: string[]): SyncSession;
|
|
138
|
+
/**
|
|
139
|
+
* Update sync session
|
|
140
|
+
*/
|
|
141
|
+
updateSyncSession(sessionId: string, updates: Partial<SyncSession>): void;
|
|
142
|
+
/**
|
|
143
|
+
* Record a conflict during sync
|
|
144
|
+
*/
|
|
145
|
+
recordConflict(
|
|
146
|
+
sessionId: string,
|
|
147
|
+
nodeId: string,
|
|
148
|
+
conflictData?: unknown
|
|
149
|
+
): void;
|
|
150
|
+
/**
|
|
151
|
+
* Update node status
|
|
152
|
+
*/
|
|
153
|
+
updateNodeStatus(nodeId: string, status: SyncNode['status']): void;
|
|
154
|
+
/**
|
|
155
|
+
* Record heartbeat from node
|
|
156
|
+
*/
|
|
157
|
+
recordHeartbeat(nodeId: string): void;
|
|
158
|
+
/**
|
|
159
|
+
* Get all nodes
|
|
160
|
+
*/
|
|
161
|
+
getNodes(): SyncNode[];
|
|
162
|
+
/**
|
|
163
|
+
* Get node by ID
|
|
164
|
+
*/
|
|
165
|
+
getNode(nodeId: string): SyncNode | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Get online nodes
|
|
168
|
+
*/
|
|
169
|
+
getOnlineNodes(): SyncNode[];
|
|
170
|
+
/**
|
|
171
|
+
* Get nodes by capability
|
|
172
|
+
*/
|
|
173
|
+
getNodesByCapability(capability: string): SyncNode[];
|
|
174
|
+
/**
|
|
175
|
+
* Get sync session
|
|
176
|
+
*/
|
|
177
|
+
getSyncSession(sessionId: string): SyncSession | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* Get all sync sessions
|
|
180
|
+
*/
|
|
181
|
+
getAllSyncSessions(): SyncSession[];
|
|
182
|
+
/**
|
|
183
|
+
* Get active sync sessions
|
|
184
|
+
*/
|
|
185
|
+
getActiveSyncSessions(): SyncSession[];
|
|
186
|
+
/**
|
|
187
|
+
* Get sessions for a node
|
|
188
|
+
*/
|
|
189
|
+
getSessionsForNode(nodeId: string): SyncSession[];
|
|
190
|
+
/**
|
|
191
|
+
* Get sync statistics
|
|
192
|
+
*/
|
|
193
|
+
getStatistics(): {
|
|
194
|
+
totalNodes: number;
|
|
195
|
+
onlineNodes: number;
|
|
196
|
+
offlineNodes: number;
|
|
197
|
+
totalSessions: number;
|
|
198
|
+
activeSessions: number;
|
|
199
|
+
completedSessions: number;
|
|
200
|
+
failedSessions: number;
|
|
201
|
+
successRate: number;
|
|
202
|
+
totalItemsSynced: number;
|
|
203
|
+
totalConflicts: number;
|
|
204
|
+
averageConflictsPerSession: number;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* Get sync events
|
|
208
|
+
*/
|
|
209
|
+
getSyncEvents(limit?: number): SyncEvent[];
|
|
210
|
+
/**
|
|
211
|
+
* Get sync events for session
|
|
212
|
+
*/
|
|
213
|
+
getSessionEvents(sessionId: string): SyncEvent[];
|
|
214
|
+
/**
|
|
215
|
+
* Check node health
|
|
216
|
+
*/
|
|
217
|
+
getNodeHealth(): Record<
|
|
218
|
+
string,
|
|
219
|
+
{
|
|
220
|
+
isHealthy: boolean;
|
|
221
|
+
downtime: number;
|
|
222
|
+
}
|
|
223
|
+
>;
|
|
224
|
+
/**
|
|
225
|
+
* Start heartbeat monitoring
|
|
226
|
+
*/
|
|
227
|
+
startHeartbeatMonitoring(interval?: number): void;
|
|
228
|
+
/**
|
|
229
|
+
* Stop heartbeat monitoring
|
|
230
|
+
*/
|
|
231
|
+
stopHeartbeatMonitoring(): void;
|
|
232
|
+
/**
|
|
233
|
+
* Clear all state (for testing)
|
|
234
|
+
*/
|
|
235
|
+
clear(): void;
|
|
236
|
+
/**
|
|
237
|
+
* Get the crypto provider (for advanced usage)
|
|
238
|
+
*/
|
|
239
|
+
getCryptoProvider(): ICryptoProvider | null;
|
|
215
240
|
}
|
|
216
241
|
|
|
217
242
|
/**
|
|
@@ -231,257 +256,286 @@ declare class SyncCoordinator extends EventEmitter {
|
|
|
231
256
|
*/
|
|
232
257
|
|
|
233
258
|
interface Replica {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
259
|
+
id: string;
|
|
260
|
+
nodeId: string;
|
|
261
|
+
status: 'primary' | 'secondary' | 'syncing' | 'failed';
|
|
262
|
+
lastSyncTime: string;
|
|
263
|
+
lagBytes: number;
|
|
264
|
+
lagMillis: number;
|
|
265
|
+
did?: string;
|
|
266
|
+
encrypted?: boolean;
|
|
242
267
|
}
|
|
243
268
|
interface ReplicationPolicy {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
269
|
+
id: string;
|
|
270
|
+
name: string;
|
|
271
|
+
replicationFactor: number;
|
|
272
|
+
consistencyLevel: 'eventual' | 'read-after-write' | 'strong';
|
|
273
|
+
syncInterval: number;
|
|
274
|
+
maxReplicationLag: number;
|
|
275
|
+
encryptionMode?: AeonEncryptionMode;
|
|
276
|
+
requiredCapabilities?: string[];
|
|
252
277
|
}
|
|
253
278
|
interface ReplicationEvent {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
279
|
+
type: 'replica-added' | 'replica-removed' | 'replica-synced' | 'sync-failed';
|
|
280
|
+
replicaId: string;
|
|
281
|
+
nodeId: string;
|
|
282
|
+
timestamp: string;
|
|
283
|
+
details?: unknown;
|
|
259
284
|
}
|
|
260
285
|
/**
|
|
261
286
|
* Encrypted replication data envelope
|
|
262
287
|
*/
|
|
263
288
|
interface EncryptedReplicationData {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
289
|
+
/** Encrypted ciphertext (base64) */
|
|
290
|
+
ct: string;
|
|
291
|
+
/** Initialization vector (base64) */
|
|
292
|
+
iv: string;
|
|
293
|
+
/** Authentication tag (base64) */
|
|
294
|
+
tag: string;
|
|
295
|
+
/** Ephemeral public key for ECIES */
|
|
296
|
+
epk?: JsonWebKey;
|
|
297
|
+
/** Sender DID */
|
|
298
|
+
senderDID?: string;
|
|
299
|
+
/** Target replica DID */
|
|
300
|
+
targetDID?: string;
|
|
301
|
+
/** Encryption timestamp */
|
|
302
|
+
encryptedAt: number;
|
|
278
303
|
}
|
|
279
304
|
interface ReplicationPersistenceData {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
305
|
+
replicas: Replica[];
|
|
306
|
+
policies: ReplicationPolicy[];
|
|
307
|
+
syncStatus: Array<{
|
|
308
|
+
nodeId: string;
|
|
309
|
+
synced: number;
|
|
310
|
+
failed: number;
|
|
311
|
+
}>;
|
|
287
312
|
}
|
|
288
313
|
interface ReplicationPersistenceConfig {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
314
|
+
adapter: StorageAdapter;
|
|
315
|
+
key?: string;
|
|
316
|
+
autoPersist?: boolean;
|
|
317
|
+
autoLoad?: boolean;
|
|
318
|
+
persistDebounceMs?: number;
|
|
319
|
+
serializer?: PersistenceSerializer<ReplicationPersistenceData>;
|
|
320
|
+
deserializer?: PersistenceDeserializer<ReplicationPersistenceData>;
|
|
296
321
|
}
|
|
297
322
|
interface ReplicationManagerOptions {
|
|
298
|
-
|
|
323
|
+
persistence?: ReplicationPersistenceConfig;
|
|
299
324
|
}
|
|
300
325
|
/**
|
|
301
326
|
* Replication Manager
|
|
302
327
|
* Manages data replication across distributed nodes
|
|
303
328
|
*/
|
|
304
329
|
declare class ReplicationManager {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
330
|
+
private static readonly DEFAULT_PERSIST_KEY;
|
|
331
|
+
private replicas;
|
|
332
|
+
private policies;
|
|
333
|
+
private replicationEvents;
|
|
334
|
+
private syncStatus;
|
|
335
|
+
private cryptoProvider;
|
|
336
|
+
private replicasByDID;
|
|
337
|
+
private persistence;
|
|
338
|
+
private persistTimer;
|
|
339
|
+
private persistInFlight;
|
|
340
|
+
private persistPending;
|
|
341
|
+
constructor(options?: ReplicationManagerOptions);
|
|
342
|
+
/**
|
|
343
|
+
* Configure cryptographic provider for encrypted replication
|
|
344
|
+
*/
|
|
345
|
+
configureCrypto(provider: ICryptoProvider): void;
|
|
346
|
+
/**
|
|
347
|
+
* Check if crypto is configured
|
|
348
|
+
*/
|
|
349
|
+
isCryptoEnabled(): boolean;
|
|
350
|
+
/**
|
|
351
|
+
* Register an authenticated replica with DID
|
|
352
|
+
*/
|
|
353
|
+
registerAuthenticatedReplica(
|
|
354
|
+
replica: Omit<Replica, 'did' | 'encrypted'> & {
|
|
355
|
+
did: string;
|
|
356
|
+
publicSigningKey?: JsonWebKey;
|
|
357
|
+
publicEncryptionKey?: JsonWebKey;
|
|
358
|
+
},
|
|
359
|
+
encrypted?: boolean
|
|
360
|
+
): Promise<Replica>;
|
|
361
|
+
/**
|
|
362
|
+
* Get replica by DID
|
|
363
|
+
*/
|
|
364
|
+
getReplicaByDID(did: string): Replica | undefined;
|
|
365
|
+
/**
|
|
366
|
+
* Get all encrypted replicas
|
|
367
|
+
*/
|
|
368
|
+
getEncryptedReplicas(): Replica[];
|
|
369
|
+
/**
|
|
370
|
+
* Encrypt data for replication to a specific replica
|
|
371
|
+
*/
|
|
372
|
+
encryptForReplica(
|
|
373
|
+
data: unknown,
|
|
374
|
+
targetReplicaDID: string
|
|
375
|
+
): Promise<EncryptedReplicationData>;
|
|
376
|
+
/**
|
|
377
|
+
* Decrypt data received from replication
|
|
378
|
+
*/
|
|
379
|
+
decryptReplicationData<T>(encrypted: EncryptedReplicationData): Promise<T>;
|
|
380
|
+
/**
|
|
381
|
+
* Create an encrypted replication policy
|
|
382
|
+
*/
|
|
383
|
+
createEncryptedPolicy(
|
|
384
|
+
name: string,
|
|
385
|
+
replicationFactor: number,
|
|
386
|
+
consistencyLevel: 'eventual' | 'read-after-write' | 'strong',
|
|
387
|
+
encryptionMode: AeonEncryptionMode,
|
|
388
|
+
options?: {
|
|
389
|
+
syncInterval?: number;
|
|
390
|
+
maxReplicationLag?: number;
|
|
391
|
+
requiredCapabilities?: string[];
|
|
392
|
+
}
|
|
393
|
+
): ReplicationPolicy;
|
|
394
|
+
/**
|
|
395
|
+
* Verify a replica's capabilities via UCAN
|
|
396
|
+
*/
|
|
397
|
+
verifyReplicaCapabilities(
|
|
398
|
+
replicaDID: string,
|
|
399
|
+
token: string,
|
|
400
|
+
policyId?: string
|
|
401
|
+
): Promise<{
|
|
402
|
+
authorized: boolean;
|
|
403
|
+
error?: string;
|
|
404
|
+
}>;
|
|
405
|
+
/**
|
|
406
|
+
* Register a replica
|
|
407
|
+
*/
|
|
408
|
+
registerReplica(replica: Replica): void;
|
|
409
|
+
/**
|
|
410
|
+
* Remove a replica
|
|
411
|
+
*/
|
|
412
|
+
removeReplica(replicaId: string): void;
|
|
413
|
+
/**
|
|
414
|
+
* Create a replication policy
|
|
415
|
+
*/
|
|
416
|
+
createPolicy(
|
|
417
|
+
name: string,
|
|
418
|
+
replicationFactor: number,
|
|
419
|
+
consistencyLevel: 'eventual' | 'read-after-write' | 'strong',
|
|
420
|
+
syncInterval?: number,
|
|
421
|
+
maxReplicationLag?: number
|
|
422
|
+
): ReplicationPolicy;
|
|
423
|
+
/**
|
|
424
|
+
* Update replica status
|
|
425
|
+
*/
|
|
426
|
+
updateReplicaStatus(
|
|
427
|
+
replicaId: string,
|
|
428
|
+
status: Replica['status'],
|
|
429
|
+
lagBytes?: number,
|
|
430
|
+
lagMillis?: number
|
|
431
|
+
): void;
|
|
432
|
+
/**
|
|
433
|
+
* Get replicas for node
|
|
434
|
+
*/
|
|
435
|
+
getReplicasForNode(nodeId: string): Replica[];
|
|
436
|
+
/**
|
|
437
|
+
* Get healthy replicas
|
|
438
|
+
*/
|
|
439
|
+
getHealthyReplicas(): Replica[];
|
|
440
|
+
/**
|
|
441
|
+
* Get syncing replicas
|
|
442
|
+
*/
|
|
443
|
+
getSyncingReplicas(): Replica[];
|
|
444
|
+
/**
|
|
445
|
+
* Get failed replicas
|
|
446
|
+
*/
|
|
447
|
+
getFailedReplicas(): Replica[];
|
|
448
|
+
/**
|
|
449
|
+
* Check replication health for policy
|
|
450
|
+
*/
|
|
451
|
+
checkReplicationHealth(policyId: string): {
|
|
452
|
+
healthy: boolean;
|
|
453
|
+
replicasInPolicy: number;
|
|
454
|
+
healthyReplicas: number;
|
|
455
|
+
replicationLag: number;
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* Get consistency level
|
|
459
|
+
*/
|
|
460
|
+
getConsistencyLevel(
|
|
461
|
+
policyId: string
|
|
462
|
+
): 'eventual' | 'read-after-write' | 'strong';
|
|
463
|
+
/**
|
|
464
|
+
* Get replica
|
|
465
|
+
*/
|
|
466
|
+
getReplica(replicaId: string): Replica | undefined;
|
|
467
|
+
/**
|
|
468
|
+
* Get all replicas
|
|
469
|
+
*/
|
|
470
|
+
getAllReplicas(): Replica[];
|
|
471
|
+
/**
|
|
472
|
+
* Get policy
|
|
473
|
+
*/
|
|
474
|
+
getPolicy(policyId: string): ReplicationPolicy | undefined;
|
|
475
|
+
/**
|
|
476
|
+
* Get all policies
|
|
477
|
+
*/
|
|
478
|
+
getAllPolicies(): ReplicationPolicy[];
|
|
479
|
+
/**
|
|
480
|
+
* Get replication statistics
|
|
481
|
+
*/
|
|
482
|
+
getStatistics(): {
|
|
483
|
+
totalReplicas: number;
|
|
484
|
+
healthyReplicas: number;
|
|
485
|
+
syncingReplicas: number;
|
|
486
|
+
failedReplicas: number;
|
|
487
|
+
healthiness: number;
|
|
488
|
+
averageReplicationLagMs: number;
|
|
489
|
+
maxReplicationLagMs: number;
|
|
490
|
+
totalPolicies: number;
|
|
491
|
+
};
|
|
492
|
+
/**
|
|
493
|
+
* Get replication events
|
|
494
|
+
*/
|
|
495
|
+
getReplicationEvents(limit?: number): ReplicationEvent[];
|
|
496
|
+
/**
|
|
497
|
+
* Get sync status for node
|
|
498
|
+
*/
|
|
499
|
+
getSyncStatus(nodeId: string): {
|
|
500
|
+
synced: number;
|
|
501
|
+
failed: number;
|
|
502
|
+
};
|
|
503
|
+
/**
|
|
504
|
+
* Get replication lag distribution
|
|
505
|
+
*/
|
|
506
|
+
getReplicationLagDistribution(): Record<string, number>;
|
|
507
|
+
/**
|
|
508
|
+
* Check if can satisfy consistency level
|
|
509
|
+
*/
|
|
510
|
+
canSatisfyConsistency(policyId: string, _requiredAcks: number): boolean;
|
|
511
|
+
/**
|
|
512
|
+
* Persist current replication state snapshot.
|
|
513
|
+
*/
|
|
514
|
+
saveToPersistence(): Promise<void>;
|
|
515
|
+
/**
|
|
516
|
+
* Load replication snapshot from persistence.
|
|
517
|
+
*/
|
|
518
|
+
loadFromPersistence(): Promise<{
|
|
519
|
+
replicas: number;
|
|
520
|
+
policies: number;
|
|
521
|
+
syncStatus: number;
|
|
522
|
+
}>;
|
|
523
|
+
/**
|
|
524
|
+
* Remove persisted replication snapshot.
|
|
525
|
+
*/
|
|
526
|
+
clearPersistence(): Promise<void>;
|
|
527
|
+
private schedulePersist;
|
|
528
|
+
private persistSafely;
|
|
529
|
+
private isValidReplica;
|
|
530
|
+
private isValidPolicy;
|
|
531
|
+
/**
|
|
532
|
+
* Clear all state (for testing)
|
|
533
|
+
*/
|
|
534
|
+
clear(): void;
|
|
535
|
+
/**
|
|
536
|
+
* Get the crypto provider (for advanced usage)
|
|
537
|
+
*/
|
|
538
|
+
getCryptoProvider(): ICryptoProvider | null;
|
|
485
539
|
}
|
|
486
540
|
|
|
487
541
|
/**
|
|
@@ -500,257 +554,292 @@ declare class ReplicationManager {
|
|
|
500
554
|
*/
|
|
501
555
|
|
|
502
556
|
interface SyncMessage {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
557
|
+
type: 'handshake' | 'sync-request' | 'sync-response' | 'ack' | 'error';
|
|
558
|
+
version: string;
|
|
559
|
+
sender: string;
|
|
560
|
+
receiver: string;
|
|
561
|
+
messageId: string;
|
|
562
|
+
timestamp: string;
|
|
563
|
+
payload?: unknown;
|
|
564
|
+
auth?: AuthenticatedMessageFields;
|
|
511
565
|
}
|
|
512
566
|
interface Handshake {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
567
|
+
protocolVersion: string;
|
|
568
|
+
nodeId: string;
|
|
569
|
+
capabilities: string[];
|
|
570
|
+
state: 'initiating' | 'responding' | 'completed';
|
|
571
|
+
did?: string;
|
|
572
|
+
publicSigningKey?: JsonWebKey;
|
|
573
|
+
publicEncryptionKey?: JsonWebKey;
|
|
574
|
+
ucan?: string;
|
|
521
575
|
}
|
|
522
576
|
/**
|
|
523
577
|
* Crypto configuration for sync protocol
|
|
524
578
|
*/
|
|
525
579
|
interface SyncProtocolCryptoConfig {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
580
|
+
/** Encryption mode for messages */
|
|
581
|
+
encryptionMode: AeonEncryptionMode;
|
|
582
|
+
/** Require all messages to be signed */
|
|
583
|
+
requireSignatures: boolean;
|
|
584
|
+
/** Require UCAN capability verification */
|
|
585
|
+
requireCapabilities: boolean;
|
|
586
|
+
/** Required capabilities for sync operations */
|
|
587
|
+
requiredCapabilities?: Array<{
|
|
588
|
+
can: string;
|
|
589
|
+
with: string;
|
|
590
|
+
}>;
|
|
537
591
|
}
|
|
538
592
|
interface SyncRequest {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
593
|
+
sessionId: string;
|
|
594
|
+
fromVersion: string;
|
|
595
|
+
toVersion: string;
|
|
596
|
+
filter?: Record<string, unknown>;
|
|
543
597
|
}
|
|
544
598
|
interface SyncResponse {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
599
|
+
sessionId: string;
|
|
600
|
+
fromVersion: string;
|
|
601
|
+
toVersion: string;
|
|
602
|
+
data: unknown[];
|
|
603
|
+
hasMore: boolean;
|
|
604
|
+
offset: number;
|
|
551
605
|
}
|
|
552
606
|
interface ProtocolError {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
607
|
+
code: string;
|
|
608
|
+
message: string;
|
|
609
|
+
recoverable: boolean;
|
|
556
610
|
}
|
|
557
611
|
interface SyncProtocolPersistenceData {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
612
|
+
protocolVersion: string;
|
|
613
|
+
messageCounter: number;
|
|
614
|
+
messageQueue: SyncMessage[];
|
|
615
|
+
handshakes: Array<{
|
|
616
|
+
nodeId: string;
|
|
617
|
+
handshake: Handshake;
|
|
618
|
+
}>;
|
|
619
|
+
protocolErrors: Array<{
|
|
620
|
+
error: ProtocolError;
|
|
621
|
+
timestamp: string;
|
|
622
|
+
}>;
|
|
569
623
|
}
|
|
570
624
|
interface SyncProtocolPersistenceConfig {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
625
|
+
adapter: StorageAdapter;
|
|
626
|
+
key?: string;
|
|
627
|
+
autoPersist?: boolean;
|
|
628
|
+
autoLoad?: boolean;
|
|
629
|
+
persistDebounceMs?: number;
|
|
630
|
+
serializer?: PersistenceSerializer<SyncProtocolPersistenceData>;
|
|
631
|
+
deserializer?: PersistenceDeserializer<SyncProtocolPersistenceData>;
|
|
578
632
|
}
|
|
579
633
|
interface SyncProtocolOptions {
|
|
580
|
-
|
|
634
|
+
persistence?: SyncProtocolPersistenceConfig;
|
|
581
635
|
}
|
|
582
636
|
/**
|
|
583
637
|
* Sync Protocol
|
|
584
638
|
* Handles synchronization protocol messages and handshaking
|
|
585
639
|
*/
|
|
586
640
|
declare class SyncProtocol {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
641
|
+
private static readonly DEFAULT_PERSIST_KEY;
|
|
642
|
+
private version;
|
|
643
|
+
private messageQueue;
|
|
644
|
+
private messageMap;
|
|
645
|
+
private handshakes;
|
|
646
|
+
private protocolErrors;
|
|
647
|
+
private messageCounter;
|
|
648
|
+
private cryptoProvider;
|
|
649
|
+
private cryptoConfig;
|
|
650
|
+
private persistence;
|
|
651
|
+
private persistTimer;
|
|
652
|
+
private persistInFlight;
|
|
653
|
+
private persistPending;
|
|
654
|
+
constructor(options?: SyncProtocolOptions);
|
|
655
|
+
/**
|
|
656
|
+
* Configure cryptographic provider for authenticated/encrypted messages
|
|
657
|
+
*/
|
|
658
|
+
configureCrypto(
|
|
659
|
+
provider: ICryptoProvider,
|
|
660
|
+
config?: Partial<SyncProtocolCryptoConfig>
|
|
661
|
+
): void;
|
|
662
|
+
/**
|
|
663
|
+
* Check if crypto is configured
|
|
664
|
+
*/
|
|
665
|
+
isCryptoEnabled(): boolean;
|
|
666
|
+
/**
|
|
667
|
+
* Get crypto configuration
|
|
668
|
+
*/
|
|
669
|
+
getCryptoConfig(): SyncProtocolCryptoConfig | null;
|
|
670
|
+
/**
|
|
671
|
+
* Get protocol version
|
|
672
|
+
*/
|
|
673
|
+
getVersion(): string;
|
|
674
|
+
/**
|
|
675
|
+
* Create authenticated handshake message with DID and keys
|
|
676
|
+
*/
|
|
677
|
+
createAuthenticatedHandshake(
|
|
678
|
+
capabilities: string[],
|
|
679
|
+
targetDID?: string
|
|
680
|
+
): Promise<SyncMessage>;
|
|
681
|
+
/**
|
|
682
|
+
* Verify and process an authenticated handshake
|
|
683
|
+
*/
|
|
684
|
+
verifyAuthenticatedHandshake(message: SyncMessage): Promise<{
|
|
685
|
+
valid: boolean;
|
|
686
|
+
handshake?: Handshake;
|
|
687
|
+
error?: string;
|
|
688
|
+
}>;
|
|
689
|
+
/**
|
|
690
|
+
* Sign and optionally encrypt a message payload
|
|
691
|
+
*/
|
|
692
|
+
signMessage<T>(
|
|
693
|
+
message: SyncMessage,
|
|
694
|
+
payload: T,
|
|
695
|
+
encrypt?: boolean
|
|
696
|
+
): Promise<SyncMessage>;
|
|
697
|
+
/**
|
|
698
|
+
* Verify signature and optionally decrypt a message
|
|
699
|
+
*/
|
|
700
|
+
verifyMessage<T>(message: SyncMessage): Promise<{
|
|
701
|
+
valid: boolean;
|
|
702
|
+
payload?: T;
|
|
703
|
+
error?: string;
|
|
704
|
+
}>;
|
|
705
|
+
/**
|
|
706
|
+
* Create handshake message
|
|
707
|
+
*/
|
|
708
|
+
createHandshakeMessage(nodeId: string, capabilities: string[]): SyncMessage;
|
|
709
|
+
/**
|
|
710
|
+
* Create sync request message
|
|
711
|
+
*/
|
|
712
|
+
createSyncRequestMessage(
|
|
713
|
+
sender: string,
|
|
714
|
+
receiver: string,
|
|
715
|
+
sessionId: string,
|
|
716
|
+
fromVersion: string,
|
|
717
|
+
toVersion: string,
|
|
718
|
+
filter?: Record<string, unknown>
|
|
719
|
+
): SyncMessage;
|
|
720
|
+
/**
|
|
721
|
+
* Create sync response message
|
|
722
|
+
*/
|
|
723
|
+
createSyncResponseMessage(
|
|
724
|
+
sender: string,
|
|
725
|
+
receiver: string,
|
|
726
|
+
sessionId: string,
|
|
727
|
+
fromVersion: string,
|
|
728
|
+
toVersion: string,
|
|
729
|
+
data: unknown[],
|
|
730
|
+
hasMore?: boolean,
|
|
731
|
+
offset?: number
|
|
732
|
+
): SyncMessage;
|
|
733
|
+
/**
|
|
734
|
+
* Create acknowledgement message
|
|
735
|
+
*/
|
|
736
|
+
createAckMessage(
|
|
737
|
+
sender: string,
|
|
738
|
+
receiver: string,
|
|
739
|
+
messageId: string
|
|
740
|
+
): SyncMessage;
|
|
741
|
+
/**
|
|
742
|
+
* Create error message
|
|
743
|
+
*/
|
|
744
|
+
createErrorMessage(
|
|
745
|
+
sender: string,
|
|
746
|
+
receiver: string,
|
|
747
|
+
error: ProtocolError,
|
|
748
|
+
relatedMessageId?: string
|
|
749
|
+
): SyncMessage;
|
|
750
|
+
/**
|
|
751
|
+
* Validate message
|
|
752
|
+
*/
|
|
753
|
+
validateMessage(message: SyncMessage): {
|
|
754
|
+
valid: boolean;
|
|
755
|
+
errors: string[];
|
|
756
|
+
};
|
|
757
|
+
/**
|
|
758
|
+
* Serialize message
|
|
759
|
+
*/
|
|
760
|
+
serializeMessage(message: SyncMessage): string;
|
|
761
|
+
/**
|
|
762
|
+
* Deserialize message
|
|
763
|
+
*/
|
|
764
|
+
deserializeMessage(data: string): SyncMessage;
|
|
765
|
+
/**
|
|
766
|
+
* Process handshake
|
|
767
|
+
*/
|
|
768
|
+
processHandshake(message: SyncMessage): Handshake;
|
|
769
|
+
/**
|
|
770
|
+
* Get message
|
|
771
|
+
*/
|
|
772
|
+
getMessage(messageId: string): SyncMessage | undefined;
|
|
773
|
+
/**
|
|
774
|
+
* Get all messages
|
|
775
|
+
*/
|
|
776
|
+
getAllMessages(): SyncMessage[];
|
|
777
|
+
/**
|
|
778
|
+
* Get messages by type
|
|
779
|
+
*/
|
|
780
|
+
getMessagesByType(type: SyncMessage['type']): SyncMessage[];
|
|
781
|
+
/**
|
|
782
|
+
* Get messages from sender
|
|
783
|
+
*/
|
|
784
|
+
getMessagesFromSender(sender: string): SyncMessage[];
|
|
785
|
+
/**
|
|
786
|
+
* Get pending messages
|
|
787
|
+
*/
|
|
788
|
+
getPendingMessages(receiver: string): SyncMessage[];
|
|
789
|
+
/**
|
|
790
|
+
* Get handshakes
|
|
791
|
+
*/
|
|
792
|
+
getHandshakes(): Map<string, Handshake>;
|
|
793
|
+
/**
|
|
794
|
+
* Get protocol statistics
|
|
795
|
+
*/
|
|
796
|
+
getStatistics(): {
|
|
797
|
+
totalMessages: number;
|
|
798
|
+
messagesByType: Record<string, number>;
|
|
799
|
+
totalHandshakes: number;
|
|
800
|
+
totalErrors: number;
|
|
801
|
+
recoverableErrors: number;
|
|
802
|
+
unrecoverableErrors: number;
|
|
803
|
+
};
|
|
804
|
+
/**
|
|
805
|
+
* Get protocol errors
|
|
806
|
+
*/
|
|
807
|
+
getErrors(): Array<{
|
|
808
|
+
error: ProtocolError;
|
|
809
|
+
timestamp: string;
|
|
810
|
+
}>;
|
|
811
|
+
/**
|
|
812
|
+
* Persist protocol state for reconnect/replay.
|
|
813
|
+
*/
|
|
814
|
+
saveToPersistence(): Promise<void>;
|
|
815
|
+
/**
|
|
816
|
+
* Load protocol state from persistence.
|
|
817
|
+
*/
|
|
818
|
+
loadFromPersistence(): Promise<{
|
|
819
|
+
messages: number;
|
|
820
|
+
handshakes: number;
|
|
821
|
+
errors: number;
|
|
822
|
+
}>;
|
|
823
|
+
/**
|
|
824
|
+
* Clear persisted protocol checkpoint.
|
|
825
|
+
*/
|
|
826
|
+
clearPersistence(): Promise<void>;
|
|
827
|
+
private schedulePersist;
|
|
828
|
+
private persistSafely;
|
|
829
|
+
private isValidHandshake;
|
|
830
|
+
private isValidProtocolErrorEntry;
|
|
831
|
+
/**
|
|
832
|
+
* Generate message ID
|
|
833
|
+
*/
|
|
834
|
+
private generateMessageId;
|
|
835
|
+
/**
|
|
836
|
+
* Clear all state (for testing)
|
|
837
|
+
*/
|
|
838
|
+
clear(): void;
|
|
839
|
+
/**
|
|
840
|
+
* Get the crypto provider (for advanced usage)
|
|
841
|
+
*/
|
|
842
|
+
getCryptoProvider(): ICryptoProvider | null;
|
|
754
843
|
}
|
|
755
844
|
|
|
756
845
|
/**
|
|
@@ -770,132 +859,158 @@ declare class SyncProtocol {
|
|
|
770
859
|
*/
|
|
771
860
|
|
|
772
861
|
interface StateVersion {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
862
|
+
version: string;
|
|
863
|
+
timestamp: string;
|
|
864
|
+
nodeId: string;
|
|
865
|
+
hash: string;
|
|
866
|
+
data: unknown;
|
|
867
|
+
signerDID?: string;
|
|
868
|
+
signature?: string;
|
|
869
|
+
signedAt?: number;
|
|
781
870
|
}
|
|
782
871
|
interface StateDiff {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
872
|
+
added: Record<string, unknown>;
|
|
873
|
+
modified: Record<
|
|
874
|
+
string,
|
|
875
|
+
{
|
|
876
|
+
old: unknown;
|
|
877
|
+
new: unknown;
|
|
878
|
+
}
|
|
879
|
+
>;
|
|
880
|
+
removed: string[];
|
|
881
|
+
timestamp: string;
|
|
790
882
|
}
|
|
791
883
|
interface ReconciliationResult {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
884
|
+
success: boolean;
|
|
885
|
+
mergedState: unknown;
|
|
886
|
+
conflictsResolved: number;
|
|
887
|
+
strategy: string;
|
|
888
|
+
timestamp: string;
|
|
797
889
|
}
|
|
798
|
-
type MergeStrategy =
|
|
890
|
+
type MergeStrategy =
|
|
891
|
+
| 'last-write-wins'
|
|
892
|
+
| 'vector-clock'
|
|
893
|
+
| 'majority-vote'
|
|
894
|
+
| 'custom';
|
|
799
895
|
/**
|
|
800
896
|
* State Reconciler
|
|
801
897
|
* Reconciles state conflicts across distributed nodes
|
|
802
898
|
*/
|
|
803
899
|
declare class StateReconciler {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
900
|
+
private stateVersions;
|
|
901
|
+
private reconciliationHistory;
|
|
902
|
+
private cryptoProvider;
|
|
903
|
+
private requireSignedVersions;
|
|
904
|
+
/**
|
|
905
|
+
* Configure cryptographic provider for signed state versions
|
|
906
|
+
*/
|
|
907
|
+
configureCrypto(provider: ICryptoProvider, requireSigned?: boolean): void;
|
|
908
|
+
/**
|
|
909
|
+
* Check if crypto is configured
|
|
910
|
+
*/
|
|
911
|
+
isCryptoEnabled(): boolean;
|
|
912
|
+
/**
|
|
913
|
+
* Record a signed state version with cryptographic verification
|
|
914
|
+
*/
|
|
915
|
+
recordSignedStateVersion(
|
|
916
|
+
key: string,
|
|
917
|
+
version: string,
|
|
918
|
+
data: unknown
|
|
919
|
+
): Promise<StateVersion>;
|
|
920
|
+
/**
|
|
921
|
+
* Verify a state version's signature
|
|
922
|
+
*/
|
|
923
|
+
verifyStateVersion(version: StateVersion): Promise<{
|
|
924
|
+
valid: boolean;
|
|
925
|
+
error?: string;
|
|
926
|
+
}>;
|
|
927
|
+
/**
|
|
928
|
+
* Reconcile with verification - only accept verified versions
|
|
929
|
+
*/
|
|
930
|
+
reconcileWithVerification(
|
|
931
|
+
key: string,
|
|
932
|
+
strategy?: MergeStrategy
|
|
933
|
+
): Promise<
|
|
934
|
+
ReconciliationResult & {
|
|
935
|
+
verificationErrors: string[];
|
|
936
|
+
}
|
|
937
|
+
>;
|
|
938
|
+
/**
|
|
939
|
+
* Record a state version
|
|
940
|
+
*/
|
|
941
|
+
recordStateVersion(
|
|
942
|
+
key: string,
|
|
943
|
+
version: string,
|
|
944
|
+
timestamp: string,
|
|
945
|
+
nodeId: string,
|
|
946
|
+
hash: string,
|
|
947
|
+
data: unknown
|
|
948
|
+
): void;
|
|
949
|
+
/**
|
|
950
|
+
* Detect conflicts in state versions
|
|
951
|
+
*/
|
|
952
|
+
detectConflicts(key: string): boolean;
|
|
953
|
+
/**
|
|
954
|
+
* Compare two states and generate diff
|
|
955
|
+
*/
|
|
956
|
+
compareStates(
|
|
957
|
+
state1: Record<string, unknown>,
|
|
958
|
+
state2: Record<string, unknown>
|
|
959
|
+
): StateDiff;
|
|
960
|
+
/**
|
|
961
|
+
* Reconcile states using last-write-wins strategy
|
|
962
|
+
*/
|
|
963
|
+
reconcileLastWriteWins(versions: StateVersion[]): ReconciliationResult;
|
|
964
|
+
/**
|
|
965
|
+
* Reconcile states using vector clock strategy
|
|
966
|
+
*/
|
|
967
|
+
reconcileVectorClock(versions: StateVersion[]): ReconciliationResult;
|
|
968
|
+
/**
|
|
969
|
+
* Reconcile states using majority vote strategy
|
|
970
|
+
*/
|
|
971
|
+
reconcileMajorityVote(versions: StateVersion[]): ReconciliationResult;
|
|
972
|
+
/**
|
|
973
|
+
* Merge multiple states
|
|
974
|
+
*/
|
|
975
|
+
mergeStates(states: Record<string, unknown>[]): unknown;
|
|
976
|
+
/**
|
|
977
|
+
* Validate state after reconciliation
|
|
978
|
+
*/
|
|
979
|
+
validateState(state: unknown): {
|
|
980
|
+
valid: boolean;
|
|
981
|
+
errors: string[];
|
|
982
|
+
};
|
|
983
|
+
/**
|
|
984
|
+
* Get state versions for a key
|
|
985
|
+
*/
|
|
986
|
+
getStateVersions(key: string): StateVersion[];
|
|
987
|
+
/**
|
|
988
|
+
* Get all state versions
|
|
989
|
+
*/
|
|
990
|
+
getAllStateVersions(): Record<string, StateVersion[]>;
|
|
991
|
+
/**
|
|
992
|
+
* Get reconciliation history
|
|
993
|
+
*/
|
|
994
|
+
getReconciliationHistory(): ReconciliationResult[];
|
|
995
|
+
/**
|
|
996
|
+
* Get reconciliation statistics
|
|
997
|
+
*/
|
|
998
|
+
getStatistics(): {
|
|
999
|
+
totalReconciliations: number;
|
|
1000
|
+
successfulReconciliations: number;
|
|
1001
|
+
totalConflictsResolved: number;
|
|
1002
|
+
averageConflictsPerReconciliation: number;
|
|
1003
|
+
strategyUsage: Record<string, number>;
|
|
1004
|
+
trackedKeys: number;
|
|
1005
|
+
};
|
|
1006
|
+
/**
|
|
1007
|
+
* Clear all state (for testing)
|
|
1008
|
+
*/
|
|
1009
|
+
clear(): void;
|
|
1010
|
+
/**
|
|
1011
|
+
* Get the crypto provider (for advanced usage)
|
|
1012
|
+
*/
|
|
1013
|
+
getCryptoProvider(): ICryptoProvider | null;
|
|
899
1014
|
}
|
|
900
1015
|
|
|
901
1016
|
export { type Handshake, type MergeStrategy, type ProtocolError, type ReconciliationResult, type Replica, type ReplicationEvent, ReplicationManager, type ReplicationManagerOptions, type ReplicationPersistenceConfig, type ReplicationPersistenceData, type ReplicationPolicy, type StateDiff, StateReconciler, type StateVersion, SyncCoordinator, type SyncEvent, type SyncMessage, type SyncNode, SyncProtocol, type SyncProtocolOptions, type SyncProtocolPersistenceConfig, type SyncProtocolPersistenceData, type SyncRequest, type SyncResponse, type SyncSession };
|