[{"data":1,"prerenderedAt":791},["ShallowReactive",2],{"blog-slugs":3,"project-queryweave-en":8},{"en":4,"ar":7},[5,6],"dynamic-generic-slots","from-renderless-component-to-composable-function",[5,6],{"id":9,"title":10,"body":11,"description":784,"extension":785,"meta":786,"navigation":83,"path":787,"seo":788,"stem":789,"__hash__":790},"projects/projects/en/queryweave.md","QueryWeave",{"type":12,"value":13,"toc":777},"minimark",[14,19,23,27,30,486,496,500,608,611,615,756,763,767,770,773],[15,16,18],"h2",{"id":17},"the-problem","The problem",[20,21,22],"p",{},"URL state shows up in the browser, on the server, in tests and in shared links. Most codebases describe it more than once: a client parser, a server parser, a serializer, and defaults repeated in each. Those copies drift apart.",[15,24,26],{"id":25},"one-model-synced-through-adapters","One model, synced through adapters",[20,28,29],{},"QueryWeave defines query state once, as a model, and syncs it through adapters. Every environment runs the same pipeline: the query string is decoded, validated into typed state, updated, and written back in a canonical encoding.",[31,32,37],"pre",{"className":33,"code":34,"language":35,"meta":36,"style":36},"language-ts shiki shiki-themes site-light site-light site-dark","import { createQueryRuntime, defineQueryModel, param } from '@queryweave/core'\n\nconst productFilters = defineQueryModel({\n  search: param.text().optional(),\n  page: param.integer({ min: 1 }).default(1),\n  archived: param.boolean().default(false),\n  sort: param.choice(['name', 'created_at', 'price']).default('created_at'),\n  tags: param.list(param.text()).default([]),\n})\n\nconst runtime = createQueryRuntime({ model: productFilters, adapter })\n\nruntime.read().values.page // 1\n\nawait runtime.update({ search: 'vue', page: 1 })\nawait runtime.update({ page: 2 }, { navigation: 'replace' })\n\nawait runtime.transaction((draft) => {\n  draft.search = 'vue'\n  draft.page = 1\n})\n","ts","",[38,39,40,78,85,105,133,174,200,243,275,281,286,314,319,344,349,384,419,424,451,467,481],"code",{"__ignoreMap":36},[41,42,45,49,53,57,60,63,65,68,71,74],"span",{"class":43,"line":44},"line",1,[41,46,48],{"class":47},"sZ9Zp","import",[41,50,52],{"class":51},"sXnUm"," {",[41,54,56],{"class":55},"sBiod"," createQueryRuntime",[41,58,59],{"class":51},",",[41,61,62],{"class":55}," defineQueryModel",[41,64,59],{"class":51},[41,66,67],{"class":55}," param ",[41,69,70],{"class":51},"}",[41,72,73],{"class":47}," from",[41,75,77],{"class":76},"sgVH1"," '@queryweave/core'\n",[41,79,81],{"class":43,"line":80},2,[41,82,84],{"emptyLinePlaceholder":83},true,"\n",[41,86,88,91,95,99,102],{"class":43,"line":87},3,[41,89,90],{"class":47},"const",[41,92,94],{"class":93},"sJ-0L"," productFilters",[41,96,98],{"class":97},"sZ7qJ"," =",[41,100,62],{"class":101},"sUqqj",[41,103,104],{"class":51},"({\n",[41,106,108,112,115,118,121,124,127,130],{"class":43,"line":107},4,[41,109,111],{"class":110},"snYWn","  search",[41,113,114],{"class":51},":",[41,116,117],{"class":55}," param",[41,119,120],{"class":51},".",[41,122,123],{"class":101},"text",[41,125,126],{"class":51},"().",[41,128,129],{"class":101},"optional",[41,131,132],{"class":51},"(),\n",[41,134,136,139,141,143,145,148,151,154,156,159,162,165,168,171],{"class":43,"line":135},5,[41,137,138],{"class":110},"  page",[41,140,114],{"class":51},[41,142,117],{"class":55},[41,144,120],{"class":51},[41,146,147],{"class":101},"integer",[41,149,150],{"class":51},"({",[41,152,153],{"class":110}," min",[41,155,114],{"class":51},[41,157,158],{"class":93}," 1",[41,160,161],{"class":51}," }).",[41,163,164],{"class":101},"default",[41,166,167],{"class":51},"(",[41,169,170],{"class":93},"1",[41,172,173],{"class":51},"),\n",[41,175,177,180,182,184,186,189,191,193,195,198],{"class":43,"line":176},6,[41,178,179],{"class":110},"  archived",[41,181,114],{"class":51},[41,183,117],{"class":55},[41,185,120],{"class":51},[41,187,188],{"class":101},"boolean",[41,190,126],{"class":51},[41,192,164],{"class":101},[41,194,167],{"class":51},[41,196,197],{"class":93},"false",[41,199,173],{"class":51},[41,201,203,206,208,210,212,215,218,221,223,226,228,231,234,236,238,241],{"class":43,"line":202},7,[41,204,205],{"class":110},"  sort",[41,207,114],{"class":51},[41,209,117],{"class":55},[41,211,120],{"class":51},[41,213,214],{"class":101},"choice",[41,216,217],{"class":51},"([",[41,219,220],{"class":76},"'name'",[41,222,59],{"class":51},[41,224,225],{"class":76}," 'created_at'",[41,227,59],{"class":51},[41,229,230],{"class":76}," 'price'",[41,232,233],{"class":51},"]).",[41,235,164],{"class":101},[41,237,167],{"class":51},[41,239,240],{"class":76},"'created_at'",[41,242,173],{"class":51},[41,244,246,249,251,253,255,258,260,263,265,267,270,272],{"class":43,"line":245},8,[41,247,248],{"class":110},"  tags",[41,250,114],{"class":51},[41,252,117],{"class":55},[41,254,120],{"class":51},[41,256,257],{"class":101},"list",[41,259,167],{"class":51},[41,261,262],{"class":55},"param",[41,264,120],{"class":51},[41,266,123],{"class":101},[41,268,269],{"class":51},"()).",[41,271,164],{"class":101},[41,273,274],{"class":51},"([]),\n",[41,276,278],{"class":43,"line":277},9,[41,279,280],{"class":51},"})\n",[41,282,284],{"class":43,"line":283},10,[41,285,84],{"emptyLinePlaceholder":83},[41,287,289,291,294,296,298,300,303,305,307,309,312],{"class":43,"line":288},11,[41,290,90],{"class":47},[41,292,293],{"class":93}," runtime",[41,295,98],{"class":97},[41,297,56],{"class":101},[41,299,150],{"class":51},[41,301,302],{"class":110}," model",[41,304,114],{"class":51},[41,306,94],{"class":55},[41,308,59],{"class":51},[41,310,311],{"class":55}," adapter ",[41,313,280],{"class":51},[41,315,317],{"class":43,"line":316},12,[41,318,84],{"emptyLinePlaceholder":83},[41,320,322,325,327,330,332,335,337,340],{"class":43,"line":321},13,[41,323,324],{"class":55},"runtime",[41,326,120],{"class":51},[41,328,329],{"class":101},"read",[41,331,126],{"class":51},[41,333,334],{"class":110},"values",[41,336,120],{"class":51},[41,338,339],{"class":110},"page",[41,341,343],{"class":342},"s5c__"," // 1\n",[41,345,347],{"class":43,"line":346},14,[41,348,84],{"emptyLinePlaceholder":83},[41,350,352,355,357,359,362,364,367,369,372,374,377,379,381],{"class":43,"line":351},15,[41,353,354],{"class":47},"await",[41,356,293],{"class":55},[41,358,120],{"class":51},[41,360,361],{"class":101},"update",[41,363,150],{"class":51},[41,365,366],{"class":110}," search",[41,368,114],{"class":51},[41,370,371],{"class":76}," 'vue'",[41,373,59],{"class":51},[41,375,376],{"class":110}," page",[41,378,114],{"class":51},[41,380,158],{"class":93},[41,382,383],{"class":51}," })\n",[41,385,387,389,391,393,395,397,399,401,404,407,409,412,414,417],{"class":43,"line":386},16,[41,388,354],{"class":47},[41,390,293],{"class":55},[41,392,120],{"class":51},[41,394,361],{"class":101},[41,396,150],{"class":51},[41,398,376],{"class":110},[41,400,114],{"class":51},[41,402,403],{"class":93}," 2",[41,405,406],{"class":51}," },",[41,408,52],{"class":51},[41,410,411],{"class":110}," navigation",[41,413,114],{"class":51},[41,415,416],{"class":76}," 'replace'",[41,418,383],{"class":51},[41,420,422],{"class":43,"line":421},17,[41,423,84],{"emptyLinePlaceholder":83},[41,425,427,429,431,433,436,439,442,445,448],{"class":43,"line":426},18,[41,428,354],{"class":47},[41,430,293],{"class":55},[41,432,120],{"class":51},[41,434,435],{"class":101},"transaction",[41,437,438],{"class":51},"((",[41,440,441],{"class":55},"draft",[41,443,444],{"class":51},")",[41,446,447],{"class":47}," =>",[41,449,450],{"class":51}," {\n",[41,452,454,457,459,462,464],{"class":43,"line":453},19,[41,455,456],{"class":55},"  draft",[41,458,120],{"class":51},[41,460,461],{"class":110},"search",[41,463,98],{"class":97},[41,465,466],{"class":76}," 'vue'\n",[41,468,470,472,474,476,478],{"class":43,"line":469},20,[41,471,456],{"class":55},[41,473,120],{"class":51},[41,475,339],{"class":110},[41,477,98],{"class":97},[41,479,480],{"class":93}," 1\n",[41,482,484],{"class":43,"line":483},21,[41,485,280],{"class":51},[20,487,488,489,492,493,495],{},"A broken link does not crash the page. ",[38,490,491],{},"?page=abc"," decodes to page ",[38,494,170],{},", and the result carries an issue explaining why, so the application can recover and tell the user.",[15,497,499],{"id":498},"vue-bindings","Vue bindings",[31,501,503],{"className":33,"code":502,"language":35,"meta":36,"style":36},"const filters = useQueryModel(productFilters)\n\nfilters.values.page // readonly reactive state\nawait filters.update({ page: 2 }) // explicit operation\n\nconst search = filters.field('search', { navigation: 'replace' }) // v-model target\n",[38,504,505,525,529,545,569,573],{"__ignoreMap":36},[41,506,507,509,512,514,517,519,522],{"class":43,"line":44},[41,508,90],{"class":47},[41,510,511],{"class":93}," filters",[41,513,98],{"class":97},[41,515,516],{"class":101}," useQueryModel",[41,518,167],{"class":51},[41,520,521],{"class":55},"productFilters",[41,523,524],{"class":51},")\n",[41,526,527],{"class":43,"line":80},[41,528,84],{"emptyLinePlaceholder":83},[41,530,531,534,536,538,540,542],{"class":43,"line":87},[41,532,533],{"class":55},"filters",[41,535,120],{"class":51},[41,537,334],{"class":110},[41,539,120],{"class":51},[41,541,339],{"class":110},[41,543,544],{"class":342}," // readonly reactive state\n",[41,546,547,549,551,553,555,557,559,561,563,566],{"class":43,"line":107},[41,548,354],{"class":47},[41,550,511],{"class":55},[41,552,120],{"class":51},[41,554,361],{"class":101},[41,556,150],{"class":51},[41,558,376],{"class":110},[41,560,114],{"class":51},[41,562,403],{"class":93},[41,564,565],{"class":51}," })",[41,567,568],{"class":342}," // explicit operation\n",[41,570,571],{"class":43,"line":135},[41,572,84],{"emptyLinePlaceholder":83},[41,574,575,577,579,581,583,585,588,590,593,595,597,599,601,603,605],{"class":43,"line":176},[41,576,90],{"class":47},[41,578,366],{"class":93},[41,580,98],{"class":97},[41,582,511],{"class":55},[41,584,120],{"class":51},[41,586,587],{"class":101},"field",[41,589,167],{"class":51},[41,591,592],{"class":76},"'search'",[41,594,59],{"class":51},[41,596,52],{"class":51},[41,598,411],{"class":110},[41,600,114],{"class":51},[41,602,416],{"class":76},[41,604,565],{"class":51},[41,606,607],{"class":342}," // v-model target\n",[20,609,610],{},"There is no hook per key, no tuple setter, and no direct mutation as the primary API. Vue and Nuxt are the first frontend integrations, but neither shapes the core.",[15,612,614],{"id":613},"nine-packages","Nine packages",[616,617,618,635],"table",{},[619,620,621],"thead",{},[622,623,624,628,631],"tr",{},[625,626,627],"th",{},"Package",[625,629,630],{},"Responsibility",[625,632,634],{"align":633},"right","min+gzip",[636,637,638,652,665,678,691,704,717,730,743],"tbody",{},[622,639,640,646,649],{},[641,642,643],"td",{},[38,644,645],{},"@queryweave/core",[641,647,648],{},"Models, codecs, decode and encode, runtime contracts",[641,650,651],{"align":633},"7.39 kB",[622,653,654,659,662],{},[641,655,656],{},[38,657,658],{},"@queryweave/browser",[641,660,661],{},"Browser History API adapter",[641,663,664],{"align":633},"564 B",[622,666,667,672,675],{},[641,668,669],{},[38,670,671],{},"@queryweave/server",[641,673,674],{},"Web-standard server helpers",[641,676,677],{"align":633},"469 B",[622,679,680,685,688],{},[641,681,682],{},[38,683,684],{},"@queryweave/node",[641,686,687],{},"Node.js request integration",[641,689,690],{"align":633},"691 B",[622,692,693,698,701],{},[641,694,695],{},[38,696,697],{},"@queryweave/standard-schema",[641,699,700],{},"Standard Schema interoperability",[641,702,703],{"align":633},"341 B",[622,705,706,711,714],{},[641,707,708],{},[38,709,710],{},"@queryweave/testing",[641,712,713],{},"Memory adapter and test utilities",[641,715,716],{"align":633},"491 B",[622,718,719,724,727],{},[641,720,721],{},[38,722,723],{},"@queryweave/vue",[641,725,726],{},"Vue bindings for query models",[641,728,729],{"align":633},"850 B",[622,731,732,737,740],{},[641,733,734],{},[38,735,736],{},"@queryweave/vue-router",[641,738,739],{},"Vue Router adapter",[641,741,742],{"align":633},"699 B",[622,744,745,750,753],{},[641,746,747],{},[38,748,749],{},"@queryweave/nuxt",[641,751,752],{},"Nuxt module and per-request runtime",[641,754,755],{"align":633},"911 B",[20,757,758,759,762],{},"The budgets are enforced: ",[38,760,761],{},"pnpm bundle:size:check"," fails when a package grows past its limit.",[15,764,766],{"id":765},"testing","Testing",[20,768,769],{},"The full gate runs every Vitest project, including Vitest Browser Mode and type-level assertions, real-browser tests in Chromium, Firefox and WebKit, and Playwright against the playground. Boundary checks cover sources, manifests and the dependency graph; artifact checks cover the built output and declaration resolution; and the packed archives are installed into clean consumer projects before a release.",[20,771,772],{},"The project is experimental and pre-1.0: the public API may change between minor versions, and every breaking change is recorded in an architecture decision record and a changeset.",[774,775,776],"style",{},"html pre.shiki code .sZ9Zp, html code.shiki .sZ9Zp{--shiki-light:#994920;--shiki-default:#994920;--shiki-dark:#ECA457}html pre.shiki code .sXnUm, html code.shiki .sXnUm{--shiki-light:#6D6863;--shiki-default:#6D6863;--shiki-dark:#96918C}html pre.shiki code .sBiod, html code.shiki .sBiod{--shiki-light:#322C28;--shiki-default:#322C28;--shiki-dark:#DBD7D0}html pre.shiki code .sgVH1, html code.shiki .sgVH1{--shiki-light:#3A6830;--shiki-default:#3A6830;--shiki-dark:#A5CF93}html pre.shiki code .sJ-0L, html code.shiki .sJ-0L{--shiki-light:#2D54A0;--shiki-default:#2D54A0;--shiki-dark:#93BDF5}html pre.shiki code .sZ7qJ, html code.shiki .sZ7qJ{--shiki-light:#6D6863;--shiki-default:#6D6863;--shiki-dark:#A39E98}html pre.shiki code .sUqqj, html code.shiki .sUqqj{--shiki-light:#4A3170;--shiki-default:#4A3170;--shiki-dark:#D9BDF0}html pre.shiki code .snYWn, html code.shiki .snYWn{--shiki-light:#624727;--shiki-default:#624727;--shiki-dark:#E2C69F}html pre.shiki code .s5c__, html code.shiki .s5c__{--shiki-light:#736D67;--shiki-light-font-style:italic;--shiki-default:#736D67;--shiki-default-font-style:italic;--shiki-dark:#979189;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":36,"searchDepth":80,"depth":80,"links":778},[779,780,781,782,783],{"id":17,"depth":80,"text":18},{"id":25,"depth":80,"text":26},{"id":498,"depth":80,"text":499},{"id":613,"depth":80,"text":614},{"id":765,"depth":80,"text":766},"A framework-independent, type-safe URL state engine.","md",{},"/projects/en/queryweave",{"title":10,"description":784},"projects/en/queryweave","dQ0WT3LWg2PTNErvSM5kd46VQ6EQw38a7xdHop5seTo",1791794146535]