nostr-double-ratchet 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Invite.d.ts +6 -5
- package/dist/Invite.d.ts.map +1 -1
- package/dist/Session.d.ts +3 -3
- package/dist/Session.d.ts.map +1 -1
- package/dist/SessionManager.d.ts +25 -9
- package/dist/SessionManager.d.ts.map +1 -1
- package/dist/StorageAdapter.d.ts +18 -0
- package/dist/StorageAdapter.d.ts.map +1 -0
- package/dist/UserRecord.d.ts +7 -15
- package/dist/UserRecord.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/nostr-double-ratchet.es.js +783 -740
- package/dist/nostr-double-ratchet.umd.js +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/Invite.ts +23 -18
- package/src/Session.ts +41 -34
- package/src/SessionManager.ts +266 -42
- package/src/StorageAdapter.ts +43 -0
- package/src/UserRecord.ts +41 -32
- package/src/index.ts +3 -2
- package/src/types.ts +2 -1
package/src/UserRecord.ts
CHANGED
|
@@ -17,15 +17,6 @@ export class UserRecord {
|
|
|
17
17
|
private deviceRecords: Map<string, DeviceRecord> = new Map();
|
|
18
18
|
private isStale: boolean = false;
|
|
19
19
|
private staleTimestamp?: number;
|
|
20
|
-
/**
|
|
21
|
-
* Temporary store for sessions when the corresponding deviceId is unknown.
|
|
22
|
-
*
|
|
23
|
-
* SessionManager currently operates at a per-user granularity (it is not
|
|
24
|
-
* yet aware of individual devices). Until full Sesame device handling is
|
|
25
|
-
* implemented we keep sessions in this simple list so that
|
|
26
|
-
* SessionManager.getActiveSessions / getAllSessions work as expected.
|
|
27
|
-
*/
|
|
28
|
-
private extraSessions: Session[] = [];
|
|
29
20
|
|
|
30
21
|
constructor(
|
|
31
22
|
public _userId: string,
|
|
@@ -53,18 +44,7 @@ export class UserRecord {
|
|
|
53
44
|
* Inserts a new session for a device, making it the active session
|
|
54
45
|
*/
|
|
55
46
|
public insertSession(deviceId: string, session: Session): void {
|
|
56
|
-
|
|
57
|
-
if (!record) {
|
|
58
|
-
throw new Error(`No device record found for ${deviceId}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Move current active session to inactive list if it exists
|
|
62
|
-
if (record.activeSession) {
|
|
63
|
-
record.inactiveSessions.unshift(record.activeSession);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Set new session as active
|
|
67
|
-
record.activeSession = session;
|
|
47
|
+
this.upsertSession(deviceId, session)
|
|
68
48
|
}
|
|
69
49
|
|
|
70
50
|
/**
|
|
@@ -194,22 +174,14 @@ export class UserRecord {
|
|
|
194
174
|
// Helper methods used by SessionManager (WIP):
|
|
195
175
|
// ---------------------------------------------------------------------------
|
|
196
176
|
|
|
197
|
-
/**
|
|
198
|
-
* Add a session without associating it with a specific device.
|
|
199
|
-
* This is mainly used by SessionManager which does not yet keep track of
|
|
200
|
-
* device identifiers. The session will be considered active.
|
|
201
|
-
*/
|
|
202
|
-
public addSession(session: Session): void {
|
|
203
|
-
this.extraSessions.push(session);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
177
|
/**
|
|
207
178
|
* Return all sessions that are currently considered *active*.
|
|
208
179
|
* For now this means any session in a non-stale device record as well as
|
|
209
180
|
* all sessions added through `addSession`.
|
|
181
|
+
* Prioritizes initiator sessions (can send first message) over responder sessions.
|
|
210
182
|
*/
|
|
211
183
|
public getActiveSessions(): Session[] {
|
|
212
|
-
const sessions: Session[] = [
|
|
184
|
+
const sessions: Session[] = [];
|
|
213
185
|
|
|
214
186
|
for (const record of this.deviceRecords.values()) {
|
|
215
187
|
if (!record.isStale && record.activeSession) {
|
|
@@ -217,6 +189,15 @@ export class UserRecord {
|
|
|
217
189
|
}
|
|
218
190
|
}
|
|
219
191
|
|
|
192
|
+
sessions.sort((a, b) => {
|
|
193
|
+
const aCanSend = !!(a.state?.theirNextNostrPublicKey && a.state?.ourCurrentNostrKey);
|
|
194
|
+
const bCanSend = !!(b.state?.theirNextNostrPublicKey && b.state?.ourCurrentNostrKey);
|
|
195
|
+
|
|
196
|
+
if (aCanSend && !bCanSend) return -1; // a comes first
|
|
197
|
+
if (!aCanSend && bCanSend) return 1; // b comes first
|
|
198
|
+
return 0; // equal priority
|
|
199
|
+
});
|
|
200
|
+
|
|
220
201
|
return sessions;
|
|
221
202
|
}
|
|
222
203
|
|
|
@@ -226,7 +207,7 @@ export class UserRecord {
|
|
|
226
207
|
* listeners to existing sessions.
|
|
227
208
|
*/
|
|
228
209
|
public getAllSessions(): Session[] {
|
|
229
|
-
const sessions: Session[] = [
|
|
210
|
+
const sessions: Session[] = [];
|
|
230
211
|
|
|
231
212
|
for (const record of this.deviceRecords.values()) {
|
|
232
213
|
if (record.activeSession) {
|
|
@@ -237,4 +218,32 @@ export class UserRecord {
|
|
|
237
218
|
|
|
238
219
|
return sessions;
|
|
239
220
|
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Unified helper that either associates the session with a device record
|
|
224
|
+
* (if deviceId provided **and** the record exists) or falls back to the
|
|
225
|
+
* legacy extraSessions list.
|
|
226
|
+
*/
|
|
227
|
+
public upsertSession(deviceId: string | undefined, session: Session) {
|
|
228
|
+
if (!deviceId) {
|
|
229
|
+
deviceId = 'unknown'
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
let record = this.deviceRecords.get(deviceId)
|
|
233
|
+
if (!record) {
|
|
234
|
+
record = {
|
|
235
|
+
publicKey: session.state?.theirNextNostrPublicKey || '',
|
|
236
|
+
inactiveSessions: [],
|
|
237
|
+
isStale: false
|
|
238
|
+
}
|
|
239
|
+
this.deviceRecords.set(deviceId, record)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (record.activeSession) {
|
|
243
|
+
record.inactiveSessions.unshift(record.activeSession)
|
|
244
|
+
}
|
|
245
|
+
// Ensure session name matches deviceId for easier identification
|
|
246
|
+
session.name = deviceId
|
|
247
|
+
record.activeSession = session
|
|
248
|
+
}
|
|
240
249
|
}
|
package/src/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -74,7 +74,8 @@ export type Rumor = UnsignedEvent & { id: string }
|
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* Callback function for handling decrypted messages
|
|
77
|
-
* @param
|
|
77
|
+
* @param _event - The decrypted message object (Rumor)
|
|
78
|
+
* @param _outerEvent - The outer Nostr event (VerifiedEvent)
|
|
78
79
|
*/
|
|
79
80
|
export type EventCallback = (_event: Rumor, _outerEvent: VerifiedEvent) => void;
|
|
80
81
|
|