mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
Improve watch history fetch parity and logging
This commit is contained in:
1 parent
6d1bbea045
commit
d8f6da2b2c
1 file changed
+334
-147
+334
-147
@@ -4020,23 +4020,61 @@ class NostrClient {
|
||||
indexEvent: null,
|
||||
chunkAddresses: new Set(),
|
||||
expectedChunkIdentifiers: new Set(),
|
||||
chunkIdentifiers: new Set(),
|
||||
needsSignerRetry: new Set(),
|
||||
decryptedChunkCount: 0,
|
||||
hadFallbackChunk: false,
|
||||
};
|
||||
if (!(bucket.needsSignerRetry instanceof Set)) {
|
||||
bucket.needsSignerRetry = new Set();
|
||||
}
|
||||
if (!(bucket.chunkIdentifiers instanceof Set)) {
|
||||
bucket.chunkIdentifiers = new Set();
|
||||
}
|
||||
if (!Number.isFinite(bucket.decryptedChunkCount)) {
|
||||
bucket.decryptedChunkCount = 0;
|
||||
}
|
||||
|
||||
const chunkPayload = {
|
||||
...payload,
|
||||
snapshot: snapshotId,
|
||||
chunkIndex,
|
||||
totalChunks,
|
||||
needsSignerRetry: !!payload?.needsSignerRetry,
|
||||
chunkIdentifier: identifierTagValue || payload?.chunkIdentifier || null,
|
||||
};
|
||||
|
||||
bucket.chunks.set(chunkIndex, {
|
||||
event,
|
||||
payload: {
|
||||
...payload,
|
||||
snapshot: snapshotId,
|
||||
chunkIndex,
|
||||
totalChunks,
|
||||
needsSignerRetry: !!payload?.needsSignerRetry,
|
||||
},
|
||||
payload: chunkPayload,
|
||||
created_at: typeof event.created_at === "number" ? event.created_at : 0,
|
||||
});
|
||||
if (identifierTagValue) {
|
||||
bucket.chunkIdentifiers.add(identifierTagValue);
|
||||
}
|
||||
const payloadVersion = Number.isFinite(chunkPayload.version)
|
||||
? chunkPayload.version
|
||||
: 0;
|
||||
const payloadItems = Array.isArray(chunkPayload.items)
|
||||
? chunkPayload.items
|
||||
: [];
|
||||
const payloadHasWatchedAt = payloadItems.every((item) =>
|
||||
item && Number.isFinite(item.watchedAt)
|
||||
);
|
||||
const payloadMatchesSnapshot =
|
||||
typeof chunkPayload.snapshot === "string"
|
||||
? chunkPayload.snapshot === snapshotId
|
||||
: true;
|
||||
const chunkComplete =
|
||||
payloadVersion >= 2 &&
|
||||
payloadMatchesSnapshot &&
|
||||
!chunkPayload.needsSignerRetry &&
|
||||
payloadHasWatchedAt;
|
||||
if (chunkComplete) {
|
||||
bucket.decryptedChunkCount += 1;
|
||||
} else {
|
||||
bucket.hadFallbackChunk = true;
|
||||
}
|
||||
bucket.expectedChunks = Math.max(bucket.expectedChunks, totalChunks);
|
||||
const createdAt =
|
||||
typeof event.created_at === "number" ? event.created_at : 0;
|
||||
@@ -4069,11 +4107,20 @@ class NostrClient {
|
||||
indexEvent: null,
|
||||
chunkAddresses: new Set(),
|
||||
expectedChunkIdentifiers: new Set(),
|
||||
chunkIdentifiers: new Set(),
|
||||
needsSignerRetry: new Set(),
|
||||
decryptedChunkCount: 0,
|
||||
hadFallbackChunk: false,
|
||||
};
|
||||
if (!(bucket.needsSignerRetry instanceof Set)) {
|
||||
bucket.needsSignerRetry = new Set();
|
||||
}
|
||||
if (!(bucket.chunkIdentifiers instanceof Set)) {
|
||||
bucket.chunkIdentifiers = new Set();
|
||||
}
|
||||
if (!Number.isFinite(bucket.decryptedChunkCount)) {
|
||||
bucket.decryptedChunkCount = 0;
|
||||
}
|
||||
|
||||
if (meta.event) {
|
||||
const createdAt =
|
||||
@@ -4162,9 +4209,17 @@ class NostrClient {
|
||||
expectedChunkIdentifiers: bucket.expectedChunkIdentifiers instanceof Set
|
||||
? new Set(bucket.expectedChunkIdentifiers)
|
||||
: new Set(),
|
||||
chunkIdentifiers:
|
||||
bucket.chunkIdentifiers instanceof Set
|
||||
? new Set(bucket.chunkIdentifiers)
|
||||
: new Set(),
|
||||
needsSignerRetry: bucket.needsSignerRetry instanceof Set
|
||||
? new Set(bucket.needsSignerRetry)
|
||||
: new Set(),
|
||||
decryptedChunkCount: Number.isFinite(bucket.decryptedChunkCount)
|
||||
? Math.max(0, Math.floor(bucket.decryptedChunkCount))
|
||||
: 0,
|
||||
hadFallbackChunk: bucket.hadFallbackChunk === true,
|
||||
};
|
||||
|
||||
if (!fallbackSnapshot) {
|
||||
@@ -4189,31 +4244,161 @@ class NostrClient {
|
||||
const storedPointerEvent =
|
||||
!snapshotChanged && stored?.pointerEvent ? stored.pointerEvent : null;
|
||||
|
||||
const previousItems = Array.isArray(previousEntry?.items)
|
||||
? previousEntry.items
|
||||
: [];
|
||||
const fallbackCandidate = previousItems.length
|
||||
? {
|
||||
source: "memory-cache",
|
||||
items: previousItems,
|
||||
pointer: previousEntry?.pointerEvent || null,
|
||||
}
|
||||
: storedItems.length
|
||||
? {
|
||||
source: "storage-cache",
|
||||
items: storedItems,
|
||||
pointer: storedPointerEvent || null,
|
||||
}
|
||||
: null;
|
||||
|
||||
const remoteItems = Array.isArray(effectiveSnapshot?.items)
|
||||
? effectiveSnapshot.items
|
||||
: [];
|
||||
|
||||
let pointerForEntry = effectiveSnapshot?.pointerEvent || null;
|
||||
if (!pointerForEntry) {
|
||||
if (previousEntry?.pointerEvent) {
|
||||
pointerForEntry = previousEntry.pointerEvent;
|
||||
} else if (storedPointerEvent) {
|
||||
pointerForEntry = storedPointerEvent;
|
||||
}
|
||||
}
|
||||
const expectedChunks = Number.isFinite(effectiveSnapshot?.expectedChunks)
|
||||
? Math.max(1, Math.floor(effectiveSnapshot.expectedChunks))
|
||||
: 1;
|
||||
const chunkCount = Number.isFinite(effectiveSnapshot?.chunkCount)
|
||||
? Math.max(0, Math.floor(effectiveSnapshot.chunkCount))
|
||||
: 0;
|
||||
const chunkIdentifiersSet =
|
||||
effectiveSnapshot?.chunkIdentifiers instanceof Set
|
||||
? effectiveSnapshot.chunkIdentifiers
|
||||
: new Set();
|
||||
const expectedChunkIdentifiersSet =
|
||||
effectiveSnapshot?.expectedChunkIdentifiers instanceof Set
|
||||
? effectiveSnapshot.expectedChunkIdentifiers
|
||||
: new Set();
|
||||
const missingIdentifierList = Array.from(expectedChunkIdentifiersSet).filter(
|
||||
(identifier) => !chunkIdentifiersSet.has(identifier)
|
||||
);
|
||||
const needsSignerRetryCount =
|
||||
effectiveSnapshot?.needsSignerRetry instanceof Set
|
||||
? effectiveSnapshot.needsSignerRetry.size
|
||||
: 0;
|
||||
const decryptedChunkCount = Number.isFinite(
|
||||
effectiveSnapshot?.decryptedChunkCount
|
||||
)
|
||||
? Math.max(0, Math.floor(effectiveSnapshot.decryptedChunkCount))
|
||||
: 0;
|
||||
const expectedDecryptedTarget = Math.min(
|
||||
expectedChunks,
|
||||
chunkCount || expectedChunks
|
||||
);
|
||||
const remoteVersion = effectiveSnapshot?.version ?? 0;
|
||||
const remoteComplete =
|
||||
!!effectiveSnapshot &&
|
||||
chunkCount >= expectedChunks &&
|
||||
missingIdentifierList.length === 0 &&
|
||||
needsSignerRetryCount === 0 &&
|
||||
effectiveSnapshot.hadFallbackChunk !== true &&
|
||||
decryptedChunkCount >= expectedDecryptedTarget;
|
||||
|
||||
let items = remoteItems;
|
||||
let pointerForEntry = effectiveSnapshot?.pointerEvent || null;
|
||||
let usedFallback = false;
|
||||
const remoteVersion = effectiveSnapshot?.version ?? 0;
|
||||
let remoteUsed = false;
|
||||
let remoteIssues = null;
|
||||
let fallbackSource = null;
|
||||
|
||||
if (!effectiveSnapshot || (remoteVersion === 0 && !remoteItems.length)) {
|
||||
if (previousEntry?.items?.length) {
|
||||
items = previousEntry.items;
|
||||
usedFallback = true;
|
||||
} else if (storedItems.length) {
|
||||
items = storedItems;
|
||||
usedFallback = true;
|
||||
if (effectiveSnapshot) {
|
||||
if (remoteComplete) {
|
||||
remoteUsed = true;
|
||||
} else {
|
||||
remoteIssues = {
|
||||
snapshotId: effectiveSnapshot.snapshotId || "",
|
||||
chunkCount,
|
||||
expectedChunks,
|
||||
decryptedChunks: decryptedChunkCount,
|
||||
missingChunkIdentifiers: missingIdentifierList.length,
|
||||
needsSignerRetry: needsSignerRetryCount,
|
||||
hadFallbackChunk: effectiveSnapshot.hadFallbackChunk === true,
|
||||
version: remoteVersion,
|
||||
};
|
||||
|
||||
if (fallbackCandidate && fallbackCandidate.items.length) {
|
||||
items = fallbackCandidate.items;
|
||||
pointerForEntry = fallbackCandidate.pointer || null;
|
||||
usedFallback = true;
|
||||
fallbackSource = fallbackCandidate.source;
|
||||
} else if (!remoteItems.length && remoteVersion === 0) {
|
||||
remoteUsed = true;
|
||||
} else {
|
||||
remoteUsed = true;
|
||||
}
|
||||
}
|
||||
} else if (fallbackCandidate && fallbackCandidate.items.length) {
|
||||
items = fallbackCandidate.items;
|
||||
pointerForEntry = fallbackCandidate.pointer || null;
|
||||
usedFallback = true;
|
||||
fallbackSource = fallbackCandidate.source;
|
||||
}
|
||||
|
||||
if (!pointerForEntry && fallbackCandidate) {
|
||||
pointerForEntry = fallbackCandidate.pointer || null;
|
||||
}
|
||||
|
||||
if (!remoteUsed && effectiveSnapshot && !usedFallback && !items.length) {
|
||||
remoteUsed = true;
|
||||
}
|
||||
|
||||
const actorPreview =
|
||||
typeof actor === "string" && actor.length > 16
|
||||
? `${actor.slice(0, 8)}…${actor.slice(-4)}`
|
||||
: actor;
|
||||
|
||||
const logContext = {
|
||||
actor: actorPreview || null,
|
||||
snapshot: effectiveSnapshot?.snapshotId || null,
|
||||
itemCount: Array.isArray(items) ? items.length : 0,
|
||||
chunkCount,
|
||||
expectedChunks,
|
||||
decryptedChunks: decryptedChunkCount,
|
||||
missingChunkIdentifiers: missingIdentifierList.length,
|
||||
needsSignerRetry: needsSignerRetryCount,
|
||||
hadFallbackChunk: effectiveSnapshot?.hadFallbackChunk === true,
|
||||
fallbackSource: fallbackSource || null,
|
||||
};
|
||||
|
||||
if (effectiveSnapshot && remoteUsed && remoteComplete) {
|
||||
console.info("[nostr] Watch history snapshot rehydrated:", {
|
||||
...logContext,
|
||||
remoteComplete: true,
|
||||
});
|
||||
} else if (effectiveSnapshot && !remoteComplete && usedFallback) {
|
||||
console.warn("[nostr] Watch history snapshot incomplete; using cached copy:", {
|
||||
...logContext,
|
||||
remoteComplete: false,
|
||||
issues: remoteIssues,
|
||||
});
|
||||
} else if (effectiveSnapshot && !remoteComplete && remoteUsed) {
|
||||
console.warn(
|
||||
"[nostr] Watch history snapshot incomplete with no fallback:",
|
||||
{
|
||||
...logContext,
|
||||
remoteComplete: false,
|
||||
issues: remoteIssues,
|
||||
}
|
||||
);
|
||||
} else if (!effectiveSnapshot && usedFallback) {
|
||||
console.info("[nostr] Watch history snapshot unavailable; using cached copy:", {
|
||||
...logContext,
|
||||
remoteComplete: false,
|
||||
});
|
||||
} else if (!effectiveSnapshot && !items.length) {
|
||||
console.info("[nostr] Watch history snapshot unavailable:", {
|
||||
actor: actorPreview || null,
|
||||
});
|
||||
}
|
||||
|
||||
const entry = this.createWatchHistoryEntry(
|
||||
@@ -4225,166 +4410,168 @@ class NostrClient {
|
||||
|
||||
if (!(entry.chunkEvents instanceof Map)) {
|
||||
entry.chunkEvents = new Map();
|
||||
} else {
|
||||
} else if (remoteUsed) {
|
||||
entry.chunkEvents.clear();
|
||||
}
|
||||
|
||||
if (!(entry.chunkNeedsSigner instanceof Set)) {
|
||||
entry.chunkNeedsSigner = new Set();
|
||||
} else {
|
||||
} else if (remoteUsed) {
|
||||
entry.chunkNeedsSigner.clear();
|
||||
}
|
||||
|
||||
const chunkPointerItemsForEntry = [];
|
||||
const chunkPointerKeys = new Set();
|
||||
let indexPointerForEntry = null;
|
||||
let firstChunkPointer = null;
|
||||
if (remoteUsed && effectiveSnapshot) {
|
||||
const chunkPointerItemsForEntry = [];
|
||||
const chunkPointerKeys = new Set();
|
||||
let indexPointerForEntry = null;
|
||||
let firstChunkPointer = null;
|
||||
|
||||
if (effectiveSnapshot?.pointerEvent) {
|
||||
const indexAddress = eventToAddressPointer(effectiveSnapshot.pointerEvent);
|
||||
if (indexAddress) {
|
||||
const pointer = clonePointerItem({
|
||||
type: "a",
|
||||
value: indexAddress,
|
||||
relay: null,
|
||||
});
|
||||
if (pointer) {
|
||||
const key = pointerKey(pointer);
|
||||
if (key) {
|
||||
chunkPointerKeys.add(key);
|
||||
const clonedIndex = cloneEventForCache(effectiveSnapshot.pointerEvent);
|
||||
if (clonedIndex) {
|
||||
entry.chunkEvents.set(key, clonedIndex);
|
||||
const pointerEventForSnapshot = effectiveSnapshot.pointerEvent;
|
||||
if (pointerEventForSnapshot) {
|
||||
const indexAddress = eventToAddressPointer(pointerEventForSnapshot);
|
||||
if (indexAddress) {
|
||||
const pointer = clonePointerItem({
|
||||
type: "a",
|
||||
value: indexAddress,
|
||||
relay: null,
|
||||
});
|
||||
if (pointer) {
|
||||
const key = pointerKey(pointer);
|
||||
if (key) {
|
||||
chunkPointerKeys.add(key);
|
||||
const clonedIndex = cloneEventForCache(pointerEventForSnapshot);
|
||||
if (clonedIndex) {
|
||||
entry.chunkEvents.set(key, clonedIndex);
|
||||
}
|
||||
indexPointerForEntry = pointer;
|
||||
}
|
||||
indexPointerForEntry = pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (effectiveSnapshot?.snapshotId) {
|
||||
const bucketForEntry = snapshotMap.get(effectiveSnapshot.snapshotId);
|
||||
if (bucketForEntry) {
|
||||
const chunkEntries = Array.from(bucketForEntry.chunks.values()).sort(
|
||||
(a, b) => a.payload.chunkIndex - b.payload.chunkIndex
|
||||
);
|
||||
for (const chunk of chunkEntries) {
|
||||
if (!chunk?.event) {
|
||||
continue;
|
||||
}
|
||||
const addressValue = eventToAddressPointer(chunk.event);
|
||||
if (!addressValue) {
|
||||
continue;
|
||||
if (effectiveSnapshot.snapshotId) {
|
||||
const bucketForEntry = snapshotMap.get(effectiveSnapshot.snapshotId);
|
||||
if (bucketForEntry) {
|
||||
const chunkEntries = Array.from(bucketForEntry.chunks.values()).sort(
|
||||
(a, b) => a.payload.chunkIndex - b.payload.chunkIndex
|
||||
);
|
||||
for (const chunk of chunkEntries) {
|
||||
if (!chunk?.event) {
|
||||
continue;
|
||||
}
|
||||
const addressValue = eventToAddressPointer(chunk.event);
|
||||
if (!addressValue) {
|
||||
continue;
|
||||
}
|
||||
const pointer = clonePointerItem({
|
||||
type: "a",
|
||||
value: addressValue,
|
||||
relay: null,
|
||||
});
|
||||
if (!pointer) {
|
||||
continue;
|
||||
}
|
||||
const key = pointerKey(pointer);
|
||||
if (!key || chunkPointerKeys.has(key)) {
|
||||
continue;
|
||||
}
|
||||
const clonedChunkEvent = cloneEventForCache(chunk.event);
|
||||
const chunkPayloadIndex = Number.isFinite(chunk.payload?.chunkIndex)
|
||||
? Math.max(0, Math.floor(chunk.payload.chunkIndex))
|
||||
: null;
|
||||
const flaggedBySnapshot =
|
||||
chunkPayloadIndex !== null &&
|
||||
effectiveSnapshot.needsSignerRetry instanceof Set &&
|
||||
effectiveSnapshot.needsSignerRetry.has(chunkPayloadIndex);
|
||||
const needsSignerRetry =
|
||||
!!chunk.payload?.needsSignerRetry || flaggedBySnapshot;
|
||||
if (needsSignerRetry) {
|
||||
entry.chunkNeedsSigner.add(key);
|
||||
entry.resolved.delete(key);
|
||||
} else if (clonedChunkEvent) {
|
||||
entry.chunkEvents.set(key, clonedChunkEvent);
|
||||
} else {
|
||||
entry.chunkEvents.set(key, chunk.event);
|
||||
}
|
||||
chunkPointerKeys.add(key);
|
||||
chunkPointerItemsForEntry.push(pointer);
|
||||
if (!firstChunkPointer && chunkPayloadIndex === 0) {
|
||||
firstChunkPointer = pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (effectiveSnapshot.chunkAddresses instanceof Set) {
|
||||
effectiveSnapshot.chunkAddresses.forEach((address) => {
|
||||
const pointer = clonePointerItem({
|
||||
type: "a",
|
||||
value: addressValue,
|
||||
value: address,
|
||||
relay: null,
|
||||
});
|
||||
if (!pointer) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
const key = pointerKey(pointer);
|
||||
if (!key || chunkPointerKeys.has(key)) {
|
||||
continue;
|
||||
}
|
||||
const clonedChunkEvent = cloneEventForCache(chunk.event);
|
||||
const chunkPayloadIndex = Number.isFinite(chunk.payload?.chunkIndex)
|
||||
? Math.max(0, Math.floor(chunk.payload.chunkIndex))
|
||||
: null;
|
||||
const flaggedBySnapshot =
|
||||
chunkPayloadIndex !== null &&
|
||||
effectiveSnapshot?.needsSignerRetry instanceof Set &&
|
||||
effectiveSnapshot.needsSignerRetry.has(chunkPayloadIndex);
|
||||
const needsSignerRetry =
|
||||
!!chunk.payload?.needsSignerRetry || flaggedBySnapshot;
|
||||
if (needsSignerRetry) {
|
||||
entry.chunkNeedsSigner.add(key);
|
||||
entry.resolved.delete(key);
|
||||
} else if (clonedChunkEvent) {
|
||||
entry.chunkEvents.set(key, clonedChunkEvent);
|
||||
} else {
|
||||
entry.chunkEvents.set(key, chunk.event);
|
||||
return;
|
||||
}
|
||||
chunkPointerKeys.add(key);
|
||||
chunkPointerItemsForEntry.push(pointer);
|
||||
if (chunk.payload?.chunkIndex === 0 && !firstChunkPointer) {
|
||||
firstChunkPointer = pointer;
|
||||
});
|
||||
}
|
||||
|
||||
const headPointer = indexPointerForEntry || firstChunkPointer || null;
|
||||
entry.chunkPointers = {
|
||||
head: headPointer,
|
||||
index: indexPointerForEntry,
|
||||
chunks: chunkPointerItemsForEntry,
|
||||
};
|
||||
|
||||
if (headPointer) {
|
||||
const headPointerKey = pointerKey(headPointer);
|
||||
if (headPointerKey) {
|
||||
chunkPointerKeys.add(headPointerKey);
|
||||
const indexPointerKey = indexPointerForEntry
|
||||
? pointerKey(indexPointerForEntry)
|
||||
: "";
|
||||
if (
|
||||
entry.pointerEvent &&
|
||||
indexPointerKey &&
|
||||
headPointerKey === indexPointerKey
|
||||
) {
|
||||
entry.chunkEvents.set(
|
||||
headPointerKey,
|
||||
cloneEventForCache(entry.pointerEvent)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (effectiveSnapshot?.chunkAddresses instanceof Set) {
|
||||
effectiveSnapshot.chunkAddresses.forEach((address) => {
|
||||
const pointer = clonePointerItem({
|
||||
type: "a",
|
||||
value: address,
|
||||
relay: null,
|
||||
});
|
||||
if (!pointer) {
|
||||
return;
|
||||
for (const key of Array.from(entry.resolved.keys())) {
|
||||
if (!key || !key.startsWith("a:")) {
|
||||
continue;
|
||||
}
|
||||
const key = pointerKey(pointer);
|
||||
if (!key || chunkPointerKeys.has(key)) {
|
||||
return;
|
||||
const pointerValue = key.slice(2);
|
||||
if (!pointerValue) {
|
||||
continue;
|
||||
}
|
||||
chunkPointerKeys.add(key);
|
||||
chunkPointerItemsForEntry.push(pointer);
|
||||
});
|
||||
}
|
||||
const pointerKind = Number.parseInt(pointerValue.split(":")[0], 10);
|
||||
if (!Number.isFinite(pointerKind) || !isWatchHistoryKind(pointerKind)) {
|
||||
continue;
|
||||
}
|
||||
if (!chunkPointerKeys.has(key)) {
|
||||
entry.resolved.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
const headPointer = indexPointerForEntry || firstChunkPointer || null;
|
||||
entry.chunkPointers = {
|
||||
head: headPointer,
|
||||
index: indexPointerForEntry,
|
||||
chunks: chunkPointerItemsForEntry,
|
||||
};
|
||||
|
||||
if (headPointer) {
|
||||
const headPointerKey = pointerKey(headPointer);
|
||||
if (headPointerKey) {
|
||||
chunkPointerKeys.add(headPointerKey);
|
||||
const indexPointerKey = indexPointerForEntry
|
||||
? pointerKey(indexPointerForEntry)
|
||||
: "";
|
||||
if (
|
||||
entry.pointerEvent &&
|
||||
indexPointerKey &&
|
||||
headPointerKey === indexPointerKey
|
||||
) {
|
||||
entry.chunkEvents.set(
|
||||
headPointerKey,
|
||||
cloneEventForCache(entry.pointerEvent)
|
||||
);
|
||||
for (const key of chunkPointerKeys) {
|
||||
const eventForKey = entry.chunkEvents.get(key);
|
||||
if (eventForKey) {
|
||||
entry.resolved.set(key, cloneEventForCache(eventForKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const key of Array.from(entry.resolved.keys())) {
|
||||
if (!key || !key.startsWith("a:")) {
|
||||
continue;
|
||||
}
|
||||
const pointerValue = key.slice(2);
|
||||
if (!pointerValue) {
|
||||
continue;
|
||||
}
|
||||
const pointerKind = Number.parseInt(pointerValue.split(":")[0], 10);
|
||||
if (!Number.isFinite(pointerKind) || !isWatchHistoryKind(pointerKind)) {
|
||||
continue;
|
||||
}
|
||||
if (!chunkPointerKeys.has(key)) {
|
||||
entry.resolved.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
for (const key of chunkPointerKeys) {
|
||||
const eventForKey = entry.chunkEvents.get(key);
|
||||
if (eventForKey) {
|
||||
entry.resolved.set(key, cloneEventForCache(eventForKey));
|
||||
}
|
||||
}
|
||||
|
||||
this.watchHistoryCache.set(actor, entry);
|
||||
this.persistWatchHistoryEntry(actor, entry);
|
||||
|
||||
|
||||
Reference in new issue
Block a user