@massalabs/gossip-sdk 0.0.2-dev.20260225142738 → 0.0.2-dev.20260302112618

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.
Files changed (95) hide show
  1. package/dist/api/authProtocol.d.ts +1 -1
  2. package/dist/api/authProtocol.js +3 -3
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/api/index.js +1 -1
  5. package/dist/api/messageProtocol/index.d.ts +3 -3
  6. package/dist/api/messageProtocol/index.js +3 -3
  7. package/dist/api/messageProtocol/rest.d.ts +2 -2
  8. package/dist/api/messageProtocol/rest.js +2 -2
  9. package/dist/config/sdk.d.ts +13 -0
  10. package/dist/config/sdk.js +9 -0
  11. package/dist/core/SdkEventEmitter.d.ts +3 -0
  12. package/dist/core/SdkEventEmitter.js +2 -0
  13. package/dist/core/SdkPolling.d.ts +4 -2
  14. package/dist/core/SdkPolling.js +19 -2
  15. package/dist/core/index.d.ts +4 -4
  16. package/dist/core/index.js +3 -3
  17. package/dist/crypto/encryption.d.ts +1 -1
  18. package/dist/crypto/encryption.js +1 -1
  19. package/dist/crypto/index.d.ts +2 -2
  20. package/dist/crypto/index.js +2 -2
  21. package/dist/db/db.d.ts +3 -9
  22. package/dist/db/db.js +0 -9
  23. package/dist/db/generated-migrations.js +3 -11
  24. package/dist/db/index.d.ts +3 -3
  25. package/dist/db/index.js +3 -3
  26. package/dist/db/queries/activeSeekers.d.ts +1 -1
  27. package/dist/db/queries/activeSeekers.js +1 -1
  28. package/dist/db/queries/announcementCursors.d.ts +1 -1
  29. package/dist/db/queries/announcementCursors.js +1 -1
  30. package/dist/db/queries/contacts.d.ts +3 -3
  31. package/dist/db/queries/contacts.js +1 -1
  32. package/dist/db/queries/discussions.d.ts +3 -6
  33. package/dist/db/queries/discussions.js +1 -8
  34. package/dist/db/queries/index.d.ts +14 -14
  35. package/dist/db/queries/index.js +8 -8
  36. package/dist/db/queries/messages.d.ts +3 -3
  37. package/dist/db/queries/messages.js +2 -2
  38. package/dist/db/queries/pendingAnnouncements.d.ts +2 -2
  39. package/dist/db/queries/pendingAnnouncements.js +1 -1
  40. package/dist/db/queries/userProfile.d.ts +2 -2
  41. package/dist/db/queries/userProfile.js +1 -1
  42. package/dist/db/schema/activeSeekers.js +1 -1
  43. package/dist/db/schema/contacts.js +1 -1
  44. package/dist/db/schema/discussions.d.ts +52 -21
  45. package/dist/db/schema/discussions.js +7 -4
  46. package/dist/db/schema/index.d.ts +8 -8
  47. package/dist/db/schema/index.js +8 -8
  48. package/dist/db/schema/messages.js +1 -1
  49. package/dist/db/schema/pendingAnnouncements.js +1 -1
  50. package/dist/db/schema/pendingEncryptedMessages.js +1 -1
  51. package/dist/db/schema/userProfile.js +1 -1
  52. package/dist/db/sqlite-worker.js +28 -1
  53. package/dist/gossip.d.ts +13 -13
  54. package/dist/gossip.js +28 -25
  55. package/dist/index.d.ts +8 -8
  56. package/dist/index.js +8 -8
  57. package/dist/services/announcement.d.ts +9 -9
  58. package/dist/services/announcement.js +12 -10
  59. package/dist/services/auth.d.ts +2 -2
  60. package/dist/services/auth.js +3 -3
  61. package/dist/services/contact.d.ts +6 -6
  62. package/dist/services/contact.js +1 -1
  63. package/dist/services/discussion.d.ts +11 -11
  64. package/dist/services/discussion.js +8 -9
  65. package/dist/services/message.d.ts +10 -10
  66. package/dist/services/message.js +22 -15
  67. package/dist/services/profile.d.ts +3 -3
  68. package/dist/services/profile.js +2 -2
  69. package/dist/services/refresh.d.ts +18 -7
  70. package/dist/services/refresh.js +173 -29
  71. package/dist/sw.d.ts +1 -1
  72. package/dist/sw.js +1 -1
  73. package/dist/utils/contacts.d.ts +4 -4
  74. package/dist/utils/contacts.js +1 -1
  75. package/dist/utils/discussions.d.ts +3 -3
  76. package/dist/utils/discussions.js +1 -1
  77. package/dist/utils/index.d.ts +8 -8
  78. package/dist/utils/index.js +8 -8
  79. package/dist/utils/messageSerialization.d.ts +2 -2
  80. package/dist/utils/messageSerialization.js +2 -2
  81. package/dist/utils/userId.js +1 -1
  82. package/dist/utils/validation.d.ts +1 -1
  83. package/dist/utils/validation.js +1 -1
  84. package/dist/wasm/bindings.d.ts +2 -2
  85. package/dist/wasm/bindings.js +2 -2
  86. package/dist/wasm/encryption.d.ts +1 -1
  87. package/dist/wasm/encryption.js +2 -2
  88. package/dist/wasm/index.d.ts +5 -5
  89. package/dist/wasm/index.js +5 -6
  90. package/dist/wasm/loader.js +1 -1
  91. package/dist/wasm/session.d.ts +1 -1
  92. package/dist/wasm/session.js +2 -2
  93. package/dist/wasm/userKeys.d.ts +1 -1
  94. package/dist/wasm/userKeys.js +2 -2
  95. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Auth Protocol — public key publishing & retrieval
3
3
  */
4
- import { RestClient } from './restClient';
4
+ import { RestClient } from './restClient.js';
5
5
  export interface IAuthProtocol {
6
6
  /** Fetches the base64-encoded public key for the given user ID. */
7
7
  fetchPublicKeyByUserId(userId: Uint8Array): Promise<string>;
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Auth Protocol — public key publishing & retrieval
3
3
  */
4
- import { RestClient } from './restClient';
5
- import { encodeToBase64 } from '../utils/base64';
6
- import { protocolConfig } from '../config/protocol';
4
+ import { RestClient } from './restClient.js';
5
+ import { encodeToBase64 } from '../utils/base64.js';
6
+ import { protocolConfig } from '../config/protocol.js';
7
7
  export function createAuthProtocol(config) {
8
8
  return new RestAuthProtocol(config?.baseUrl ?? protocolConfig.baseUrl, config?.timeout ?? protocolConfig.timeout, config?.retryAttempts ?? protocolConfig.retryAttempts);
9
9
  }
@@ -1 +1 @@
1
- export { restMessageProtocol, RestMessageProtocol, type EncryptedMessage, } from './messageProtocol';
1
+ export { restMessageProtocol, RestMessageProtocol, type EncryptedMessage, } from './messageProtocol/index.js';
package/dist/api/index.js CHANGED
@@ -1 +1 @@
1
- export { restMessageProtocol, RestMessageProtocol, } from './messageProtocol';
1
+ export { restMessageProtocol, RestMessageProtocol, } from './messageProtocol/index.js';
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Factory functions and exports for message protocol implementations.
5
5
  */
6
- export type { EncryptedMessage, IMessageProtocol, MessageProtocolResponse, BulletinItem, } from './types';
7
- import type { IMessageProtocol } from './types';
6
+ export type { EncryptedMessage, IMessageProtocol, MessageProtocolResponse, BulletinItem, } from './types.js';
7
+ import type { IMessageProtocol } from './types.js';
8
8
  /**
9
9
  * Factory function to create message protocol instances
10
10
  */
@@ -14,4 +14,4 @@ export declare function createMessageProtocol(config?: Partial<{
14
14
  retryAttempts: number;
15
15
  }>): IMessageProtocol;
16
16
  export declare const restMessageProtocol: IMessageProtocol;
17
- export { RestMessageProtocol } from './rest';
17
+ export { RestMessageProtocol } from './rest.js';
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Factory functions and exports for message protocol implementations.
5
5
  */
6
- import { protocolConfig } from '../../config/protocol';
7
- import { RestMessageProtocol } from './rest';
6
+ import { protocolConfig } from '../../config/protocol.js';
7
+ import { RestMessageProtocol } from './rest.js';
8
8
  /**
9
9
  * Factory function to create message protocol instances
10
10
  */
@@ -12,4 +12,4 @@ export function createMessageProtocol(config) {
12
12
  return new RestMessageProtocol(config?.baseUrl ?? protocolConfig.baseUrl, config?.timeout ?? protocolConfig.timeout, config?.retryAttempts ?? protocolConfig.retryAttempts);
13
13
  }
14
14
  export const restMessageProtocol = createMessageProtocol();
15
- export { RestMessageProtocol } from './rest';
15
+ export { RestMessageProtocol } from './rest.js';
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * REST API implementation of the message protocol
3
3
  */
4
- import { BulletinItem, EncryptedMessage, IMessageProtocol, MessageProtocolResponse } from './types';
5
- import { RestClient } from '../restClient';
4
+ import { BulletinItem, EncryptedMessage, IMessageProtocol, MessageProtocolResponse } from './types.js';
5
+ import { RestClient } from '../restClient.js';
6
6
  export type BulletinsPage = {
7
7
  counter: string;
8
8
  data: string;
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * REST API implementation of the message protocol
3
3
  */
4
- import { RestClient } from '../restClient';
5
- import { encodeToBase64, decodeFromBase64 } from '../../utils/base64';
4
+ import { RestClient } from '../restClient.js';
5
+ import { encodeToBase64, decodeFromBase64 } from '../../utils/base64.js';
6
6
  const BULLETIN_ENDPOINT = '/bulletin';
7
7
  const MESSAGES_ENDPOINT = '/messages';
8
8
  export class RestMessageProtocol extends RestClient {
@@ -57,6 +57,17 @@ export interface AnnouncementsConfig {
57
57
  /** Delay before retrying a failed announcement send in ms (default: 15000 = 15 seconds) */
58
58
  retryDelayMs: number;
59
59
  }
60
+ /**
61
+ * Session recovery configuration
62
+ */
63
+ export interface SessionRecoveryConfig {
64
+ /** Delay before retrying a killed session reset (default: 15 minutes) */
65
+ killedRetryDelayMs: number;
66
+ /** Jitter applied (default: 2 minutes) */
67
+ JitterMs: number;
68
+ /** Delay before retrying a saturated session reset (default: 5 minutes) */
69
+ saturatedRetryDelayMs: number;
70
+ }
60
71
  /**
61
72
  * Complete SDK configuration
62
73
  */
@@ -69,6 +80,8 @@ export interface SdkConfig {
69
80
  messages: MessagesConfig;
70
81
  /** Announcement settings */
71
82
  announcements: AnnouncementsConfig;
83
+ /** Session recovery settings */
84
+ sessionRecovery: SessionRecoveryConfig;
72
85
  }
73
86
  /**
74
87
  * Default SDK configuration values
@@ -29,6 +29,11 @@ export const defaultSdkConfig = {
29
29
  brokenThresholdMs: 60 * 60 * 1000, // 1 hour
30
30
  retryDelayMs: 15000, // 15 seconds
31
31
  },
32
+ sessionRecovery: {
33
+ killedRetryDelayMs: 15 * 60 * 1000,
34
+ JitterMs: 2 * 60 * 1000,
35
+ saturatedRetryDelayMs: 5 * 60 * 1000,
36
+ },
32
37
  };
33
38
  /**
34
39
  * Deep merge partial config with defaults
@@ -53,5 +58,9 @@ export function mergeConfig(partial) {
53
58
  ...defaultSdkConfig.announcements,
54
59
  ...partial.announcements,
55
60
  },
61
+ sessionRecovery: {
62
+ ...defaultSdkConfig.sessionRecovery,
63
+ ...partial.sessionRecovery,
64
+ },
56
65
  };
57
66
  }
@@ -4,6 +4,7 @@
4
4
  * Type-safe event emitter for SDK events.
5
5
  */
6
6
  import type { Message, Discussion, Contact } from '../db';
7
+ import type { SessionStatus } from '../wasm/bindings';
7
8
  export declare enum SdkEventType {
8
9
  MESSAGE_RECEIVED = "messageReceived",
9
10
  MESSAGE_SENT = "messageSent",
@@ -14,6 +15,7 @@ export declare enum SdkEventType {
14
15
  SESSION_RENEWED = "sessionRenewed",
15
16
  SESSION_ACCEPTED = "sessionAccepted",
16
17
  SEEKERS_UPDATED = "seekersUpdated",
18
+ SESSION_STATUS_CHANGED = "sessionStatusChanged",
17
19
  ERROR = "error"
18
20
  }
19
21
  export interface SdkEventHandlers {
@@ -26,6 +28,7 @@ export interface SdkEventHandlers {
26
28
  [SdkEventType.SESSION_RENEWED]: (discussion: Discussion) => void;
27
29
  [SdkEventType.SESSION_ACCEPTED]: (contactUserId: string) => void;
28
30
  [SdkEventType.SEEKERS_UPDATED]: (seekers: Uint8Array[]) => void;
31
+ [SdkEventType.SESSION_STATUS_CHANGED]: (contactUserId: string, status: SessionStatus) => void;
29
32
  [SdkEventType.ERROR]: (error: Error, context: string) => void;
30
33
  }
31
34
  export declare class SdkEventEmitter {
@@ -17,6 +17,7 @@ export var SdkEventType;
17
17
  SdkEventType["SESSION_RENEWED"] = "sessionRenewed";
18
18
  SdkEventType["SESSION_ACCEPTED"] = "sessionAccepted";
19
19
  SdkEventType["SEEKERS_UPDATED"] = "seekersUpdated";
20
+ SdkEventType["SESSION_STATUS_CHANGED"] = "sessionStatusChanged";
20
21
  SdkEventType["ERROR"] = "error";
21
22
  })(SdkEventType || (SdkEventType = {}));
22
23
  // ─────────────────────────────────────────────────────────────────────────────
@@ -38,6 +39,7 @@ export class SdkEventEmitter {
38
39
  [SdkEventType.SESSION_RENEWED]: new Set(),
39
40
  [SdkEventType.SESSION_ACCEPTED]: new Set(),
40
41
  [SdkEventType.SEEKERS_UPDATED]: new Set(),
42
+ [SdkEventType.SESSION_STATUS_CHANGED]: new Set(),
41
43
  [SdkEventType.ERROR]: new Set(),
42
44
  }
43
45
  });
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Manages polling timers for messages, announcements, and session refresh.
5
5
  */
6
- import type { SdkConfig } from '../config/sdk';
7
- import { SdkEventEmitter } from './SdkEventEmitter';
6
+ import type { SdkConfig } from '../config/sdk.js';
7
+ import { SdkEventEmitter } from './SdkEventEmitter.js';
8
8
  export interface PollingCallbacks {
9
9
  /** Fetch messages from protocol */
10
10
  fetchMessages: () => Promise<void>;
@@ -12,6 +12,8 @@ export interface PollingCallbacks {
12
12
  fetchAnnouncements: () => Promise<void>;
13
13
  /** Handle session refresh (state update) */
14
14
  handleSessionRefresh: () => Promise<void>;
15
+ /** Check for session status changes and emit events */
16
+ refreshSessionsStatusEvent: () => Promise<void>;
15
17
  }
16
18
  export declare class SdkPolling {
17
19
  private timers;
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Manages polling timers for messages, announcements, and session refresh.
5
5
  */
6
- import { SdkEventType } from './SdkEventEmitter';
6
+ import { SdkEventType } from './SdkEventEmitter.js';
7
+ const SESSION_STATUS_POLL_INTERVAL_MS = 3000;
7
8
  // ─────────────────────────────────────────────────────────────────────────────
8
9
  // Polling Manager Class
9
10
  // ─────────────────────────────────────────────────────────────────────────────
@@ -17,6 +18,7 @@ export class SdkPolling {
17
18
  messages: null,
18
19
  announcements: null,
19
20
  sessionRefresh: null,
21
+ sessionStatus: null,
20
22
  }
21
23
  });
22
24
  Object.defineProperty(this, "callbacks", {
@@ -75,6 +77,16 @@ export class SdkPolling {
75
77
  this.eventEmitter?.emit(SdkEventType.ERROR, err, 'session_update');
76
78
  }
77
79
  }, config.polling.sessionRefreshIntervalMs);
80
+ // Start session status change polling (fixed 3s interval)
81
+ this.timers.sessionStatus = setInterval(async () => {
82
+ try {
83
+ await this.callbacks?.refreshSessionsStatusEvent();
84
+ }
85
+ catch (error) {
86
+ const err = error instanceof Error ? error : new Error(String(error));
87
+ this.eventEmitter?.emit(SdkEventType.ERROR, err, 'session_status_polling');
88
+ }
89
+ }, SESSION_STATUS_POLL_INTERVAL_MS);
78
90
  }
79
91
  /**
80
92
  * Stop all polling timers.
@@ -92,6 +104,10 @@ export class SdkPolling {
92
104
  clearInterval(this.timers.sessionRefresh);
93
105
  this.timers.sessionRefresh = null;
94
106
  }
107
+ if (this.timers.sessionStatus) {
108
+ clearInterval(this.timers.sessionStatus);
109
+ this.timers.sessionStatus = null;
110
+ }
95
111
  this.callbacks = null;
96
112
  this.eventEmitter = null;
97
113
  }
@@ -101,6 +117,7 @@ export class SdkPolling {
101
117
  isRunning() {
102
118
  return (this.timers.messages !== null ||
103
119
  this.timers.announcements !== null ||
104
- this.timers.sessionRefresh !== null);
120
+ this.timers.sessionRefresh !== null ||
121
+ this.timers.sessionStatus !== null);
105
122
  }
106
123
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Core SDK components
3
3
  */
4
- export { SdkEventEmitter } from './SdkEventEmitter';
5
- export { SdkEventType, type SdkEventHandlers } from './SdkEventEmitter';
6
- export { SdkPolling } from './SdkPolling';
7
- export type { PollingCallbacks } from './SdkPolling';
4
+ export { SdkEventEmitter } from './SdkEventEmitter.js';
5
+ export { SdkEventType, type SdkEventHandlers } from './SdkEventEmitter.js';
6
+ export { SdkPolling } from './SdkPolling.js';
7
+ export type { PollingCallbacks } from './SdkPolling.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Core SDK components
3
3
  */
4
- export { SdkEventEmitter } from './SdkEventEmitter';
5
- export { SdkEventType } from './SdkEventEmitter';
6
- export { SdkPolling } from './SdkPolling';
4
+ export { SdkEventEmitter } from './SdkEventEmitter.js';
5
+ export { SdkEventType } from './SdkEventEmitter.js';
6
+ export { SdkPolling } from './SdkPolling.js';
@@ -4,7 +4,7 @@
4
4
  * Provides convenient wrappers for encrypting and decrypting strings
5
5
  * using the WASM encryption primitives.
6
6
  */
7
- import { EncryptionKey } from '../wasm/encryption';
7
+ import { EncryptionKey } from '../wasm/encryption.js';
8
8
  /**
9
9
  * Encrypt a plaintext string using AES-256-SIV
10
10
  *
@@ -4,7 +4,7 @@
4
4
  * Provides convenient wrappers for encrypting and decrypting strings
5
5
  * using the WASM encryption primitives.
6
6
  */
7
- import { decryptAead, encryptAead, EncryptionKey, generateNonce, Nonce, } from '../wasm/encryption';
7
+ import { decryptAead, encryptAead, EncryptionKey, generateNonce, Nonce, } from '../wasm/encryption.js';
8
8
  /**
9
9
  * Encrypt a plaintext string using AES-256-SIV
10
10
  *
@@ -1,2 +1,2 @@
1
- export * from './bip39';
2
- export * from './encryption';
1
+ export * from './bip39.js';
2
+ export * from './encryption.js';
@@ -1,2 +1,2 @@
1
- export * from './bip39';
2
- export * from './encryption';
1
+ export * from './bip39.js';
2
+ export * from './encryption.js';
package/dist/db/db.d.ts CHANGED
@@ -65,14 +65,6 @@ export interface UserProfile {
65
65
  updatedAt: Date;
66
66
  lastPublicKeyPush?: Date;
67
67
  }
68
- export declare enum DiscussionStatus {
69
- PENDING = "pending",
70
- ACTIVE = "active",
71
- CLOSED = "closed",// closed by the user
72
- BROKEN = "broken",// The session is killed. Need to be reinitiated
73
- SEND_FAILED = "sendFailed",// The discussion was initiated by the session manager but could not be broadcasted on network
74
- RECONNECTING = "reconnecting"
75
- }
76
68
  export declare enum DiscussionDirection {
77
69
  RECEIVED = "received",
78
70
  INITIATED = "initiated"
@@ -128,7 +120,6 @@ export interface Discussion {
128
120
  weAccepted: boolean;
129
121
  sendAnnouncement: SendAnnouncement;
130
122
  direction: DiscussionDirection;
131
- status: DiscussionStatus;
132
123
  nextSeeker: Uint8Array | null;
133
124
  initiationAnnouncement: Uint8Array | null;
134
125
  announcementMessage: string | null;
@@ -139,6 +130,9 @@ export interface Discussion {
139
130
  lastMessageContent: string | null;
140
131
  lastMessageTimestamp: Date | null;
141
132
  unreadCount: number;
133
+ killedNextRetryAt?: Date | null;
134
+ saturatedRetryAt?: Date | null;
135
+ saturatedRetryDone: boolean;
142
136
  createdAt: Date;
143
137
  updatedAt: Date;
144
138
  }
package/dist/db/db.js CHANGED
@@ -7,15 +7,6 @@
7
7
  // Constants
8
8
  export const MESSAGE_ID_SIZE = 12;
9
9
  // Unified discussion interface combining protocol state and UI metadata
10
- export var DiscussionStatus;
11
- (function (DiscussionStatus) {
12
- DiscussionStatus["PENDING"] = "pending";
13
- DiscussionStatus["ACTIVE"] = "active";
14
- DiscussionStatus["CLOSED"] = "closed";
15
- DiscussionStatus["BROKEN"] = "broken";
16
- DiscussionStatus["SEND_FAILED"] = "sendFailed";
17
- DiscussionStatus["RECONNECTING"] = "reconnecting";
18
- })(DiscussionStatus || (DiscussionStatus = {}));
19
10
  export var DiscussionDirection;
20
11
  (function (DiscussionDirection) {
21
12
  DiscussionDirection["RECEIVED"] = "received";
@@ -4,7 +4,7 @@ export const MIGRATIONS = [
4
4
  {
5
5
  idx: 0,
6
6
  tag: '0000_nifty_molly_hayes',
7
- when: 1771825473415,
7
+ when: 1730000000000,
8
8
  statements: [
9
9
  'CREATE TABLE `activeSeekers` (\n\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\n\t`seeker` blob NOT NULL\n);',
10
10
  'CREATE INDEX `active_seekers_seeker_idx` ON `activeSeekers` (`seeker`);',
@@ -12,9 +12,8 @@ export const MIGRATIONS = [
12
12
  'CREATE TABLE `contacts` (\n\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\n\t`ownerUserId` text NOT NULL,\n\t`userId` text NOT NULL,\n\t`name` text NOT NULL,\n\t`avatar` text,\n\t`publicKeys` blob NOT NULL,\n\t`isOnline` integer NOT NULL,\n\t`lastSeen` integer NOT NULL,\n\t`createdAt` integer NOT NULL\n);',
13
13
  'CREATE INDEX `contacts_owner_user_idx` ON `contacts` (`ownerUserId`,`userId`);',
14
14
  'CREATE INDEX `contacts_owner_name_idx` ON `contacts` (`ownerUserId`,`name`);',
15
- 'CREATE TABLE `discussions` (\n\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\n\t`ownerUserId` text NOT NULL,\n\t`contactUserId` text NOT NULL,\n\t`weAccepted` integer DEFAULT false NOT NULL,\n\t`sendAnnouncement` text,\n\t`direction` text NOT NULL,\n\t`status` text NOT NULL,\n\t`nextSeeker` blob,\n\t`initiationAnnouncement` blob,\n\t`announcementMessage` text,\n\t`lastSyncTimestamp` integer,\n\t`customName` text,\n\t`lastMessageId` integer,\n\t`lastMessageContent` text,\n\t`lastMessageTimestamp` integer,\n\t`unreadCount` integer DEFAULT 0 NOT NULL,\n\t`createdAt` integer NOT NULL,\n\t`updatedAt` integer NOT NULL\n);',
15
+ 'CREATE TABLE `discussions` (\n\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\n\t`ownerUserId` text NOT NULL,\n\t`contactUserId` text NOT NULL,\n\t`weAccepted` integer DEFAULT false NOT NULL,\n\t`sendAnnouncement` text,\n\t`direction` text NOT NULL,\n\t`nextSeeker` blob,\n\t`initiationAnnouncement` blob,\n\t`announcementMessage` text,\n\t`lastSyncTimestamp` integer,\n\t`customName` text,\n\t`lastMessageId` integer,\n\t`lastMessageContent` text,\n\t`lastMessageTimestamp` integer,\n\t`unreadCount` integer DEFAULT 0 NOT NULL,\n\t`killedNextRetryAt` integer,\n\t`saturatedRetryAt` integer,\n\t`saturatedRetryDone` integer DEFAULT 0 NOT NULL,\n\t`createdAt` integer NOT NULL,\n\t`updatedAt` integer NOT NULL\n);',
16
16
  'CREATE UNIQUE INDEX `discussions_owner_contact_idx` ON `discussions` (`ownerUserId`,`contactUserId`);',
17
- 'CREATE INDEX `discussions_owner_status_idx` ON `discussions` (`ownerUserId`,`status`);',
18
17
  'CREATE TABLE `messages` (\n\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\n\t`ownerUserId` text NOT NULL,\n\t`contactUserId` text NOT NULL,\n\t`messageId` blob,\n\t`content` text NOT NULL,\n\t`serializedContent` blob,\n\t`type` text NOT NULL,\n\t`direction` text NOT NULL,\n\t`status` text NOT NULL,\n\t`timestamp` integer NOT NULL,\n\t`metadata` text,\n\t`seeker` blob,\n\t`replyTo` text,\n\t`forwardOf` text,\n\t`encryptedMessage` blob,\n\t`whenToSend` integer\n);',
19
18
  'CREATE INDEX `messages_owner_contact_idx` ON `messages` (`ownerUserId`,`contactUserId`);',
20
19
  'CREATE INDEX `messages_owner_status_idx` ON `messages` (`ownerUserId`,`status`);',
@@ -23,6 +22,7 @@ export const MIGRATIONS = [
23
22
  'CREATE INDEX `messages_owner_contact_dir_idx` ON `messages` (`ownerUserId`,`contactUserId`,`direction`);',
24
23
  'CREATE INDEX `messages_owner_dir_status_idx` ON `messages` (`ownerUserId`,`direction`,`status`);',
25
24
  'CREATE INDEX `messages_timestamp_idx` ON `messages` (`timestamp`);',
25
+ 'CREATE INDEX `messages_owner_contact_msgid_idx` ON `messages` (`ownerUserId`,`contactUserId`,`messageId`);',
26
26
  'CREATE TABLE `pendingAnnouncements` (\n\t`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\n\t`announcement` blob NOT NULL,\n\t`fetchedAt` integer NOT NULL,\n\t`counter` text\n);',
27
27
  'CREATE UNIQUE INDEX `pending_announcements_announcement_idx` ON `pendingAnnouncements` (`announcement`);',
28
28
  'CREATE INDEX `pending_announcements_fetchedAt_idx` ON `pendingAnnouncements` (`fetchedAt`);',
@@ -34,12 +34,4 @@ export const MIGRATIONS = [
34
34
  'CREATE INDEX `userProfile_status_idx` ON `userProfile` (`status`);',
35
35
  ],
36
36
  },
37
- {
38
- idx: 1,
39
- tag: '0001_flowery_storm',
40
- when: 1771827090330,
41
- statements: [
42
- 'CREATE INDEX `messages_owner_contact_msgid_idx` ON `messages` (`ownerUserId`,`contactUserId`,`messageId`);',
43
- ],
44
- },
45
37
  ];
@@ -1,3 +1,3 @@
1
- export * from './db';
2
- export * from './queries';
3
- export * from './sqlite';
1
+ export * from './db.js';
2
+ export * from './queries/index.js';
3
+ export * from './sqlite.js';
package/dist/db/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from './db';
2
- export * from './queries';
3
- export * from './sqlite';
1
+ export * from './db.js';
2
+ export * from './queries/index.js';
3
+ export * from './sqlite.js';
@@ -1,4 +1,4 @@
1
- import type { DatabaseConnection } from '../sqlite';
1
+ import type { DatabaseConnection } from '../sqlite.js';
2
2
  export declare class ActiveSeekerQueries {
3
3
  private conn;
4
4
  constructor(conn: DatabaseConnection);
@@ -1,4 +1,4 @@
1
- import * as schema from '../schema';
1
+ import * as schema from '../schema/index.js';
2
2
  export class ActiveSeekerQueries {
3
3
  constructor(conn) {
4
4
  Object.defineProperty(this, "conn", {
@@ -1,4 +1,4 @@
1
- import type { DatabaseConnection } from '../sqlite';
1
+ import type { DatabaseConnection } from '../sqlite.js';
2
2
  export declare class AnnouncementCursorQueries {
3
3
  private conn;
4
4
  constructor(conn: DatabaseConnection);
@@ -1,5 +1,5 @@
1
1
  import { eq } from 'drizzle-orm';
2
- import * as schema from '../schema';
2
+ import * as schema from '../schema/index.js';
3
3
  export class AnnouncementCursorQueries {
4
4
  constructor(conn) {
5
5
  Object.defineProperty(this, "conn", {
@@ -1,6 +1,6 @@
1
- import * as schema from '../schema';
2
- import type { DatabaseConnection } from '../sqlite';
3
- import { Contact } from '../db';
1
+ import * as schema from '../schema/index.js';
2
+ import type { DatabaseConnection } from '../sqlite.js';
3
+ import type { Contact } from '../db.js';
4
4
  export type ContactRow = typeof schema.contacts.$inferSelect;
5
5
  type ContactInsert = typeof schema.contacts.$inferInsert;
6
6
  export declare class ContactQueries {
@@ -1,5 +1,5 @@
1
1
  import { eq, and, sql } from 'drizzle-orm';
2
- import * as schema from '../schema';
2
+ import * as schema from '../schema/index.js';
3
3
  /** Escape LIKE wildcard characters so they match literally. */
4
4
  function escapeLike(value) {
5
5
  return value.replace(/[%_]/g, '\\$&');
@@ -1,8 +1,7 @@
1
- import * as schema from '../schema';
2
- import type { DatabaseConnection } from '../sqlite';
3
- import type { DiscussionStatus } from '../db';
1
+ import * as schema from '../schema/index.js';
2
+ import type { DatabaseConnection } from '../sqlite.js';
4
3
  export type DiscussionRow = typeof schema.discussions.$inferSelect;
5
- type DiscussionInsert = typeof schema.discussions.$inferInsert;
4
+ export type DiscussionInsert = typeof schema.discussions.$inferInsert;
6
5
  export declare class DiscussionQueries {
7
6
  private conn;
8
7
  constructor(conn: DatabaseConnection);
@@ -15,6 +14,4 @@ export declare class DiscussionQueries {
15
14
  deleteByOwnerAndContact(ownerUserId: string, contactUserId: string): Promise<void>;
16
15
  incrementUnreadCount(discussionId: number): Promise<void>;
17
16
  decrementUnreadCount(discussionId: number): Promise<void>;
18
- getByOwnerAndStatus(ownerUserId: string, status: DiscussionStatus): Promise<DiscussionRow[]>;
19
17
  }
20
- export {};
@@ -1,5 +1,5 @@
1
1
  import { eq, and, gt, sql } from 'drizzle-orm';
2
- import * as schema from '../schema';
2
+ import * as schema from '../schema/index.js';
3
3
  export class DiscussionQueries {
4
4
  constructor(conn) {
5
5
  Object.defineProperty(this, "conn", {
@@ -66,11 +66,4 @@ export class DiscussionQueries {
66
66
  })
67
67
  .where(and(eq(schema.discussions.id, discussionId), gt(schema.discussions.unreadCount, 0)));
68
68
  }
69
- async getByOwnerAndStatus(ownerUserId, status) {
70
- return this.conn.db
71
- .select()
72
- .from(schema.discussions)
73
- .where(and(eq(schema.discussions.ownerUserId, ownerUserId), eq(schema.discussions.status, status)))
74
- .all();
75
- }
76
69
  }
@@ -1,17 +1,17 @@
1
- import type { DatabaseConnection } from '../sqlite';
2
- import { ContactQueries } from './contacts';
3
- import { DiscussionQueries } from './discussions';
4
- import { MessageQueries } from './messages';
5
- import { UserProfileQueries } from './userProfile';
6
- import { AnnouncementCursorQueries } from './announcementCursors';
7
- import { PendingAnnouncementQueries } from './pendingAnnouncements';
8
- import { ActiveSeekerQueries } from './activeSeekers';
9
- export type { ContactRow } from './contacts';
10
- export type { DiscussionRow } from './discussions';
11
- export type { MessageRow, MessageInsert } from './messages';
12
- export type { UserProfileRow, UserProfileInsert } from './userProfile';
13
- export { rowToUserProfile, userProfileToRow } from './userProfile';
14
- export type { PendingAnnouncementRow } from './pendingAnnouncements';
1
+ import type { DatabaseConnection } from '../sqlite.js';
2
+ import { ContactQueries } from './contacts.js';
3
+ import { DiscussionQueries } from './discussions.js';
4
+ import { MessageQueries } from './messages.js';
5
+ import { UserProfileQueries } from './userProfile.js';
6
+ import { AnnouncementCursorQueries } from './announcementCursors.js';
7
+ import { PendingAnnouncementQueries } from './pendingAnnouncements.js';
8
+ import { ActiveSeekerQueries } from './activeSeekers.js';
9
+ export type { ContactRow } from './contacts.js';
10
+ export type { DiscussionRow } from './discussions.js';
11
+ export type { MessageRow, MessageInsert } from './messages.js';
12
+ export type { UserProfileRow, UserProfileInsert } from './userProfile.js';
13
+ export { rowToUserProfile, userProfileToRow } from './userProfile.js';
14
+ export type { PendingAnnouncementRow } from './pendingAnnouncements.js';
15
15
  /**
16
16
  * Bundle of all query classes, scoped to a single DatabaseConnection.
17
17
  *
@@ -1,11 +1,11 @@
1
- import { ContactQueries } from './contacts';
2
- import { DiscussionQueries } from './discussions';
3
- import { MessageQueries } from './messages';
4
- import { UserProfileQueries } from './userProfile';
5
- import { AnnouncementCursorQueries } from './announcementCursors';
6
- import { PendingAnnouncementQueries } from './pendingAnnouncements';
7
- import { ActiveSeekerQueries } from './activeSeekers';
8
- export { rowToUserProfile, userProfileToRow } from './userProfile';
1
+ import { ContactQueries } from './contacts.js';
2
+ import { DiscussionQueries } from './discussions.js';
3
+ import { MessageQueries } from './messages.js';
4
+ import { UserProfileQueries } from './userProfile.js';
5
+ import { AnnouncementCursorQueries } from './announcementCursors.js';
6
+ import { PendingAnnouncementQueries } from './pendingAnnouncements.js';
7
+ import { ActiveSeekerQueries } from './activeSeekers.js';
8
+ export { rowToUserProfile, userProfileToRow } from './userProfile.js';
9
9
  /**
10
10
  * Bundle of all query classes, scoped to a single DatabaseConnection.
11
11
  *
@@ -1,6 +1,6 @@
1
- import * as schema from '../schema';
2
- import type { DatabaseConnection } from '../sqlite';
3
- import { MessageStatus } from '../../db/db';
1
+ import * as schema from '../schema/index.js';
2
+ import type { DatabaseConnection } from '../sqlite.js';
3
+ import { MessageStatus } from '../../db/db.js';
4
4
  export type MessageRow = typeof schema.messages.$inferSelect;
5
5
  export type MessageInsert = typeof schema.messages.$inferInsert;
6
6
  export declare class MessageQueries {
@@ -1,6 +1,6 @@
1
1
  import { eq, and, sql, inArray, asc } from 'drizzle-orm';
2
- import * as schema from '../schema';
3
- import { MessageDirection, MessageStatus, MessageType } from '../../db/db';
2
+ import * as schema from '../schema/index.js';
3
+ import { MessageDirection, MessageStatus, MessageType } from '../../db/db.js';
4
4
  export class MessageQueries {
5
5
  constructor(conn) {
6
6
  Object.defineProperty(this, "conn", {
@@ -1,5 +1,5 @@
1
- import * as schema from '../schema';
2
- import type { DatabaseConnection } from '../sqlite';
1
+ import * as schema from '../schema/index.js';
2
+ import type { DatabaseConnection } from '../sqlite.js';
3
3
  export type PendingAnnouncementRow = typeof schema.pendingAnnouncements.$inferSelect;
4
4
  export declare class PendingAnnouncementQueries {
5
5
  private conn;
@@ -1,5 +1,5 @@
1
1
  import { inArray } from 'drizzle-orm';
2
- import * as schema from '../schema';
2
+ import * as schema from '../schema/index.js';
3
3
  export class PendingAnnouncementQueries {
4
4
  constructor(conn) {
5
5
  Object.defineProperty(this, "conn", {
@@ -1,5 +1,5 @@
1
- import * as schema from '../schema';
2
- import type { DatabaseConnection } from '../sqlite';
1
+ import * as schema from '../schema/index.js';
2
+ import type { DatabaseConnection } from '../sqlite.js';
3
3
  import type { UserProfile } from '../db';
4
4
  export type UserProfileRow = typeof schema.userProfile.$inferSelect;
5
5
  export type UserProfileInsert = typeof schema.userProfile.$inferInsert;
@@ -1,5 +1,5 @@
1
1
  import { and, desc, eq, ne, sql } from 'drizzle-orm';
2
- import * as schema from '../schema';
2
+ import * as schema from '../schema/index.js';
3
3
  /**
4
4
  * Restore a Uint8Array from JSON-parsed data.
5
5
  * Handles: number[] (correct format), {0:x, 1:y, ...} (corrupted from
@@ -1,5 +1,5 @@
1
1
  import { sqliteTable, integer, index } from 'drizzle-orm/sqlite-core';
2
- import { bytes } from './_helpers';
2
+ import { bytes } from './_helpers.js';
3
3
  export const activeSeekers = sqliteTable('activeSeekers', {
4
4
  id: integer('id').primaryKey({ autoIncrement: true }),
5
5
  seeker: bytes('seeker').notNull(),