@massalabs/gossip-sdk 0.0.2-dev.20260130095807 → 0.0.2-dev.20260130145448

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.
@@ -36,6 +36,12 @@ export declare class AnnouncementService {
36
36
  }>;
37
37
  fetchAndProcessAnnouncements(): Promise<AnnouncementReceptionResult>;
38
38
  resendAnnouncements(failedDiscussions: Discussion[]): Promise<void>;
39
+ /**
40
+ * Persist lastBulletinCounter for the current user.
41
+ * Uses put() so the cursor is saved even when no profile row exists yet
42
+ * (e.g. headless bot that never created a profile via app UI).
43
+ */
44
+ private _upsertLastBulletinCounter;
39
45
  private _fetchAnnouncements;
40
46
  private _generateTemporaryContactName;
41
47
  private _processIncomingAnnouncement;
@@ -153,9 +153,7 @@ export class AnnouncementService {
153
153
  }
154
154
  if (fetchedCounters.length > 0) {
155
155
  const highestCounter = fetchedCounters.reduce((a, b) => Number(a) > Number(b) ? a : b);
156
- await this.db.userProfile.update(this.session.userIdEncoded, {
157
- lastBulletinCounter: highestCounter,
158
- });
156
+ await this._upsertLastBulletinCounter(highestCounter);
159
157
  log.info('updated lastBulletinCounter', { highestCounter });
160
158
  }
161
159
  return {
@@ -189,10 +187,15 @@ export class AnnouncementService {
189
187
  }
190
188
  if (fetchedCounters.length > 0) {
191
189
  const highestCounter = fetchedCounters.reduce((a, b) => Number(a) > Number(b) ? a : b);
192
- await this.db.userProfile.update(this.session.userIdEncoded, {
193
- lastBulletinCounter: highestCounter,
190
+ const cursorNum = cursor !== undefined ? Number(cursor) : 0;
191
+ const highestNum = Number(highestCounter);
192
+ // If API returned a batch with max <= cursor (same or older page), advance past it
193
+ // so we don't re-fetch the same page forever (e.g. API returning "latest" regardless of after)
194
+ const nextCounter = highestNum <= cursorNum ? String(cursorNum + 1) : highestCounter;
195
+ await this._upsertLastBulletinCounter(nextCounter);
196
+ log.info('updated lastBulletinCounter', {
197
+ lastBulletinCounter: nextCounter,
194
198
  });
195
- log.info('updated lastBulletinCounter', { highestCounter });
196
199
  }
197
200
  return {
198
201
  success: errors.length === 0 || newAnnouncementsCount > 0,
@@ -304,6 +307,32 @@ export class AnnouncementService {
304
307
  broken: brokenDiscussions.length,
305
308
  });
306
309
  }
310
+ /**
311
+ * Persist lastBulletinCounter for the current user.
312
+ * Uses put() so the cursor is saved even when no profile row exists yet
313
+ * (e.g. headless bot that never created a profile via app UI).
314
+ */
315
+ async _upsertLastBulletinCounter(nextCounter) {
316
+ const userId = this.session.userIdEncoded;
317
+ const existing = await this.db.userProfile.get(userId);
318
+ if (existing) {
319
+ await this.db.userProfile.update(userId, {
320
+ lastBulletinCounter: nextCounter,
321
+ updatedAt: new Date(),
322
+ });
323
+ return;
324
+ }
325
+ // Minimal profile so cursor persists; headless bots may never create a full profile
326
+ await this.db.userProfile.put({
327
+ userId,
328
+ username: '',
329
+ status: 'offline',
330
+ lastSeen: new Date(),
331
+ createdAt: new Date(),
332
+ updatedAt: new Date(),
333
+ lastBulletinCounter: nextCounter,
334
+ });
335
+ }
307
336
  async _fetchAnnouncements(cursor, limit) {
308
337
  const fetchLimit = limit ?? this.config.announcements.fetchLimit;
309
338
  const log = logger.forMethod('_fetchAnnouncements');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massalabs/gossip-sdk",
3
- "version": "0.0.2-dev.20260130095807",
3
+ "version": "0.0.2-dev.20260130145448",
4
4
  "description": "Gossip SDK for automation, chatbot, and integration use cases",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,8 @@
31
31
  "copy:wasm": "mkdir -p dist/assets/generated/wasm dist/assets/generated/wasm-node && cp -R src/assets/generated/wasm/* dist/assets/generated/wasm/ && cp -R src/assets/generated/wasm-node/* dist/assets/generated/wasm-node/",
32
32
  "test": "vitest",
33
33
  "test:run": "vitest run",
34
- "test:coverage": "vitest run --coverage"
34
+ "test:coverage": "vitest run --coverage",
35
+ "test:e2e": "vitest run test/e2e/"
35
36
  },
36
37
  "keywords": [
37
38
  "gossip",