mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-06 01:20:41 +00:00
Worker + NodeJS support for puter.ai.txt2img and puter.ai.txt2vid (#2051)
* Attempt to get workers working with AI media generation * add FileReader polyfill * fix import path
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
function toBase64FromBuffer(buffer) {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
// use the requested reduce logic
|
||||
const binary = bytes.reduce((data, byte) => data + String.fromCharCode(byte), '');
|
||||
return typeof btoa === 'function' ? btoa(binary) : Buffer.from(binary, 'binary').toString('base64');
|
||||
}
|
||||
|
||||
export class FileReaderPoly {
|
||||
constructor() {
|
||||
this.result = null;
|
||||
this.error = null;
|
||||
this.onloadend = null;
|
||||
}
|
||||
readAsDataURL(blob) {
|
||||
const self = this;
|
||||
(async function () {
|
||||
try {
|
||||
let buffer;
|
||||
if (blob && typeof blob.arrayBuffer === 'function') {
|
||||
buffer = await blob.arrayBuffer();
|
||||
} else if (blob instanceof ArrayBuffer) {
|
||||
buffer = blob;
|
||||
} else if (ArrayBuffer.isView(blob)) {
|
||||
buffer = blob.buffer;
|
||||
} else {
|
||||
buffer = new Uint8Array(0).buffer;
|
||||
}
|
||||
|
||||
const base64 = toBase64FromBuffer(buffer);
|
||||
const mime = (blob && blob.type) || 'application/octet-stream';
|
||||
self.result = 'data:' + mime + ';base64,' + base64;
|
||||
if (typeof self.onloadend === 'function') self.onloadend();
|
||||
} catch (err) {
|
||||
self.error = err;
|
||||
if (typeof self.onloadend === 'function') self.onloadend();
|
||||
}
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { FileReaderPoly } from "./polyfills/fileReaderPoly.js";
|
||||
|
||||
/**
|
||||
* Parses a given response text into a JSON object. If the parsing fails due to invalid JSON format,
|
||||
* the original response text is returned.
|
||||
@@ -589,7 +591,7 @@ class TeePromise {
|
||||
|
||||
async function blob_to_url (blob) {
|
||||
const tp = new TeePromise();
|
||||
const reader = new FileReader();
|
||||
const reader = new (globalThis.FileReader || FileReaderPoly)();
|
||||
reader.onloadend = () => tp.resolve(reader.result);
|
||||
reader.readAsDataURL(blob);
|
||||
return await tp;
|
||||
@@ -597,7 +599,7 @@ async function blob_to_url (blob) {
|
||||
|
||||
function blobToDataUri (blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
const reader = new (globalThis.FileReader || FileReaderPoly)();
|
||||
reader.onload = function (event) {
|
||||
resolve(event.target.result);
|
||||
};
|
||||
@@ -611,7 +613,7 @@ function blobToDataUri (blob) {
|
||||
function arrayBufferToDataUri (arrayBuffer) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const blob = new Blob([arrayBuffer]);
|
||||
const reader = new FileReader();
|
||||
const reader = new (globalThis.FileReader || FileReaderPoly)();
|
||||
reader.onload = function (event) {
|
||||
resolve(event.target.result);
|
||||
};
|
||||
@@ -622,10 +624,6 @@ function arrayBufferToDataUri (arrayBuffer) {
|
||||
});
|
||||
}
|
||||
|
||||
export { parseResponse, uuidv4, handle_resp, handle_error, initXhr, setupXhrEventHandlers, driverCall,
|
||||
TeePromise,
|
||||
make_driver_method,
|
||||
blob_to_url,
|
||||
arrayBufferToDataUri,
|
||||
blobToDataUri,
|
||||
};
|
||||
export {
|
||||
arrayBufferToDataUri, blob_to_url, blobToDataUri, driverCall, handle_error, handle_resp, initXhr, make_driver_method, parseResponse, setupXhrEventHandlers, TeePromise, uuidv4
|
||||
};
|
||||
|
||||
@@ -391,7 +391,8 @@ class AI {
|
||||
} else {
|
||||
throw { message: 'Unexpected audio response format', code: 'invalid_audio_response' };
|
||||
}
|
||||
const audio = new Audio(url);
|
||||
const audio = new (globalThis.Audio || Object)();
|
||||
audio.src = url;
|
||||
audio.toString = () => url;
|
||||
audio.valueOf = () => url;
|
||||
return audio;
|
||||
@@ -1061,7 +1062,7 @@ class AI {
|
||||
} else {
|
||||
throw { message: 'Unexpected image response format', code: 'invalid_image_response' };
|
||||
}
|
||||
let img = new Image();
|
||||
let img = new (globalThis.Image || Object)();
|
||||
img.src = url;
|
||||
img.toString = () => img.src;
|
||||
img.valueOf = () => img.src;
|
||||
@@ -1153,7 +1154,7 @@ class AI {
|
||||
return result;
|
||||
}
|
||||
|
||||
const video = document.createElement('video');
|
||||
const video = (globalThis.document?.createElement('video') || {setAttribute: ()=>{}});
|
||||
video.src = sourceUrl;
|
||||
video.controls = true;
|
||||
video.preload = 'metadata';
|
||||
|
||||
Reference in New Issue
Block a user