@pmate/chat-sdk 0.9.6 → 0.9.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.
- package/lib/runtime/readSync.js +28 -1
- package/package.json +1 -1
package/lib/runtime/readSync.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createReadIndex, installReadSnapshot } from "./readIndex.js";
|
|
1
|
+
import { applyReadChange, ReadSyncGap, createReadIndex, installReadSnapshot } from "./readIndex.js";
|
|
2
2
|
/** Keeps local operations until an authoritative projection covers them. */
|
|
3
3
|
export class ReadSyncClient {
|
|
4
4
|
options;
|
|
@@ -57,6 +57,31 @@ export class ReadSyncClient {
|
|
|
57
57
|
this.readAfter = Math.max(this.readAfter, receipt.acceptedAt);
|
|
58
58
|
}
|
|
59
59
|
const query = new URLSearchParams({ appId, profileId });
|
|
60
|
+
if (!this.readAfter && current.syncCursor !== "0") {
|
|
61
|
+
const delta = await this.request(`/api/social/reading/changes?${new URLSearchParams({ appId, profileId, after: current.syncCursor })}`);
|
|
62
|
+
if (delta.appId !== appId || delta.profileId !== profileId || typeof delta.syncCursor !== "string"
|
|
63
|
+
|| typeof delta.snapshotRequired !== "boolean" || !Array.isArray(delta.changes))
|
|
64
|
+
throw new Error("INVALID_READ_DELTA");
|
|
65
|
+
if (!delta.snapshotRequired) {
|
|
66
|
+
try {
|
|
67
|
+
if (this.controller.signal.aborted)
|
|
68
|
+
throw new Error("READ_SYNC_STOPPED");
|
|
69
|
+
const next = await persistence.update(appId, profileId, state => {
|
|
70
|
+
const applied = delta.changes.reduce(applyReadChange, state);
|
|
71
|
+
if (applied.syncCursor !== delta.syncCursor)
|
|
72
|
+
throw new ReadSyncGap(applied.syncCursor);
|
|
73
|
+
return applied;
|
|
74
|
+
});
|
|
75
|
+
if (!this.controller.signal.aborted)
|
|
76
|
+
this.options.onChange?.(next);
|
|
77
|
+
return next;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (!(error instanceof ReadSyncGap))
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
60
85
|
const snapshot = await this.request(`/api/social/reading/snapshot?${query}`, {
|
|
61
86
|
headers: this.readAfter ? { "x-pmate-read-after-time": String(this.readAfter) } : {},
|
|
62
87
|
});
|
|
@@ -64,6 +89,8 @@ export class ReadSyncClient {
|
|
|
64
89
|
throw new Error("READ_SYNC_STOPPED");
|
|
65
90
|
// Merge into the latest transaction, including reads made while HTTP was pending.
|
|
66
91
|
const next = await persistence.update(appId, profileId, state => installReadSnapshot(state, snapshot));
|
|
92
|
+
if (!next.pending.length)
|
|
93
|
+
this.readAfter = 0;
|
|
67
94
|
if (!this.controller.signal.aborted)
|
|
68
95
|
this.options.onChange?.(next);
|
|
69
96
|
return next;
|