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

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:
2026-06-14 00:25:22 +02:00
co-authored by Cursor
parent f0d79aa627
commit bb0ac930ad
69 changed files with 2306 additions and 430 deletions
@@ -0,0 +1,108 @@
import '@angular/compiler';
import {
afterEach,
beforeEach,
describe,
expect,
it,
vi
} from 'vitest';
import { EnvironmentInjector, Injector } from '@angular/core';
import { PerfDiagnosticsCollector } from './diagnostics.collector';
import {
bootstrapPerfDiagnostics,
registerImmediatePerfDiagCollector,
resetDiagnosticsBootstrapStateForTests
} from './diagnostics.bootstrap';
import type { PerfDiagEntry } from './diagnostics.models';
describe('diagnostics.bootstrap', () => {
let injector: EnvironmentInjector;
let collector: {
collectSample: ReturnType<typeof vi.fn>;
buildEntries: ReturnType<typeof vi.fn>;
};
beforeEach(() => {
resetDiagnosticsBootstrapStateForTests();
collector = {
collectSample: vi.fn(() => ({
storeDomains: { attachment: 1024 },
storeBytes: { attachment: 1024 },
components: { ChatMessageItemComponent: 12 },
componentDomains: { chat: 12 },
suspectedLeaks: [],
heap: { usedJsHeapMb: 256, totalJsHeapMb: 300 },
route: '/room/test',
durationMs: 2
})),
buildEntries: vi.fn(() => ([
{
collectedAt: 1,
source: 'renderer',
type: 'store',
payload: { domains: { attachment: 1024 } }
},
{
collectedAt: 1,
source: 'renderer',
type: 'components',
payload: { domains: { chat: 12 } }
},
{
collectedAt: 1,
source: 'renderer',
type: 'heap',
payload: { usedJsHeapMb: 256 }
}
] satisfies PerfDiagEntry[]))
};
injector = Injector.create({
providers: [{ provide: PerfDiagnosticsCollector, useValue: collector }]
}) as EnvironmentInjector;
});
afterEach(() => {
resetDiagnosticsBootstrapStateForTests();
});
it('registers immediate renderer samples without perf diagnostics being enabled', () => {
registerImmediatePerfDiagCollector(injector);
const entries = globalThis.__collectPerfDiagSample?.() ?? [];
expect(entries).toHaveLength(3);
expect(entries.find((entry) => entry.type === 'store')?.payload).toEqual({
domains: { attachment: 1024 }
});
expect(entries.find((entry) => entry.type === 'components')?.payload).toEqual({
domains: { chat: 12 }
});
});
it('keeps the immediate collector registered after periodic sampling stops', async () => {
vi.useFakeTimers();
vi.stubGlobal('window', { addEventListener: vi.fn() });
registerImmediatePerfDiagCollector(injector);
const reportSample = vi.fn(async () => {
throw new Error('writer unavailable');
});
await bootstrapPerfDiagnostics({
isPerfDiagEnabled: async () => true,
reportPerfDiagSample: reportSample
}, injector);
await vi.runOnlyPendingTimersAsync();
expect(globalThis.__collectPerfDiagSample?.()).toHaveLength(3);
vi.useRealTimers();
vi.unstubAllGlobals();
});
});
@@ -16,11 +16,38 @@ const SAMPLE_INTERVAL_MS = 10_000;
let started = false;
let sampleTimer: ReturnType<typeof setInterval> | null = null;
let immediateCollectorRegistered = false;
export function registerImmediatePerfDiagCollector(injector: EnvironmentInjector): void {
if (immediateCollectorRegistered) {
return;
}
let immediateSampleCollector: PerfDiagnosticsCollector | null = null;
runInInjectionContext(injector, () => {
immediateSampleCollector = inject(PerfDiagnosticsCollector);
});
globalThis.__collectPerfDiagSample = () => {
if (!immediateSampleCollector) {
return [];
}
const sample = immediateSampleCollector.collectSample();
return sample ? immediateSampleCollector.buildEntries(sample) : [];
};
immediateCollectorRegistered = true;
}
export async function bootstrapPerfDiagnostics(
api: ElectronApi,
injector: EnvironmentInjector
): Promise<void> {
registerImmediatePerfDiagCollector(injector);
const reportSample = api.reportPerfDiagSample;
if (started || !api.isPerfDiagEnabled || !reportSample) {
@@ -41,22 +68,6 @@ export async function bootstrapPerfDiagnostics(
started = true;
let immediateSampleCollector: PerfDiagnosticsCollector | null = null;
runInInjectionContext(injector, () => {
immediateSampleCollector = inject(PerfDiagnosticsCollector);
});
globalThis.__collectPerfDiagSample = () => {
if (!immediateSampleCollector) {
return [];
}
const sample = immediateSampleCollector.collectSample();
return sample ? immediateSampleCollector.buildEntries(sample) : [];
};
const reporter: PerfDiagReporter = {
report: (entry: PerfDiagEntry) => reportSample(entry)
};
@@ -113,6 +124,12 @@ function stopPerfDiagnosticsSampling(): void {
sampleTimer = null;
}
delete globalThis.__collectPerfDiagSample;
started = false;
}
/** @internal Resets module state between unit tests. */
export function resetDiagnosticsBootstrapStateForTests(): void {
stopPerfDiagnosticsSampling();
immediateCollectorRegistered = false;
delete globalThis.__collectPerfDiagSample;
}