@pylonsync/sync 0.3.185 → 0.3.186
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/package.json +1 -1
- package/src/index.ts +32 -17
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1598,23 +1598,38 @@ export class SyncEngine {
|
|
|
1598
1598
|
this.lastSeenToken = tokenNow;
|
|
1599
1599
|
|
|
1600
1600
|
try {
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
//
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1601
|
+
// Snapshot pagination: when the cursor is 0 and the server's
|
|
1602
|
+
// table is larger than a single batch, the response carries
|
|
1603
|
+
// `snapshot_after` for the next page. Loop until exhausted
|
|
1604
|
+
// BEFORE returning so a fresh client always observes a
|
|
1605
|
+
// consistent full snapshot, not a 1k-row prefix it mistakes
|
|
1606
|
+
// for the whole replica.
|
|
1607
|
+
let snapshotAfter: string | undefined;
|
|
1608
|
+
let firstPass = true;
|
|
1609
|
+
while (firstPass || snapshotAfter) {
|
|
1610
|
+
firstPass = false;
|
|
1611
|
+
const params = new URLSearchParams();
|
|
1612
|
+
params.set("since", String(this.cursor.last_seq));
|
|
1613
|
+
if (snapshotAfter) {
|
|
1614
|
+
params.set("snapshot_after", snapshotAfter);
|
|
1615
|
+
}
|
|
1616
|
+
const resp = await this.request<
|
|
1617
|
+
PullResponse & { snapshot_after?: string | null }
|
|
1618
|
+
>("GET", `/api/sync/pull?${params.toString()}`);
|
|
1619
|
+
this.consecutive_410s = 0;
|
|
1620
|
+
await this.enqueueApply(resp.changes, resp.cursor);
|
|
1621
|
+
// `snapshot_after` is only set when the server is mid-snapshot.
|
|
1622
|
+
// Continue paginating in the same loop iteration so we don't
|
|
1623
|
+
// leave a fresh client with a partial replica.
|
|
1624
|
+
snapshotAfter = resp.snapshot_after ?? undefined;
|
|
1625
|
+
// The change-log tail also paginates via `has_more` — handle
|
|
1626
|
+
// that one recursively after the snapshot loop completes so
|
|
1627
|
+
// backpressure on the change-log path uses the existing
|
|
1628
|
+
// tail-pull semantics.
|
|
1629
|
+
if (!snapshotAfter && resp.has_more) {
|
|
1630
|
+
await this.pull();
|
|
1631
|
+
break;
|
|
1632
|
+
}
|
|
1618
1633
|
}
|
|
1619
1634
|
} catch (err) {
|
|
1620
1635
|
// Swallow network + transient errors so the poll/reconnect loop
|