Keep older chat history and image previews stable (#2490)
* fix(app): keep timeline history and previews stable Treat persisted timeline replicas as display-only so authoritative pagination always comes from the daemon. Require renewed user intent between older-history pages unless the viewport genuinely remains at the history edge. Model assistant image acquisition as loading, loaded, or failed so recreating a preview URL cannot be rendered as an error. * fix(app): keep file image previews current * fix(app): stabilize history pagination edges * fix(app): recover transient timeline loads * fix(app): retain assistant image previews * Stabilize history pagination lifecycle * Stabilize history settlement and image previews * Retry file images after reconnect * Keep active previews and pagination requests alive * Replace image hook tests with typed ports * Integrate timeline hydration with submission authority * Harden pre-hydration timeline reconciliation * Make rewind E2E use real scroll intent * Preserve live timeline state through hydration * Keep mounted image attachments retained * Protect preview persistence and lifecycle hydration * Preserve idless live assistant continuations * Preserve timeline rows across delayed hydration * test(app): cover real assistant image files * Preserve assistant tool ordering during hydration
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
createImageSourceCacheKey,
|
||||
createPreviewAttachmentId,
|
||||
fileUriToPath,
|
||||
localFileSourceToPath,
|
||||
parseDataUrl,
|
||||
@@ -86,4 +87,29 @@ describe("parseImageDataUrl", () => {
|
||||
it("ignores SVG data URLs", () => {
|
||||
expect(parseImageDataUrl("data:image/svg+xml;base64,PHN2ZyAvPg==")).toBeNull();
|
||||
});
|
||||
|
||||
it("distinguishes image data that differs only in the middle", () => {
|
||||
const prefix = "a".repeat(64);
|
||||
const suffix = "z".repeat(64);
|
||||
const first = `data:image/png;base64,${prefix}${"b".repeat(256)}${suffix}`;
|
||||
const second = `data:image/png;base64,${prefix}${"c".repeat(256)}${suffix}`;
|
||||
|
||||
expect(createImageSourceCacheKey(first)).not.toBe(createImageSourceCacheKey(second));
|
||||
});
|
||||
|
||||
it("gives equal-length preview content distinct attachment identities", () => {
|
||||
expect(
|
||||
createPreviewAttachmentId({
|
||||
mimeType: "image/png",
|
||||
contentLength: 512,
|
||||
contentKey: "first-content",
|
||||
}),
|
||||
).not.toBe(
|
||||
createPreviewAttachmentId({
|
||||
mimeType: "image/png",
|
||||
contentLength: 512,
|
||||
contentKey: "second-content",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user