@memrosetta/sync-client 0.1.6 → 0.1.7

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 (2) hide show
  1. package/dist/index.js +42 -34
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -263,6 +263,7 @@ function applyInboxOps(db, ops) {
263
263
 
264
264
  // src/sync-client.ts
265
265
  var MAX_OPS_PER_PUSH = 400;
266
+ var PULL_PAGE_SIZE = 1e3;
266
267
  var SyncClient = class {
267
268
  db;
268
269
  config;
@@ -355,48 +356,55 @@ var SyncClient = class {
355
356
  }
356
357
  async pull() {
357
358
  this.setState("last_pull_attempt_at", (/* @__PURE__ */ new Date()).toISOString());
358
- const since = this.getCursor();
359
- const params = new URLSearchParams({
360
- since: String(since),
361
- userId: this.config.userId
362
- });
363
- const url = `${this.config.serverUrl}/sync/pull?${params.toString()}`;
364
- const response = await fetch(url, {
365
- method: "GET",
366
- headers: {
367
- Authorization: `Bearer ${this.config.apiKey}`
359
+ let totalPulled = 0;
360
+ let totalSkipped = 0;
361
+ let hasMore = true;
362
+ while (hasMore) {
363
+ const since = this.getCursor();
364
+ const params = new URLSearchParams({
365
+ since: String(since),
366
+ userId: this.config.userId,
367
+ limit: String(PULL_PAGE_SIZE)
368
+ });
369
+ const url = `${this.config.serverUrl}/sync/pull?${params.toString()}`;
370
+ const response = await fetch(url, {
371
+ method: "GET",
372
+ headers: {
373
+ Authorization: `Bearer ${this.config.apiKey}`
374
+ }
375
+ });
376
+ if (!response.ok) {
377
+ throw new Error(`Pull failed: ${response.status} ${response.statusText}`);
368
378
  }
369
- });
370
- if (!response.ok) {
371
- throw new Error(`Pull failed: ${response.status} ${response.statusText}`);
372
- }
373
- const body = await response.json();
374
- const { ops, nextCursor } = body.data;
375
- if (ops.length > 0) {
376
- this.inbox.addOps(ops);
377
- }
378
- const pending = this.inbox.getPending();
379
- let skippedCount = 0;
380
- if (pending.length > 0) {
381
- const result = applyInboxOps(this.db, pending);
382
- if (result.applied.length > 0) {
383
- this.inbox.markApplied(result.applied);
379
+ const body = await response.json();
380
+ const { ops, nextCursor } = body.data;
381
+ hasMore = body.data.hasMore ?? false;
382
+ if (ops.length > 0) {
383
+ this.inbox.addOps(ops);
384
384
  }
385
- skippedCount = result.skipped.length;
386
- if (skippedCount > 0) {
387
- for (const s of result.skipped) {
388
- process.stderr.write(
389
- `[sync] apply skipped op ${s.opId}: ${s.reason}
385
+ const pending = this.inbox.getPending();
386
+ if (pending.length > 0) {
387
+ const result = applyInboxOps(this.db, pending);
388
+ if (result.applied.length > 0) {
389
+ this.inbox.markApplied(result.applied);
390
+ }
391
+ totalSkipped += result.skipped.length;
392
+ if (result.skipped.length > 0) {
393
+ for (const s of result.skipped) {
394
+ process.stderr.write(
395
+ `[sync] apply skipped op ${s.opId}: ${s.reason}
390
396
  `
391
- );
397
+ );
398
+ }
392
399
  }
393
400
  }
401
+ this.setCursor(nextCursor);
402
+ totalPulled += ops.length;
394
403
  }
395
- this.setCursor(nextCursor);
396
- if (skippedCount === 0) {
404
+ if (totalSkipped === 0) {
397
405
  this.setState("last_pull_success_at", (/* @__PURE__ */ new Date()).toISOString());
398
406
  }
399
- return ops.length;
407
+ return totalPulled;
400
408
  }
401
409
  /** For tests / advanced callers: apply currently-pending inbox ops manually. */
402
410
  applyPendingInbox() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memrosetta/sync-client",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Local-first sync client for MemRosetta (outbox/inbox, push/pull)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",