@affectively/aeon 1.3.0 → 1.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/LICENSE +21 -21
- package/README.md +342 -342
- package/dist/compression/index.cjs.map +1 -1
- package/dist/compression/index.js.map +1 -1
- package/dist/core/index.d.cts +213 -213
- package/dist/core/index.d.ts +213 -213
- package/dist/crypto/index.cjs.map +1 -1
- package/dist/crypto/index.d.cts +441 -441
- package/dist/crypto/index.d.ts +441 -441
- package/dist/crypto/index.js.map +1 -1
- package/dist/distributed/index.cjs.map +1 -1
- package/dist/distributed/index.d.cts +1005 -1005
- package/dist/distributed/index.d.ts +1005 -1005
- package/dist/distributed/index.js.map +1 -1
- package/dist/index.cjs +32 -723
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -5
- package/dist/index.d.ts +50 -5
- package/dist/index.js +29 -722
- package/dist/index.js.map +1 -1
- package/dist/offline/index.cjs.map +1 -1
- package/dist/offline/index.d.cts +148 -148
- package/dist/offline/index.d.ts +148 -148
- 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 +57 -57
- package/dist/persistence/index.d.ts +57 -57
- 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-B7gCpNX9.d.cts → types-B7CxsoLh.d.cts} +30 -30
- package/dist/{types-B7gCpNX9.d.ts → types-B7CxsoLh.d.ts} +30 -30
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +35 -35
- package/dist/utils/index.d.ts +35 -35
- package/dist/utils/index.js.map +1 -1
- 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.map +1 -1
- package/package.json +196 -196
package/dist/index.cjs
CHANGED
|
@@ -195,230 +195,6 @@ var InMemoryStorageAdapter = class {
|
|
|
195
195
|
}
|
|
196
196
|
};
|
|
197
197
|
|
|
198
|
-
// src/versioning/SchemaVersionManager.ts
|
|
199
|
-
var SchemaVersionManager = class {
|
|
200
|
-
versions = /* @__PURE__ */ new Map();
|
|
201
|
-
versionHistory = [];
|
|
202
|
-
compatibilityMatrix = /* @__PURE__ */ new Map();
|
|
203
|
-
currentVersion = null;
|
|
204
|
-
constructor() {
|
|
205
|
-
this.initializeDefaultVersions();
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Initialize default versions
|
|
209
|
-
*/
|
|
210
|
-
initializeDefaultVersions() {
|
|
211
|
-
const v1_0_0 = {
|
|
212
|
-
major: 1,
|
|
213
|
-
minor: 0,
|
|
214
|
-
patch: 0,
|
|
215
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
216
|
-
description: "Initial schema version",
|
|
217
|
-
breaking: false
|
|
218
|
-
};
|
|
219
|
-
this.registerVersion(v1_0_0);
|
|
220
|
-
this.currentVersion = v1_0_0;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Register a new schema version
|
|
224
|
-
*/
|
|
225
|
-
registerVersion(version) {
|
|
226
|
-
const versionString = this.versionToString(version);
|
|
227
|
-
this.versions.set(versionString, version);
|
|
228
|
-
this.versionHistory.push(version);
|
|
229
|
-
logger.debug("[SchemaVersionManager] Version registered", {
|
|
230
|
-
version: versionString,
|
|
231
|
-
breaking: version.breaking,
|
|
232
|
-
description: version.description
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Get current version
|
|
237
|
-
*/
|
|
238
|
-
getCurrentVersion() {
|
|
239
|
-
if (!this.currentVersion) {
|
|
240
|
-
throw new Error("No current version set");
|
|
241
|
-
}
|
|
242
|
-
return this.currentVersion;
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Set current version
|
|
246
|
-
*/
|
|
247
|
-
setCurrentVersion(version) {
|
|
248
|
-
if (!this.versions.has(this.versionToString(version))) {
|
|
249
|
-
throw new Error(
|
|
250
|
-
`Version ${this.versionToString(version)} not registered`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
this.currentVersion = version;
|
|
254
|
-
logger.debug("[SchemaVersionManager] Current version set", {
|
|
255
|
-
version: this.versionToString(version)
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Get version history
|
|
260
|
-
*/
|
|
261
|
-
getVersionHistory() {
|
|
262
|
-
return [...this.versionHistory];
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Check if version exists
|
|
266
|
-
*/
|
|
267
|
-
hasVersion(version) {
|
|
268
|
-
return this.versions.has(this.versionToString(version));
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Get version by string (e.g., "1.2.3")
|
|
272
|
-
*/
|
|
273
|
-
getVersion(versionString) {
|
|
274
|
-
return this.versions.get(versionString);
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Register compatibility rule
|
|
278
|
-
*/
|
|
279
|
-
registerCompatibility(rule) {
|
|
280
|
-
if (!this.compatibilityMatrix.has(rule.from)) {
|
|
281
|
-
this.compatibilityMatrix.set(rule.from, []);
|
|
282
|
-
}
|
|
283
|
-
const rules = this.compatibilityMatrix.get(rule.from);
|
|
284
|
-
if (rules) {
|
|
285
|
-
rules.push(rule);
|
|
286
|
-
}
|
|
287
|
-
logger.debug("[SchemaVersionManager] Compatibility rule registered", {
|
|
288
|
-
from: rule.from,
|
|
289
|
-
to: rule.to,
|
|
290
|
-
compatible: rule.compatible,
|
|
291
|
-
requiresMigration: rule.requiresMigration
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Check if migration path exists
|
|
296
|
-
*/
|
|
297
|
-
canMigrate(fromVersion, toVersion) {
|
|
298
|
-
const fromStr = typeof fromVersion === "string" ? fromVersion : this.versionToString(fromVersion);
|
|
299
|
-
const toStr = typeof toVersion === "string" ? toVersion : this.versionToString(toVersion);
|
|
300
|
-
const rules = this.compatibilityMatrix.get(fromStr) || [];
|
|
301
|
-
return rules.some((r) => r.to === toStr && r.requiresMigration);
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Get migration path
|
|
305
|
-
*/
|
|
306
|
-
getMigrationPath(fromVersion, toVersion) {
|
|
307
|
-
const path = [];
|
|
308
|
-
let current = fromVersion;
|
|
309
|
-
const maxSteps = 100;
|
|
310
|
-
let steps = 0;
|
|
311
|
-
while (this.compareVersions(current, toVersion) !== 0 && steps < maxSteps) {
|
|
312
|
-
const fromStr = this.versionToString(current);
|
|
313
|
-
const rules = this.compatibilityMatrix.get(fromStr) || [];
|
|
314
|
-
let found = false;
|
|
315
|
-
for (const rule of rules) {
|
|
316
|
-
const nextVersion = this.getVersion(rule.to);
|
|
317
|
-
if (nextVersion) {
|
|
318
|
-
if (this.compareVersions(nextVersion, toVersion) <= 0 || this.compareVersions(current, nextVersion) < this.compareVersions(current, toVersion)) {
|
|
319
|
-
current = nextVersion;
|
|
320
|
-
path.push(current);
|
|
321
|
-
found = true;
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
if (!found) {
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
steps++;
|
|
330
|
-
}
|
|
331
|
-
return path;
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Compare two versions
|
|
335
|
-
* Returns: -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
336
|
-
*/
|
|
337
|
-
compareVersions(v1, v2) {
|
|
338
|
-
const ver1 = typeof v1 === "string" ? this.parseVersion(v1) : v1;
|
|
339
|
-
const ver2 = typeof v2 === "string" ? this.parseVersion(v2) : v2;
|
|
340
|
-
if (ver1.major !== ver2.major) {
|
|
341
|
-
return ver1.major < ver2.major ? -1 : 1;
|
|
342
|
-
}
|
|
343
|
-
if (ver1.minor !== ver2.minor) {
|
|
344
|
-
return ver1.minor < ver2.minor ? -1 : 1;
|
|
345
|
-
}
|
|
346
|
-
if (ver1.patch !== ver2.patch) {
|
|
347
|
-
return ver1.patch < ver2.patch ? -1 : 1;
|
|
348
|
-
}
|
|
349
|
-
return 0;
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Parse version string to SchemaVersion
|
|
353
|
-
*/
|
|
354
|
-
parseVersion(versionString) {
|
|
355
|
-
const parts = versionString.split(".").map(Number);
|
|
356
|
-
return {
|
|
357
|
-
major: parts[0] || 0,
|
|
358
|
-
minor: parts[1] || 0,
|
|
359
|
-
patch: parts[2] || 0,
|
|
360
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
361
|
-
description: "",
|
|
362
|
-
breaking: false
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Create new version
|
|
367
|
-
*/
|
|
368
|
-
createVersion(major, minor, patch, description, breaking = false) {
|
|
369
|
-
return {
|
|
370
|
-
major,
|
|
371
|
-
minor,
|
|
372
|
-
patch,
|
|
373
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
374
|
-
description,
|
|
375
|
-
breaking
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Convert version to string
|
|
380
|
-
*/
|
|
381
|
-
versionToString(version) {
|
|
382
|
-
return `${version.major}.${version.minor}.${version.patch}`;
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Get version metadata
|
|
386
|
-
*/
|
|
387
|
-
getVersionMetadata(version) {
|
|
388
|
-
const history = this.versionHistory;
|
|
389
|
-
const currentIndex = history.findIndex(
|
|
390
|
-
(v) => this.versionToString(v) === this.versionToString(version)
|
|
391
|
-
);
|
|
392
|
-
return {
|
|
393
|
-
version,
|
|
394
|
-
previousVersion: currentIndex > 0 ? history[currentIndex - 1] : void 0,
|
|
395
|
-
changes: [version.description],
|
|
396
|
-
migrationsRequired: this.canMigrate(
|
|
397
|
-
this.currentVersion || version,
|
|
398
|
-
version
|
|
399
|
-
) ? [this.versionToString(version)] : [],
|
|
400
|
-
rollbackPossible: currentIndex > 0
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Get all registered versions
|
|
405
|
-
*/
|
|
406
|
-
getAllVersions() {
|
|
407
|
-
return Array.from(this.versions.values()).sort(
|
|
408
|
-
(a, b) => this.compareVersions(a, b)
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Clear all versions (for testing)
|
|
413
|
-
*/
|
|
414
|
-
clear() {
|
|
415
|
-
this.versions.clear();
|
|
416
|
-
this.versionHistory = [];
|
|
417
|
-
this.compatibilityMatrix.clear();
|
|
418
|
-
this.currentVersion = null;
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
|
-
|
|
422
198
|
// src/versioning/MigrationEngine.ts
|
|
423
199
|
var MigrationEngine = class {
|
|
424
200
|
migrations = /* @__PURE__ */ new Map();
|
|
@@ -1323,489 +1099,6 @@ var MigrationTracker = class _MigrationTracker {
|
|
|
1323
1099
|
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
1324
1100
|
}
|
|
1325
1101
|
};
|
|
1326
|
-
var SyncCoordinator = class extends eventemitter3.EventEmitter {
|
|
1327
|
-
nodes = /* @__PURE__ */ new Map();
|
|
1328
|
-
sessions = /* @__PURE__ */ new Map();
|
|
1329
|
-
syncEvents = [];
|
|
1330
|
-
nodeHeartbeats = /* @__PURE__ */ new Map();
|
|
1331
|
-
heartbeatInterval = null;
|
|
1332
|
-
// Crypto support
|
|
1333
|
-
cryptoProvider = null;
|
|
1334
|
-
nodesByDID = /* @__PURE__ */ new Map();
|
|
1335
|
-
// DID -> nodeId
|
|
1336
|
-
constructor() {
|
|
1337
|
-
super();
|
|
1338
|
-
}
|
|
1339
|
-
/**
|
|
1340
|
-
* Configure cryptographic provider for authenticated sync
|
|
1341
|
-
*/
|
|
1342
|
-
configureCrypto(provider) {
|
|
1343
|
-
this.cryptoProvider = provider;
|
|
1344
|
-
logger.debug("[SyncCoordinator] Crypto configured", {
|
|
1345
|
-
initialized: provider.isInitialized()
|
|
1346
|
-
});
|
|
1347
|
-
}
|
|
1348
|
-
/**
|
|
1349
|
-
* Check if crypto is configured
|
|
1350
|
-
*/
|
|
1351
|
-
isCryptoEnabled() {
|
|
1352
|
-
return this.cryptoProvider !== null && this.cryptoProvider.isInitialized();
|
|
1353
|
-
}
|
|
1354
|
-
/**
|
|
1355
|
-
* Register a node with DID-based identity
|
|
1356
|
-
*/
|
|
1357
|
-
async registerAuthenticatedNode(nodeInfo) {
|
|
1358
|
-
const node = {
|
|
1359
|
-
...nodeInfo
|
|
1360
|
-
};
|
|
1361
|
-
this.nodes.set(node.id, node);
|
|
1362
|
-
this.nodeHeartbeats.set(node.id, Date.now());
|
|
1363
|
-
this.nodesByDID.set(nodeInfo.did, node.id);
|
|
1364
|
-
if (this.cryptoProvider) {
|
|
1365
|
-
await this.cryptoProvider.registerRemoteNode({
|
|
1366
|
-
id: node.id,
|
|
1367
|
-
did: nodeInfo.did,
|
|
1368
|
-
publicSigningKey: nodeInfo.publicSigningKey,
|
|
1369
|
-
publicEncryptionKey: nodeInfo.publicEncryptionKey
|
|
1370
|
-
});
|
|
1371
|
-
}
|
|
1372
|
-
const event = {
|
|
1373
|
-
type: "node-joined",
|
|
1374
|
-
nodeId: node.id,
|
|
1375
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1376
|
-
data: { did: nodeInfo.did, authenticated: true }
|
|
1377
|
-
};
|
|
1378
|
-
this.syncEvents.push(event);
|
|
1379
|
-
this.emit("node-joined", node);
|
|
1380
|
-
logger.debug("[SyncCoordinator] Authenticated node registered", {
|
|
1381
|
-
nodeId: node.id,
|
|
1382
|
-
did: nodeInfo.did,
|
|
1383
|
-
version: node.version
|
|
1384
|
-
});
|
|
1385
|
-
return node;
|
|
1386
|
-
}
|
|
1387
|
-
/**
|
|
1388
|
-
* Get node by DID
|
|
1389
|
-
*/
|
|
1390
|
-
getNodeByDID(did) {
|
|
1391
|
-
const nodeId = this.nodesByDID.get(did);
|
|
1392
|
-
if (!nodeId) return void 0;
|
|
1393
|
-
return this.nodes.get(nodeId);
|
|
1394
|
-
}
|
|
1395
|
-
/**
|
|
1396
|
-
* Get all authenticated nodes (nodes with DIDs)
|
|
1397
|
-
*/
|
|
1398
|
-
getAuthenticatedNodes() {
|
|
1399
|
-
return Array.from(this.nodes.values()).filter((n) => n.did);
|
|
1400
|
-
}
|
|
1401
|
-
/**
|
|
1402
|
-
* Create an authenticated sync session with UCAN-based authorization
|
|
1403
|
-
*/
|
|
1404
|
-
async createAuthenticatedSyncSession(initiatorDID, participantDIDs, options) {
|
|
1405
|
-
const initiatorNodeId = this.nodesByDID.get(initiatorDID);
|
|
1406
|
-
if (!initiatorNodeId) {
|
|
1407
|
-
throw new Error(`Initiator node with DID ${initiatorDID} not found`);
|
|
1408
|
-
}
|
|
1409
|
-
const participantIds = [];
|
|
1410
|
-
for (const did of participantDIDs) {
|
|
1411
|
-
const nodeId = this.nodesByDID.get(did);
|
|
1412
|
-
if (nodeId) {
|
|
1413
|
-
participantIds.push(nodeId);
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
let sessionToken;
|
|
1417
|
-
if (this.cryptoProvider && this.cryptoProvider.isInitialized()) {
|
|
1418
|
-
const capabilities = (options?.requiredCapabilities || ["aeon:sync:read", "aeon:sync:write"]).map((cap) => ({ can: cap, with: "*" }));
|
|
1419
|
-
if (participantDIDs.length > 0) {
|
|
1420
|
-
sessionToken = await this.cryptoProvider.createUCAN(
|
|
1421
|
-
participantDIDs[0],
|
|
1422
|
-
capabilities,
|
|
1423
|
-
{ expirationSeconds: 3600 }
|
|
1424
|
-
// 1 hour
|
|
1425
|
-
);
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
const session = {
|
|
1429
|
-
id: `sync-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
1430
|
-
initiatorId: initiatorNodeId,
|
|
1431
|
-
participantIds,
|
|
1432
|
-
status: "pending",
|
|
1433
|
-
startTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1434
|
-
itemsSynced: 0,
|
|
1435
|
-
itemsFailed: 0,
|
|
1436
|
-
conflictsDetected: 0,
|
|
1437
|
-
initiatorDID,
|
|
1438
|
-
participantDIDs,
|
|
1439
|
-
encryptionMode: options?.encryptionMode || "none",
|
|
1440
|
-
requiredCapabilities: options?.requiredCapabilities,
|
|
1441
|
-
sessionToken
|
|
1442
|
-
};
|
|
1443
|
-
this.sessions.set(session.id, session);
|
|
1444
|
-
const event = {
|
|
1445
|
-
type: "sync-started",
|
|
1446
|
-
sessionId: session.id,
|
|
1447
|
-
nodeId: initiatorNodeId,
|
|
1448
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1449
|
-
data: {
|
|
1450
|
-
authenticated: true,
|
|
1451
|
-
initiatorDID,
|
|
1452
|
-
participantCount: participantDIDs.length,
|
|
1453
|
-
encryptionMode: session.encryptionMode
|
|
1454
|
-
}
|
|
1455
|
-
};
|
|
1456
|
-
this.syncEvents.push(event);
|
|
1457
|
-
this.emit("sync-started", session);
|
|
1458
|
-
logger.debug("[SyncCoordinator] Authenticated sync session created", {
|
|
1459
|
-
sessionId: session.id,
|
|
1460
|
-
initiatorDID,
|
|
1461
|
-
participants: participantDIDs.length,
|
|
1462
|
-
encryptionMode: session.encryptionMode
|
|
1463
|
-
});
|
|
1464
|
-
return session;
|
|
1465
|
-
}
|
|
1466
|
-
/**
|
|
1467
|
-
* Verify a node's UCAN capabilities for a session
|
|
1468
|
-
*/
|
|
1469
|
-
async verifyNodeCapabilities(sessionId, nodeDID, token) {
|
|
1470
|
-
if (!this.cryptoProvider) {
|
|
1471
|
-
return { authorized: true };
|
|
1472
|
-
}
|
|
1473
|
-
const session = this.sessions.get(sessionId);
|
|
1474
|
-
if (!session) {
|
|
1475
|
-
return { authorized: false, error: `Session ${sessionId} not found` };
|
|
1476
|
-
}
|
|
1477
|
-
const result = await this.cryptoProvider.verifyUCAN(token, {
|
|
1478
|
-
requiredCapabilities: session.requiredCapabilities?.map((cap) => ({
|
|
1479
|
-
can: cap,
|
|
1480
|
-
with: "*"
|
|
1481
|
-
}))
|
|
1482
|
-
});
|
|
1483
|
-
if (!result.authorized) {
|
|
1484
|
-
logger.warn("[SyncCoordinator] Node capability verification failed", {
|
|
1485
|
-
sessionId,
|
|
1486
|
-
nodeDID,
|
|
1487
|
-
error: result.error
|
|
1488
|
-
});
|
|
1489
|
-
}
|
|
1490
|
-
return result;
|
|
1491
|
-
}
|
|
1492
|
-
/**
|
|
1493
|
-
* Register a node in the cluster
|
|
1494
|
-
*/
|
|
1495
|
-
registerNode(node) {
|
|
1496
|
-
this.nodes.set(node.id, node);
|
|
1497
|
-
this.nodeHeartbeats.set(node.id, Date.now());
|
|
1498
|
-
const event = {
|
|
1499
|
-
type: "node-joined",
|
|
1500
|
-
nodeId: node.id,
|
|
1501
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1502
|
-
};
|
|
1503
|
-
this.syncEvents.push(event);
|
|
1504
|
-
this.emit("node-joined", node);
|
|
1505
|
-
logger.debug("[SyncCoordinator] Node registered", {
|
|
1506
|
-
nodeId: node.id,
|
|
1507
|
-
address: node.address,
|
|
1508
|
-
version: node.version
|
|
1509
|
-
});
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
* Deregister a node from the cluster
|
|
1513
|
-
*/
|
|
1514
|
-
deregisterNode(nodeId) {
|
|
1515
|
-
const node = this.nodes.get(nodeId);
|
|
1516
|
-
if (!node) {
|
|
1517
|
-
throw new Error(`Node ${nodeId} not found`);
|
|
1518
|
-
}
|
|
1519
|
-
this.nodes.delete(nodeId);
|
|
1520
|
-
this.nodeHeartbeats.delete(nodeId);
|
|
1521
|
-
const event = {
|
|
1522
|
-
type: "node-left",
|
|
1523
|
-
nodeId,
|
|
1524
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1525
|
-
};
|
|
1526
|
-
this.syncEvents.push(event);
|
|
1527
|
-
this.emit("node-left", node);
|
|
1528
|
-
logger.debug("[SyncCoordinator] Node deregistered", { nodeId });
|
|
1529
|
-
}
|
|
1530
|
-
/**
|
|
1531
|
-
* Create a new sync session
|
|
1532
|
-
*/
|
|
1533
|
-
createSyncSession(initiatorId, participantIds) {
|
|
1534
|
-
const node = this.nodes.get(initiatorId);
|
|
1535
|
-
if (!node) {
|
|
1536
|
-
throw new Error(`Initiator node ${initiatorId} not found`);
|
|
1537
|
-
}
|
|
1538
|
-
const session = {
|
|
1539
|
-
id: `sync-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
1540
|
-
initiatorId,
|
|
1541
|
-
participantIds,
|
|
1542
|
-
status: "pending",
|
|
1543
|
-
startTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1544
|
-
itemsSynced: 0,
|
|
1545
|
-
itemsFailed: 0,
|
|
1546
|
-
conflictsDetected: 0
|
|
1547
|
-
};
|
|
1548
|
-
this.sessions.set(session.id, session);
|
|
1549
|
-
const event = {
|
|
1550
|
-
type: "sync-started",
|
|
1551
|
-
sessionId: session.id,
|
|
1552
|
-
nodeId: initiatorId,
|
|
1553
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1554
|
-
};
|
|
1555
|
-
this.syncEvents.push(event);
|
|
1556
|
-
this.emit("sync-started", session);
|
|
1557
|
-
logger.debug("[SyncCoordinator] Sync session created", {
|
|
1558
|
-
sessionId: session.id,
|
|
1559
|
-
initiator: initiatorId,
|
|
1560
|
-
participants: participantIds.length
|
|
1561
|
-
});
|
|
1562
|
-
return session;
|
|
1563
|
-
}
|
|
1564
|
-
/**
|
|
1565
|
-
* Update sync session
|
|
1566
|
-
*/
|
|
1567
|
-
updateSyncSession(sessionId, updates) {
|
|
1568
|
-
const session = this.sessions.get(sessionId);
|
|
1569
|
-
if (!session) {
|
|
1570
|
-
throw new Error(`Session ${sessionId} not found`);
|
|
1571
|
-
}
|
|
1572
|
-
Object.assign(session, updates);
|
|
1573
|
-
if (updates.status === "completed" || updates.status === "failed") {
|
|
1574
|
-
session.endTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
1575
|
-
const event = {
|
|
1576
|
-
type: "sync-completed",
|
|
1577
|
-
sessionId,
|
|
1578
|
-
nodeId: session.initiatorId,
|
|
1579
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1580
|
-
data: { status: updates.status, itemsSynced: session.itemsSynced }
|
|
1581
|
-
};
|
|
1582
|
-
this.syncEvents.push(event);
|
|
1583
|
-
this.emit("sync-completed", session);
|
|
1584
|
-
}
|
|
1585
|
-
logger.debug("[SyncCoordinator] Sync session updated", {
|
|
1586
|
-
sessionId,
|
|
1587
|
-
status: session.status,
|
|
1588
|
-
itemsSynced: session.itemsSynced
|
|
1589
|
-
});
|
|
1590
|
-
}
|
|
1591
|
-
/**
|
|
1592
|
-
* Record a conflict during sync
|
|
1593
|
-
*/
|
|
1594
|
-
recordConflict(sessionId, nodeId, conflictData) {
|
|
1595
|
-
const session = this.sessions.get(sessionId);
|
|
1596
|
-
if (session) {
|
|
1597
|
-
session.conflictsDetected++;
|
|
1598
|
-
const event = {
|
|
1599
|
-
type: "conflict-detected",
|
|
1600
|
-
sessionId,
|
|
1601
|
-
nodeId,
|
|
1602
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1603
|
-
data: conflictData
|
|
1604
|
-
};
|
|
1605
|
-
this.syncEvents.push(event);
|
|
1606
|
-
this.emit("conflict-detected", { session, nodeId, conflictData });
|
|
1607
|
-
logger.debug("[SyncCoordinator] Conflict recorded", {
|
|
1608
|
-
sessionId,
|
|
1609
|
-
nodeId,
|
|
1610
|
-
totalConflicts: session.conflictsDetected
|
|
1611
|
-
});
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
/**
|
|
1615
|
-
* Update node status
|
|
1616
|
-
*/
|
|
1617
|
-
updateNodeStatus(nodeId, status) {
|
|
1618
|
-
const node = this.nodes.get(nodeId);
|
|
1619
|
-
if (!node) {
|
|
1620
|
-
throw new Error(`Node ${nodeId} not found`);
|
|
1621
|
-
}
|
|
1622
|
-
node.status = status;
|
|
1623
|
-
this.nodeHeartbeats.set(nodeId, Date.now());
|
|
1624
|
-
logger.debug("[SyncCoordinator] Node status updated", {
|
|
1625
|
-
nodeId,
|
|
1626
|
-
status
|
|
1627
|
-
});
|
|
1628
|
-
}
|
|
1629
|
-
/**
|
|
1630
|
-
* Record heartbeat from node
|
|
1631
|
-
*/
|
|
1632
|
-
recordHeartbeat(nodeId) {
|
|
1633
|
-
const node = this.nodes.get(nodeId);
|
|
1634
|
-
if (!node) {
|
|
1635
|
-
return;
|
|
1636
|
-
}
|
|
1637
|
-
node.lastHeartbeat = (/* @__PURE__ */ new Date()).toISOString();
|
|
1638
|
-
this.nodeHeartbeats.set(nodeId, Date.now());
|
|
1639
|
-
}
|
|
1640
|
-
/**
|
|
1641
|
-
* Get all nodes
|
|
1642
|
-
*/
|
|
1643
|
-
getNodes() {
|
|
1644
|
-
return Array.from(this.nodes.values());
|
|
1645
|
-
}
|
|
1646
|
-
/**
|
|
1647
|
-
* Get node by ID
|
|
1648
|
-
*/
|
|
1649
|
-
getNode(nodeId) {
|
|
1650
|
-
return this.nodes.get(nodeId);
|
|
1651
|
-
}
|
|
1652
|
-
/**
|
|
1653
|
-
* Get online nodes
|
|
1654
|
-
*/
|
|
1655
|
-
getOnlineNodes() {
|
|
1656
|
-
return Array.from(this.nodes.values()).filter((n) => n.status === "online");
|
|
1657
|
-
}
|
|
1658
|
-
/**
|
|
1659
|
-
* Get nodes by capability
|
|
1660
|
-
*/
|
|
1661
|
-
getNodesByCapability(capability) {
|
|
1662
|
-
return Array.from(this.nodes.values()).filter(
|
|
1663
|
-
(n) => n.capabilities.includes(capability)
|
|
1664
|
-
);
|
|
1665
|
-
}
|
|
1666
|
-
/**
|
|
1667
|
-
* Get sync session
|
|
1668
|
-
*/
|
|
1669
|
-
getSyncSession(sessionId) {
|
|
1670
|
-
return this.sessions.get(sessionId);
|
|
1671
|
-
}
|
|
1672
|
-
/**
|
|
1673
|
-
* Get all sync sessions
|
|
1674
|
-
*/
|
|
1675
|
-
getAllSyncSessions() {
|
|
1676
|
-
return Array.from(this.sessions.values());
|
|
1677
|
-
}
|
|
1678
|
-
/**
|
|
1679
|
-
* Get active sync sessions
|
|
1680
|
-
*/
|
|
1681
|
-
getActiveSyncSessions() {
|
|
1682
|
-
return Array.from(this.sessions.values()).filter(
|
|
1683
|
-
(s) => s.status === "active"
|
|
1684
|
-
);
|
|
1685
|
-
}
|
|
1686
|
-
/**
|
|
1687
|
-
* Get sessions for a node
|
|
1688
|
-
*/
|
|
1689
|
-
getSessionsForNode(nodeId) {
|
|
1690
|
-
return Array.from(this.sessions.values()).filter(
|
|
1691
|
-
(s) => s.initiatorId === nodeId || s.participantIds.includes(nodeId)
|
|
1692
|
-
);
|
|
1693
|
-
}
|
|
1694
|
-
/**
|
|
1695
|
-
* Get sync statistics
|
|
1696
|
-
*/
|
|
1697
|
-
getStatistics() {
|
|
1698
|
-
const sessions = Array.from(this.sessions.values());
|
|
1699
|
-
const completed = sessions.filter((s) => s.status === "completed").length;
|
|
1700
|
-
const failed = sessions.filter((s) => s.status === "failed").length;
|
|
1701
|
-
const active = sessions.filter((s) => s.status === "active").length;
|
|
1702
|
-
const totalItemsSynced = sessions.reduce(
|
|
1703
|
-
(sum, s) => sum + s.itemsSynced,
|
|
1704
|
-
0
|
|
1705
|
-
);
|
|
1706
|
-
const totalConflicts = sessions.reduce(
|
|
1707
|
-
(sum, s) => sum + s.conflictsDetected,
|
|
1708
|
-
0
|
|
1709
|
-
);
|
|
1710
|
-
return {
|
|
1711
|
-
totalNodes: this.nodes.size,
|
|
1712
|
-
onlineNodes: this.getOnlineNodes().length,
|
|
1713
|
-
offlineNodes: this.nodes.size - this.getOnlineNodes().length,
|
|
1714
|
-
totalSessions: sessions.length,
|
|
1715
|
-
activeSessions: active,
|
|
1716
|
-
completedSessions: completed,
|
|
1717
|
-
failedSessions: failed,
|
|
1718
|
-
successRate: sessions.length > 0 ? completed / sessions.length * 100 : 0,
|
|
1719
|
-
totalItemsSynced,
|
|
1720
|
-
totalConflicts,
|
|
1721
|
-
averageConflictsPerSession: sessions.length > 0 ? totalConflicts / sessions.length : 0
|
|
1722
|
-
};
|
|
1723
|
-
}
|
|
1724
|
-
/**
|
|
1725
|
-
* Get sync events
|
|
1726
|
-
*/
|
|
1727
|
-
getSyncEvents(limit) {
|
|
1728
|
-
const events = [...this.syncEvents];
|
|
1729
|
-
if (limit) {
|
|
1730
|
-
return events.slice(-limit);
|
|
1731
|
-
}
|
|
1732
|
-
return events;
|
|
1733
|
-
}
|
|
1734
|
-
/**
|
|
1735
|
-
* Get sync events for session
|
|
1736
|
-
*/
|
|
1737
|
-
getSessionEvents(sessionId) {
|
|
1738
|
-
return this.syncEvents.filter((e) => e.sessionId === sessionId);
|
|
1739
|
-
}
|
|
1740
|
-
/**
|
|
1741
|
-
* Check node health
|
|
1742
|
-
*/
|
|
1743
|
-
getNodeHealth() {
|
|
1744
|
-
const health = {};
|
|
1745
|
-
for (const [nodeId, lastHeartbeat] of this.nodeHeartbeats) {
|
|
1746
|
-
const now = Date.now();
|
|
1747
|
-
const downtime = now - lastHeartbeat;
|
|
1748
|
-
const isHealthy = downtime < 3e4;
|
|
1749
|
-
health[nodeId] = {
|
|
1750
|
-
isHealthy,
|
|
1751
|
-
downtime
|
|
1752
|
-
};
|
|
1753
|
-
}
|
|
1754
|
-
return health;
|
|
1755
|
-
}
|
|
1756
|
-
/**
|
|
1757
|
-
* Start heartbeat monitoring
|
|
1758
|
-
*/
|
|
1759
|
-
startHeartbeatMonitoring(interval = 5e3) {
|
|
1760
|
-
if (this.heartbeatInterval) {
|
|
1761
|
-
return;
|
|
1762
|
-
}
|
|
1763
|
-
this.heartbeatInterval = setInterval(() => {
|
|
1764
|
-
const health = this.getNodeHealth();
|
|
1765
|
-
for (const [nodeId, { isHealthy }] of Object.entries(health)) {
|
|
1766
|
-
const node = this.nodes.get(nodeId);
|
|
1767
|
-
if (!node) {
|
|
1768
|
-
continue;
|
|
1769
|
-
}
|
|
1770
|
-
const newStatus = isHealthy ? "online" : "offline";
|
|
1771
|
-
if (node.status !== newStatus) {
|
|
1772
|
-
this.updateNodeStatus(nodeId, newStatus);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
}, interval);
|
|
1776
|
-
logger.debug("[SyncCoordinator] Heartbeat monitoring started", {
|
|
1777
|
-
interval
|
|
1778
|
-
});
|
|
1779
|
-
}
|
|
1780
|
-
/**
|
|
1781
|
-
* Stop heartbeat monitoring
|
|
1782
|
-
*/
|
|
1783
|
-
stopHeartbeatMonitoring() {
|
|
1784
|
-
if (this.heartbeatInterval) {
|
|
1785
|
-
clearInterval(this.heartbeatInterval);
|
|
1786
|
-
this.heartbeatInterval = null;
|
|
1787
|
-
logger.debug("[SyncCoordinator] Heartbeat monitoring stopped");
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
/**
|
|
1791
|
-
* Clear all state (for testing)
|
|
1792
|
-
*/
|
|
1793
|
-
clear() {
|
|
1794
|
-
this.nodes.clear();
|
|
1795
|
-
this.sessions.clear();
|
|
1796
|
-
this.syncEvents = [];
|
|
1797
|
-
this.nodeHeartbeats.clear();
|
|
1798
|
-
this.nodesByDID.clear();
|
|
1799
|
-
this.cryptoProvider = null;
|
|
1800
|
-
this.stopHeartbeatMonitoring();
|
|
1801
|
-
}
|
|
1802
|
-
/**
|
|
1803
|
-
* Get the crypto provider (for advanced usage)
|
|
1804
|
-
*/
|
|
1805
|
-
getCryptoProvider() {
|
|
1806
|
-
return this.cryptoProvider;
|
|
1807
|
-
}
|
|
1808
|
-
};
|
|
1809
1102
|
|
|
1810
1103
|
// src/distributed/ReplicationManager.ts
|
|
1811
1104
|
var ReplicationManager = class _ReplicationManager {
|
|
@@ -5250,15 +4543,7 @@ var AdaptiveCompressionOptimizer = class {
|
|
|
5250
4543
|
};
|
|
5251
4544
|
}
|
|
5252
4545
|
};
|
|
5253
|
-
var adaptiveOptimizerInstance = null;
|
|
5254
|
-
function getAdaptiveCompressionOptimizer() {
|
|
5255
|
-
if (!adaptiveOptimizerInstance) {
|
|
5256
|
-
adaptiveOptimizerInstance = new AdaptiveCompressionOptimizer();
|
|
5257
|
-
}
|
|
5258
|
-
return adaptiveOptimizerInstance;
|
|
5259
|
-
}
|
|
5260
4546
|
function resetAdaptiveCompressionOptimizer() {
|
|
5261
|
-
adaptiveOptimizerInstance = null;
|
|
5262
4547
|
}
|
|
5263
4548
|
var logger8 = getLogger();
|
|
5264
4549
|
var AgentPresenceManager = class extends eventemitter3.EventEmitter {
|
|
@@ -5703,12 +4988,6 @@ var AgentPresenceManager = class extends eventemitter3.EventEmitter {
|
|
|
5703
4988
|
}
|
|
5704
4989
|
};
|
|
5705
4990
|
var instances = /* @__PURE__ */ new Map();
|
|
5706
|
-
function getAgentPresenceManager(sessionId) {
|
|
5707
|
-
if (!instances.has(sessionId)) {
|
|
5708
|
-
instances.set(sessionId, new AgentPresenceManager(sessionId));
|
|
5709
|
-
}
|
|
5710
|
-
return instances.get(sessionId);
|
|
5711
|
-
}
|
|
5712
4991
|
function clearAgentPresenceManager(sessionId) {
|
|
5713
4992
|
const instance = instances.get(sessionId);
|
|
5714
4993
|
if (instance) {
|
|
@@ -5810,6 +5089,34 @@ var NullCryptoProvider = class {
|
|
|
5810
5089
|
}
|
|
5811
5090
|
};
|
|
5812
5091
|
|
|
5092
|
+
// src/index.ts
|
|
5093
|
+
var Link = (() => {
|
|
5094
|
+
throw new Error(
|
|
5095
|
+
"Link: Stub called from @affectively/aeon. Import from @affectively/aeon-flux-react or mock in tests."
|
|
5096
|
+
);
|
|
5097
|
+
});
|
|
5098
|
+
var useAeonPage = (() => {
|
|
5099
|
+
throw new Error(
|
|
5100
|
+
"useAeonPage: Stub called from @affectively/aeon. Import from @affectively/aeon-flux-react or mock in tests."
|
|
5101
|
+
);
|
|
5102
|
+
});
|
|
5103
|
+
var getAdaptiveCompressionOptimizer = (() => {
|
|
5104
|
+
throw new Error("getAdaptiveCompressionOptimizer: Stub");
|
|
5105
|
+
});
|
|
5106
|
+
var SchemaVersionManager2 = class {
|
|
5107
|
+
constructor() {
|
|
5108
|
+
throw new Error("SchemaVersionManager: Stub");
|
|
5109
|
+
}
|
|
5110
|
+
};
|
|
5111
|
+
var getAgentPresenceManager = (() => {
|
|
5112
|
+
throw new Error("getAgentPresenceManager: Stub");
|
|
5113
|
+
});
|
|
5114
|
+
var SyncCoordinator2 = class {
|
|
5115
|
+
constructor() {
|
|
5116
|
+
throw new Error("SyncCoordinator: Stub");
|
|
5117
|
+
}
|
|
5118
|
+
};
|
|
5119
|
+
|
|
5813
5120
|
exports.AEON_CAPABILITIES = AEON_CAPABILITIES;
|
|
5814
5121
|
exports.AdaptiveCompressionOptimizer = AdaptiveCompressionOptimizer;
|
|
5815
5122
|
exports.AgentPresenceManager = AgentPresenceManager;
|
|
@@ -5820,15 +5127,16 @@ exports.DashStorageAdapter = DashStorageAdapter;
|
|
|
5820
5127
|
exports.DataTransformer = DataTransformer;
|
|
5821
5128
|
exports.DeltaSyncOptimizer = DeltaSyncOptimizer;
|
|
5822
5129
|
exports.InMemoryStorageAdapter = InMemoryStorageAdapter;
|
|
5130
|
+
exports.Link = Link;
|
|
5823
5131
|
exports.MigrationEngine = MigrationEngine;
|
|
5824
5132
|
exports.MigrationTracker = MigrationTracker;
|
|
5825
5133
|
exports.NullCryptoProvider = NullCryptoProvider;
|
|
5826
5134
|
exports.OfflineOperationQueue = OfflineOperationQueue;
|
|
5827
5135
|
exports.PrefetchingEngine = PrefetchingEngine;
|
|
5828
5136
|
exports.ReplicationManager = ReplicationManager;
|
|
5829
|
-
exports.SchemaVersionManager =
|
|
5137
|
+
exports.SchemaVersionManager = SchemaVersionManager2;
|
|
5830
5138
|
exports.StateReconciler = StateReconciler;
|
|
5831
|
-
exports.SyncCoordinator =
|
|
5139
|
+
exports.SyncCoordinator = SyncCoordinator2;
|
|
5832
5140
|
exports.SyncProtocol = SyncProtocol;
|
|
5833
5141
|
exports.clearAgentPresenceManager = clearAgentPresenceManager;
|
|
5834
5142
|
exports.createNamespacedLogger = createNamespacedLogger;
|
|
@@ -5850,5 +5158,6 @@ exports.resetLogger = resetLogger;
|
|
|
5850
5158
|
exports.resetOfflineOperationQueue = resetOfflineOperationQueue;
|
|
5851
5159
|
exports.resetPrefetchingEngine = resetPrefetchingEngine;
|
|
5852
5160
|
exports.setLogger = setLogger;
|
|
5161
|
+
exports.useAeonPage = useAeonPage;
|
|
5853
5162
|
//# sourceMappingURL=index.cjs.map
|
|
5854
5163
|
//# sourceMappingURL=index.cjs.map
|