UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in

113 lines 4.21 kB
// workaround for this is not a function when deployed // see https://github.com/pvorb/node-md5/issues/52 import md5 from "md5"; export class Upload_Result { success; filename; hash; size; url; constructor(success, filename, hash, size) { this.success = success; this.filename = filename; this.hash = hash; this.size = size; } } export async function upload_file(file, url) { const buffer = await file.arrayBuffer(); const hashString = hash(buffer); const ext = file.name.split('.').pop(); const filename = hashString + "." + ext; const alias = file.name.split('.').shift(); console.assert(alias !== undefined); const body = { alias: alias, filename: filename }; const exists = await fetch(url + '/exists', { method: "POST", body: JSON.stringify(body) }); const answer = await exists.json(); if (!answer.success) { console.warn("exists check did fail"); } if (answer.exists) { console.log("file already exists", hashString); return new Upload_Result(true, filename, hashString, file.size); } console.log("begin uploading file", alias, file.size); const formData = new FormData(); formData.append("file", file); const headers = {}; headers["filesize"] = file.size; if (alias) headers["alias"] = alias; const upload_res_raw = await fetch(url + '/upload/file', { method: "POST", body: formData, headers: headers }); const upload_res = await upload_res_raw.json(); if (upload_res?.success === false) { if (upload_res.message !== undefined) { console.error("Upload failed:", upload_res.message); } else { console.error("Upload failed"); } return null; } console.assert(upload_res.hash_sum === hashString, "hash sum did not match", "received:", upload_res.hash_sum, "expected:", hashString); if (upload_res.success) console.log("successfully uploaded", hashString, upload_res.id); const res = new Upload_Result(upload_res.success, filename, hashString, file.size); res.url = url; return res; } export function hash(buffer) { return md5(new Uint8Array(buffer)); } ; export async function download_file(filename, expectedHash, expectedSize, serverUrl, skipChecks = false) { try { const download_res = await fetch(serverUrl + '/download/file', { method: "POST", body: filename }); if (download_res.status !== 200) { // const res = await download_res.json(); console.error("download failed", download_res); return null; } const bin = await download_res.blob(); const buffer = await bin.arrayBuffer(); if (!skipChecks) console.assert(bin.size === expectedSize, "size mismatch", "expected:", expectedSize, "got:", bin.size); const result_hash = hash(buffer); if (!skipChecks) console.assert(result_hash === expectedHash, "hash mismatch, downloaded file is invalid"); return bin.arrayBuffer(); } catch (err) { console.error(err); } return null; } export async function download(url, progressCallback) { const response = await fetch(url); const reader = response.body?.getReader(); const contentLength = response.headers.get('Content-Length'); const total = contentLength ? parseInt(contentLength) : 0; if (!reader) return null; let received = 0; const chunks = []; while (true) { const { done, value } = await reader.read(); if (value) { chunks.push(value); received += value.length; progressCallback.call(null, new ProgressEvent('progress', { loaded: received, total: total })); } if (done) { break; } } const final = new Uint8Array(received); let position = 0; for (const chunk of chunks) { final.set(chunk, position); position += chunk.length; } return final; } //# sourceMappingURL=engine_web_api.js.map