[{"data":1,"prerenderedAt":1137},["ShallowReactive",2],{"docs-nav:en":3,"docs:\u002Fdocs\u002Fconcepts\u002Fthe-base":186},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,12,16,20,24,28,50,75,120,145],{"title":10,"path":6,"stem":11},"What is Fougere","docs\u002Findex",{"title":13,"path":14,"stem":15},"Getting started","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",{"title":17,"path":18,"stem":19},"An app you already have","\u002Fdocs\u002Fexisting-app","docs\u002F02.existing-app",{"title":21,"path":22,"stem":23},"Bring your schema","\u002Fdocs\u002Fbring-your-schema","docs\u002F03.bring-your-schema",{"title":25,"path":26,"stem":27},"The CLI","\u002Fdocs\u002Fcli","docs\u002F04.cli",{"title":29,"path":30,"stem":31,"children":32,"page":49},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[33,37,41,45],{"title":34,"path":35,"stem":36},"Philosophy","\u002Fdocs\u002Fconcepts\u002Fphilosophy","docs\u002F2.concepts\u002F1.philosophy",{"title":38,"path":39,"stem":40},"The Frond","\u002Fdocs\u002Fconcepts\u002Ffrond","docs\u002F2.concepts\u002F2.frond",{"title":42,"path":43,"stem":44},"The shortest path","\u002Fdocs\u002Fconcepts\u002Fshortest-path","docs\u002F2.concepts\u002F3.shortest-path",{"title":46,"path":47,"stem":48},"The base","\u002Fdocs\u002Fconcepts\u002Fthe-base","docs\u002F2.concepts\u002F4.the-base",false,{"title":51,"path":52,"stem":53,"children":54,"page":49},"Schema","\u002Fdocs\u002Fschema","docs\u002F3.schema",[55,59,63,67,71],{"title":56,"path":57,"stem":58},"Entities","\u002Fdocs\u002Fschema\u002Fentities","docs\u002F3.schema\u002F1.entities",{"title":60,"path":61,"stem":62},"Views","\u002Fdocs\u002Fschema\u002Fviews","docs\u002F3.schema\u002F2.views",{"title":64,"path":65,"stem":66},"The identity card","\u002Fdocs\u002Fschema\u002Fcard","docs\u002F3.schema\u002F3.card",{"title":68,"path":69,"stem":70},"Standard Schema","\u002Fdocs\u002Fschema\u002Fstandard-schema","docs\u002F3.schema\u002F4.standard-schema",{"title":72,"path":73,"stem":74},"How a schema moves","\u002Fdocs\u002Fschema\u002Fevolution","docs\u002F3.schema\u002F5.evolution",{"title":76,"path":77,"stem":78,"children":79,"page":49},"Business","\u002Fdocs\u002Fbusiness","docs\u002F4.business",[80,84,88,92,96,100,104,108,112,116],{"title":81,"path":82,"stem":83},"Handlers","\u002Fdocs\u002Fbusiness\u002Fhandlers","docs\u002F4.business\u002F1.handlers",{"title":85,"path":86,"stem":87},"Ports","\u002Fdocs\u002Fbusiness\u002Fports","docs\u002F4.business\u002F10.ports",{"title":89,"path":90,"stem":91},"Presenters","\u002Fdocs\u002Fbusiness\u002Fpresenters","docs\u002F4.business\u002F2.presenters",{"title":93,"path":94,"stem":95},"Collectors","\u002Fdocs\u002Fbusiness\u002Fcollectors","docs\u002F4.business\u002F3.collectors",{"title":97,"path":98,"stem":99},"Errors","\u002Fdocs\u002Fbusiness\u002Ferrors","docs\u002F4.business\u002F4.errors",{"title":101,"path":102,"stem":103},"Seeds","\u002Fdocs\u002Fbusiness\u002Fseeds","docs\u002F4.business\u002F5.seeds",{"title":105,"path":106,"stem":107},"Facts","\u002Fdocs\u002Fbusiness\u002Ffacts","docs\u002F4.business\u002F6.facts",{"title":109,"path":110,"stem":111},"Storage","\u002Fdocs\u002Fbusiness\u002Fstorage","docs\u002F4.business\u002F7.storage",{"title":113,"path":114,"stem":115},"Writes that stand or fall as one","\u002Fdocs\u002Fbusiness\u002Ftogether","docs\u002F4.business\u002F8.together",{"title":117,"path":118,"stem":119},"Repositories","\u002Fdocs\u002Fbusiness\u002Frepositories","docs\u002F4.business\u002F9.repositories",{"title":121,"path":122,"stem":123,"children":124,"page":49},"Client","\u002Fdocs\u002Fclient","docs\u002F5.client",[125,129,133,137,141],{"title":126,"path":127,"stem":128},"Queries & commands","\u002Fdocs\u002Fclient\u002Fqueries-commands","docs\u002F5.client\u002F1.queries-commands",{"title":130,"path":131,"stem":132},"Forms","\u002Fdocs\u002Fclient\u002Fforms","docs\u002F5.client\u002F2.forms",{"title":134,"path":135,"stem":136},"Session","\u002Fdocs\u002Fclient\u002Fsession","docs\u002F5.client\u002F3.session",{"title":138,"path":139,"stem":140},"invoke","\u002Fdocs\u002Fclient\u002Finvoke","docs\u002F5.client\u002F4.invoke",{"title":142,"path":143,"stem":144},"Back-office","\u002Fdocs\u002Fclient\u002Fadmin","docs\u002F5.client\u002F5.admin",{"title":146,"path":147,"stem":148,"children":149,"page":49},"Infrastructure","\u002Fdocs\u002Finfra","docs\u002F6.infra",[150,154,158,162,166,170,174,178,182],{"title":151,"path":152,"stem":153},"The gradient","\u002Fdocs\u002Finfra\u002Fgradient","docs\u002F6.infra\u002F1.gradient",{"title":155,"path":156,"stem":157},"Surfaces — REST & GraphQL","\u002Fdocs\u002Finfra\u002Fsurfaces","docs\u002F6.infra\u002F2.surfaces",{"title":159,"path":160,"stem":161},"Deployment","\u002Fdocs\u002Finfra\u002Fdeployment","docs\u002F6.infra\u002F3.deployment",{"title":163,"path":164,"stem":165},"Hosts","\u002Fdocs\u002Finfra\u002Fhosts","docs\u002F6.infra\u002F4.hosts",{"title":167,"path":168,"stem":169},"Sources","\u002Fdocs\u002Finfra\u002Fsources","docs\u002F6.infra\u002F5.sources",{"title":171,"path":172,"stem":173},"Lifecycle","\u002Fdocs\u002Finfra\u002Flifecycle","docs\u002F6.infra\u002F6.lifecycle",{"title":175,"path":176,"stem":177},"Identity across Fronds","\u002Fdocs\u002Finfra\u002Fidentity","docs\u002F6.infra\u002F7.identity",{"title":179,"path":180,"stem":181},"Observability","\u002Fdocs\u002Finfra\u002Fobservability","docs\u002F6.infra\u002F8.observability",{"title":183,"path":184,"stem":185},"Testing","\u002Fdocs\u002Finfra\u002Ftesting","docs\u002F6.infra\u002F9.testing",{"id":187,"title":46,"body":188,"description":1131,"extension":1132,"meta":1133,"navigation":1134,"path":47,"seo":1135,"stem":48,"__hash__":1136},"docs_en\u002Fdocs\u002F2.concepts\u002F4.the-base.md",{"type":189,"value":190,"toc":1122},"minimark",[191,195,199,202,207,317,329,333,344,468,476,479,484,491,776,792,799,802,833,837,844,924,951,955,958,1076,1079,1088,1092,1107,1113,1118],[192,193,46],"h1",{"id":194},"the-base",[196,197,198],"p",{},"The base of a Fougere application is not what the framework ships. It is the entity you\nwrote.",[196,200,201],{},"Everything Fougere hands back is indexed by that declaration, and it comes in three\nforms. Knowing the three is enough to predict where the schema goes in an API you have\nnever seen: between the parentheses of a class you extend, in the type of a value you\nreceive, or as the first argument of a call you write.",[203,204,206],"h2",{"id":205},"three-forms-one-parameter","Three forms, one parameter",[208,209,210,226],"table",{},[211,212,213],"thead",{},[214,215,216,220,223],"tr",{},[217,218,219],"th",{},"Form",[217,221,222],{},"What you write",[217,224,225],{},"Examples",[227,228,229,266,293],"tbody",{},[214,230,231,239,245],{},[232,233,234,235],"td",{},"a class you ",[236,237,238],"strong",{},"extend",[232,240,241],{},[242,243,244],"code",{},"extends Crud(Post)",[232,246,247,250,251,250,254,250,257,250,260,250,263],{},[242,248,249],{},"entity",", ",[242,252,253],{},"Crud",[242,255,256],{},"Presenter",[242,258,259],{},"Collector",[242,261,262],{},"Repository",[242,264,265],{},"Mirror",[214,267,268,274,279],{},[232,269,270,271],{},"a value you ",[236,272,273],{},"receive",[232,275,276],{},[242,277,278],{},"constructor(posts: RepositoryOf\u003CPost>)",[232,280,281,250,284,250,287,250,290],{},[242,282,283],{},"RepositoryOf\u003CE>",[242,285,286],{},"Emit\u003CF>",[242,288,289],{},"Fact\u003CF>",[242,291,292],{},"Facade\u003CH>",[214,294,295,301,306],{},[232,296,297,298],{},"a call you ",[236,299,300],{},"write",[232,302,303],{},[242,304,305],{},"useQuery(Post, 'list')",[232,307,308,250,311,250,314],{},[242,309,310],{},"useQuery",[242,312,313],{},"useCommand",[242,315,316],{},"useFormFor",[196,318,319,320,324,325,328],{},"The parameter is always something you declared yourself — usually an entity, sometimes a\n",[321,322,323],"a",{"href":106},"fact"," or a ",[321,326,327],{"href":82},"handler",". Nothing in that\ncolumn is a string, a name, or a key registered elsewhere: rename the class and the\ncompiler follows every reader of it.",[203,330,332],{"id":331},"a-class-you-extend","A class you extend",[196,334,335,336,339,340,343],{},"Six of them. What varies is not their nature but how much your declaration determines —\n",[242,337,338],{},"Collector(User)"," can derive almost nothing from \"I resolve a User\", while ",[242,341,342],{},"Crud(Post)","\nderives five whole operations from Post's table.",[208,345,346,360],{},[211,347,348],{},[214,349,350,352,355,358],{},[217,351],{},[217,353,354],{},"The parentheses hold",[217,356,357],{},"What you inherit",[217,359,222],{},[227,361,362,380,397,414,432,450],{},[214,363,364,371,374,377],{},[232,365,366],{},[321,367,368],{"href":57},[242,369,370],{},"entity({…})",[232,372,373],{},"the fields",[232,375,376],{},"the type, the judge, the metadata",[232,378,379],{},"the field map",[214,381,382,388,391,394],{},[232,383,384],{},[321,385,386],{"href":82},[242,387,342],{},[232,389,390],{},"an entity",[232,392,393],{},"five operations",[232,395,396],{},"nothing, or the ones you redefine",[214,398,399,406,408,411],{},[232,400,401],{},[321,402,403],{"href":90},[242,404,405],{},"Presenter(Post)",[232,407,390],{},[232,409,410],{},"the target the scan reads",[232,412,413],{},"one method per computed field",[214,415,416,422,425,427],{},[232,417,418],{},[321,419,420],{"href":94},[242,421,338],{},[232,423,424],{},"any class",[232,426,410],{},[232,428,429],{},[242,430,431],{},"collect(ctx)",[214,433,434,441,444,447],{},[232,435,436],{},[321,437,438],{"href":118},[242,439,440],{},"Repository(Reading)",[232,442,443],{},"one entity, or the several it owns",[232,445,446],{},"every gesture of the guarded port — or none, from two on",[232,448,449],{},"the queries you name",[214,451,452,457,460,463],{},[232,453,454],{},[242,455,456],{},"Mirror(BookCard)",[232,458,459],{},"a shape",[232,461,462],{},"the loop, the age, the judge, the write",[232,464,465],{},[242,466,467],{},"pull()",[196,469,470,471,475],{},"Only the first is mandatory. A handler that extends nothing is an ordinary handler; a\nrepository you never write still resolves. Where extending ",[472,473,474],"em",{},"is"," the declaration —\npresenters, collectors — the base carries a target and no behaviour at all.",[196,477,478],{},"Each of them is documented where it is used, and the links above go there. One has no\npage of its own, because it belongs to no single step: it is the base itself.",[480,481,483],"h3",{"id":482},"mirror-a-local-copy-of-rows-you-cannot-query","Mirror — a local copy of rows you cannot query",[196,485,486,487,490],{},"A real database is queried where it is. ",[242,488,489],{},"Mirror(Shape)"," is the answer for a source with\nno algebra: an HTTP API, a partner's catalog, a Frond behind a wire. The subclass supplies\none thing, the pull:",[492,493,498],"pre",{"className":494,"code":495,"language":496,"meta":497,"style":497},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F services\u002FPartnerCatalog.ts\nexport default class PartnerCatalog extends Mirror(BookCard) {\n  async *pull(since?: Date) {\n    for (let page = 0; page !== null; ) {\n      const body = await fetch(`${api}?page=${page}&since=${since?.toISOString() ?? ''}`);\n      const { items, next } = await body.json();\n      yield items.map(toCard);\n      page = next;\n    }\n  }\n}\n","ts","",[242,499,500,509,542,575,617,687,724,746,758,764,770],{"__ignoreMap":497},[501,502,505],"span",{"class":503,"line":504},"line",1,[501,506,508],{"class":507},"sutJx","\u002F\u002F services\u002FPartnerCatalog.ts\n",[501,510,512,516,519,523,527,530,534,538],{"class":503,"line":511},2,[501,513,515],{"class":514},"sVHd0","export",[501,517,518],{"class":514}," default",[501,520,522],{"class":521},"sbsja"," class",[501,524,526],{"class":525},"sbgvK"," PartnerCatalog",[501,528,529],{"class":521}," extends",[501,531,533],{"class":532},"sGLFI"," Mirror",[501,535,537],{"class":536},"su5hD","(BookCard) ",[501,539,541],{"class":540},"sP7_E","{\n",[501,543,545,548,552,556,559,563,566,569,572],{"class":503,"line":544},3,[501,546,547],{"class":521},"  async",[501,549,551],{"class":550},"smGrS"," *",[501,553,555],{"class":554},"sVXei","pull",[501,557,558],{"class":540},"(",[501,560,562],{"class":561},"s99_P","since",[501,564,565],{"class":550},"?:",[501,567,568],{"class":525}," Date",[501,570,571],{"class":540},")",[501,573,574],{"class":540}," {\n",[501,576,578,581,585,588,591,594,598,601,603,606,610,612,615],{"class":503,"line":577},4,[501,579,580],{"class":514},"    for",[501,582,584],{"class":583},"skxfh"," (",[501,586,587],{"class":521},"let",[501,589,590],{"class":536}," page",[501,592,593],{"class":550}," =",[501,595,597],{"class":596},"srdBf"," 0",[501,599,600],{"class":540},";",[501,602,590],{"class":536},[501,604,605],{"class":550}," !==",[501,607,609],{"class":608},"s39Yj"," null",[501,611,600],{"class":540},[501,613,614],{"class":583}," ) ",[501,616,541],{"class":540},[501,618,620,623,627,629,632,635,637,641,644,647,651,654,657,659,662,664,666,669,672,676,679,682,684],{"class":503,"line":619},5,[501,621,622],{"class":521},"      const",[501,624,626],{"class":625},"s_hVV"," body",[501,628,593],{"class":550},[501,630,631],{"class":514}," await",[501,633,634],{"class":532}," fetch",[501,636,558],{"class":583},[501,638,640],{"class":639},"sjJ54","`${",[501,642,643],{"class":536},"api",[501,645,646],{"class":639},"}",[501,648,650],{"class":649},"s_sjI","?page=",[501,652,653],{"class":639},"${",[501,655,656],{"class":536},"page",[501,658,646],{"class":639},[501,660,661],{"class":649},"&since=",[501,663,653],{"class":639},[501,665,562],{"class":536},[501,667,668],{"class":639},"?.",[501,670,671],{"class":532},"toISOString",[501,673,675],{"class":674},"sfo-9","() ",[501,677,678],{"class":550},"??",[501,680,681],{"class":639}," ''}`",[501,683,571],{"class":583},[501,685,686],{"class":540},";\n",[501,688,690,692,695,698,701,704,707,709,711,713,716,719,722],{"class":503,"line":689},6,[501,691,622],{"class":521},[501,693,694],{"class":540}," {",[501,696,697],{"class":625}," items",[501,699,700],{"class":540},",",[501,702,703],{"class":625}," next",[501,705,706],{"class":540}," }",[501,708,593],{"class":550},[501,710,631],{"class":514},[501,712,626],{"class":536},[501,714,715],{"class":540},".",[501,717,718],{"class":532},"json",[501,720,721],{"class":583},"()",[501,723,686],{"class":540},[501,725,727,730,732,734,737,739,742,744],{"class":503,"line":726},7,[501,728,729],{"class":514},"      yield",[501,731,697],{"class":536},[501,733,715],{"class":540},[501,735,736],{"class":532},"map",[501,738,558],{"class":583},[501,740,741],{"class":536},"toCard",[501,743,571],{"class":583},[501,745,686],{"class":540},[501,747,749,752,754,756],{"class":503,"line":748},8,[501,750,751],{"class":536},"      page",[501,753,593],{"class":550},[501,755,703],{"class":536},[501,757,686],{"class":540},[501,759,761],{"class":503,"line":760},9,[501,762,763],{"class":540},"    }\n",[501,765,767],{"class":503,"line":766},10,[501,768,769],{"class":540},"  }\n",[501,771,773],{"class":503,"line":772},11,[501,774,775],{"class":540},"}\n",[196,777,778,779,782,783,788,789,791],{},"Everything around it is the same for every mirror and lives in the base: ",[242,780,781],{},"refresh()"," reads\nthe high-water mark, pulls from there, judges each page and writes it. The shape must\ncarry an ",[321,784,785],{"href":57},[242,786,787],{},"updated()"," field — a copy that cannot say when it was\npulled reads exactly like live rows — and ",[242,790,265],{}," refuses at construction otherwise.",[196,793,794,795,798],{},"A page is client input, so it meets the same judge as any other, strictly: a partner\nrenaming ",[242,796,797],{},"label"," writes nulls in silence otherwise. A refused page stops the pass; what\nearlier pages wrote stays, because an upsert is idempotent and the next run resumes from\nthe mark.",[196,800,801],{},"It does not schedule itself. A boot hook, a cron, an operation behind a door are all\nlegitimate and none of them is this class's business.",[803,804,805],"note",{},[196,806,807,809,810,813,814,817,818,821,822,825,826,829,830,832],{},[242,808,265],{}," has no directory of its own in the Frond vocabulary yet — unlike ",[242,811,812],{},"presenters\u002F","\nand ",[242,815,816],{},"collectors\u002F",", a ",[242,819,820],{},"mirrors\u002F"," folder is not scanned. Place it where providers are read\n(",[242,823,824],{},"services\u002F"," or ",[242,827,828],{},"repositories\u002F","). As a storage holder, it is handed the ",[242,831,109],{}," its\nprefab was built on; handlers, presenters and collectors do not have that exception.",[203,834,836],{"id":835},"a-value-you-receive","A value you receive",[196,838,839,840,843],{},"The second form is a constructor parameter, resolved by ",[236,841,842],{},"type"," — never by parameter\nname, never by a string key:",[492,845,847],{"className":494,"code":846,"language":496,"meta":497,"style":497},"export default class PostHandler {\n  constructor(\n    private posts: RepositoryOf\u003CPost>,\n    private announce: Emit\u003CPostPublished>,\n  ) {}\n}\n",[242,848,849,862,870,893,912,920],{"__ignoreMap":497},[501,850,851,853,855,857,860],{"class":503,"line":504},[501,852,515],{"class":514},[501,854,518],{"class":514},[501,856,522],{"class":521},[501,858,859],{"class":525}," PostHandler",[501,861,574],{"class":540},[501,863,864,867],{"class":503,"line":511},[501,865,866],{"class":521},"  constructor",[501,868,869],{"class":540},"(\n",[501,871,872,875,878,881,884,887,890],{"class":503,"line":544},[501,873,874],{"class":521},"    private",[501,876,877],{"class":561}," posts",[501,879,880],{"class":550},":",[501,882,883],{"class":525}," RepositoryOf",[501,885,886],{"class":540},"\u003C",[501,888,889],{"class":525},"Post",[501,891,892],{"class":540},">,\n",[501,894,895,897,900,902,905,907,910],{"class":503,"line":577},[501,896,874],{"class":521},[501,898,899],{"class":561}," announce",[501,901,880],{"class":550},[501,903,904],{"class":525}," Emit",[501,906,886],{"class":540},[501,908,909],{"class":525},"PostPublished",[501,911,892],{"class":540},[501,913,914,917],{"class":503,"line":619},[501,915,916],{"class":540},"  )",[501,918,919],{"class":540}," {}\n",[501,921,922],{"class":503,"line":689},[501,923,775],{"class":540},[196,925,926,928,929,932,933,936,937,941,942,944,945,950],{},[242,927,283],{}," is the default repository shape: it forwards the guarded storage port and\nresolves even when no repository file exists. Injecting ",[242,930,931],{},"Storage\u003CE>"," directly into a\nhandler, presenter or collector is refused at boot; name storage access through a\n",[321,934,935],{"href":118},"repository",". ",[321,938,939],{"href":106},[242,940,286],{}," announces a\nfact, and accepting a ",[242,943,289],{}," is the subscription — no topic, no register call.\n",[321,946,948],{"href":947},"\u002Fdocs\u002Fbusiness\u002Fhandlers#reaching-another-frond",[242,949,292],{}," is the one whose parameter\nis not an entity: it names another Frond's handler, which is a declaration of yours all\nthe same.",[203,952,954],{"id":953},"a-call-you-write","A call you write",[196,956,957],{},"The third form is the client side, and the entity is the first argument:",[492,959,961],{"className":494,"code":960,"language":496,"meta":497,"style":497},"const { items } = await useQuery(Post, 'list');\nconst publish = useCommand(Post, 'publish');\nconst form = useFormFor(Post, { op: 'update', params: { id } });\n",[242,962,963,999,1026],{"__ignoreMap":497},[501,964,965,968,970,972,974,976,978,981,984,986,989,992,995,997],{"class":503,"line":504},[501,966,967],{"class":521},"const",[501,969,694],{"class":540},[501,971,697],{"class":625},[501,973,706],{"class":540},[501,975,593],{"class":550},[501,977,631],{"class":514},[501,979,980],{"class":532}," useQuery",[501,982,983],{"class":536},"(Post",[501,985,700],{"class":540},[501,987,988],{"class":639}," '",[501,990,991],{"class":649},"list",[501,993,994],{"class":639},"'",[501,996,571],{"class":536},[501,998,686],{"class":540},[501,1000,1001,1003,1006,1008,1011,1013,1015,1017,1020,1022,1024],{"class":503,"line":511},[501,1002,967],{"class":521},[501,1004,1005],{"class":625}," publish",[501,1007,593],{"class":550},[501,1009,1010],{"class":532}," useCommand",[501,1012,983],{"class":536},[501,1014,700],{"class":540},[501,1016,988],{"class":639},[501,1018,1019],{"class":649},"publish",[501,1021,994],{"class":639},[501,1023,571],{"class":536},[501,1025,686],{"class":540},[501,1027,1028,1030,1033,1035,1038,1040,1042,1044,1047,1049,1051,1054,1056,1058,1061,1063,1065,1068,1070,1072,1074],{"class":503,"line":544},[501,1029,967],{"class":521},[501,1031,1032],{"class":625}," form",[501,1034,593],{"class":550},[501,1036,1037],{"class":532}," useFormFor",[501,1039,983],{"class":536},[501,1041,700],{"class":540},[501,1043,694],{"class":540},[501,1045,1046],{"class":583}," op",[501,1048,880],{"class":540},[501,1050,988],{"class":639},[501,1052,1053],{"class":649},"update",[501,1055,994],{"class":639},[501,1057,700],{"class":540},[501,1059,1060],{"class":583}," params",[501,1062,880],{"class":540},[501,1064,694],{"class":540},[501,1066,1067],{"class":536}," id ",[501,1069,646],{"class":540},[501,1071,706],{"class":540},[501,1073,571],{"class":536},[501,1075,686],{"class":540},[196,1077,1078],{},"Same designation as the server, so the local judge is the remote judge and a form\ncontract is not a second declaration of the entity.",[196,1080,1081,1082,1087],{},"One exception worth stating: ",[321,1083,1084],{"href":135},[242,1085,1086],{},"useCurrentUser()"," takes no argument.\nIt reads its entity from the session rather than from a call site.",[203,1089,1091],{"id":1090},"why-a-class-and-never-a-decorator","Why a class, and never a decorator",[196,1093,1094,1095,1098,1099,1102,1103,1106],{},"A decorator would have to ",[472,1096,1097],{},"modify"," the runtime to attach the storage, the target, or the five\noperations. ",[242,1100,1101],{},"extends"," states the same thing in the language: the type follows without a\nsecond declaration, ",[242,1104,1105],{},"getFields()"," is a plain static, and nothing is registered behind your\nback.",[196,1108,1109,1110,1112],{},"It also survives where a scan cannot reach. ",[242,1111,253],{}," declares its operations at runtime, on\nthe class, so an installed Frond whose source no parser can open still publishes its\ncontract. Decorator metadata would need a compiler flag and a reflection library to say as\nmuch, and would say it only where both were configured.",[196,1114,1115,1116,715],{},"Next: ",[321,1117,56],{"href":57},[1119,1120,1121],"style",{},"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}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 .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 .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}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 pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .sfo-9, html code.shiki .sfo-9{--shiki-light:#90A4AE;--shiki-default:#032F62;--shiki-dark:#9ECBFF}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":497,"searchDepth":511,"depth":511,"links":1123},[1124,1125,1128,1129,1130],{"id":205,"depth":511,"text":206},{"id":331,"depth":511,"text":332,"children":1126},[1127],{"id":482,"depth":544,"text":483},{"id":835,"depth":511,"text":836},{"id":953,"depth":511,"text":954},{"id":1090,"depth":511,"text":1091},"Everything Fougere hands you is indexed by your own declaration — a class you extend, a value you receive, or a call you write.","md",{},true,{"title":46,"description":1131},"geR0-cPJI-TO_CRMkFoAq4zT--CrV2xWGc6wSyuN5KI",1788560230169]