[{"data":1,"prerenderedAt":789},["ShallowReactive",2],{"blog-slugs":3,"project-queryweave-ar":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":782,"extension":783,"meta":784,"navigation":82,"path":785,"seo":786,"stem":787,"__hash__":788},"projects/projects/ar/queryweave.md","QueryWeave",{"type":12,"value":13,"toc":775},"minimark",[14,18,22,26,29,485,495,499,607,610,614,755,762,765,768,771],[15,16,17],"h2",{"id":17},"المشكلة",[19,20,21],"p",{},"حالة عنوان URL حاضرة في أكثر من موضع: في المتصفح، وعلى الخادم، وفي الاختبارات، وفي الروابط التي يتبادلها المستخدمون. وفي أغلب المشاريع تُوصف هذه الحالة أكثر من مرة: دالة تقرؤها في المتصفح، وأخرى على الخادم، وثالثة تكتبها، وقيم افتراضية مكرّرة في كل واحدة. ومع الوقت تختلف هذه النسخ.",[15,23,25],{"id":24},"نموذج-واحد-ومحوّلات","نموذج واحد ومحوّلات",[19,27,28],{},"في QueryWeave تُعرَّف حالة الاستعلام مرة واحدة في نموذج، ويتولّى محوّل لكل بيئة مزامنتها. والمسار واحد في كل البيئات: يُقرأ نص الاستعلام، ويُتحقَّق منه فيصير حالة محدَّدة الأنواع، ثم تُحدَّث الحالة، ثم تُكتب في العنوان بصيغة قياسية.",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"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","",[37,38,39,77,84,104,132,173,199,242,274,280,285,313,318,343,348,383,418,423,450,466,480],"code",{"__ignoreMap":35},[40,41,44,48,52,56,59,62,64,67,70,73],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sZ9Zp","import",[40,49,51],{"class":50},"sXnUm"," {",[40,53,55],{"class":54},"sBiod"," createQueryRuntime",[40,57,58],{"class":50},",",[40,60,61],{"class":54}," defineQueryModel",[40,63,58],{"class":50},[40,65,66],{"class":54}," param ",[40,68,69],{"class":50},"}",[40,71,72],{"class":46}," from",[40,74,76],{"class":75},"sgVH1"," '@queryweave/core'\n",[40,78,80],{"class":42,"line":79},2,[40,81,83],{"emptyLinePlaceholder":82},true,"\n",[40,85,87,90,94,98,101],{"class":42,"line":86},3,[40,88,89],{"class":46},"const",[40,91,93],{"class":92},"sJ-0L"," productFilters",[40,95,97],{"class":96},"sZ7qJ"," =",[40,99,61],{"class":100},"sUqqj",[40,102,103],{"class":50},"({\n",[40,105,107,111,114,117,120,123,126,129],{"class":42,"line":106},4,[40,108,110],{"class":109},"snYWn","  search",[40,112,113],{"class":50},":",[40,115,116],{"class":54}," param",[40,118,119],{"class":50},".",[40,121,122],{"class":100},"text",[40,124,125],{"class":50},"().",[40,127,128],{"class":100},"optional",[40,130,131],{"class":50},"(),\n",[40,133,135,138,140,142,144,147,150,153,155,158,161,164,167,170],{"class":42,"line":134},5,[40,136,137],{"class":109},"  page",[40,139,113],{"class":50},[40,141,116],{"class":54},[40,143,119],{"class":50},[40,145,146],{"class":100},"integer",[40,148,149],{"class":50},"({",[40,151,152],{"class":109}," min",[40,154,113],{"class":50},[40,156,157],{"class":92}," 1",[40,159,160],{"class":50}," }).",[40,162,163],{"class":100},"default",[40,165,166],{"class":50},"(",[40,168,169],{"class":92},"1",[40,171,172],{"class":50},"),\n",[40,174,176,179,181,183,185,188,190,192,194,197],{"class":42,"line":175},6,[40,177,178],{"class":109},"  archived",[40,180,113],{"class":50},[40,182,116],{"class":54},[40,184,119],{"class":50},[40,186,187],{"class":100},"boolean",[40,189,125],{"class":50},[40,191,163],{"class":100},[40,193,166],{"class":50},[40,195,196],{"class":92},"false",[40,198,172],{"class":50},[40,200,202,205,207,209,211,214,217,220,222,225,227,230,233,235,237,240],{"class":42,"line":201},7,[40,203,204],{"class":109},"  sort",[40,206,113],{"class":50},[40,208,116],{"class":54},[40,210,119],{"class":50},[40,212,213],{"class":100},"choice",[40,215,216],{"class":50},"([",[40,218,219],{"class":75},"'name'",[40,221,58],{"class":50},[40,223,224],{"class":75}," 'created_at'",[40,226,58],{"class":50},[40,228,229],{"class":75}," 'price'",[40,231,232],{"class":50},"]).",[40,234,163],{"class":100},[40,236,166],{"class":50},[40,238,239],{"class":75},"'created_at'",[40,241,172],{"class":50},[40,243,245,248,250,252,254,257,259,262,264,266,269,271],{"class":42,"line":244},8,[40,246,247],{"class":109},"  tags",[40,249,113],{"class":50},[40,251,116],{"class":54},[40,253,119],{"class":50},[40,255,256],{"class":100},"list",[40,258,166],{"class":50},[40,260,261],{"class":54},"param",[40,263,119],{"class":50},[40,265,122],{"class":100},[40,267,268],{"class":50},"()).",[40,270,163],{"class":100},[40,272,273],{"class":50},"([]),\n",[40,275,277],{"class":42,"line":276},9,[40,278,279],{"class":50},"})\n",[40,281,283],{"class":42,"line":282},10,[40,284,83],{"emptyLinePlaceholder":82},[40,286,288,290,293,295,297,299,302,304,306,308,311],{"class":42,"line":287},11,[40,289,89],{"class":46},[40,291,292],{"class":92}," runtime",[40,294,97],{"class":96},[40,296,55],{"class":100},[40,298,149],{"class":50},[40,300,301],{"class":109}," model",[40,303,113],{"class":50},[40,305,93],{"class":54},[40,307,58],{"class":50},[40,309,310],{"class":54}," adapter ",[40,312,279],{"class":50},[40,314,316],{"class":42,"line":315},12,[40,317,83],{"emptyLinePlaceholder":82},[40,319,321,324,326,329,331,334,336,339],{"class":42,"line":320},13,[40,322,323],{"class":54},"runtime",[40,325,119],{"class":50},[40,327,328],{"class":100},"read",[40,330,125],{"class":50},[40,332,333],{"class":109},"values",[40,335,119],{"class":50},[40,337,338],{"class":109},"page",[40,340,342],{"class":341},"s5c__"," // 1\n",[40,344,346],{"class":42,"line":345},14,[40,347,83],{"emptyLinePlaceholder":82},[40,349,351,354,356,358,361,363,366,368,371,373,376,378,380],{"class":42,"line":350},15,[40,352,353],{"class":46},"await",[40,355,292],{"class":54},[40,357,119],{"class":50},[40,359,360],{"class":100},"update",[40,362,149],{"class":50},[40,364,365],{"class":109}," search",[40,367,113],{"class":50},[40,369,370],{"class":75}," 'vue'",[40,372,58],{"class":50},[40,374,375],{"class":109}," page",[40,377,113],{"class":50},[40,379,157],{"class":92},[40,381,382],{"class":50}," })\n",[40,384,386,388,390,392,394,396,398,400,403,406,408,411,413,416],{"class":42,"line":385},16,[40,387,353],{"class":46},[40,389,292],{"class":54},[40,391,119],{"class":50},[40,393,360],{"class":100},[40,395,149],{"class":50},[40,397,375],{"class":109},[40,399,113],{"class":50},[40,401,402],{"class":92}," 2",[40,404,405],{"class":50}," },",[40,407,51],{"class":50},[40,409,410],{"class":109}," navigation",[40,412,113],{"class":50},[40,414,415],{"class":75}," 'replace'",[40,417,382],{"class":50},[40,419,421],{"class":42,"line":420},17,[40,422,83],{"emptyLinePlaceholder":82},[40,424,426,428,430,432,435,438,441,444,447],{"class":42,"line":425},18,[40,427,353],{"class":46},[40,429,292],{"class":54},[40,431,119],{"class":50},[40,433,434],{"class":100},"transaction",[40,436,437],{"class":50},"((",[40,439,440],{"class":54},"draft",[40,442,443],{"class":50},")",[40,445,446],{"class":46}," =>",[40,448,449],{"class":50}," {\n",[40,451,453,456,458,461,463],{"class":42,"line":452},19,[40,454,455],{"class":54},"  draft",[40,457,119],{"class":50},[40,459,460],{"class":109},"search",[40,462,97],{"class":96},[40,464,465],{"class":75}," 'vue'\n",[40,467,469,471,473,475,477],{"class":42,"line":468},20,[40,470,455],{"class":54},[40,472,119],{"class":50},[40,474,338],{"class":109},[40,476,97],{"class":96},[40,478,479],{"class":92}," 1\n",[40,481,483],{"class":42,"line":482},21,[40,484,279],{"class":50},[19,486,487,488,491,492,494],{},"والرابط الذي فيه خطأ لا يعطّل الصفحة. فالاستعلام ",[37,489,490],{},"?page=abc"," يُقرأ على أنه الصفحة ",[37,493,169],{},"، ومع النتيجة ملاحظة تبيّن السبب، فيستطيع التطبيق أن يكمل عمله وأن يُعلم المستخدم.",[15,496,498],{"id":497},"الاستعمال-في-vue","الاستعمال في Vue",[30,500,502],{"className":32,"code":501,"language":34,"meta":35,"style":35},"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",[37,503,504,524,528,544,568,572],{"__ignoreMap":35},[40,505,506,508,511,513,516,518,521],{"class":42,"line":43},[40,507,89],{"class":46},[40,509,510],{"class":92}," filters",[40,512,97],{"class":96},[40,514,515],{"class":100}," useQueryModel",[40,517,166],{"class":50},[40,519,520],{"class":54},"productFilters",[40,522,523],{"class":50},")\n",[40,525,526],{"class":42,"line":79},[40,527,83],{"emptyLinePlaceholder":82},[40,529,530,533,535,537,539,541],{"class":42,"line":86},[40,531,532],{"class":54},"filters",[40,534,119],{"class":50},[40,536,333],{"class":109},[40,538,119],{"class":50},[40,540,338],{"class":109},[40,542,543],{"class":341}," // readonly reactive state\n",[40,545,546,548,550,552,554,556,558,560,562,565],{"class":42,"line":106},[40,547,353],{"class":46},[40,549,510],{"class":54},[40,551,119],{"class":50},[40,553,360],{"class":100},[40,555,149],{"class":50},[40,557,375],{"class":109},[40,559,113],{"class":50},[40,561,402],{"class":92},[40,563,564],{"class":50}," })",[40,566,567],{"class":341}," // explicit operation\n",[40,569,570],{"class":42,"line":134},[40,571,83],{"emptyLinePlaceholder":82},[40,573,574,576,578,580,582,584,587,589,592,594,596,598,600,602,604],{"class":42,"line":175},[40,575,89],{"class":46},[40,577,365],{"class":92},[40,579,97],{"class":96},[40,581,510],{"class":54},[40,583,119],{"class":50},[40,585,586],{"class":100},"field",[40,588,166],{"class":50},[40,590,591],{"class":75},"'search'",[40,593,58],{"class":50},[40,595,51],{"class":50},[40,597,410],{"class":109},[40,599,113],{"class":50},[40,601,415],{"class":75},[40,603,564],{"class":50},[40,605,606],{"class":341}," // v-model target\n",[19,608,609],{},"لا دالة خاصة بكل مفتاح، ولا دالة تعيين تُرجَع مع القيمة، ولا تعديل مباشر للحالة. و Vue و Nuxt أول ما دعمتُه من الواجهات، لكن تصميم النواة لا يعتمد على أيٍّ منهما.",[15,611,613],{"id":612},"تسع-حزم","تسع حزم",[615,616,617,634],"table",{},[618,619,620],"thead",{},[621,622,623,627,630],"tr",{},[624,625,626],"th",{},"الحزمة",[624,628,629],{},"الدور",[624,631,633],{"align":632},"right","الحجم بعد الضغط",[635,636,637,651,664,677,690,703,716,729,742],"tbody",{},[621,638,639,645,648],{},[640,641,642],"td",{},[37,643,644],{},"@queryweave/core",[640,646,647],{},"النماذج، وقراءة العنوان وكتابته، وعقود بيئة التشغيل",[640,649,650],{"align":632},"7.39 كيلوبايت",[621,652,653,658,661],{},[640,654,655],{},[37,656,657],{},"@queryweave/browser",[640,659,660],{},"محوّل History API في المتصفح",[640,662,663],{"align":632},"564 بايت",[621,665,666,671,674],{},[640,667,668],{},[37,669,670],{},"@queryweave/server",[640,672,673],{},"أدوات للخادم مبنية على معايير الويب",[640,675,676],{"align":632},"469 بايت",[621,678,679,684,687],{},[640,680,681],{},[37,682,683],{},"@queryweave/node",[640,685,686],{},"التعامل مع طلبات Node.js",[640,688,689],{"align":632},"691 بايت",[621,691,692,697,700],{},[640,693,694],{},[37,695,696],{},"@queryweave/standard-schema",[640,698,699],{},"التوافق مع Standard Schema",[640,701,702],{"align":632},"341 بايت",[621,704,705,710,713],{},[640,706,707],{},[37,708,709],{},"@queryweave/testing",[640,711,712],{},"محوّل يعمل في الذاكرة وأدوات للاختبار",[640,714,715],{"align":632},"491 بايت",[621,717,718,723,726],{},[640,719,720],{},[37,721,722],{},"@queryweave/vue",[640,724,725],{},"ربط نماذج الاستعلام بـ Vue",[640,727,728],{"align":632},"850 بايت",[621,730,731,736,739],{},[640,732,733],{},[37,734,735],{},"@queryweave/vue-router",[640,737,738],{},"محوّل Vue Router",[640,740,741],{"align":632},"699 بايت",[621,743,744,749,752],{},[640,745,746],{},[37,747,748],{},"@queryweave/nuxt",[640,750,751],{},"وحدة Nuxt، وبيئة تشغيل لكل طلب",[640,753,754],{"align":632},"911 بايت",[19,756,757,758,761],{},"وهذه الحدود مفروضة: يفشل الأمر ",[37,759,760],{},"pnpm bundle:size:check"," إذا تجاوزت حزمةٌ حدّها.",[15,763,764],{"id":764},"الاختبارات",[19,766,767],{},"قبل كل إصدار تُشغَّل كل مشاريع Vitest، ومنها الاختبارات داخل المتصفح واختبارات الأنواع، ثم اختبارات في متصفحات فعلية هي Chromium و Firefox و WebKit، ثم Playwright على تطبيق التجربة. وتُفحص حدود الحزم في المصادر وملفات التعريف ومخطط التبعيات، ويُفحص ما يُبنى وملفات الأنواع المرافقة له، ثم تُثبَّت الحزم بعد تحزيمها في مشاريع نظيفة للتأكد من أنها تعمل عند من يستعملها.",[19,769,770],{},"والمشروع تجريبي ولم يبلغ الإصدار 1.0 بعد: قد تتغيّر واجهته العامة بين إصدار وآخر، وكل تغيير غير متوافق يُدوَّن في سجل القرارات المعمارية وفي changeset.",[772,773,774],"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":35,"searchDepth":79,"depth":79,"links":776},[777,778,779,780,781],{"id":17,"depth":79,"text":17},{"id":24,"depth":79,"text":25},{"id":497,"depth":79,"text":498},{"id":612,"depth":79,"text":613},{"id":764,"depth":79,"text":764},"محرّك لإدارة حالة عنوان URL، محدَّد الأنواع ولا يرتبط بأي إطار عمل.","md",{},"/projects/ar/queryweave",{"title":10,"description":782},"projects/ar/queryweave","4irYRwLK4FQVx-b4m1Sy9ChEdHL_YM2shj-SJqzE2H8",1791794147975]