@massalabs/gossip-sdk 0.0.2-dev.20260416094547 → 0.0.2-dev.20260417075224
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.
|
@@ -15,12 +15,6 @@ export declare enum SdkEventType {
|
|
|
15
15
|
SEEKERS_UPDATED = "seekersUpdated",
|
|
16
16
|
SESSION_STATUS_CHANGED = "sessionStatusChanged",
|
|
17
17
|
DISCUSSION_UPDATED = "discussionUpdated",
|
|
18
|
-
WRITE_FAILED = "writeFailed",
|
|
19
|
-
MESSAGE_OPTIMISTIC = "messageOptimistic",
|
|
20
|
-
MESSAGE_DELETED_OPTIMISTIC = "messageDeletedOptimistic",
|
|
21
|
-
MESSAGE_EDITED_OPTIMISTIC = "messageEditedOptimistic",
|
|
22
|
-
MESSAGE_DELETE_FAILED = "messageDeleteFailed",
|
|
23
|
-
MESSAGE_EDIT_FAILED = "messageEditFailed",
|
|
24
18
|
MESSAGE_ACKNOWLEDGED = "messageAcknowledged",
|
|
25
19
|
ERROR = "error"
|
|
26
20
|
}
|
|
@@ -47,33 +41,6 @@ export type SdkEvents = {
|
|
|
47
41
|
status: SessionStatus;
|
|
48
42
|
};
|
|
49
43
|
[SdkEventType.DISCUSSION_UPDATED]: string;
|
|
50
|
-
[SdkEventType.WRITE_FAILED]: {
|
|
51
|
-
messageId: Uint8Array | undefined;
|
|
52
|
-
entityType: 'message' | 'discussion' | 'contact';
|
|
53
|
-
error: Error;
|
|
54
|
-
};
|
|
55
|
-
[SdkEventType.MESSAGE_OPTIMISTIC]: Message;
|
|
56
|
-
[SdkEventType.MESSAGE_DELETED_OPTIMISTIC]: {
|
|
57
|
-
contactUserId: string;
|
|
58
|
-
messageDbId: number;
|
|
59
|
-
originalMsgId: Uint8Array;
|
|
60
|
-
};
|
|
61
|
-
[SdkEventType.MESSAGE_EDITED_OPTIMISTIC]: {
|
|
62
|
-
contactUserId: string;
|
|
63
|
-
messageDbId: number;
|
|
64
|
-
newContent: string;
|
|
65
|
-
metadata: Record<string, unknown>;
|
|
66
|
-
};
|
|
67
|
-
[SdkEventType.MESSAGE_DELETE_FAILED]: {
|
|
68
|
-
contactUserId: string;
|
|
69
|
-
messageDbId: number;
|
|
70
|
-
original: Message;
|
|
71
|
-
};
|
|
72
|
-
[SdkEventType.MESSAGE_EDIT_FAILED]: {
|
|
73
|
-
contactUserId: string;
|
|
74
|
-
messageDbId: number;
|
|
75
|
-
original: Message;
|
|
76
|
-
};
|
|
77
44
|
[SdkEventType.MESSAGE_ACKNOWLEDGED]: {
|
|
78
45
|
contactUserId: string;
|
|
79
46
|
messageDbId: number;
|
|
@@ -15,12 +15,6 @@ export var SdkEventType;
|
|
|
15
15
|
SdkEventType["SEEKERS_UPDATED"] = "seekersUpdated";
|
|
16
16
|
SdkEventType["SESSION_STATUS_CHANGED"] = "sessionStatusChanged";
|
|
17
17
|
SdkEventType["DISCUSSION_UPDATED"] = "discussionUpdated";
|
|
18
|
-
SdkEventType["WRITE_FAILED"] = "writeFailed";
|
|
19
|
-
SdkEventType["MESSAGE_OPTIMISTIC"] = "messageOptimistic";
|
|
20
|
-
SdkEventType["MESSAGE_DELETED_OPTIMISTIC"] = "messageDeletedOptimistic";
|
|
21
|
-
SdkEventType["MESSAGE_EDITED_OPTIMISTIC"] = "messageEditedOptimistic";
|
|
22
|
-
SdkEventType["MESSAGE_DELETE_FAILED"] = "messageDeleteFailed";
|
|
23
|
-
SdkEventType["MESSAGE_EDIT_FAILED"] = "messageEditFailed";
|
|
24
18
|
SdkEventType["MESSAGE_ACKNOWLEDGED"] = "messageAcknowledged";
|
|
25
19
|
SdkEventType["ERROR"] = "error";
|
|
26
20
|
})(SdkEventType || (SdkEventType = {}));
|
|
@@ -117,13 +117,6 @@ export declare class MessageService {
|
|
|
117
117
|
getReactions(contactUserId: string): Promise<Message[]>;
|
|
118
118
|
/** Send a message and await the full DB write + queue pipeline. */
|
|
119
119
|
send(message: Omit<Message, 'id'>): Promise<SendMessageResult>;
|
|
120
|
-
/**
|
|
121
|
-
* Optimistic send: generates messageId, emits MESSAGE_OPTIMISTIC immediately,
|
|
122
|
-
* and persists in the background. Returns synchronously.
|
|
123
|
-
*/
|
|
124
|
-
send(message: Omit<Message, 'id'>, options: {
|
|
125
|
-
optimistic: true;
|
|
126
|
-
}): SendMessageResult;
|
|
127
120
|
/**
|
|
128
121
|
* Send a text message (simplified).
|
|
129
122
|
* Builds the Message internally, sends it via queue, and triggers state update.
|
package/dist/services/message.js
CHANGED
|
@@ -1307,50 +1307,12 @@ export class MessageService {
|
|
|
1307
1307
|
const rows = await this.queries.messages.getReactionsByOwnerAndContact(this.session.userIdEncoded, contactUserId);
|
|
1308
1308
|
return rows.map(rowToMessage);
|
|
1309
1309
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
}
|
|
1315
|
-
return this.sendMessage(message);
|
|
1316
|
-
}
|
|
1317
|
-
const log = logger.forMethod('send:optimistic');
|
|
1318
|
-
const peerId = decodeUserId(message.contactUserId);
|
|
1319
|
-
if (peerId.length !== 32) {
|
|
1320
|
-
return {
|
|
1321
|
-
success: false,
|
|
1322
|
-
error: 'Invalid contact userId (must be 32 bytes)',
|
|
1323
|
-
};
|
|
1310
|
+
/** Send a message and await the full DB write + queue pipeline. */
|
|
1311
|
+
async send(message) {
|
|
1312
|
+
if (this.queueManager) {
|
|
1313
|
+
return this.queueManager.enqueue(message.contactUserId, () => this.sendMessage(message));
|
|
1324
1314
|
}
|
|
1325
|
-
|
|
1326
|
-
message.type !== MessageType.RETENTION_POLICY
|
|
1327
|
-
? crypto.getRandomValues(new Uint8Array(MESSAGE_ID_SIZE))
|
|
1328
|
-
: undefined;
|
|
1329
|
-
const optimisticMessage = {
|
|
1330
|
-
...message,
|
|
1331
|
-
messageId,
|
|
1332
|
-
status: MessageStatus.WAITING_SESSION,
|
|
1333
|
-
};
|
|
1334
|
-
this.eventEmitter.emit(SdkEventType.MESSAGE_OPTIMISTIC, optimisticMessage);
|
|
1335
|
-
log.info('optimistic send', { messageType: message.type });
|
|
1336
|
-
// Persist in background (non-optimistic path)
|
|
1337
|
-
this.send({ ...message, messageId }).then(result => {
|
|
1338
|
-
if (!result.success) {
|
|
1339
|
-
this.eventEmitter.emit(SdkEventType.WRITE_FAILED, {
|
|
1340
|
-
messageId,
|
|
1341
|
-
entityType: 'message',
|
|
1342
|
-
error: new Error(result.error ?? 'Unknown error'),
|
|
1343
|
-
});
|
|
1344
|
-
}
|
|
1345
|
-
}, error => {
|
|
1346
|
-
log.error('optimistic send failed', { error });
|
|
1347
|
-
this.eventEmitter.emit(SdkEventType.WRITE_FAILED, {
|
|
1348
|
-
messageId,
|
|
1349
|
-
entityType: 'message',
|
|
1350
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
1351
|
-
});
|
|
1352
|
-
});
|
|
1353
|
-
return { success: true, message: optimisticMessage };
|
|
1315
|
+
return this.sendMessage(message);
|
|
1354
1316
|
}
|
|
1355
1317
|
/**
|
|
1356
1318
|
* Send a text message (simplified).
|
|
@@ -1389,57 +1351,30 @@ export class MessageService {
|
|
|
1389
1351
|
return false;
|
|
1390
1352
|
if (!row.messageId)
|
|
1391
1353
|
throw new Error('Cannot delete a message that has no messageId');
|
|
1392
|
-
const original = rowToMessage(row);
|
|
1393
1354
|
const ownerUserId = this.session.userIdEncoded;
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
contactUserId: row.contactUserId,
|
|
1399
|
-
messageDbId: id,
|
|
1400
|
-
originalMsgId: row.messageId,
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
try {
|
|
1404
|
-
const messageId = row.messageId;
|
|
1405
|
-
await this.queries.conn.withTransaction(async () => {
|
|
1406
|
-
await this.queries.messages.updateById(id, {
|
|
1407
|
-
content: '[Message deleted]',
|
|
1408
|
-
type: MessageType.DELETED,
|
|
1409
|
-
});
|
|
1410
|
-
await this.queries.messages.deleteReactionsForMessage(ownerUserId, row.contactUserId, encodeToBase64(messageId));
|
|
1411
|
-
});
|
|
1412
|
-
const controlMessage = {
|
|
1413
|
-
ownerUserId,
|
|
1414
|
-
contactUserId: row.contactUserId,
|
|
1415
|
-
content: '',
|
|
1355
|
+
const messageId = row.messageId;
|
|
1356
|
+
await this.queries.conn.withTransaction(async () => {
|
|
1357
|
+
await this.queries.messages.updateById(id, {
|
|
1358
|
+
content: '[Message deleted]',
|
|
1416
1359
|
type: MessageType.DELETED,
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
// Best-effort DB rollback
|
|
1438
|
-
await this.queries.messages
|
|
1439
|
-
.updateById(id, { content: original.content, type: original.type })
|
|
1440
|
-
.catch(() => { });
|
|
1441
|
-
throw error;
|
|
1442
|
-
}
|
|
1360
|
+
});
|
|
1361
|
+
await this.queries.messages.deleteReactionsForMessage(ownerUserId, row.contactUserId, encodeToBase64(messageId));
|
|
1362
|
+
});
|
|
1363
|
+
const controlMessage = {
|
|
1364
|
+
ownerUserId,
|
|
1365
|
+
contactUserId: row.contactUserId,
|
|
1366
|
+
content: '',
|
|
1367
|
+
type: MessageType.DELETED,
|
|
1368
|
+
direction: MessageDirection.OUTGOING,
|
|
1369
|
+
status: MessageStatus.WAITING_SESSION,
|
|
1370
|
+
timestamp: new Date(),
|
|
1371
|
+
deleteOf: { originalMsgId: row.messageId },
|
|
1372
|
+
};
|
|
1373
|
+
const result = await this.send(controlMessage);
|
|
1374
|
+
if (!result.success)
|
|
1375
|
+
throw new Error(result.error ?? 'Failed to enqueue delete message');
|
|
1376
|
+
await this.refreshService?.stateUpdate();
|
|
1377
|
+
return true;
|
|
1443
1378
|
}
|
|
1444
1379
|
async sendReaction(contactUserId, emoji, originalMsgId) {
|
|
1445
1380
|
const message = {
|
|
@@ -1469,53 +1404,29 @@ export class MessageService {
|
|
|
1469
1404
|
return false;
|
|
1470
1405
|
if (!row.messageId || row.messageId.length !== MESSAGE_ID_SIZE)
|
|
1471
1406
|
throw new Error('Cannot edit a message that has no valid messageId');
|
|
1472
|
-
const original = rowToMessage(row);
|
|
1473
1407
|
const ownerUserId = this.session.userIdEncoded;
|
|
1474
1408
|
const existingMetadata = deserializeMetadata(row.metadata) ?? {};
|
|
1475
1409
|
const mergedMetadata = { ...existingMetadata, edited: true };
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
messageDbId: id,
|
|
1480
|
-
newContent,
|
|
1481
|
-
metadata: mergedMetadata,
|
|
1410
|
+
await this.queries.messages.updateById(id, {
|
|
1411
|
+
content: newContent,
|
|
1412
|
+
metadata: serializeMetadata(mergedMetadata),
|
|
1482
1413
|
});
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
const result = await this.send(controlMessage);
|
|
1500
|
-
if (!result.success)
|
|
1501
|
-
throw new Error(result.error ?? 'Failed to enqueue edit message');
|
|
1502
|
-
await this.refreshService?.stateUpdate();
|
|
1503
|
-
return true;
|
|
1504
|
-
}
|
|
1505
|
-
catch (error) {
|
|
1506
|
-
this.eventEmitter.emit(SdkEventType.MESSAGE_EDIT_FAILED, {
|
|
1507
|
-
contactUserId: row.contactUserId,
|
|
1508
|
-
messageDbId: id,
|
|
1509
|
-
original,
|
|
1510
|
-
});
|
|
1511
|
-
await this.queries.messages
|
|
1512
|
-
.updateById(id, {
|
|
1513
|
-
content: original.content,
|
|
1514
|
-
metadata: row.metadata ?? undefined,
|
|
1515
|
-
})
|
|
1516
|
-
.catch(() => { });
|
|
1517
|
-
throw error;
|
|
1518
|
-
}
|
|
1414
|
+
const controlMessage = {
|
|
1415
|
+
ownerUserId,
|
|
1416
|
+
contactUserId: row.contactUserId,
|
|
1417
|
+
content: newContent,
|
|
1418
|
+
type: MessageType.TEXT,
|
|
1419
|
+
direction: MessageDirection.OUTGOING,
|
|
1420
|
+
status: MessageStatus.WAITING_SESSION,
|
|
1421
|
+
timestamp: new Date(),
|
|
1422
|
+
editOf: { originalMsgId: row.messageId },
|
|
1423
|
+
metadata: { control: 'edit' },
|
|
1424
|
+
};
|
|
1425
|
+
const result = await this.send(controlMessage);
|
|
1426
|
+
if (!result.success)
|
|
1427
|
+
throw new Error(result.error ?? 'Failed to enqueue edit message');
|
|
1428
|
+
await this.refreshService?.stateUpdate();
|
|
1429
|
+
return true;
|
|
1519
1430
|
}
|
|
1520
1431
|
/**
|
|
1521
1432
|
* Hard-delete messages that have exceeded their discussion retention duration.
|
package/package.json
CHANGED