97 lines
3.8 KiB
JavaScript
97 lines
3.8 KiB
JavaScript
/**
|
|
* File Download Runtime Provider
|
|
*
|
|
* Provides returnDownloadableFile() for creating user downloads.
|
|
* Files returned this way are NOT accessible to the LLM later (one-time download).
|
|
* Works both online (sends to extension) and offline (triggers browser download directly).
|
|
* Collects files for retrieval by caller.
|
|
*/
|
|
export class FileDownloadRuntimeProvider {
|
|
constructor() {
|
|
this.files = [];
|
|
}
|
|
getData() {
|
|
// No data needed
|
|
return {};
|
|
}
|
|
getRuntime() {
|
|
return (_sandboxId) => {
|
|
window.returnDownloadableFile = async (fileName, content, mimeType) => {
|
|
let finalContent, finalMimeType;
|
|
if (content instanceof Blob) {
|
|
const arrayBuffer = await content.arrayBuffer();
|
|
finalContent = new Uint8Array(arrayBuffer);
|
|
finalMimeType = mimeType || content.type || "application/octet-stream";
|
|
if (!mimeType && !content.type) {
|
|
throw new Error("returnDownloadableFile: MIME type is required for Blob content. Please provide a mimeType parameter (e.g., 'image/png').");
|
|
}
|
|
}
|
|
else if (content instanceof Uint8Array) {
|
|
finalContent = content;
|
|
if (!mimeType) {
|
|
throw new Error("returnDownloadableFile: MIME type is required for Uint8Array content. Please provide a mimeType parameter (e.g., 'image/png').");
|
|
}
|
|
finalMimeType = mimeType;
|
|
}
|
|
else if (typeof content === "string") {
|
|
finalContent = content;
|
|
finalMimeType = mimeType || "text/plain";
|
|
}
|
|
else {
|
|
finalContent = JSON.stringify(content, null, 2);
|
|
finalMimeType = mimeType || "application/json";
|
|
}
|
|
// Send to extension if in extension context (online mode)
|
|
if (window.sendRuntimeMessage) {
|
|
const response = await window.sendRuntimeMessage({
|
|
type: "file-returned",
|
|
fileName,
|
|
content: finalContent,
|
|
mimeType: finalMimeType,
|
|
});
|
|
if (response.error)
|
|
throw new Error(response.error);
|
|
}
|
|
else {
|
|
// Offline mode: trigger browser download directly
|
|
const blob = new Blob([finalContent instanceof Uint8Array ? finalContent : finalContent], {
|
|
type: finalMimeType,
|
|
});
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement("a");
|
|
a.href = url;
|
|
a.download = fileName;
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
};
|
|
};
|
|
}
|
|
async handleMessage(message, respond) {
|
|
if (message.type === "file-returned") {
|
|
// Collect file for caller
|
|
this.files.push({
|
|
fileName: message.fileName,
|
|
content: message.content,
|
|
mimeType: message.mimeType,
|
|
});
|
|
respond({ success: true });
|
|
}
|
|
}
|
|
/**
|
|
* Get collected files
|
|
*/
|
|
getFiles() {
|
|
return this.files;
|
|
}
|
|
/**
|
|
* Reset state for reuse
|
|
*/
|
|
reset() {
|
|
this.files = [];
|
|
}
|
|
getDescription() {
|
|
return "returnDownloadableFile(filename, content, mimeType?) - Create downloadable file for user (one-time download, not accessible later)";
|
|
}
|
|
}
|
|
//# sourceMappingURL=FileDownloadRuntimeProvider.js.map
|