@massalabs/gossip-sdk 0.0.2-dev.20260211172752 → 0.0.2-dev.20260212083011
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 +109 -196
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/messageProtocol/index.d.ts +2 -4
- package/dist/api/messageProtocol/index.js +4 -15
- package/dist/crypto/index.d.ts +2 -0
- package/dist/crypto/index.js +2 -0
- package/dist/db.d.ts +2 -13
- package/dist/db.js +4 -45
- package/dist/{gossipSdk.d.ts → gossip.d.ts} +20 -20
- package/dist/{gossipSdk.js → gossip.js} +74 -55
- package/dist/index.d.ts +10 -53
- package/dist/index.js +10 -54
- package/dist/services/announcement.d.ts +1 -4
- package/dist/services/announcement.js +1 -12
- package/dist/services/auth.d.ts +1 -8
- package/dist/services/auth.js +2 -6
- package/dist/services/discussion.d.ts +1 -4
- package/dist/services/discussion.js +2 -27
- package/dist/services/message.d.ts +1 -4
- package/dist/services/message.js +1 -16
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/wasm/index.d.ts +1 -0
- package/dist/wasm/index.js +1 -0
- package/package.json +1 -1
- package/dist/types.d.ts +0 -32
- package/dist/types.js +0 -7
- package/dist/utils.d.ts +0 -30
- package/dist/utils.js +0 -37
package/README.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# Gossip SDK
|
|
2
2
|
|
|
3
|
-
A platform-agnostic SDK for the Gossip messenger app.
|
|
3
|
+
A platform-agnostic SDK for the Gossip messenger app. Enables automation, chatbot integrations, and programmatic access to Gossip functionality.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
7
|
The Gossip SDK provides a clean, typed interface for:
|
|
8
8
|
|
|
9
|
-
- **Account Management** - Create, load, restore, and manage user accounts
|
|
10
9
|
- **Contact Management** - Add, update, and delete contacts
|
|
11
10
|
- **Discussion Management** - Initialize and manage encrypted discussions
|
|
12
11
|
- **Message Operations** - Send and receive encrypted messages
|
|
@@ -16,73 +15,53 @@ The Gossip SDK provides a clean, typed interface for:
|
|
|
16
15
|
## Installation
|
|
17
16
|
|
|
18
17
|
```bash
|
|
19
|
-
|
|
20
|
-
npm install
|
|
18
|
+
npm install @massalabs/gossip-sdk
|
|
21
19
|
```
|
|
22
20
|
|
|
23
|
-
### Peer Dependencies
|
|
24
|
-
|
|
25
|
-
The SDK requires these peer dependencies (provided by the host project):
|
|
26
|
-
|
|
27
|
-
- `dexie` ^4.0.0 - IndexedDB wrapper for local storage
|
|
28
|
-
|
|
29
21
|
## Quick Start
|
|
30
22
|
|
|
31
|
-
The SDK uses a
|
|
23
|
+
The SDK uses a factory pattern — each call to `createGossipSdk()` returns a new instance:
|
|
32
24
|
|
|
33
25
|
```typescript
|
|
34
|
-
import {
|
|
26
|
+
import { createGossipSdk } from '@massalabs/gossip-sdk';
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
const db = new GossipDatabase();
|
|
38
|
-
await db.open();
|
|
28
|
+
const sdk = createGossipSdk();
|
|
39
29
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
protocolBaseUrl: 'https://api.example.com',
|
|
43
|
-
});
|
|
30
|
+
// 1. Initialize (optional config)
|
|
31
|
+
await sdk.init();
|
|
44
32
|
|
|
45
33
|
// 2. Open session (login)
|
|
46
|
-
await
|
|
34
|
+
await sdk.openSession({
|
|
47
35
|
mnemonic: 'word1 word2 word3 ... word12',
|
|
48
|
-
// For existing session:
|
|
49
|
-
encryptedSession: savedBlob,
|
|
50
|
-
encryptionKey,
|
|
51
|
-
// For persistence:
|
|
52
|
-
onPersist: async (blob, key) => {
|
|
53
|
-
await saveToStorage(blob, key);
|
|
54
|
-
},
|
|
55
36
|
});
|
|
56
37
|
|
|
57
38
|
// 3. Use the SDK
|
|
58
|
-
const contacts = await
|
|
59
|
-
await
|
|
60
|
-
await
|
|
39
|
+
const contacts = await sdk.contacts.list(sdk.userId);
|
|
40
|
+
await sdk.discussions.start(contact);
|
|
41
|
+
await sdk.messages.send(message);
|
|
61
42
|
|
|
62
43
|
// 4. Listen to events
|
|
63
|
-
|
|
64
|
-
console.log('New message:', msg
|
|
44
|
+
sdk.on(SdkEventType.MESSAGE_RECEIVED, msg => {
|
|
45
|
+
console.log('New message:', msg);
|
|
65
46
|
});
|
|
66
47
|
|
|
67
48
|
// 5. Logout
|
|
68
|
-
await
|
|
49
|
+
await sdk.closeSession();
|
|
69
50
|
```
|
|
70
51
|
|
|
71
52
|
## Lifecycle
|
|
72
53
|
|
|
73
54
|
### 1. Initialize
|
|
74
55
|
|
|
75
|
-
Call `init()` once at app startup
|
|
56
|
+
Call `init()` once at app startup. All options are optional:
|
|
76
57
|
|
|
77
58
|
```typescript
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
db: new GossipDatabase(),
|
|
59
|
+
// Uses GOSSIP_API_URL / VITE_GOSSIP_API_URL env var, or defaults to api.usegossip.com
|
|
60
|
+
await sdk.init();
|
|
81
61
|
|
|
82
|
-
|
|
62
|
+
// Or with explicit config
|
|
63
|
+
await sdk.init({
|
|
83
64
|
protocolBaseUrl: 'https://api.usegossip.com',
|
|
84
|
-
|
|
85
|
-
// Optional: Configuration overrides
|
|
86
65
|
config: {
|
|
87
66
|
polling: {
|
|
88
67
|
enabled: true,
|
|
@@ -98,23 +77,23 @@ Call `openSession()` to authenticate and create a cryptographic session:
|
|
|
98
77
|
|
|
99
78
|
```typescript
|
|
100
79
|
// New account (no existing session)
|
|
101
|
-
await
|
|
80
|
+
await sdk.openSession({
|
|
102
81
|
mnemonic: 'word1 word2 word3 ... word12',
|
|
103
82
|
});
|
|
104
83
|
|
|
105
84
|
// Restore existing session
|
|
106
|
-
await
|
|
85
|
+
await sdk.openSession({
|
|
107
86
|
mnemonic: 'word1 word2 word3 ... word12',
|
|
108
87
|
encryptedSession: savedBlob,
|
|
109
88
|
encryptionKey: savedKey,
|
|
110
89
|
});
|
|
111
90
|
|
|
112
91
|
// With persistence (saves session on changes)
|
|
113
|
-
await
|
|
92
|
+
await sdk.openSession({
|
|
114
93
|
mnemonic: 'word1 word2 word3 ... word12',
|
|
115
94
|
encryptionKey,
|
|
116
95
|
onPersist: async (blob, key) => {
|
|
117
|
-
await
|
|
96
|
+
await storage.save({ session: blob });
|
|
118
97
|
},
|
|
119
98
|
});
|
|
120
99
|
```
|
|
@@ -122,7 +101,7 @@ await gossipSdk.openSession({
|
|
|
122
101
|
### 3. Close Session (Logout)
|
|
123
102
|
|
|
124
103
|
```typescript
|
|
125
|
-
await
|
|
104
|
+
await sdk.closeSession();
|
|
126
105
|
```
|
|
127
106
|
|
|
128
107
|
## Service APIs
|
|
@@ -133,8 +112,8 @@ All services are available after `openSession()` is called.
|
|
|
133
112
|
|
|
134
113
|
```typescript
|
|
135
114
|
// Send a message
|
|
136
|
-
const result = await
|
|
137
|
-
ownerUserId:
|
|
115
|
+
const result = await sdk.messages.send({
|
|
116
|
+
ownerUserId: sdk.userId,
|
|
138
117
|
contactUserId: contactId,
|
|
139
118
|
content: 'Hello!',
|
|
140
119
|
type: MessageType.TEXT,
|
|
@@ -144,51 +123,48 @@ const result = await gossipSdk.messages.send({
|
|
|
144
123
|
});
|
|
145
124
|
|
|
146
125
|
// Fetch new messages from server
|
|
147
|
-
const fetchResult = await
|
|
148
|
-
|
|
149
|
-
// Resend failed messages
|
|
150
|
-
await gossipSdk.messages.resend(failedMessagesMap);
|
|
126
|
+
const fetchResult = await sdk.messages.fetch();
|
|
151
127
|
|
|
152
128
|
// Find message by seeker
|
|
153
|
-
const msg = await
|
|
129
|
+
const msg = await sdk.messages.findBySeeker(seeker, ownerUserId);
|
|
130
|
+
|
|
131
|
+
// Mark as read
|
|
132
|
+
await sdk.messages.markAsRead(messageId);
|
|
154
133
|
```
|
|
155
134
|
|
|
156
135
|
### Discussions
|
|
157
136
|
|
|
158
137
|
```typescript
|
|
159
138
|
// Start a new discussion
|
|
160
|
-
const
|
|
139
|
+
const result = await sdk.discussions.start(contact);
|
|
161
140
|
|
|
162
141
|
// Accept an incoming discussion request
|
|
163
|
-
await
|
|
142
|
+
await sdk.discussions.accept(discussion);
|
|
164
143
|
|
|
165
144
|
// Renew a broken session
|
|
166
|
-
await
|
|
145
|
+
await sdk.discussions.renew(contactUserId);
|
|
167
146
|
|
|
168
|
-
//
|
|
169
|
-
const
|
|
170
|
-
ownerUserId,
|
|
171
|
-
contactUserId
|
|
172
|
-
);
|
|
147
|
+
// Get session status for a contact
|
|
148
|
+
const status = sdk.discussions.getStatus(contactUserId);
|
|
173
149
|
|
|
174
150
|
// List all discussions
|
|
175
|
-
const discussions = await
|
|
151
|
+
const discussions = await sdk.discussions.list(ownerUserId);
|
|
176
152
|
|
|
177
153
|
// Get a specific discussion
|
|
178
|
-
const discussion = await
|
|
154
|
+
const discussion = await sdk.discussions.get(ownerUserId, contactUserId);
|
|
179
155
|
```
|
|
180
156
|
|
|
181
157
|
### Contacts
|
|
182
158
|
|
|
183
159
|
```typescript
|
|
184
160
|
// List all contacts
|
|
185
|
-
const contacts = await
|
|
161
|
+
const contacts = await sdk.contacts.list(ownerUserId);
|
|
186
162
|
|
|
187
163
|
// Get a specific contact
|
|
188
|
-
const contact = await
|
|
164
|
+
const contact = await sdk.contacts.get(ownerUserId, contactUserId);
|
|
189
165
|
|
|
190
166
|
// Add a new contact
|
|
191
|
-
const result = await
|
|
167
|
+
const result = await sdk.contacts.add(
|
|
192
168
|
ownerUserId,
|
|
193
169
|
contactUserId,
|
|
194
170
|
'Alice',
|
|
@@ -196,100 +172,54 @@ const result = await gossipSdk.contacts.add(
|
|
|
196
172
|
);
|
|
197
173
|
|
|
198
174
|
// Update contact name
|
|
199
|
-
await
|
|
175
|
+
await sdk.contacts.updateName(ownerUserId, contactUserId, 'Alice Smith');
|
|
200
176
|
|
|
201
177
|
// Delete contact and all associated data
|
|
202
|
-
await
|
|
178
|
+
await sdk.contacts.delete(ownerUserId, contactUserId);
|
|
203
179
|
```
|
|
204
180
|
|
|
205
181
|
### Announcements
|
|
206
182
|
|
|
207
183
|
```typescript
|
|
208
184
|
// Fetch and process announcements from server
|
|
209
|
-
const result = await
|
|
210
|
-
|
|
211
|
-
// Resend failed announcements
|
|
212
|
-
await gossipSdk.announcements.resend(failedDiscussions);
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Auth (Available before session)
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
// Create a new account
|
|
219
|
-
const result = await gossipSdk.auth.createAccount(
|
|
220
|
-
username,
|
|
221
|
-
mnemonic,
|
|
222
|
-
encryptionKey
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
// Restore account from mnemonic
|
|
226
|
-
const result = await gossipSdk.auth.restoreAccount(
|
|
227
|
-
username,
|
|
228
|
-
mnemonic,
|
|
229
|
-
encryptionKey
|
|
230
|
-
);
|
|
185
|
+
const result = await sdk.announcements.fetch();
|
|
231
186
|
```
|
|
232
187
|
|
|
233
|
-
###
|
|
188
|
+
### Auth (Available after init, before session)
|
|
234
189
|
|
|
235
190
|
```typescript
|
|
236
|
-
//
|
|
237
|
-
await
|
|
191
|
+
// Publish public key so the user is discoverable
|
|
192
|
+
await sdk.auth.ensurePublicKeyPublished(publicKey, userId);
|
|
238
193
|
```
|
|
239
194
|
|
|
240
195
|
## Events
|
|
241
196
|
|
|
242
|
-
Subscribe to SDK events
|
|
197
|
+
Subscribe to SDK events using `SdkEventType`:
|
|
243
198
|
|
|
244
199
|
```typescript
|
|
245
|
-
|
|
246
|
-
gossipSdk.on('message', message => {
|
|
247
|
-
// New message received
|
|
248
|
-
});
|
|
200
|
+
import { SdkEventType } from '@massalabs/gossip-sdk';
|
|
249
201
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
gossipSdk.on('messageFailed', (message, error) => {
|
|
255
|
-
// Message failed to send
|
|
256
|
-
});
|
|
202
|
+
// Message events
|
|
203
|
+
sdk.on(SdkEventType.MESSAGE_RECEIVED, message => { ... });
|
|
204
|
+
sdk.on(SdkEventType.MESSAGE_SENT, message => { ... });
|
|
257
205
|
|
|
258
206
|
// Discussion events
|
|
259
|
-
|
|
260
|
-
// Incoming discussion request
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
gossipSdk.on('discussionStatusChanged', discussion => {
|
|
264
|
-
// Discussion status changed
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// Session events
|
|
268
|
-
gossipSdk.on('sessionBroken', discussion => {
|
|
269
|
-
// Session broken (deprecated - use auto-renewal)
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
gossipSdk.on('sessionRenewed', discussion => {
|
|
273
|
-
// Session successfully renewed
|
|
274
|
-
});
|
|
207
|
+
sdk.on(SdkEventType.SESSION_REQUESTED, (discussion, contact) => { ... });
|
|
275
208
|
|
|
276
209
|
// Error handling
|
|
277
|
-
|
|
210
|
+
sdk.on(SdkEventType.ERROR, (error, context) => {
|
|
278
211
|
console.error(`Error in ${context}:`, error);
|
|
279
212
|
});
|
|
280
213
|
|
|
281
214
|
// Unsubscribe
|
|
282
|
-
|
|
215
|
+
sdk.off(SdkEventType.MESSAGE_RECEIVED, handler);
|
|
283
216
|
```
|
|
284
217
|
|
|
285
218
|
## Polling
|
|
286
219
|
|
|
287
|
-
The SDK can automatically poll for messages, announcements, and session refresh:
|
|
288
|
-
|
|
289
220
|
```typescript
|
|
290
221
|
// Enable via config
|
|
291
|
-
await
|
|
292
|
-
db,
|
|
222
|
+
await sdk.init({
|
|
293
223
|
config: {
|
|
294
224
|
polling: {
|
|
295
225
|
enabled: true,
|
|
@@ -301,76 +231,37 @@ await gossipSdk.init({
|
|
|
301
231
|
});
|
|
302
232
|
|
|
303
233
|
// Or control manually
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
console.log(
|
|
234
|
+
sdk.polling.start();
|
|
235
|
+
sdk.polling.stop();
|
|
236
|
+
console.log(sdk.polling.isRunning);
|
|
307
237
|
```
|
|
308
238
|
|
|
309
239
|
## Session Info
|
|
310
240
|
|
|
311
|
-
Access session information after `openSession()`:
|
|
312
|
-
|
|
313
241
|
```typescript
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
// User ID (raw bytes)
|
|
318
|
-
const userIdBytes = gossipSdk.userIdBytes;
|
|
319
|
-
|
|
320
|
-
// Public keys
|
|
321
|
-
const publicKeys = gossipSdk.publicKeys;
|
|
242
|
+
const userId = sdk.userId; // Encoded string
|
|
243
|
+
const userIdBytes = sdk.userIdBytes; // Raw bytes
|
|
244
|
+
const publicKeys = sdk.publicKeys;
|
|
322
245
|
|
|
323
|
-
//
|
|
324
|
-
console.log(
|
|
325
|
-
console.log(gossipSdk.isSessionOpen); // true after openSession()
|
|
246
|
+
console.log(sdk.isInitialized); // true after init()
|
|
247
|
+
console.log(sdk.isSessionOpen); // true after openSession()
|
|
326
248
|
|
|
327
249
|
// Get encrypted session for manual persistence
|
|
328
|
-
const blob =
|
|
250
|
+
const blob = sdk.getEncryptedSession();
|
|
329
251
|
```
|
|
330
252
|
|
|
331
|
-
##
|
|
253
|
+
## State Update
|
|
332
254
|
|
|
333
|
-
|
|
255
|
+
Trigger a full state refresh for all discussions (session renewal, queued messages, keep-alives):
|
|
334
256
|
|
|
335
257
|
```typescript
|
|
336
|
-
await
|
|
337
|
-
db,
|
|
338
|
-
config: {
|
|
339
|
-
// Network settings
|
|
340
|
-
protocol: {
|
|
341
|
-
baseUrl: 'https://api.usegossip.com', // API endpoint
|
|
342
|
-
timeout: 10000, // Request timeout (ms)
|
|
343
|
-
retryAttempts: 3, // Retry count
|
|
344
|
-
},
|
|
345
|
-
|
|
346
|
-
// Polling settings
|
|
347
|
-
polling: {
|
|
348
|
-
enabled: false, // Auto-start polling
|
|
349
|
-
messagesIntervalMs: 5000, // Message fetch interval
|
|
350
|
-
announcementsIntervalMs: 10000, // Announcement fetch interval
|
|
351
|
-
sessionRefreshIntervalMs: 30000, // Session refresh interval
|
|
352
|
-
},
|
|
353
|
-
|
|
354
|
-
// Message settings
|
|
355
|
-
messages: {
|
|
356
|
-
fetchDelayMs: 100, // Delay between fetch iterations
|
|
357
|
-
maxFetchIterations: 30, // Max iterations per fetch call
|
|
358
|
-
deduplicationWindowMs: 30000, // Duplicate detection window
|
|
359
|
-
},
|
|
360
|
-
|
|
361
|
-
// Announcement settings
|
|
362
|
-
announcements: {
|
|
363
|
-
fetchLimit: 500, // Max announcements per request
|
|
364
|
-
brokenThresholdMs: 3600000, // Time before marking broken (1 hour)
|
|
365
|
-
},
|
|
366
|
-
},
|
|
367
|
-
});
|
|
258
|
+
await sdk.updateState();
|
|
368
259
|
```
|
|
369
260
|
|
|
370
261
|
## Utilities
|
|
371
262
|
|
|
372
263
|
```typescript
|
|
373
|
-
const utils =
|
|
264
|
+
const utils = sdk.utils;
|
|
374
265
|
|
|
375
266
|
// Validate user ID format
|
|
376
267
|
const result = utils.validateUserId(userId);
|
|
@@ -384,16 +275,47 @@ const encoded = utils.encodeUserId(rawBytes);
|
|
|
384
275
|
const decoded = utils.decodeUserId(encodedString);
|
|
385
276
|
```
|
|
386
277
|
|
|
278
|
+
## Configuration
|
|
279
|
+
|
|
280
|
+
Full configuration options with defaults:
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
await sdk.init({
|
|
284
|
+
config: {
|
|
285
|
+
protocol: {
|
|
286
|
+
baseUrl: 'https://api.usegossip.com',
|
|
287
|
+
timeout: 10000,
|
|
288
|
+
retryAttempts: 3,
|
|
289
|
+
},
|
|
290
|
+
polling: {
|
|
291
|
+
enabled: false,
|
|
292
|
+
messagesIntervalMs: 5000,
|
|
293
|
+
announcementsIntervalMs: 10000,
|
|
294
|
+
sessionRefreshIntervalMs: 30000,
|
|
295
|
+
},
|
|
296
|
+
messages: {
|
|
297
|
+
fetchDelayMs: 100,
|
|
298
|
+
maxFetchIterations: 30,
|
|
299
|
+
deduplicationWindowMs: 30000,
|
|
300
|
+
},
|
|
301
|
+
announcements: {
|
|
302
|
+
fetchLimit: 500,
|
|
303
|
+
brokenThresholdMs: 3600000,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
387
309
|
## Session Persistence
|
|
388
310
|
|
|
389
|
-
For restoring sessions across app restarts
|
|
311
|
+
For restoring sessions across app restarts:
|
|
390
312
|
|
|
391
313
|
```typescript
|
|
392
|
-
await
|
|
314
|
+
await sdk.openSession({
|
|
393
315
|
mnemonic,
|
|
394
316
|
encryptionKey,
|
|
395
317
|
onPersist: async (blob, key) => {
|
|
396
|
-
await
|
|
318
|
+
await storage.save({ session: blob });
|
|
397
319
|
},
|
|
398
320
|
});
|
|
399
321
|
```
|
|
@@ -407,24 +329,20 @@ The SDK automatically handles session recovery:
|
|
|
407
329
|
3. **Auto-Accept** - When peer sends announcement, SDK auto-accepts for existing contacts
|
|
408
330
|
4. **Message Processing** - After session becomes active, queued messages are sent automatically
|
|
409
331
|
|
|
410
|
-
See [STATUS-REFERENCE.md](./docs/STATUS-REFERENCE.md) for detailed status documentation.
|
|
411
|
-
|
|
412
332
|
## Types
|
|
413
333
|
|
|
414
|
-
Import types from the SDK:
|
|
415
|
-
|
|
416
334
|
```typescript
|
|
417
335
|
import type {
|
|
418
336
|
UserProfile,
|
|
419
337
|
Contact,
|
|
420
338
|
Discussion,
|
|
421
339
|
Message,
|
|
422
|
-
DiscussionStatus,
|
|
423
|
-
DiscussionDirection,
|
|
424
340
|
MessageStatus,
|
|
425
341
|
MessageDirection,
|
|
426
342
|
MessageType,
|
|
427
|
-
} from 'gossip-sdk';
|
|
343
|
+
} from '@massalabs/gossip-sdk';
|
|
344
|
+
|
|
345
|
+
import { SessionStatus, SdkEventType } from '@massalabs/gossip-sdk';
|
|
428
346
|
```
|
|
429
347
|
|
|
430
348
|
## Testing
|
|
@@ -432,7 +350,6 @@ import type {
|
|
|
432
350
|
```bash
|
|
433
351
|
npm test # Watch mode
|
|
434
352
|
npm run test:run # Single run
|
|
435
|
-
npm run test:coverage # With coverage report
|
|
436
353
|
```
|
|
437
354
|
|
|
438
355
|
Tests use `fake-indexeddb` to simulate IndexedDB in Node.js environment.
|
|
@@ -442,7 +359,7 @@ Tests use `fake-indexeddb` to simulate IndexedDB in Node.js environment.
|
|
|
442
359
|
```
|
|
443
360
|
gossip-sdk/
|
|
444
361
|
├── src/
|
|
445
|
-
│ ├── gossipSdk.ts #
|
|
362
|
+
│ ├── gossipSdk.ts # SDK class & factory
|
|
446
363
|
│ ├── db.ts # Database (Dexie) implementation
|
|
447
364
|
│ ├── contacts.ts # Contact operations
|
|
448
365
|
│ ├── api/
|
|
@@ -459,14 +376,10 @@ gossip-sdk/
|
|
|
459
376
|
│ │ ├── discussion.ts # Discussion service
|
|
460
377
|
│ │ ├── announcement.ts # Announcement service
|
|
461
378
|
│ │ └── refresh.ts # Session refresh service
|
|
462
|
-
│ ├── types/
|
|
463
|
-
│ │ └── events.ts # Event type definitions
|
|
379
|
+
│ ├── types/ # Type definitions
|
|
464
380
|
│ ├── utils/ # Utility modules
|
|
465
381
|
│ └── wasm/ # WASM module wrappers
|
|
466
|
-
|
|
467
|
-
├── docs/
|
|
468
|
-
│ └── STATUS-REFERENCE.md # Status documentation
|
|
469
|
-
└── README.md
|
|
382
|
+
└── test/ # Test files
|
|
470
383
|
```
|
|
471
384
|
|
|
472
385
|
## License
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { restMessageProtocol, RestMessageProtocol, type EncryptedMessage, } from './messageProtocol';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { restMessageProtocol, RestMessageProtocol, } from './messageProtocol';
|
|
@@ -4,16 +4,14 @@
|
|
|
4
4
|
* Factory functions and exports for message protocol implementations.
|
|
5
5
|
*/
|
|
6
6
|
export type { EncryptedMessage, IMessageProtocol, MessageProtocolResponse, BulletinItem, } from './types';
|
|
7
|
-
export { RestMessageProtocol } from './rest';
|
|
8
|
-
export { MessageProtocol } from './mock';
|
|
9
7
|
import type { IMessageProtocol } from './types';
|
|
10
|
-
import { type MessageProtocolType } from '../../config/protocol';
|
|
11
8
|
/**
|
|
12
9
|
* Factory function to create message protocol instances
|
|
13
10
|
*/
|
|
14
|
-
export declare function createMessageProtocol(
|
|
11
|
+
export declare function createMessageProtocol(config?: Partial<{
|
|
15
12
|
baseUrl: string;
|
|
16
13
|
timeout: number;
|
|
17
14
|
retryAttempts: number;
|
|
18
15
|
}>): IMessageProtocol;
|
|
19
16
|
export declare const restMessageProtocol: IMessageProtocol;
|
|
17
|
+
export { RestMessageProtocol } from './rest';
|
|
@@ -3,24 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Factory functions and exports for message protocol implementations.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
export { MessageProtocol } from './mock';
|
|
8
|
-
import { defaultMessageProtocol, protocolConfig, } from '../../config/protocol';
|
|
6
|
+
import { protocolConfig } from '../../config/protocol';
|
|
9
7
|
import { RestMessageProtocol } from './rest';
|
|
10
|
-
import { MessageProtocol } from './mock';
|
|
11
8
|
/**
|
|
12
9
|
* Factory function to create message protocol instances
|
|
13
10
|
*/
|
|
14
|
-
export function createMessageProtocol(
|
|
15
|
-
|
|
16
|
-
case 'rest': {
|
|
17
|
-
return new RestMessageProtocol(config?.baseUrl || protocolConfig.baseUrl, config?.timeout || 10000, config?.retryAttempts || 3);
|
|
18
|
-
}
|
|
19
|
-
case 'mock': {
|
|
20
|
-
return new MessageProtocol(config?.baseUrl || protocolConfig.baseUrl, config?.timeout || 10000, config?.retryAttempts || 3);
|
|
21
|
-
}
|
|
22
|
-
default:
|
|
23
|
-
throw new Error(`Unsupported message protocol type: ${type}`);
|
|
24
|
-
}
|
|
11
|
+
export function createMessageProtocol(config) {
|
|
12
|
+
return new RestMessageProtocol(config?.baseUrl ?? protocolConfig.baseUrl, config?.timeout ?? protocolConfig.timeout, config?.retryAttempts ?? protocolConfig.retryAttempts);
|
|
25
13
|
}
|
|
26
14
|
export const restMessageProtocol = createMessageProtocol();
|
|
15
|
+
export { RestMessageProtocol } from './rest';
|
package/dist/db.d.ts
CHANGED
|
@@ -166,17 +166,6 @@ export declare class GossipDatabase extends Dexie {
|
|
|
166
166
|
getActiveSeekers(): Promise<Uint8Array[]>;
|
|
167
167
|
}
|
|
168
168
|
/**
|
|
169
|
-
* Get the database instance.
|
|
170
|
-
* Creates a default instance if none was set via setDb().
|
|
169
|
+
* Get the database instance. Creates a default instance on first call.
|
|
171
170
|
*/
|
|
172
|
-
export declare function
|
|
173
|
-
/**
|
|
174
|
-
* Set the database instance.
|
|
175
|
-
* Call this before using any SDK functions if you need a custom db instance.
|
|
176
|
-
*/
|
|
177
|
-
export declare function setDb(database: GossipDatabase): void;
|
|
178
|
-
/**
|
|
179
|
-
* Get the database instance.
|
|
180
|
-
* Creates a default instance if none was set via setDb().
|
|
181
|
-
*/
|
|
182
|
-
export declare const db: GossipDatabase;
|
|
171
|
+
export declare function gossipDb(): GossipDatabase;
|
package/dist/db.js
CHANGED
|
@@ -245,55 +245,14 @@ export class GossipDatabase extends Dexie {
|
|
|
245
245
|
return activeSeekers.map(item => item.seeker);
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
// Database instance -
|
|
248
|
+
// Database instance - lazily initialized singleton
|
|
249
249
|
let _db = null;
|
|
250
|
-
let _warnedGlobalDbAccess = false;
|
|
251
|
-
// Store a reference to the Proxy to detect it
|
|
252
|
-
let _proxyDb = null;
|
|
253
250
|
/**
|
|
254
|
-
* Get the database instance.
|
|
255
|
-
* Creates a default instance if none was set via setDb().
|
|
251
|
+
* Get the database instance. Creates a default instance on first call.
|
|
256
252
|
*/
|
|
257
|
-
export function
|
|
258
|
-
|
|
259
|
-
if (!_db || _db === _proxyDb || !(_db instanceof GossipDatabase)) {
|
|
253
|
+
export function gossipDb() {
|
|
254
|
+
if (!_db || !(_db instanceof GossipDatabase)) {
|
|
260
255
|
_db = new GossipDatabase();
|
|
261
256
|
}
|
|
262
257
|
return _db;
|
|
263
258
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Set the database instance.
|
|
266
|
-
* Call this before using any SDK functions if you need a custom db instance.
|
|
267
|
-
*/
|
|
268
|
-
export function setDb(database) {
|
|
269
|
-
// Prevent setting the Proxy itself to avoid infinite recursion
|
|
270
|
-
// The Proxy is not an instance of GossipDatabase, so we can detect it that way
|
|
271
|
-
if (!(database instanceof GossipDatabase) || database === _proxyDb) {
|
|
272
|
-
// If Proxy is passed, ensure _db exists by calling getDb()
|
|
273
|
-
// This will reuse existing _db if it was already created (e.g., by db.open())
|
|
274
|
-
// or create a new one if needed. This ensures we always use the same instance.
|
|
275
|
-
getDb();
|
|
276
|
-
// Don't overwrite _db - just ensure it exists and is consistent
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
_db = database;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Get the database instance.
|
|
284
|
-
* Creates a default instance if none was set via setDb().
|
|
285
|
-
*/
|
|
286
|
-
export const db = (_proxyDb = new Proxy({}, {
|
|
287
|
-
get(_target, prop) {
|
|
288
|
-
if (!_warnedGlobalDbAccess) {
|
|
289
|
-
_warnedGlobalDbAccess = true;
|
|
290
|
-
console.warn('[GossipSdk] Global db access is deprecated. Use createGossipSdk() or setDb().');
|
|
291
|
-
}
|
|
292
|
-
const target = getDb();
|
|
293
|
-
const value = Reflect.get(target, prop);
|
|
294
|
-
if (typeof value === 'function') {
|
|
295
|
-
return value.bind(target);
|
|
296
|
-
}
|
|
297
|
-
return value;
|
|
298
|
-
},
|
|
299
|
-
}));
|