@thezelijah/majik-message 1.0.12 → 1.0.13
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,9 +15,11 @@ export declare class MajikMessageChat {
|
|
|
15
15
|
private timestamp;
|
|
16
16
|
private expires_at;
|
|
17
17
|
private read_by;
|
|
18
|
+
private conversation_id;
|
|
18
19
|
private static readonly MAX_MESSAGE_LENGTH;
|
|
19
|
-
constructor(id: MajikMessageChatID, account: MajikMessageAccountID, message: string, sender: MajikMessagePublicKey, recipients: MajikMessagePublicKey[], timestamp: string, expires_at: string, read_by?: string[]);
|
|
20
|
+
constructor(id: MajikMessageChatID, account: MajikMessageAccountID, message: string, sender: MajikMessagePublicKey, recipients: MajikMessagePublicKey[], timestamp: string, expires_at: string, read_by?: string[], conversation_id?: string);
|
|
20
21
|
getID(): string;
|
|
22
|
+
getConversationID(): string;
|
|
21
23
|
get account(): MajikMessageAccountID;
|
|
22
24
|
set account(account: MajikMessageIdentity);
|
|
23
25
|
/**
|
|
@@ -53,17 +55,16 @@ export declare class MajikMessageChat {
|
|
|
53
55
|
*/
|
|
54
56
|
static create(account: MajikMessageIdentity, message: string, recipients: string[], expiresInMs?: number): Promise<MajikMessageChat>;
|
|
55
57
|
/**
|
|
56
|
-
* Generate a deterministic conversation ID from a message
|
|
57
|
-
*
|
|
58
|
-
* then hashes with SHA-256 and encodes as base64
|
|
58
|
+
* Generate a deterministic conversation ID from a message JSON
|
|
59
|
+
* Reads sender and recipients directly from JSON without parsing
|
|
59
60
|
*/
|
|
60
|
-
static generateConversationID(message: MajikMessageChatJSON):
|
|
61
|
+
static generateConversationID(message: MajikMessageChatJSON): string;
|
|
61
62
|
/**
|
|
62
63
|
* Generate a deterministic conversation ID from a message
|
|
63
64
|
* Automatically includes sender and all recipients, normalized by alphabetical order
|
|
64
65
|
* then hashes with SHA-256 and encodes as base64
|
|
65
66
|
*/
|
|
66
|
-
generateConversationID():
|
|
67
|
+
generateConversationID(): string;
|
|
67
68
|
/**
|
|
68
69
|
* Get all participants for a message (sender + recipients)
|
|
69
70
|
*/
|
|
@@ -15,9 +15,10 @@ export class MajikMessageChat {
|
|
|
15
15
|
timestamp;
|
|
16
16
|
expires_at;
|
|
17
17
|
read_by;
|
|
18
|
+
conversation_id;
|
|
18
19
|
// Maximum allowed length for the compressed message string
|
|
19
20
|
static MAX_MESSAGE_LENGTH = 10000;
|
|
20
|
-
constructor(id, account, message, sender, recipients, timestamp, expires_at, read_by = []) {
|
|
21
|
+
constructor(id, account, message, sender, recipients, timestamp, expires_at, read_by = [], conversation_id) {
|
|
21
22
|
this.validateID(id);
|
|
22
23
|
this.validateAccount(account);
|
|
23
24
|
this.validateMessage(message);
|
|
@@ -34,11 +35,15 @@ export class MajikMessageChat {
|
|
|
34
35
|
this.timestamp = timestamp;
|
|
35
36
|
this.expires_at = expires_at;
|
|
36
37
|
this.read_by = [...read_by]; // Clone to prevent external mutation
|
|
38
|
+
this.conversation_id = conversation_id || this.generateConversationID();
|
|
37
39
|
}
|
|
38
40
|
// ============= GETTERS =============
|
|
39
41
|
getID() {
|
|
40
42
|
return this.id;
|
|
41
43
|
}
|
|
44
|
+
getConversationID() {
|
|
45
|
+
return this.conversation_id;
|
|
46
|
+
}
|
|
42
47
|
get account() {
|
|
43
48
|
return this._account;
|
|
44
49
|
}
|
|
@@ -152,16 +157,14 @@ export class MajikMessageChat {
|
|
|
152
157
|
}
|
|
153
158
|
// ============= STATIC HELPER METHODS =============
|
|
154
159
|
/**
|
|
155
|
-
* Generate a deterministic conversation ID from a message
|
|
156
|
-
*
|
|
157
|
-
* then hashes with SHA-256 and encodes as base64
|
|
160
|
+
* Generate a deterministic conversation ID from a message JSON
|
|
161
|
+
* Reads sender and recipients directly from JSON without parsing
|
|
158
162
|
*/
|
|
159
|
-
static
|
|
160
|
-
|
|
161
|
-
// Get all participants (sender + recipients)
|
|
163
|
+
static generateConversationID(message) {
|
|
164
|
+
// Get all participants (sender + recipients) directly from JSON
|
|
162
165
|
const participants = new Set();
|
|
163
|
-
participants.add(
|
|
164
|
-
|
|
166
|
+
participants.add(message.sender);
|
|
167
|
+
message.recipients.forEach((r) => participants.add(r));
|
|
165
168
|
// Sort alphabetically to ensure same conversation ID regardless of order
|
|
166
169
|
const sorted = Array.from(participants).sort();
|
|
167
170
|
// Join with delimiter
|
|
@@ -178,7 +181,7 @@ export class MajikMessageChat {
|
|
|
178
181
|
* Automatically includes sender and all recipients, normalized by alphabetical order
|
|
179
182
|
* then hashes with SHA-256 and encodes as base64
|
|
180
183
|
*/
|
|
181
|
-
|
|
184
|
+
generateConversationID() {
|
|
182
185
|
// Get all participants (sender + recipients)
|
|
183
186
|
const participants = new Set();
|
|
184
187
|
participants.add(this.getSender());
|
|
@@ -257,6 +260,7 @@ export class MajikMessageChat {
|
|
|
257
260
|
throw new Error("Cannot add sender as a recipient");
|
|
258
261
|
}
|
|
259
262
|
this.recipients.push(trimmedId);
|
|
263
|
+
this.conversation_id = this.generateConversationID();
|
|
260
264
|
}
|
|
261
265
|
removeRecipient(recipientId) {
|
|
262
266
|
if (!recipientId ||
|
|
@@ -278,6 +282,7 @@ export class MajikMessageChat {
|
|
|
278
282
|
if (this.recipients.length === 0) {
|
|
279
283
|
throw new Error("Cannot remove last recipient: message must have at least one recipient");
|
|
280
284
|
}
|
|
285
|
+
this.conversation_id = this.generateConversationID();
|
|
281
286
|
}
|
|
282
287
|
hasRecipient(recipientId) {
|
|
283
288
|
if (!recipientId || typeof recipientId !== "string") {
|
|
@@ -342,6 +347,7 @@ export class MajikMessageChat {
|
|
|
342
347
|
toJSON() {
|
|
343
348
|
return {
|
|
344
349
|
id: this.id,
|
|
350
|
+
conversation_id: this.conversation_id,
|
|
345
351
|
account: this.account,
|
|
346
352
|
message: this.message,
|
|
347
353
|
sender: this.sender,
|
|
@@ -356,7 +362,7 @@ export class MajikMessageChat {
|
|
|
356
362
|
if (!this.isValidJSON(rawParse)) {
|
|
357
363
|
throw new Error("Invalid JSON: missing required fields or invalid types");
|
|
358
364
|
}
|
|
359
|
-
return new MajikMessageChat(rawParse.id, rawParse.account, rawParse.message, rawParse.sender, rawParse.recipients || [], rawParse.timestamp, rawParse.expires_at, rawParse.read_by || []);
|
|
365
|
+
return new MajikMessageChat(rawParse.id, rawParse.account, rawParse.message, rawParse.sender, rawParse.recipients || [], rawParse.timestamp, rawParse.expires_at, rawParse.read_by || [], rawParse?.conversation_id);
|
|
360
366
|
}
|
|
361
367
|
// ============= REDIS METHODS =============
|
|
362
368
|
// Generate Redis key
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MajikMessageAccountID, MajikMessageChatID, MajikMessagePublicKey } from "../../types";
|
|
2
2
|
export interface MajikMessageChatJSON {
|
|
3
3
|
id: MajikMessageChatID;
|
|
4
|
+
conversation_id: string;
|
|
4
5
|
account: MajikMessageAccountID;
|
|
5
6
|
message: string;
|
|
6
7
|
sender: MajikMessagePublicKey;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@thezelijah/majik-message",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Encrypt and decrypt messages on any website. Secure chats with keypairs and seed-based accounts. Open source.",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.13",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": "Zelijah",
|
|
8
8
|
"main": "./dist/index.js",
|