mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 00:42:30 +00:00
Ensure watch history snapshots advance created_at
This commit is contained in:
1 parent
61e8cc88fe
commit
32f04b94cb
2 files changed
+97
-1
No files matched your search
+29
-1
@@ -1528,7 +1528,33 @@ class NostrClient {
|
||||
}
|
||||
|
||||
const totalChunks = chunkItemsList.length || 1;
|
||||
const baseTimestamp = Math.floor(Date.now() / 1000);
|
||||
|
||||
const nowSeconds = Math.floor(Date.now() / 1000);
|
||||
let lastCreatedAt = 0;
|
||||
|
||||
const pointerCandidates = [];
|
||||
if (existingEntry?.pointerEvent) {
|
||||
pointerCandidates.push(existingEntry.pointerEvent);
|
||||
}
|
||||
|
||||
const cachedPointerEvent = this.watchHistoryCache.get(normalizedActor)?.pointerEvent;
|
||||
if (cachedPointerEvent) {
|
||||
pointerCandidates.push(cachedPointerEvent);
|
||||
}
|
||||
|
||||
for (const candidate of pointerCandidates) {
|
||||
if (!candidate || typeof candidate !== "object") {
|
||||
continue;
|
||||
}
|
||||
const createdAt = Number.isFinite(candidate.created_at)
|
||||
? Math.floor(candidate.created_at)
|
||||
: null;
|
||||
if (createdAt !== null && createdAt > lastCreatedAt) {
|
||||
lastCreatedAt = createdAt;
|
||||
}
|
||||
}
|
||||
|
||||
const baseTimestamp = Math.max(nowSeconds, lastCreatedAt + totalChunks);
|
||||
const chunkResults = [];
|
||||
let overallSuccess = true;
|
||||
|
||||
@@ -1578,6 +1604,8 @@ class NostrClient {
|
||||
tags.splice(2, 0, ["head", "1"]);
|
||||
}
|
||||
|
||||
// Ensure created_at stays monotonic so chunk 0 always outranks prior snapshots
|
||||
// even when multiple publishes land within the same wall-clock second.
|
||||
const event = {
|
||||
kind: WATCH_HISTORY_KIND,
|
||||
pubkey: normalizedActor,
|
||||
|
||||
@@ -158,6 +158,74 @@ assert.deepEqual(
|
||||
"chunked fetch should preserve pointer order"
|
||||
);
|
||||
|
||||
const MONOTONIC_ACTOR = `${ACTOR}-monotonic`;
|
||||
const { client: monotonicPublishingClient, publishedEvents: monotonicEvents } =
|
||||
createPublishingClient(MONOTONIC_ACTOR);
|
||||
|
||||
const monotonicOriginalDateNow = Date.now;
|
||||
try {
|
||||
const monotonicBaseSeconds = 1_700_123_456;
|
||||
Date.now = () => monotonicBaseSeconds * 1000;
|
||||
|
||||
const firstMonotonicPointers = [
|
||||
{ type: "e", value: "event-monotonic-1", relay: null },
|
||||
{ type: "e", value: "event-monotonic-2", relay: null },
|
||||
];
|
||||
|
||||
const firstSnapshot = await monotonicPublishingClient.publishWatchHistorySnapshot(
|
||||
MONOTONIC_ACTOR,
|
||||
firstMonotonicPointers
|
||||
);
|
||||
|
||||
const baselineEntry = monotonicPublishingClient.createWatchHistoryEntry(
|
||||
firstSnapshot.event,
|
||||
firstMonotonicPointers,
|
||||
Date.now()
|
||||
);
|
||||
monotonicPublishingClient.watchHistoryCache.set(
|
||||
MONOTONIC_ACTOR,
|
||||
baselineEntry
|
||||
);
|
||||
|
||||
const secondMonotonicPointers = [
|
||||
{ type: "e", value: "event-monotonic-3", relay: null },
|
||||
{ type: "e", value: "event-monotonic-1", relay: null },
|
||||
];
|
||||
|
||||
const secondSnapshot = await monotonicPublishingClient.publishWatchHistorySnapshot(
|
||||
MONOTONIC_ACTOR,
|
||||
secondMonotonicPointers,
|
||||
baselineEntry
|
||||
);
|
||||
|
||||
assert(
|
||||
secondSnapshot.event.created_at > firstSnapshot.event.created_at,
|
||||
"new snapshot should advance created_at when reusing the same second"
|
||||
);
|
||||
|
||||
const monotonicDecryptClient = createDecryptClient(MONOTONIC_ACTOR);
|
||||
monotonicDecryptClient.pool = { list: async () => monotonicEvents };
|
||||
|
||||
const monotonicFetched = await monotonicDecryptClient.fetchWatchHistory(
|
||||
MONOTONIC_ACTOR
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
monotonicFetched.items.map((item) => ({
|
||||
type: item.type,
|
||||
value: item.value,
|
||||
relay: item.relay || null,
|
||||
})),
|
||||
[
|
||||
{ type: "e", value: "event-monotonic-3", relay: null },
|
||||
{ type: "e", value: "event-monotonic-1", relay: null },
|
||||
],
|
||||
"newer snapshot should win pointer ordering"
|
||||
);
|
||||
} finally {
|
||||
Date.now = monotonicOriginalDateNow;
|
||||
}
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
const originalDateNow = Date.now;
|
||||
|
||||
Reference in new issue
Block a user