[{"data":1,"prerenderedAt":691},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs":137},[4],{"title":5,"path":6,"stem":7,"children":8,"page":44},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13,"page":-1},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,45,66,95,116],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"App Nuxt existante","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F03.cli",{"title":28,"path":29,"stem":30,"children":31,"page":44},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[32,36,40],{"title":33,"path":34,"stem":35},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":37,"path":38,"stem":39},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":41,"path":42,"stem":43},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",false,{"title":46,"path":47,"stem":48,"children":49,"page":44},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[50,54,58,62],{"title":51,"path":52,"stem":53},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":55,"path":56,"stem":57},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":59,"path":60,"stem":61},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":63,"path":64,"stem":65},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":67,"path":68,"stem":69,"children":70,"page":44},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[71,75,79,83,87,91],{"title":72,"path":73,"stem":74},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":76,"path":77,"stem":78},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":80,"path":81,"stem":82},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":84,"path":85,"stem":86},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":88,"path":89,"stem":90},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":92,"path":93,"stem":94},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":96,"path":97,"stem":98,"children":99,"page":44},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[100,104,108,112],{"title":101,"path":102,"stem":103},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":105,"path":106,"stem":107},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":109,"path":110,"stem":111},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":113,"path":114,"stem":115},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":117,"path":118,"stem":119,"children":120,"page":44},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[121,125,129,133],{"title":122,"path":123,"stem":124},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":126,"path":127,"stem":128},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":130,"path":131,"stem":132},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":134,"path":135,"stem":136},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"id":138,"title":10,"body":139,"description":686,"extension":687,"meta":688,"navigation":254,"path":11,"seo":689,"stem":12,"__hash__":690},"docs_fr\u002Ffr\u002Fdocs\u002Findex.md",{"type":140,"value":141,"toc":683},"minimark",[142,146,150,167,469,472,475,532,546,581,588,591,596,607,637,650,662,679],[143,144,10],"h1",{"id":145},"quest-ce-que-fougere",[147,148,149],"p",{},"Fougere est un framework TypeScript construit autour de deux idées.",[147,151,152,156,157,161,162,166],{},[153,154,155],"strong",{},"Single-schema."," Une classe d'entité déclare vos données une fois — et juge elle-même\nses entrées : le même ",[158,159,160],"code",{},"validate()"," tourne dans le navigateur et à la façade. Le juge est\nlui-même une projection — dérivée de l'axe shape — mais une projection normative,\nembarquée avec la classe : toutes les autres doivent lui obéir, et elle ne peut pas\ndériver seule. Les tables\nSQLite, les types GraphQL, les contrats de formulaire et les surfaces d'API sont des\n",[163,164,165],"em",{},"projections"," de cette déclaration — rien n'est écrit deux fois.",[168,169,174],"pre",{"className":170,"code":171,"language":172,"meta":173,"style":173},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","import { entity, primary, text, created, oneOf, date, readOnly, optional } from '@fougere\u002Fschema';\n\nexport default class Post extends entity({\n  id: primary(),\n  title: text({ min: 1, max: 160 }),\n  body: optional(text()),\n  createdAt: created(),\n  status: readOnly(oneOf('draft', 'published', { default: 'draft' })),\n  publishedAt: readOnly(optional(date())),\n}) {}\n","ts","",[158,175,176,249,256,285,303,344,364,378,432,457],{"__ignoreMap":173},[177,178,181,185,189,193,196,199,201,204,206,209,211,214,216,219,221,224,226,229,232,235,239,243,246],"span",{"class":179,"line":180},"line",1,[177,182,184],{"class":183},"sVHd0","import",[177,186,188],{"class":187},"sP7_E"," {",[177,190,192],{"class":191},"su5hD"," entity",[177,194,195],{"class":187},",",[177,197,198],{"class":191}," primary",[177,200,195],{"class":187},[177,202,203],{"class":191}," text",[177,205,195],{"class":187},[177,207,208],{"class":191}," created",[177,210,195],{"class":187},[177,212,213],{"class":191}," oneOf",[177,215,195],{"class":187},[177,217,218],{"class":191}," date",[177,220,195],{"class":187},[177,222,223],{"class":191}," readOnly",[177,225,195],{"class":187},[177,227,228],{"class":191}," optional",[177,230,231],{"class":187}," }",[177,233,234],{"class":183}," from",[177,236,238],{"class":237},"sjJ54"," '",[177,240,242],{"class":241},"s_sjI","@fougere\u002Fschema",[177,244,245],{"class":237},"'",[177,247,248],{"class":187},";\n",[177,250,252],{"class":179,"line":251},2,[177,253,255],{"emptyLinePlaceholder":254},true,"\n",[177,257,259,262,265,269,273,276,279,282],{"class":179,"line":258},3,[177,260,261],{"class":183},"export",[177,263,264],{"class":183}," default",[177,266,268],{"class":267},"sbsja"," class",[177,270,272],{"class":271},"sbgvK"," Post",[177,274,275],{"class":267}," extends",[177,277,192],{"class":278},"sGLFI",[177,280,281],{"class":191},"(",[177,283,284],{"class":187},"{\n",[177,286,288,292,295,297,300],{"class":179,"line":287},4,[177,289,291],{"class":290},"skxfh","  id",[177,293,294],{"class":187},":",[177,296,198],{"class":278},[177,298,299],{"class":191},"()",[177,301,302],{"class":187},",\n",[177,304,306,309,311,313,315,318,321,323,327,329,332,334,337,339,342],{"class":179,"line":305},5,[177,307,308],{"class":290},"  title",[177,310,294],{"class":187},[177,312,203],{"class":278},[177,314,281],{"class":191},[177,316,317],{"class":187},"{",[177,319,320],{"class":290}," min",[177,322,294],{"class":187},[177,324,326],{"class":325},"srdBf"," 1",[177,328,195],{"class":187},[177,330,331],{"class":290}," max",[177,333,294],{"class":187},[177,335,336],{"class":325}," 160",[177,338,231],{"class":187},[177,340,341],{"class":191},")",[177,343,302],{"class":187},[177,345,347,350,352,354,356,359,362],{"class":179,"line":346},6,[177,348,349],{"class":290},"  body",[177,351,294],{"class":187},[177,353,228],{"class":278},[177,355,281],{"class":191},[177,357,358],{"class":278},"text",[177,360,361],{"class":191},"())",[177,363,302],{"class":187},[177,365,367,370,372,374,376],{"class":179,"line":366},7,[177,368,369],{"class":290},"  createdAt",[177,371,294],{"class":187},[177,373,208],{"class":278},[177,375,299],{"class":191},[177,377,302],{"class":187},[177,379,381,384,386,388,390,393,395,397,400,402,404,406,409,411,413,415,417,419,421,423,425,427,430],{"class":179,"line":380},8,[177,382,383],{"class":290},"  status",[177,385,294],{"class":187},[177,387,223],{"class":278},[177,389,281],{"class":191},[177,391,392],{"class":278},"oneOf",[177,394,281],{"class":191},[177,396,245],{"class":237},[177,398,399],{"class":241},"draft",[177,401,245],{"class":237},[177,403,195],{"class":187},[177,405,238],{"class":237},[177,407,408],{"class":241},"published",[177,410,245],{"class":237},[177,412,195],{"class":187},[177,414,188],{"class":187},[177,416,264],{"class":290},[177,418,294],{"class":187},[177,420,238],{"class":237},[177,422,399],{"class":241},[177,424,245],{"class":237},[177,426,231],{"class":187},[177,428,429],{"class":191},"))",[177,431,302],{"class":187},[177,433,435,438,440,442,444,447,449,452,455],{"class":179,"line":434},9,[177,436,437],{"class":290},"  publishedAt",[177,439,294],{"class":187},[177,441,223],{"class":278},[177,443,281],{"class":191},[177,445,446],{"class":278},"optional",[177,448,281],{"class":191},[177,450,451],{"class":278},"date",[177,453,454],{"class":191},"()))",[177,456,302],{"class":187},[177,458,460,463,466],{"class":179,"line":459},10,[177,461,462],{"class":187},"}",[177,464,465],{"class":191},") ",[177,467,468],{"class":187},"{}\n",[470,471],"derivation-diagram",{},[147,473,474],{},"Cette seule classe est à la fois :",[476,477,478,494,503,513,522],"ul",{},[479,480,481,482,485,486,489,490,493],"li",{},"le ",[153,483,484],{},"type TypeScript"," d'une ligne (",[158,487,488],{},"function render(p: Post)"," — pas d'",[158,491,492],{},"Infer\u003Ctypeof …>","),",[479,495,481,496,499,500,493],{},[153,497,498],{},"validateur"," des entrées client (",[158,501,502],{},"Post.validate(input)",[479,504,505,506,509,510,493],{},"la ",[153,507,508],{},"metadata"," que chaque adapter lit (",[158,511,512],{},"Post.getFields()",[479,514,505,515,518,519,493],{},[153,516,517],{},"désignation"," que les pages utilisent pour appeler les opérations (",[158,520,521],{},"useQuery(Post, 'list')",[479,523,481,524,527,528,531],{},[153,525,526],{},"nom nominal"," que l'injection de dépendances matche dans les signatures (",[158,529,530],{},"user: User | null",").",[147,533,534,537,538,541,542,545],{},[153,535,536],{},"Le gradient."," La logique métier vit dans des ",[163,539,540],{},"Fronds"," — des modules autonomes\nd'entités, handlers, collectors et seeds. Une Frond tourne in-process aujourd'hui et dans\nson propre process demain, derrière JSON-RPC 2.0, avec un ",[153,543,544],{},"code utilisateur identique",".\nL'énoncé de topologie entier tient en une ligne de config :",[168,547,549],{"className":170,"code":548,"language":172,"meta":173,"style":173},"\u002F\u002F fougere.config.ts\nremotes: { blog: 'http:\u002F\u002F127.0.0.1:4100' }\n",[158,550,551,557],{"__ignoreMap":173},[177,552,553],{"class":179,"line":180},[177,554,556],{"class":555},"sutJx","\u002F\u002F fougere.config.ts\n",[177,558,559,562,564,566,569,571,573,576,578],{"class":179,"line":251},[177,560,561],{"class":271},"remotes",[177,563,294],{"class":187},[177,565,188],{"class":187},[177,567,568],{"class":271}," blog",[177,570,294],{"class":187},[177,572,238],{"class":237},[177,574,575],{"class":241},"http:\u002F\u002F127.0.0.1:4100",[177,577,245],{"class":237},[177,579,580],{"class":187}," }\n",[147,582,583,584,587],{},"Pas de RPC sans voyage : un appel est une valeur ",[158,585,586],{},"(entity, operation, invocation)"," ; le\nrunner l'exécute directement en mémoire quand la Frond est locale et la met sur le fil\nquand elle est distante. Les transports déplacent la valeur — ils ne la remodèlent jamais.",[147,589,590],{},"Donc le split coûte le saut et le JSON qui voyage avec, et rien d'autre : aucune\nsérialisation que le chemin local éviterait, aucun impôt du framework par-dessus le réseau.",[592,593,595],"h2",{"id":594},"ordre-de-lecture","Ordre de lecture",[147,597,598,600,601,604,605],{},[153,599,28],{}," — ",[602,603,33],"a",{"href":34}," · ",[602,606,37],{"href":38},[147,608,609,600,612,604,614,616,617,616,619,604,621,616,623,604,625,616,627,604,629,604,631,604,633,616,635],{},[153,610,611],{},"Côté serveur",[602,613,16],{"href":17},[602,615,20],{"href":21}," ·\n",[602,618,24],{"href":25},[602,620,51],{"href":52},[602,622,55],{"href":56},[602,624,63],{"href":64},[602,626,72],{"href":73},[602,628,76],{"href":77},[602,630,80],{"href":81},[602,632,84],{"href":85},[602,634,88],{"href":89},[602,636,92],{"href":93},[147,638,639,600,642,616,644,604,646,604,648],{},[153,640,641],{},"Côté client",[602,643,101],{"href":102},[602,645,105],{"href":106},[602,647,109],{"href":110},[602,649,113],{"href":114},[147,651,652,600,655,604,657,616,660],{},[153,653,654],{},"Topologie",[602,656,122],{"href":123},[602,658,659],{"href":127},"Surfaces",[602,661,130],{"href":131},[663,664,665],"blockquote",{},[147,666,667,670,671,674,675,678],{},[153,668,669],{},"Statut."," Fougere est en alpha : les paquets ",[158,672,673],{},"@fougere\u002F*"," sont sur npm sous le tag\n",[158,676,677],{},"alpha",", et cette documentation décrit l'API telle qu'elle existe dans le dépôt\naujourd'hui. Ce site tourne dessus.",[680,681,682],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}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);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}",{"title":173,"searchDepth":251,"depth":251,"links":684},[685],{"id":594,"depth":251,"text":595},"Un framework TypeScript construit autour de deux idées — single-schema et le gradient.","md",{},{"title":10,"description":686},"0Ps7GMVnaXECS3fRKjft9ZgmobVWfMpeWDcY2ckGJvQ",1786637819107]