|
|
@ -78,7 +78,7 @@ function App() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function handleQuery() {
|
|
|
|
function handleQuery() {
|
|
|
|
if (!db) {
|
|
|
|
if (!db || inProgress) {
|
|
|
|
setInProgress(false);
|
|
|
|
setInProgress(false);
|
|
|
|
setErrorMessage([]);
|
|
|
|
setErrorMessage([]);
|
|
|
|
setStatusMessage(['database not ready']);
|
|
|
|
setStatusMessage(['database not ready']);
|
|
|
@ -92,38 +92,42 @@ function App() {
|
|
|
|
setErrorMessage([]);
|
|
|
|
setErrorMessage([]);
|
|
|
|
setStatusMessage('');
|
|
|
|
setStatusMessage('');
|
|
|
|
setQueryResults(null);
|
|
|
|
setQueryResults(null);
|
|
|
|
try {
|
|
|
|
requestAnimationFrame(() => {
|
|
|
|
const t0 = performance.now();
|
|
|
|
setTimeout(() => {
|
|
|
|
const res_str = db.run(query, params);
|
|
|
|
try {
|
|
|
|
const t1 = performance.now();
|
|
|
|
const t0 = performance.now();
|
|
|
|
const res = JSON.parse(res_str);
|
|
|
|
const res_str = db.run(query, params);
|
|
|
|
if (res.ok) {
|
|
|
|
const t1 = performance.now();
|
|
|
|
setStatusMessage(`finished with ${res.rows.length} rows in ${(t1 - t0).toFixed(1)}ms`);
|
|
|
|
const res = JSON.parse(res_str);
|
|
|
|
if (!res.headers) {
|
|
|
|
if (res.ok) {
|
|
|
|
res.headers = [];
|
|
|
|
setStatusMessage(`finished with ${res.rows.length} rows in ${(t1 - t0).toFixed(1)}ms`);
|
|
|
|
if (res.rows.length) {
|
|
|
|
if (!res.headers) {
|
|
|
|
for (let i = 0; i < res.rows[0].length; i++) {
|
|
|
|
res.headers = [];
|
|
|
|
res.headers.push('' + i);
|
|
|
|
if (res.rows.length) {
|
|
|
|
|
|
|
|
for (let i = 0; i < res.rows[0].length; i++) {
|
|
|
|
|
|
|
|
res.headers.push('' + i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.error('Query failed', res);
|
|
|
|
|
|
|
|
setStatusMessage(`finished with errors`);
|
|
|
|
|
|
|
|
if (res.display) {
|
|
|
|
|
|
|
|
const messages = parse(res.display);
|
|
|
|
|
|
|
|
setErrorMessage(messages.spans);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
setErrorMessage([res.message]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setQueryResults(res);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
setStatusMessage(`query failed`);
|
|
|
|
|
|
|
|
setErrorMessage(['' + e]);
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
setInProgress(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
}, 0)
|
|
|
|
console.error('Query failed', res);
|
|
|
|
})
|
|
|
|
setStatusMessage(`finished with errors`);
|
|
|
|
|
|
|
|
if (res.display) {
|
|
|
|
|
|
|
|
const messages = parse(res.display);
|
|
|
|
|
|
|
|
setErrorMessage(messages.spans);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
setErrorMessage([res.message]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setQueryResults(res);
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
setStatusMessage(`query failed`);
|
|
|
|
|
|
|
|
setErrorMessage(['' + e]);
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
setInProgress(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -157,7 +161,7 @@ function App() {
|
|
|
|
<div style={{paddingTop: 10, display: 'flex', flexDirection: 'row'}}>
|
|
|
|
<div style={{paddingTop: 10, display: 'flex', flexDirection: 'row'}}>
|
|
|
|
<Button
|
|
|
|
<Button
|
|
|
|
icon="play"
|
|
|
|
icon="play"
|
|
|
|
text={db ? "Run script" : "Loading WASM ..."}
|
|
|
|
text={db ? (inProgress ? "Query is running" : "Run script") : "Loading WASM ..."}
|
|
|
|
onClick={() => handleQuery()}
|
|
|
|
onClick={() => handleQuery()}
|
|
|
|
disabled={!db || inProgress}
|
|
|
|
disabled={!db || inProgress}
|
|
|
|
intent={Intent.PRIMARY}
|
|
|
|
intent={Intent.PRIMARY}
|
|
|
@ -211,7 +215,7 @@ function App() {
|
|
|
|
cellRenderer={renderCell(idx)}
|
|
|
|
cellRenderer={renderCell(idx)}
|
|
|
|
/>)}
|
|
|
|
/>)}
|
|
|
|
</Table2> : null) : null}
|
|
|
|
</Table2> : null) : null}
|
|
|
|
{!(queryResults || errorMessage.length) && <div id="welcome">
|
|
|
|
{!(queryResults || errorMessage.length || inProgress) && <div id="welcome">
|
|
|
|
<p>
|
|
|
|
<p>
|
|
|
|
This is the demo page for Cozo running in your browser as
|
|
|
|
This is the demo page for Cozo running in your browser as
|
|
|
|
a <a href="https://webassembly.org/">Web assembly</a> module.
|
|
|
|
a <a href="https://webassembly.org/">Web assembly</a> module.
|
|
|
@ -259,6 +263,7 @@ function ImportUrl({db}) {
|
|
|
|
let content = await resp.text();
|
|
|
|
let content = await resp.text();
|
|
|
|
const res = JSON.parse(db.import_relations(content));
|
|
|
|
const res = JSON.parse(db.import_relations(content));
|
|
|
|
if (res.ok) {
|
|
|
|
if (res.ok) {
|
|
|
|
|
|
|
|
AppToaster.show({message: "Imported", intent: Intent.SUCCESS})
|
|
|
|
handleClose()
|
|
|
|
handleClose()
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
AppToaster.show({message: res.message, intent: Intent.DANGER})
|
|
|
|
AppToaster.show({message: res.message, intent: Intent.DANGER})
|
|
|
@ -310,6 +315,7 @@ function ImportFile({db}) {
|
|
|
|
let content = await file.text();
|
|
|
|
let content = await file.text();
|
|
|
|
const res = JSON.parse(db.import_relations(content));
|
|
|
|
const res = JSON.parse(db.import_relations(content));
|
|
|
|
if (res.ok) {
|
|
|
|
if (res.ok) {
|
|
|
|
|
|
|
|
AppToaster.show({message: "Imported", intent: Intent.SUCCESS})
|
|
|
|
handleClose()
|
|
|
|
handleClose()
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
AppToaster.show({message: res.message, intent: Intent.DANGER})
|
|
|
|
AppToaster.show({message: res.message, intent: Intent.DANGER})
|
|
|
@ -370,6 +376,7 @@ function Export({db}) {
|
|
|
|
if (res.ok) {
|
|
|
|
if (res.ok) {
|
|
|
|
const blob = new Blob([JSON.stringify(res.data)], {type: "text/plain;charset=utf-8"});
|
|
|
|
const blob = new Blob([JSON.stringify(res.data)], {type: "text/plain;charset=utf-8"});
|
|
|
|
saveAs(blob, "export.json");
|
|
|
|
saveAs(blob, "export.json");
|
|
|
|
|
|
|
|
AppToaster.show({message: "Exported", intent: Intent.SUCCESS})
|
|
|
|
handleClose()
|
|
|
|
handleClose()
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
AppToaster.show({message: res.message, intent: Intent.DANGER})
|
|
|
|
AppToaster.show({message: res.message, intent: Intent.DANGER})
|
|
|
|