db utils should be reusable

This commit is contained in:
Jade Rowland 2023-12-10 10:19:57 -05:00
parent a7713213f9
commit ace71693b7

View File

@ -3,8 +3,13 @@ import { registerSound, onTriggerSample } from '@strudel.cycles/webaudio';
import { isAudioFile } from './files.mjs'; import { isAudioFile } from './files.mjs';
//choose a directory to locally import samples //choose a directory to locally import samples
const userSamplesDB = 'testdb3';
const sampleObject = 'testsamples'; const userSamplesDBConfig = {
dbName: 'samples',
table: 'usersamples',
columns: ['blob', 'title'],
version: 1,
};
function clearData() { function clearData() {
window.indexedDB window.indexedDB
@ -17,8 +22,8 @@ function clearData() {
}); });
} }
const registerSamples = () => { const registerSamplesFromDB = (config) => {
openDB((objectStore) => { openDB(config, (objectStore) => {
let query = objectStore.getAll(); let query = objectStore.getAll();
query.onsuccess = (event) => { query.onsuccess = (event) => {
const soundFiles = event.target.result; const soundFiles = event.target.result;
@ -63,20 +68,20 @@ async function bufferToDataUrl(buf) {
}); });
} }
const openDB = (onOpened) => { const openDB = (config, onOpened) => {
if ('indexedDB' in window) { const { dbName, version, table, columns } = config;
// indexedDB supported if (!('indexedDB' in window)) {
} else {
console.log('IndexedDB is not supported.'); console.log('IndexedDB is not supported.');
return;
} }
const dbOpen = indexedDB.open(userSamplesDB, 6); const dbOpen = indexedDB.open(dbName, version);
dbOpen.onupgradeneeded = (_event) => { dbOpen.onupgradeneeded = (_event) => {
const db = dbOpen.result; const db = dbOpen.result;
const objectStore = db.createObjectStore(sampleObject, { keyPath: 'id', autoIncrement: false }); const objectStore = db.createObjectStore(table, { keyPath: 'id', autoIncrement: false });
// objectStore.createIndex('name', 'name', { unique: false }); columns.forEach((c) => {
objectStore.createIndex('blob', 'blob', { unique: false }); objectStore.createIndex(c, c, { unique: false });
objectStore.createIndex('title', 'title', { unique: false }); });
}; };
dbOpen.onerror = (err) => { dbOpen.onerror = (err) => {
console.error(`indexedDB error: ${err.errorCode}`); console.error(`indexedDB error: ${err.errorCode}`);
@ -86,42 +91,43 @@ const openDB = (onOpened) => {
const db = dbOpen.result; const db = dbOpen.result;
const // lock store for writing const // lock store for writing
writeTransaction = db.transaction([sampleObject], 'readwrite'), writeTransaction = db.transaction([table], 'readwrite'),
// get object store // get object store
objectStore = writeTransaction.objectStore(sampleObject); objectStore = writeTransaction.objectStore(table);
// objectStore.put({ title: 'test', blob: 'test' });
onOpened(objectStore, db); onOpened(objectStore, db);
}; };
}; };
const processFilesForIDB = async (files) => { const processFilesForIDB = async (files) => {
return await Promise.all( return await Promise.all(
Array.from(files).map(async (s) => { Array.from(files)
const title = s.name; .map(async (s) => {
if (!isAudioFile(title)) { const title = s.name;
return; if (!isAudioFile(title)) {
} return;
// const id = crypto.randomUUID(); }
const sUrl = URL.createObjectURL(s); //create obscured url to file system that can be fetched
const buf = await fetch(sUrl).then((res) => res.arrayBuffer()); const sUrl = URL.createObjectURL(s);
const base64 = await bufferToDataUrl(buf); //fetch the sound and turn it into a buffer array
const f = { const buf = await fetch(sUrl).then((res) => res.arrayBuffer());
title, //create a url blob containing all of the buffer data
blob: base64, const base64 = await bufferToDataUrl(buf);
id: s.webkitRelativePath, return {
}; title,
return f; blob: base64,
}), id: s.webkitRelativePath,
};
})
.filter(Boolean),
).catch((error) => { ).catch((error) => {
console.error(error); console.error(error);
}); });
}; };
const setupUserSamplesDB = async (files, onComplete) => { const uploadSamplesToDB = async (config, files) => {
//clearData(); // clearData();
await processFilesForIDB(files).then((files) => { await processFilesForIDB(files).then((files) => {
const onOpened = (objectStore, db) => { const onOpened = (objectStore, _db) => {
files.forEach((file) => { files.forEach((file) => {
if (file == null) { if (file == null) {
return; return;
@ -129,23 +135,22 @@ const setupUserSamplesDB = async (files, onComplete) => {
const mutation = objectStore.put(file); const mutation = objectStore.put(file);
mutation.onsuccess = () => {}; mutation.onsuccess = () => {};
}); });
onComplete(objectStore, db);
}; };
openDB(onOpened); openDB(config, onOpened);
}); });
}; };
export default function ImportSoundsButton({ onComplete }) { export default function ImportSoundsButton({ onComplete }) {
let fileUploadRef = React.createRef(); let fileUploadRef = React.createRef();
const onChange = useCallback(async () => { const onChange = useCallback(async () => {
await setupUserSamplesDB(fileUploadRef.current.files, (objectStore, db) => {}).then(async () => { await uploadSamplesToDB(userSamplesDBConfig, fileUploadRef.current.files).then(() => {
registerSamples(); registerSamplesFromDB(userSamplesDBConfig);
onComplete(); onComplete();
}); });
}); });
useEffect(() => { useEffect(() => {
registerSamples(); registerSamplesFromDB(userSamplesDBConfig);
}, []); }, []);
return ( return (