Improve attachment memory safety, downloads, and high-memory alert UX.
Queue Release Build / prepare (push) Successful in 20s
Deploy Web Apps / deploy (push) Successful in 9m2s
Queue Release Build / build-windows (push) Successful in 28m8s
Queue Release Build / build-linux (push) Successful in 47m26s
Queue Release Build / build-android (push) Successful in 19m52s
Queue Release Build / finalize (push) Successful in 4m42s
Queue Release Build / prepare (push) Successful in 20s
Deploy Web Apps / deploy (push) Successful in 9m2s
Queue Release Build / build-windows (push) Successful in 28m8s
Queue Release Build / build-linux (push) Successful in 47m26s
Queue Release Build / build-android (push) Successful in 19m52s
Queue Release Build / finalize (push) Successful in 4m42s
Stream large receives to disk with chunk acks to cap renderer RAM, evict off-screen display blobs, and route exports through a disk-aware download service. Fix the high-memory dialog (backdrop dismiss, copy, log actions), allow diagnostics paths in the path jail, and restore persisted image hydration after reload. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+37
-5
@@ -11,6 +11,7 @@ import {
|
||||
decodeBase64ToUint8Array,
|
||||
yieldToAttachmentHydrationLoop
|
||||
} from '../../domain/logic/attachment-blob.rules';
|
||||
import { canRevokeAttachmentDisplayBlob } from '../../domain/logic/attachment-blob-eviction.rules';
|
||||
import { isBlobObjectUrl, needsBlobObjectUrlForInlineDisplay } from '../../domain/logic/attachment-display-url.rules';
|
||||
import { mergeAttachmentLocalPaths } from '../../domain/logic/attachment-persistence.rules';
|
||||
import { isAttachmentMedia } from '../../domain/logic/attachment.logic';
|
||||
@@ -119,7 +120,7 @@ export class AttachmentPersistenceService {
|
||||
}
|
||||
|
||||
async tryRestoreAttachmentFromLocal(attachment: Attachment): Promise<boolean> {
|
||||
const restored = await this.ensurePersistedUploadHost(attachment);
|
||||
const restored = await this.ensurePersistedUploadHost(attachment, { hydrateMediaForDisplay: true });
|
||||
|
||||
if (restored) {
|
||||
attachment.requestError = undefined;
|
||||
@@ -128,11 +129,30 @@ export class AttachmentPersistenceService {
|
||||
return restored;
|
||||
}
|
||||
|
||||
async ensurePersistedUploadHost(attachment: Attachment): Promise<boolean> {
|
||||
async tryRestoreAttachmentHostOnly(attachment: Attachment): Promise<boolean> {
|
||||
return this.ensurePersistedUploadHost(attachment, { hydrateMediaForDisplay: false });
|
||||
}
|
||||
|
||||
revokeAttachmentDisplayBlob(attachment: Attachment): boolean {
|
||||
if (!canRevokeAttachmentDisplayBlob(attachment)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.revokeAttachmentObjectUrl(attachment);
|
||||
attachment.objectUrl = undefined;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async ensurePersistedUploadHost(
|
||||
attachment: Attachment,
|
||||
options: { hydrateMediaForDisplay?: boolean } = {}
|
||||
): Promise<boolean> {
|
||||
const hydrateMediaForDisplay = options.hydrateMediaForDisplay !== false;
|
||||
const existingPath = await this.attachmentStorage.resolveExistingPath(attachment);
|
||||
|
||||
if (existingPath) {
|
||||
return this.hydrateAttachmentFromStoredPath(attachment, existingPath);
|
||||
return this.hydrateAttachmentFromStoredPath(attachment, existingPath, hydrateMediaForDisplay);
|
||||
}
|
||||
|
||||
if (!attachment.filePath?.trim() || !this.attachmentStorage.canCopyFiles()) {
|
||||
@@ -147,13 +167,22 @@ export class AttachmentPersistenceService {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.hydrateAttachmentFromStoredPath(attachment, savedPath);
|
||||
return this.hydrateAttachmentFromStoredPath(attachment, savedPath, hydrateMediaForDisplay);
|
||||
}
|
||||
|
||||
private async hydrateAttachmentFromStoredPath(attachment: Attachment, diskPath: string): Promise<boolean> {
|
||||
private async hydrateAttachmentFromStoredPath(
|
||||
attachment: Attachment,
|
||||
diskPath: string,
|
||||
hydrateMediaForDisplay = true
|
||||
): Promise<boolean> {
|
||||
attachment.savedPath = diskPath;
|
||||
|
||||
if (isAttachmentMedia(attachment)) {
|
||||
if (!hydrateMediaForDisplay) {
|
||||
void this.persistAttachmentMeta(attachment);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.ensureInlineDisplayObjectUrl(attachment);
|
||||
}
|
||||
|
||||
@@ -192,6 +221,7 @@ export class AttachmentPersistenceService {
|
||||
this.revokeAttachmentObjectUrl(attachment);
|
||||
attachment.objectUrl = nativeUrl;
|
||||
attachment.available = true;
|
||||
this.runtimeStore.touch();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -366,6 +396,8 @@ export class AttachmentPersistenceService {
|
||||
`${attachment.messageId}:${attachment.id}`,
|
||||
new File([blob], attachment.filename, { type: attachment.mime })
|
||||
);
|
||||
|
||||
this.runtimeStore.touch();
|
||||
}
|
||||
|
||||
private revokeAttachmentObjectUrl(attachment: Attachment): void {
|
||||
|
||||
Reference in New Issue
Block a user