fix(web): bind query parameters, and set the URL without the router

Two failures, both reaching a browser for the first time now that the
database actually opens.

Parameters never reached SQLite. The worker forwards its arguments
straight to sql.js:

  this.db.query = (...args) => toObjects(this.db.exec(...args))

and exec(sql, params) takes the whole parameter list as its second
argument, ignoring anything that is not an array. Spreading them handed
it a bare string, so every ? stayed unbound and read as NULL: the exam
id lookup failed on LIMIT NULL with "datatype mismatch", and name search
quietly matched nothing. The library's own type says ...params and is
wrong about its own implementation.

The address bar update went through SvelteKit's replaceState, which
reaches into the client router's root component. That is undefined until
the router has initialized, and the call then fails inside SvelteKit
with "Cannot read properties of undefined (reading '$set')"
(sveltejs/kit#12204). The native History API does the same job; passing
the current history.state back unchanged leaves SvelteKit's own
bookkeeping intact, and nothing reads page.url after the initial deep
link.
This commit is contained in:
tiennm99 committed 2026-08-14 16:25:24 +07:00
1 parent 6ab7c1f855
commit 70374f1274
2 files changed
+13 -6

No files matched your search

+6 -1
View File
@@ -124,7 +124,12 @@ export class RemoteDatabase {
const worker = this.#worker ?? (await this.#opening);
const started = performance.now();
try {
return await worker.db.query(sql, ...params);
// One array argument, never spread. The worker forwards its arguments to
// sql.js's exec(sql, params), which takes the whole parameter list as its
// second argument and ignores anything that is not an array — leaving
// every ? unbound, which reads as NULL. The library's own type says
// `...params`, and it is wrong.
return await worker.db.query(sql, params);
} finally {
await this.#account(worker, label ?? firstLine(sql), performance.now() - started);
}
+7 -5
View File
@@ -1,6 +1,5 @@
<script>
import { browser } from "$app/environment";
import { replaceState } from "$app/navigation";
import { base, resolve } from "$app/paths";
import { page } from "$app/state";
import CustomQuery from "$lib/components/custom-query.svelte";
@@ -54,10 +53,13 @@
// the page and a copied URL still reproduces the search.
function writeUrlQuery(q) {
const route = resolve("/[dataset]", { dataset: dataset.id });
// The target IS resolve()'d; the lint rule cannot see through the template
// literal that appends the query string.
// eslint-disable-next-line svelte/no-navigation-without-resolve
replaceState(q ? `${route}?q=${encodeURIComponent(q)}` : route, page.state);
// The native History API rather than SvelteKit's replaceState: that one
// reaches into the client router's root component, which is undefined
// until the router has initialized, and then fails inside its own
// internals (sveltejs/kit#12204). Passing the current history.state back
// unchanged leaves SvelteKit's history bookkeeping intact, and nothing
// here reads page.url after the initial deep link.
history.replaceState(history.state, "", q ? `${route}?q=${encodeURIComponent(q)}` : route);
}
async function search(q) {