I successfully implemented TUS.
I load this script on a global app workflow (thanks https://weweb-embed.statechange.ai/):
if(!window["scp-loading-fe9fdf6a-9c05-4016-8f9c-62ea62b08990"]) {
window["scp-loading-fe9fdf6a-9c05-4016-8f9c-62ea62b08990"] = true;
let doc;
/* Adding script from https://cdn.jsdelivr.net/npm/tus-js-client@latest/dist/tus.js */
doc = document.createElement('script');
doc.src = 'https://cdn.jsdelivr.net/npm/tus-js-client@latest/dist/tus.js';
document.body.appendChild(doc);
}
Then i run this on submit. It’s a lot of logging, but i had some problems i had to troubleshoot.
I’m also checking if the script is loaded, and if not, i load it. Not sure if needed, but ChatGPT and I did it anyway. I had some issues where I had to manually load the package.
I’m using the supabase auth session token to authenticate as well. Hopefully its secure enough.
const projectId = '**SUPABASE PROJECT ID**';
// Importing tus.js library asynchronously
(function() {
if (!window["scp-loading-fe9fdf6a-9c05-4016-8f9c-62ea62b08990"]) {
window["scp-loading-fe9fdf6a-9c05-4016-8f9c-62ea62b08990"] = true;
let script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/tus-js-client@4.1.0/lib.es5/browser/index.min.js';
script.onload = function() {
startUpload();
};
document.body.appendChild(script);
} else {
startUpload();
}
})();
async function uploadFile(bucketName, filePath, fileName, file) {
console.log('Starting upload process...');
const {
data: {
session
}
} = await wwLib.wwPlugins.supabaseAuth.publicInstance.auth.getSession();
console.log('Session retrieved:', session);
return new Promise((resolve, reject) => {
console.log('Creating tus upload...');
var upload = new tus.Upload(file, {
endpoint: `https://${projectId}.supabase.co/storage/v1/upload/resumable`,
retryDelays: [0, 3000, 5000, 10000, 20000],
headers: {
authorization: `Bearer ${session.access_token}`,
'x-upsert': 'true',
},
uploadDataDuringCreation: true,
removeFingerprintOnSuccess: true,
metadata: {
bucketName: bucketName,
objectName: fileName,
contentType: file.type,
cacheControl: '3600',
},
chunkSize: 6 * 1024 * 1024,
onError: function(error) {
console.log('Upload failed:', error);
reject(error);
},
onProgress: function(bytesUploaded, bytesTotal) {
var percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(0);
console.log('Upload progress:', percentage + '%');
// Update progress to context variables if it exists
if (context.component && context.component.variables && context.component.variables['**SOMEWHERE TO DISPLAY %**'] !== undefined) {
context.component.variables['**SOMEWHERE TO DISPLAY %**'] = percentage;
} else {
console.warn('Progress variable not found in context');
}
},
onSuccess: function() {
console.log('Download %s from %s', upload.file.name, upload.url)
resolve()
},
});
upload.findPreviousUploads().then(function(previousUploads) {
console.log('Previous uploads found:', previousUploads);
if (previousUploads.length) {
upload.resumeFromPreviousUpload(previousUploads[0]);
}
console.log('Starting the upload...');
upload.start();
}).catch((error) => {
console.log('Error finding previous uploads:', error);
reject(error);
});
});
}
function startUpload() {
console.log('Starting upload script...');
const file = '**YOUR ACTUAL FILE**';
if (!file) {
console.error('No file found in context variables');
return;
}
const filePath = `**CONSTRUCT FILE PATH**`;
const bucketName = '**YOUR BUCKET NAME**';
const fileName = `**YOUR FILE PATH + FILE NAME.EXT**`;
uploadFile(bucketName, filePath, fileName, file).then(() => {
console.log('File uploaded successfully');
};
}).catch((error) => {
console.error('File upload failed', error);
});
}
Additionally, you can trigger ie. a variable change or something onSuccess. I’m doing a variable change to true, and triggering a new workflow (with solution from @MatthewS Triggering Component Workflow w/ JS Workaround - #2 by Doc )