Skip to content

Commit eca2541

Browse files
authored
Add SQLite session and changeset extension support (#5)
* Add getUsedSize() method to calculate total open file size * add changeset * Upgrade SQLite to version 3.49.0 * fix demo * add dist * Add SQLite session and changeset extension support * add dist files
1 parent 27eb8ce commit eca2541

File tree

14 files changed

+613
-160
lines changed

14 files changed

+613
-160
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@effect-x/wa-sqlite": patch
3+
---
4+
5+
feat

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# @effect/wa-sqlite
1+
# @effect-x/wa-sqlite
22

33
## 0.1.3
44

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# dependencies
2-
SQLITE_VERSION = version-3.47.0
2+
SQLITE_VERSION = version-3.49.0
33
SQLITE_TARBALL_URL = https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=${SQLITE_VERSION}
44

55
EXTENSION_FUNCTIONS = extension-functions.c
@@ -111,6 +111,8 @@ WASQLITE_DEFINES = \
111111
-DSQLITE_THREADSAFE=0 \
112112
-DSQLITE_USE_ALLOCA \
113113
-DSQLITE_ENABLE_BATCH_ATOMIC_WRITE \
114+
-DSQLITE_ENABLE_SESSION \
115+
-DSQLITE_ENABLE_PREUPDATE_HOOK \
114116
$(WASQLITE_EXTRA_DEFINES)
115117

116118
# directories

demo/demo.js

Lines changed: 104 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,140 +2,149 @@
22

33
// This is the path to the Monaco editor distribution. For development
44
// this loads from the local server (uses Yarn 2 path).
5-
const MONACO_VS = location.hostname.endsWith('localhost') ?
6-
'/.yarn/unplugged/monaco-editor-npm-0.34.1-03d887d213/node_modules/monaco-editor/dev/vs' :
7-
'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs';
5+
const MONACO_VS =
6+
"https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs"
87

9-
const SQL_KEY = 'wa-sqlite demo sql';
8+
const SQL_KEY = "wa-sqlite demo sql"
109
const DEFAULT_SQL = `
1110
-- Optionally select statements to execute.
1211
1312
CREATE TABLE IF NOT EXISTS t(x PRIMARY KEY, y);
1413
INSERT OR REPLACE INTO t VALUES ('good', 'bad'), ('hot', 'cold'), ('up', 'down');
1514
SELECT * FROM t;
16-
`.trim();
15+
`.trim()
1716

18-
window.addEventListener('DOMContentLoaded', async function() {
17+
window.addEventListener("DOMContentLoaded", async function () {
1918
// Load the Monaco editor
20-
const button = /** @type {HTMLButtonElement} */(document.getElementById('execute'));
21-
const editorReady = createMonacoEditor().then(editor => {
19+
const button = /** @type {HTMLButtonElement} */ (
20+
document.getElementById("execute")
21+
)
22+
const editorReady = createMonacoEditor().then((editor) => {
2223
// Change the button text with selection.
23-
editor.onDidChangeCursorSelection(({selection}) => {
24-
button.textContent = selection.isEmpty() ?
25-
'Execute' :
26-
'Execute selection';
27-
});
24+
editor.onDidChangeCursorSelection(({ selection }) => {
25+
button.textContent = selection.isEmpty() ? "Execute" : "Execute selection"
26+
})
2827

2928
// Persist editor content across page loads.
30-
let change;
31-
editor.onDidChangeModelContent(function() {
32-
clearTimeout(change);
33-
change = setTimeout(function() {
34-
localStorage.setItem(SQL_KEY, editor.getValue());
35-
}, 1000);
36-
});
37-
editor.setValue(localStorage.getItem(SQL_KEY) ?? DEFAULT_SQL);
38-
39-
return editor;
40-
});
29+
let change
30+
editor.onDidChangeModelContent(function () {
31+
clearTimeout(change)
32+
change = setTimeout(function () {
33+
localStorage.setItem(SQL_KEY, editor.getValue())
34+
}, 1000)
35+
})
36+
editor.setValue(localStorage.getItem(SQL_KEY) ?? DEFAULT_SQL)
37+
38+
return editor
39+
})
4140

4241
// Start the Worker.
4342
// Propagate the main page search parameters to the Worker URL.
44-
const workerURL = new URL('./demo-worker.js', import.meta.url);
45-
workerURL.search = location.search;
46-
const worker = new Worker(workerURL, { type: 'module' });
47-
worker.addEventListener('message', function(event) {
48-
// The Worker will response with null on successful start, or with
49-
// an error message on failure.
50-
if (event.data) {
51-
document.getElementById('output').innerHTML = `<pre>${event.data.error.stack}</pre>`;
52-
} else {
53-
document.getElementById('output').innerHTML =
54-
JSON.stringify([...new URLSearchParams(location.search).entries()]);
55-
button.disabled = false;
56-
}
57-
}, { once: true });
43+
const workerURL = new URL("./demo-worker.js", import.meta.url)
44+
workerURL.search = location.search
45+
const worker = new Worker(workerURL, { type: "module" })
46+
worker.addEventListener(
47+
"message",
48+
function (event) {
49+
// The Worker will response with null on successful start, or with
50+
// an error message on failure.
51+
if (event.data) {
52+
document.getElementById("output").innerHTML =
53+
`<pre>${event.data.error.stack}</pre>`
54+
} else {
55+
document.getElementById("output").innerHTML = JSON.stringify([
56+
...new URLSearchParams(location.search).entries(),
57+
])
58+
button.disabled = false
59+
}
60+
},
61+
{ once: true },
62+
)
5863

5964
// Execute SQL on button click.
60-
button.addEventListener('click', async function() {
61-
button.disabled = true;
65+
button.addEventListener("click", async function () {
66+
button.disabled = true
6267

6368
// Get SQL from editor.
64-
const editor = await editorReady;
65-
const selection = editor.getSelection();
66-
const queries = selection.isEmpty() ?
67-
editor.getValue() :
68-
editor.getModel().getValueInRange(selection);
69+
const editor = await editorReady
70+
const selection = editor.getSelection()
71+
const queries = selection.isEmpty()
72+
? editor.getValue()
73+
: editor.getModel().getValueInRange(selection)
6974

7075
// Clear any previous output on the page.
71-
const output = document.getElementById('output');
72-
while (output.firstChild) output.removeChild(output.lastChild);
73-
74-
const timestamp = document.getElementById('timestamp');
75-
timestamp.textContent = new Date().toLocaleTimeString();
76-
77-
let time = performance.now();
78-
worker.postMessage(queries);
79-
worker.addEventListener('message', async function(event) {
80-
timestamp.textContent += ` ${(performance.now() - time).toFixed(1)} milliseconds`;
81-
if (event.data.results) {
82-
// Format the results as tables.
83-
event.data.results
84-
.map(formatTable)
85-
.forEach(table => output.append(table));
86-
} else {
87-
output.innerHTML = `<pre>${event.data.error.message}</pre>`;
88-
}
89-
button.disabled = false;
90-
}, { once: true });
91-
});
92-
});
76+
const output = document.getElementById("output")
77+
while (output.firstChild) output.removeChild(output.lastChild)
78+
79+
const timestamp = document.getElementById("timestamp")
80+
timestamp.textContent = new Date().toLocaleTimeString()
81+
82+
let time = performance.now()
83+
worker.postMessage(queries)
84+
worker.addEventListener(
85+
"message",
86+
async function (event) {
87+
timestamp.textContent += ` ${(performance.now() - time).toFixed(1)} milliseconds`
88+
if (event.data.results) {
89+
// Format the results as tables.
90+
event.data.results
91+
.map(formatTable)
92+
.forEach((table) => output.append(table))
93+
} else {
94+
output.innerHTML = `<pre>${event.data.error.message}</pre>`
95+
}
96+
button.disabled = false
97+
},
98+
{ once: true },
99+
)
100+
})
101+
})
93102

94103
async function createMonacoEditor() {
95104
// Insert a script element to bootstrap the monaco loader.
96-
await new Promise(resolve => {
97-
const loader = document.createElement('script');
98-
loader.src = `${MONACO_VS}/loader.js`;
99-
loader.async = true;
100-
loader.addEventListener('load', resolve, { once: true });
101-
document.head.appendChild(loader);
102-
});
105+
await new Promise((resolve) => {
106+
const loader = document.createElement("script")
107+
loader.src = `${MONACO_VS}/loader.js`
108+
loader.async = true
109+
loader.addEventListener("load", resolve, { once: true })
110+
document.head.appendChild(loader)
111+
})
103112

104113
// Load monaco itself.
105-
/** @type {any} */ const require = globalThis.require;
106-
require.config({ paths: { vs: MONACO_VS } });
107-
const monaco = await new Promise(resolve => {
108-
require(['vs/editor/editor.main'], resolve);
109-
});
114+
/** @type {any} */ const require = globalThis.require
115+
require.config({ paths: { vs: MONACO_VS } })
116+
const monaco = await new Promise((resolve) => {
117+
require(["vs/editor/editor.main"], resolve)
118+
})
110119

111120
// Create editor.
112121
// https://microsoft.github.io/monaco-editor/api/modules/monaco.editor.html#create
113-
return monaco.editor.create(document.getElementById('editor-container'), {
114-
language: 'sql',
122+
return monaco.editor.create(document.getElementById("editor-container"), {
123+
language: "sql",
115124
minimap: { enabled: false },
116-
automaticLayout: true
117-
});
125+
automaticLayout: true,
126+
})
118127
}
119128

120129
function formatTable({ columns, rows }) {
121-
const table = document.createElement('table');
130+
const table = document.createElement("table")
122131

123-
const thead = table.appendChild(document.createElement('thead'));
124-
thead.appendChild(formatRow(columns, 'th'));
132+
const thead = table.appendChild(document.createElement("thead"))
133+
thead.appendChild(formatRow(columns, "th"))
125134

126-
const tbody = table.appendChild(document.createElement('tbody'));
135+
const tbody = table.appendChild(document.createElement("tbody"))
127136
for (const row of rows) {
128-
tbody.appendChild(formatRow(row));
137+
tbody.appendChild(formatRow(row))
129138
}
130139

131-
return table;
140+
return table
132141
}
133142

134-
function formatRow(data, tag = 'td') {
135-
const row = document.createElement('tr');
143+
function formatRow(data, tag = "td") {
144+
const row = document.createElement("tr")
136145
for (const value of data) {
137-
const cell = row.appendChild(document.createElement(tag));
138-
cell.textContent = value !== null ? value.toString() : 'null';
146+
const cell = row.appendChild(document.createElement(tag))
147+
cell.textContent = value !== null ? value.toString() : "null"
139148
}
140-
return row;
141-
}
149+
return row
150+
}

dist/wa-sqlite-async.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/wa-sqlite-async.wasm

53.6 KB
Binary file not shown.

dist/wa-sqlite-jspi.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/wa-sqlite-jspi.wasm

23.3 KB
Binary file not shown.

dist/wa-sqlite.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/wa-sqlite.wasm

23.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)