Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use arrayBuffer for fetching and caching local Snaps #2884

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 5 additions & 18 deletions packages/snaps-controllers/src/snaps/location/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,7 @@ export interface HttpOptions {
}

export class HttpLocation implements SnapLocation {
// We keep contents separate because then we can use only one Blob in cache,
// which we convert to Uint8Array when actually returning the file.
//
// That avoids deepCloning file contents.
// I imagine ArrayBuffers are copy-on-write optimized, meaning
// in most often case we'll only have one file contents in common case.
private readonly cache = new Map<
string,
{ file: VirtualFile; contents: Blob }
>();
private readonly cache = new Map<string, VirtualFile>();

private validatedManifest?: VirtualFile<SnapManifest>;

Expand Down Expand Up @@ -80,11 +71,7 @@ export class HttpLocation implements SnapLocation {
const relativePath = normalizeRelative(path);
const cached = this.cache.get(relativePath);
if (cached !== undefined) {
const { file, contents } = cached;
const value = new Uint8Array(await contents.arrayBuffer());
const vfile = file.clone();
vfile.value = value;
return vfile;
return cached.clone();
}

const canonicalPath = this.toCanonical(relativePath).toString();
Expand All @@ -94,17 +81,17 @@ export class HttpLocation implements SnapLocation {
`Failed to fetch "${canonicalPath}". Status code: ${response.status}.`,
);
}
const buffer = await response.arrayBuffer();
const vfile = new VirtualFile({
value: '',
value: new Uint8Array(buffer),
path: relativePath,
data: { canonicalPath },
});
const blob = await response.blob();
assert(
!this.cache.has(relativePath),
'Corrupted cache, multiple files with same path.',
);
this.cache.set(relativePath, { file: vfile, contents: blob });
this.cache.set(relativePath, vfile);

return this.fetch(relativePath);
}
Expand Down
Loading