Public
Edited
Dec 29, 2023
Insert cell
Insert cell
Insert cell
sqliteWasm = import("https://esm.sh/@vlcn.io/crsqlite-wasm@0.16.0")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
### Let's try and do something with our DBConnection

Nice! This test passes:
```
describe "it should query" $ do
it "runs basic queryDB" do
bracket (newDB ":memory:") closeDB \db -> do
res <- queryDB db "SELECT 1 + 1" []
case runExcept $ (traverse <<< traverse) readInt =<< traverse readArray =<< readArray res of
Left err -> throwError $ error $ show err
Right ints -> ints `shouldEqual` [[2]]
```

[Committed](https://github.com/jmatsushita/purescript-wasm-sqlite/tree/b4732e1c23febb6abc979e33ddb99d7a758b1820).

Ok continued with a few more tests and modified the API to reflect the names of the JS library. Also added an example in the readme with instructions on how to run it in the browser.

![image@2.png](${await FileAttachment("image@2.png").url()})

Ok I'm happy with where it is right now. https://github.com/jmatsushita/purescript-wasm-sqlite

It would be nice to implement a selda backend with it now, but I might go straight back to [the incremental relational lenses work](https://observablehq.com/d/60ebd812c78e5fe1) since it should have unblocked me and that work should not be too strongly coupled with Selda anyway.
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
module.val
Insert cell
Insert cell
module.greet("me")
Insert cell
Insert cell
module.main()
Insert cell
Insert cell
Insert cell
ps = await Purescript(source)
Insert cell
// module = ps.module
module = (await Purescript(source)).module
Insert cell
errors = ps.errors
Insert cell
warnings = ps.warnings
Insert cell
renderCompilationStatus = (source, warnings, errors) => {
const renderedWarnings = warnings && warnings.length >0 ?
htl.html`<h3>Compiler warnings</h3><table style="max-width: none;"><thead>
<tr>${toColumns(warnings).map(col => htl.html`<th>${col}</th>`)}</tr>
</thead>
<tbody>
${toTable(warnings, source).map(row => htl.html`<tr>
${Object.values(row).map(cell => htl.html`<td><pre style="text-wrap: balance;">${cell}</pre></td>`)}
</tr>`)}
</tbody>
</table>
` : htl.html`<code>No warnings</code><br>`

const renderedErrors = errors ? htl.html`<h3>Compiler errors</h3><table style="max-width: none;">
<thead>
<tr>
${toColumns(errors).map(col => htl.html`<th>${col}</th>`)}
</tr>
</thead>
<tbody>
${toTable(errors, source).map(row => htl.html`<tr>
${Object.values(row).map(cell => htl.html`<td><pre style="text-wrap: balance;">${cell}</pre></td>`)}
</tr>`)}
</tbody>
</table>
` : htl.html`<code>No errors</code>`
return htl.html`${renderedWarnings}${renderedErrors}`
}
Insert cell
import { Purescript } from '@jmatsushita/purescript'
Insert cell
Purescript
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
PurescriptEditor = async (doc = '', extensions = []) => {
const {StreamLanguage} = await import(`https://jspm.dev/@codemirror/language@6.9.3`)
const { haskell } = await import(`https://jspm.dev/@codemirror/legacy-modes/mode/haskell`);
return CodeMirror(doc, {
extensions: [myDefaultTheme, StreamLanguage.define(haskell), ...extensions]
});
}
Insert cell
Insert cell
import {localStorageView} from '@tomlarkworthy/local-storage-view'
Insert cell
Insert cell
Insert cell
Insert cell
viewof source = localStorageView("source", { defaultValue: example })
Insert cell
// creating a fake source to subscribe from, together with a bound localStorageView didn't work.
// Uncaught TypeError: e.closest is not a function
// at inputs.min.js:40:1444
// viewof source = Inputs.input()
// viewof sourceStorage = localStorageView("sourceStorage")
// Inputs.bind(viewof source, viewof sourceStorage)
// See reproducer here https://observablehq.com/d/f7e7508476855e8b#cell-264
Insert cell
Inputs.bind(viewof editor, viewof source)
Insert cell
// Note you need to get these the right way round to have the page load work correctly
// Inputs.bind(viewof source, viewof sourceStorage)
Insert cell
// set helper
function set(input, value) {
input.value = value;
input.dispatchEvent(new Event("input", {bubbles: true}));
}
Insert cell
Insert cell
toTable = (array, source) => array ? array.map(row => objectFilter(objectMap(row, toReadableRow(source)), hideColumns)) : []
Insert cell
hideColumns = k => k !== "allSpans" && k !== "moduleName" && k !== "filename" && k !== "errorLink"
Insert cell
toColumns = array => array && array[0] ? Object.keys(array[0]).filter(hideColumns) : []
Insert cell
toReadableRow = source => (v,k) => {
switch(k) {
case "allSpans":
return JSON.stringify(v)

case "position":
// console.log(source.split("\n"))
// console.log(source.split("\n").slice(v.startLine - 1, v.endLine))
return source.split("\n").slice(v.startLine - 1, v.endLine).join("\n")
default:
return v;
}
}
Insert cell
toTable(warnings, source)
Insert cell
toColumns(warnings)
Insert cell
warnings
Insert cell
errors.contents
Insert cell
toColumns(errors.contents)
Insert cell
toTable(errors.contents, source)
Insert cell
Insert cell
Insert cell
Insert cell
function unsafe_html() {
const span = document.createElement("span");
span.innerHTML = String.raw.apply(this, arguments);
return span;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more