[{"data":1,"prerenderedAt":501},["ShallowReactive",2],{"fougere:post.list:{}":3,"docs:\u002Fdocs\u002Fextending\u002Fextensions":6,"docs-uses":189,"docs-nav":363},{"items":4,"hasMore":5},[],false,{"id":7,"title":8,"body":9,"description":179,"extension":180,"forms":181,"kind":182,"meta":183,"navigation":184,"path":185,"seo":186,"stem":187,"step":181,"uses":181,"__hash__":188},"docs\u002Fdocs\u002F8.extending\u002F6.extensions.md","Run code at boot and shutdown",{"type":10,"value":11,"toc":177},"minimark",[12,26,139,158,173],[13,14,15,16,20,21,25],"p",{},"An ",[17,18,19],"strong",{},"extension"," is something that rises and falls with the process: it opens a connection, starts a\ntimer, registers what other classes will ask for, and undoes it all on the way down. Put it in a\nfrond's ",[22,23,24],"code",{},"extensions\u002F"," directory, beside the code it serves:",[27,28,33],"pre",{"className":29,"code":30,"language":31,"meta":32,"style":32},"language-ts shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","\u002F\u002F fronds\u002Fblog\u002Fextensions\u002Faudit.ts\nexport default {\n  name: 'audit',\n  async up(app) { … },\n  async down(app) { … },\n};\n","ts","",[22,34,35,44,58,82,113,133],{"__ignoreMap":32},[36,37,40],"span",{"class":38,"line":39},"line",1,[36,41,43],{"class":42},"skXKP","\u002F\u002F fronds\u002Fblog\u002Fextensions\u002Faudit.ts\n",[36,45,47,51,54],{"class":38,"line":46},2,[36,48,50],{"class":49},"sK6XW","export",[36,52,53],{"class":49}," default",[36,55,57],{"class":56},"s15xx"," {\n",[36,59,61,65,68,72,76,79],{"class":38,"line":60},3,[36,62,64],{"class":63},"sHtqg","  name",[36,66,67],{"class":56},":",[36,69,71],{"class":70},"sDDC1"," '",[36,73,75],{"class":74},"sN-8n","audit",[36,77,78],{"class":70},"'",[36,80,81],{"class":56},",\n",[36,83,85,89,93,96,100,103,106,110],{"class":38,"line":84},4,[36,86,88],{"class":87},"s76I7","  async",[36,90,92],{"class":91},"shDkW"," up",[36,94,95],{"class":56},"(",[36,97,99],{"class":98},"shDUQ","app",[36,101,102],{"class":56},")",[36,104,105],{"class":56}," {",[36,107,109],{"class":108},"ssXpW"," … ",[36,111,112],{"class":56},"},\n",[36,114,116,118,121,123,125,127,129,131],{"class":38,"line":115},5,[36,117,88],{"class":87},[36,119,120],{"class":91}," down",[36,122,95],{"class":56},[36,124,99],{"class":98},[36,126,102],{"class":56},[36,128,105],{"class":56},[36,130,109],{"class":108},[36,132,112],{"class":56},[36,134,136],{"class":38,"line":135},6,[36,137,138],{"class":56},"};\n",[13,140,141,142,145,146,149,150,153,154,157],{},"A file there is recognized by its shape — a module stating ",[22,143,144],{},"up",", ",[22,147,148],{},"down"," or ",[22,151,152],{},"state"," — and it travels\nwith its frond: when the frond moves to another process, the extension rises there. That is why no\nconfig key spreads it to every process: what must be in every process is a frond every process holds,\nwhich an extension's own ",[22,155,156],{},"fronds"," brings.",[13,159,160,161,163,164,166,167,172],{},"How ",[22,162,144],{}," and ",[22,165,148],{}," run, and what refuses: ",[168,169,171],"a",{"href":170},"\u002Fdocs\u002Fextending\u002Fboot","The boot, step by step",".",[174,175,176],"style",{},"html pre.shiki code .skXKP, html code.shiki .skXKP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#7D8C80;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sK6XW, html code.shiki .sK6XW{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#8FCF86;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s15xx, html code.shiki .s15xx{--shiki-light:#39ADB5;--shiki-default:#A3B0A5;--shiki-dark:#89DDFF}html pre.shiki code .sHtqg, html code.shiki .sHtqg{--shiki-light:#E53935;--shiki-default:#93CFC0;--shiki-dark:#F07178}html pre.shiki code .sDDC1, html code.shiki .sDDC1{--shiki-light:#39ADB5;--shiki-default:#EE9F6B;--shiki-dark:#89DDFF}html pre.shiki code .sN-8n, html code.shiki .sN-8n{--shiki-light:#91B859;--shiki-default:#EE9F6B;--shiki-dark:#C3E88D}html pre.shiki code .s76I7, html code.shiki .s76I7{--shiki-light:#9C3EDA;--shiki-default:#8FCF86;--shiki-dark:#C792EA}html pre.shiki code .shDkW, html code.shiki .shDkW{--shiki-light:#E53935;--shiki-default:#C9B6EA;--shiki-dark:#F07178}html pre.shiki code .shDUQ, html code.shiki .shDUQ{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#DDE5DA;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .ssXpW, html code.shiki .ssXpW{--shiki-light:#E53935;--shiki-default:#DDE5DA;--shiki-dark:#F07178}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":32,"searchDepth":46,"depth":46,"links":178},[],"What rises and falls with the process.","md",null,"extending",{},true,"\u002Fdocs\u002Fextending\u002Fextensions",{"title":8,"description":179},"docs\u002F8.extending\u002F6.extensions","rVyHApVYRZioGETvvKeFx8q1HbsTc2bTa6suJHlzZQY",[190,193,196,199,202,205,208,211,214,220,226,231,235,239,243,247,251,256,260,264,269,273,278,282,286,290,294,298,302,306,310,314,318,322,326,330,334,337,340,341,344,347,350,351,354,357,360],{"path":191,"title":192,"uses":181},"\u002Fdocs\u002Fconcepts\u002Fentity","Entity",{"path":194,"title":195,"uses":181},"\u002Fdocs\u002Fconcepts\u002Fhandler","Handler",{"path":197,"title":198,"uses":181},"\u002Fdocs\u002Fconcepts\u002Frepository","Repository",{"path":200,"title":201,"uses":181},"\u002Fdocs\u002Fconcepts\u002Ffrond","Frond",{"path":203,"title":204,"uses":181},"\u002Fdocs\u002Fconcepts\u002Ffacade","Facade",{"path":206,"title":207,"uses":181},"\u002Fdocs\u002Fconcepts\u002Ffact","Fact",{"path":209,"title":210,"uses":181},"\u002Fdocs\u002Fconcepts\u002Fport","Port",{"path":212,"title":213,"uses":181},"\u002Fdocs\u002Fconcepts\u002Fconfiguration","Configuration",{"path":215,"title":216,"uses":217},"\u002Fdocs\u002Faccess\u002Fauthentication","Authentication",[218,219],"port","frond",{"path":221,"title":222,"uses":223},"\u002Fdocs\u002Faccess\u002Fstate","Keep a caller's state",[224,225],"configuration","handler",{"path":227,"title":228,"uses":229},"\u002Fdocs\u002Fdata\u002Fsql","SQLite or Postgres",[230,224],"entity",{"path":232,"title":233,"uses":234},"\u002Fdocs\u002Fdata\u002Fseveral-databases","Several databases",[224,230],{"path":236,"title":237,"uses":238},"\u002Fdocs\u002Fdata\u002Fcomputed-field","A computed field",[230,218],{"path":240,"title":241,"uses":242},"\u002Fdocs\u002Fdata\u002Fevolve","Evolve a schema",[230],{"path":244,"title":245,"uses":246},"\u002Fdocs\u002Fdata\u002Fseeds","Seed data",[230],{"path":248,"title":249,"uses":250},"\u002Fdocs\u002Fdata\u002Fvalues","Read settings and secrets",[230,224],{"path":252,"title":253,"uses":254},"\u002Fdocs\u002Fdata\u002Fmirror","Mirror a source you cannot query",[255],"repository",{"path":257,"title":258,"uses":259},"\u002Fdocs\u002Fdata\u002Ftogether","Two writes as one",[255],{"path":261,"title":262,"uses":263},"\u002Fdocs\u002Fbehaviour\u002Faround-every-call","Around every call",[218,219],{"path":265,"title":266,"uses":267},"\u002Fdocs\u002Fbehaviour\u002Ffinish-a-fact","Finish a fact",[268],"fact",{"path":270,"title":271,"uses":272},"\u002Fdocs\u002Fserve\u002Frest-graphql","REST, OpenAPI, GraphQL",[225,224],{"path":274,"title":275,"uses":276},"\u002Fdocs\u002Fserve\u002Fpages","Pages: queries and commands",[225,277],"facade",{"path":279,"title":280,"uses":281},"\u002Fdocs\u002Fserve\u002Fforms","A form",[230],{"path":283,"title":284,"uses":285},"\u002Fdocs\u002Fserve\u002Fadmin","An admin panel",[225],{"path":287,"title":288,"uses":289},"\u002Fdocs\u002Frun\u002Fdeploy","Deploy a split",[224,219],{"path":291,"title":292,"uses":293},"\u002Fdocs\u002Frun\u002Fsecure","Secure calls between processes",[224,219],{"path":295,"title":296,"uses":297},"\u002Fdocs\u002Frun\u002Flifecycle","Reload and shut down",[224],{"path":299,"title":300,"uses":301},"\u002Fdocs\u002Frun\u002Fobserve","Observe",[224,225],{"path":303,"title":304,"uses":305},"\u002Fdocs\u002Frun\u002Fdev-panel","The dev panel",[225],{"path":307,"title":308,"uses":309},"\u002Fdocs\u002Frun\u002Ftest","Test",[230,218],{"path":311,"title":312,"uses":313},"\u002Fdocs\u002Fadopt\u002Fnew-project","Start a project",[219,224],{"path":315,"title":316,"uses":317},"\u002Fdocs\u002Fadopt\u002Fexisting-app","Add Fougere to an existing app",[219,224],{"path":319,"title":320,"uses":321},"\u002Fdocs\u002Fadopt\u002Fbring-your-schema","Bring your schema",[230],{"path":323,"title":324,"uses":325},"\u002Fdocs\u002Fadopt\u002Fhosts","Pick a host",[224],{"path":327,"title":328,"uses":329},"\u002Fdocs\u002Fadopt\u002Fanother-repository","A frond from another repository",[277,219],{"path":331,"title":332,"uses":333},"\u002Fdocs\u002Fadopt\u002Fdemos","Demos",[],{"path":335,"title":336,"uses":181},"\u002Fdocs\u002Fextending\u002Fscan","How the scan reads a project",{"path":338,"title":339,"uses":181},"\u002Fdocs\u002Fextending\u002Fwithout-compiler","Boot without the compiler",{"path":170,"title":171,"uses":181},{"path":342,"title":343,"uses":181},"\u002Fdocs\u002Fextending\u002Fcard-and-wire","The card and the wire",{"path":345,"title":346,"uses":181},"\u002Fdocs\u002Fextending\u002Fextension-points","Registries and extension points",{"path":348,"title":349,"uses":181},"\u002Fdocs\u002Fextending\u002Fvocabulary","Teach a word",{"path":185,"title":8,"uses":181},{"path":352,"title":353,"uses":181},"\u002Fdocs\u002Fextending\u002Fsource-adapter","Write a source adapter",{"path":355,"title":356,"uses":181},"\u002Fdocs\u002Fextending\u002Fsurface","Write a surface",{"path":358,"title":359,"uses":181},"\u002Fdocs\u002Fextending\u002Fforeign-frond","A frond in another language",{"path":361,"title":362,"uses":181},"\u002Fdocs","What is Fougere",[364],{"title":365,"path":361,"stem":366,"children":367,"page":-1},"Docs","docs",[368,370,391,400,421,430,443,460,477],{"title":362,"path":361,"stem":369},"docs\u002Findex",{"title":371,"path":372,"stem":373,"children":374,"page":5},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F1.concepts",[375,377,379,381,383,385,387,389],{"title":192,"path":191,"stem":376},"docs\u002F1.concepts\u002F1.entity",{"title":195,"path":194,"stem":378},"docs\u002F1.concepts\u002F2.handler",{"title":198,"path":197,"stem":380},"docs\u002F1.concepts\u002F3.repository",{"title":201,"path":200,"stem":382},"docs\u002F1.concepts\u002F4.frond",{"title":204,"path":203,"stem":384},"docs\u002F1.concepts\u002F5.facade",{"title":207,"path":206,"stem":386},"docs\u002F1.concepts\u002F6.fact",{"title":210,"path":209,"stem":388},"docs\u002F1.concepts\u002F7.port",{"title":213,"path":212,"stem":390},"docs\u002F1.concepts\u002F8.configuration",{"title":392,"path":393,"stem":394,"children":395,"page":5},"Access","\u002Fdocs\u002Faccess","docs\u002F2.access",[396,398],{"title":216,"path":215,"stem":397},"docs\u002F2.access\u002F1.authentication",{"title":222,"path":221,"stem":399},"docs\u002F2.access\u002F2.state",{"title":401,"path":402,"stem":403,"children":404,"page":5},"Data","\u002Fdocs\u002Fdata","docs\u002F3.data",[405,407,409,411,413,415,417,419],{"title":228,"path":227,"stem":406},"docs\u002F3.data\u002F1.sql",{"title":233,"path":232,"stem":408},"docs\u002F3.data\u002F2.several-databases",{"title":237,"path":236,"stem":410},"docs\u002F3.data\u002F3.computed-field",{"title":241,"path":240,"stem":412},"docs\u002F3.data\u002F4.evolve",{"title":245,"path":244,"stem":414},"docs\u002F3.data\u002F5.seeds",{"title":249,"path":248,"stem":416},"docs\u002F3.data\u002F6.values",{"title":253,"path":252,"stem":418},"docs\u002F3.data\u002F7.mirror",{"title":258,"path":257,"stem":420},"docs\u002F3.data\u002F8.together",{"title":422,"path":423,"stem":424,"children":425,"page":5},"Behaviour","\u002Fdocs\u002Fbehaviour","docs\u002F4.behaviour",[426,428],{"title":262,"path":261,"stem":427},"docs\u002F4.behaviour\u002F1.around-every-call",{"title":266,"path":265,"stem":429},"docs\u002F4.behaviour\u002F2.finish-a-fact",{"title":431,"path":432,"stem":433,"children":434,"page":5},"Serve","\u002Fdocs\u002Fserve","docs\u002F5.serve",[435,437,439,441],{"title":271,"path":270,"stem":436},"docs\u002F5.serve\u002F1.rest-graphql",{"title":275,"path":274,"stem":438},"docs\u002F5.serve\u002F2.pages",{"title":280,"path":279,"stem":440},"docs\u002F5.serve\u002F3.forms",{"title":284,"path":283,"stem":442},"docs\u002F5.serve\u002F4.admin",{"title":444,"path":445,"stem":446,"children":447,"page":5},"Run","\u002Fdocs\u002Frun","docs\u002F6.run",[448,450,452,454,456,458],{"title":288,"path":287,"stem":449},"docs\u002F6.run\u002F1.deploy",{"title":292,"path":291,"stem":451},"docs\u002F6.run\u002F2.secure",{"title":296,"path":295,"stem":453},"docs\u002F6.run\u002F3.lifecycle",{"title":300,"path":299,"stem":455},"docs\u002F6.run\u002F4.observe",{"title":304,"path":303,"stem":457},"docs\u002F6.run\u002F5.dev-panel",{"title":308,"path":307,"stem":459},"docs\u002F6.run\u002F6.test",{"title":461,"path":462,"stem":463,"children":464,"page":5},"Adopt","\u002Fdocs\u002Fadopt","docs\u002F7.adopt",[465,467,469,471,473,475],{"title":312,"path":311,"stem":466},"docs\u002F7.adopt\u002F1.new-project",{"title":316,"path":315,"stem":468},"docs\u002F7.adopt\u002F2.existing-app",{"title":320,"path":319,"stem":470},"docs\u002F7.adopt\u002F3.bring-your-schema",{"title":324,"path":323,"stem":472},"docs\u002F7.adopt\u002F4.hosts",{"title":328,"path":327,"stem":474},"docs\u002F7.adopt\u002F5.another-repository",{"title":332,"path":331,"stem":476},"docs\u002F7.adopt\u002F6.demos",{"title":478,"path":479,"stem":480,"children":481,"page":5},"Extending","\u002Fdocs\u002Fextending","docs\u002F8.extending",[482,484,486,488,490,492,494,495,497,499],{"title":336,"path":335,"stem":483},"docs\u002F8.extending\u002F1.scan",{"title":339,"path":338,"stem":485},"docs\u002F8.extending\u002F10.without-compiler",{"title":171,"path":170,"stem":487},"docs\u002F8.extending\u002F2.boot",{"title":343,"path":342,"stem":489},"docs\u002F8.extending\u002F3.card-and-wire",{"title":346,"path":345,"stem":491},"docs\u002F8.extending\u002F4.extension-points",{"title":349,"path":348,"stem":493},"docs\u002F8.extending\u002F5.vocabulary",{"title":8,"path":185,"stem":187},{"title":353,"path":352,"stem":496},"docs\u002F8.extending\u002F7.source-adapter",{"title":356,"path":355,"stem":498},"docs\u002F8.extending\u002F8.surface",{"title":359,"path":358,"stem":500},"docs\u002F8.extending\u002F9.foreign-frond",1794396615347]