@queryweave/core
Owns the domain vocabulary: parameters, codecs, models, decode results, issues, and the runtime.
Define your query model once. Decode, validate, encode, synchronize, and reuse it across browsers, servers, Node.js, and framework adapters.
pnpm add @queryweave/corev0.1.0-alpha.1 is the current source version
?search=vue&page=2{ search: "vue", page: 2 }search=vue&page=2History1 / 1
The adapter writes through the History API and re-reads on popstate.
Type a query, press Enter.
Typed state
{
"page": 1,
"sort": "created_at",
"status": "all"
}Canonical URL
Valid/productsDefine the query parameters your page accepts. Each one describes how to decode and encode its value, so you never maintain a separate parser and serializer.
import { defineQueryModel, param } from "@queryweave/core";
const products = defineQueryModel({ search: param.text().optional(), page: param.integer({ min: 1 }).default(1), sort: param.choice(["name", "created_at", "price"]).default("created_at"),});Call decode() with a query string and you get typed values back. page is a number here, not
the string "2". An invalid value recovers to its default and is reported as an issue — it never
throws and never disappears silently.
const result = products.decode("?search=vue&page=2");
if (result.ok) { result.value.page; // 2, typed as number} else { result.partial; // the keys that did decode result.issues; // why the rest did not}A runtime wires your model to a specific environment. The adapter handles navigation and reports URL changes. Validation stays in the model, not the adapter.
import { createBrowserAdapter } from "@queryweave/browser";import { createQueryRuntime } from "@queryweave/core";
const runtime = createQueryRuntime({ model: products, adapter: createBrowserAdapter(),});
await runtime.update({ search: "vue" });await runtime.update({ page: 2 }, { navigation: "replace" });Use the same model on the server, in the browser, and in Vue. The model has no framework dependencies, so you define it once and import it wherever the query appears.
// A request, on any web-standard runtime.import { readRequestQuery } from "@queryweave/server";
const decoded = readRequestQuery(request, products);
// The same model, bound to Vue reactivity.import { useQueryModel } from "@queryweave/vue";
const filters = useQueryModel(products);The model defines parameters, defaults, validation, and canonical encoding. Adapters handle where the query lives and how navigation works. You pick the adapter; the model stays the same.
QueryWeave package dependency map. Core is the shared foundation. Node builds on the server package. Nuxt builds on the Vue and Vue Router packages.
Node request bridge → Web server helpers. Nuxt integration → Vue bindings. Nuxt integration → Vue Router adapter.
One framework-independent foundation, eight focused integrations. Choose a package to trace the thread it adds.
Owns the domain vocabulary: parameters, codecs, models, decode results, issues, and the runtime.
Synchronizes a runtime with the History API and reports `popstate` changes.
Decodes and builds queries from web-standard `Request` and `URL` values.
Resolves an absolute URL from a Node request and delegates decoding.
Provides the memory adapter every other package is tested against.
Turns any Standard Schema validator into a QueryWeave refinement.
Binds one model to Vue reactivity with readonly values and explicit operations.
Turns a Vue Router instance into an adapter, preserving path and hash.
Registers a request-scoped runtime plugin and the Vue auto-imports.
QueryWeave 0.1.0-alpha.1 is experimental and pre-1.0. The public API may change between minor versions, every breaking change is recorded in an architecture decision record, and the packages are not on npm yet. See the roadmap for what is deliberately absent.