Changeset View
Changeset View
Standalone View
Standalone View
web/database/worker/db-worker.js
// @flow | // @flow | ||||
import localforage from 'localforage'; | import localforage from 'localforage'; | ||||
import initSqlJs from 'sql.js'; | |||||
import { | import { | ||||
type SharedWorkerMessageEvent, | type SharedWorkerMessageEvent, | ||||
type WorkerRequestMessage, | type WorkerRequestMessage, | ||||
type WorkerResponseMessage, | type WorkerResponseMessage, | ||||
workerRequestMessageTypes, | workerRequestMessageTypes, | ||||
workerResponseMessageTypes, | workerResponseMessageTypes, | ||||
type WorkerRequestProxyMessage, | type WorkerRequestProxyMessage, | ||||
} from '../../types/worker-types.js'; | } from '../../types/worker-types.js'; | ||||
import { SQLITE_CONTENT } from '../utils/constants.js'; | |||||
const localforageConfig: PartialConfig = { | const localforageConfig: PartialConfig = { | ||||
driver: localforage.INDEXEDDB, | driver: localforage.INDEXEDDB, | ||||
name: 'comm', | name: 'comm', | ||||
storeName: 'commStorage', | storeName: 'commStorage', | ||||
description: 'Comm encrypted database storage', | description: 'Comm encrypted database storage', | ||||
version: '1.0', | version: '1.0', | ||||
}; | }; | ||||
localforage.config(localforageConfig); | localforage.config(localforageConfig); | ||||
function processAppRequest( | let sqliteDb = null; | ||||
async function initDatabase(sqljsFilePath: string, sqljsFilename: ?string) { | |||||
const content = await localforage.getItem(SQLITE_CONTENT); | |||||
const locateFile = defaultFilename => { | |||||
if (sqljsFilename) { | |||||
return `${sqljsFilePath}/${sqljsFilename}`; | |||||
} | |||||
return `${sqljsFilePath}/${defaultFilename}`; | |||||
}; | |||||
const SQL = await initSqlJs({ | |||||
locateFile, | |||||
}); | |||||
if (content) { | |||||
sqliteDb = new SQL.Database(new Uint8Array(content)); | |||||
} else { | |||||
sqliteDb = new SQL.Database(); | |||||
} | |||||
const versionData = sqliteDb.exec('PRAGMA user_version;'); | |||||
if (versionData.length && versionData[0].values.length) { | |||||
console.info(`Db version: ${versionData[0].values[0]}`); | |||||
} else { | |||||
throw new Error('Error while retrieving database version'); | |||||
} | |||||
} | |||||
async function processAppRequest( | |||||
message: WorkerRequestMessage, | message: WorkerRequestMessage, | ||||
): ?WorkerResponseMessage { | ): Promise<?WorkerResponseMessage> { | ||||
if (message.type === workerRequestMessageTypes.PING) { | if (message.type === workerRequestMessageTypes.PING) { | ||||
return { | return { | ||||
type: workerResponseMessageTypes.PONG, | type: workerResponseMessageTypes.PONG, | ||||
text: 'PONG', | text: 'PONG', | ||||
}; | }; | ||||
} else if (message.type === workerRequestMessageTypes.INIT) { | |||||
await initDatabase(message.sqljsFilePath, message.sqljsFilename); | |||||
return; | |||||
} | } | ||||
throw new Error('Request type not supported'); | throw new Error('Request type not supported'); | ||||
} | } | ||||
function connectHandler(event: SharedWorkerMessageEvent) { | function connectHandler(event: SharedWorkerMessageEvent) { | ||||
if (!event.ports.length) { | if (!event.ports.length) { | ||||
return; | return; | ||||
} | } | ||||
const port: MessagePort = event.ports[0]; | const port: MessagePort = event.ports[0]; | ||||
console.log('Web database worker alive!'); | console.log('Web database worker alive!'); | ||||
port.onmessage = async function (messageEvent: MessageEvent) { | port.onmessage = async function (messageEvent: MessageEvent) { | ||||
const data: WorkerRequestProxyMessage = (messageEvent.data: any); | const data: WorkerRequestProxyMessage = (messageEvent.data: any); | ||||
const { id, message } = data; | const { id, message } = data; | ||||
if (!id) { | if (!id) { | ||||
port.postMessage({ | port.postMessage({ | ||||
error: new Error('Request without identifier'), | error: new Error('Request without identifier'), | ||||
}); | }); | ||||
} | } | ||||
try { | try { | ||||
const result = processAppRequest(message); | const result = await processAppRequest(message); | ||||
port.postMessage({ | port.postMessage({ | ||||
id, | id, | ||||
message: result, | message: result, | ||||
}); | }); | ||||
} catch (e) { | } catch (e) { | ||||
port.postMessage({ | port.postMessage({ | ||||
id, | id, | ||||
error: e, | error: e, | ||||
}); | }); | ||||
} | } | ||||
}; | }; | ||||
} | } | ||||
self.addEventListener('connect', connectHandler); | self.addEventListener('connect', connectHandler); |