[{"data":1,"prerenderedAt":255},["ShallowReactive",2],{"i-lucide:layers":3,"i-lucide:git-commit-horizontal":8,"i-lucide:refresh-cw":10,"i-lucide:book-open":12,"i-lucide:image":14,"i-lucide:webhook":16,"i-lucide:home":18,"i-lucide:layout-grid":20,"i-lucide:tag":22,"i-lucide:newspaper":24,"i-lucide:map":26,"i-lucide:flask-conical":28,"i-lucide:arrow-right":30,"i-lucide:chevron-right":32,"i-lucide:search":34,"i-lucide:monitor":36,"content:\u002Finternal\u002Farchitecture\u002Fevent-sourcing":38,"i-lucide:triangle-alert":253,"i-lucide:layers-2":250,"i-lucide:key-round":250,"i-lucide:shield-check":250,"i-lucide:box":250,"i-lucide:share-2":250,"i-lucide:clock":250,"i-lucide:dices":250,"i-lucide:building-2":250,"i-lucide:bell":250,"i-lucide:sprout":250,"i-lucide:puzzle":250,"i-lucide:shield-alert":250,"i-lucide:activity":250,"i-lucide:blocks":250},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\"\u002F>\u003Cpath d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\"\u002F>\u003Cpath d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"3\"\u002F>\u003Cpath d=\"M3 12h6m6 0h6\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M3 12a9 9 0 0 1 9-9a9.75 9.75 0 0 1 6.74 2.74L21 8\"\u002F>\u003Cpath d=\"M21 3v5h-5m5 4a9 9 0 0 1-9 9a9.75 9.75 0 0 1-6.74-2.74L3 16\"\u002F>\u003Cpath d=\"M8 16H3v5\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m8.001-2A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"\u002F>\u003Ccircle cx=\"9\" cy=\"9\" r=\"2\"\u002F>\u003Cpath d=\"m21 15l-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2\"\u002F>\u003Cpath d=\"m6 17l3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06\"\u002F>\u003Cpath d=\"m12 6l3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"\u002F>\u003Cpath d=\"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"14\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"14\" y=\"14\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\"\u002F>\u003Ccircle cx=\"7.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":25},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 18h-5m8-4h-8m-6 8h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2\"\u002F>\u003Crect width=\"8\" height=\"4\" x=\"10\" y=\"6\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":27},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0zm.894.211v15M9 3.236v15\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":29},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2M6.453 15h11.094M8.5 2h7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":31},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":33},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":35},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":37},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M8 21h8m-4-4v4\"\u002F>\u003C\u002Fg>",{"id":39,"title":40,"body":41,"description":243,"extension":244,"eyebrow":245,"hostedOnly":6,"meta":246,"navigation":247,"path":248,"seo":249,"short":250,"stem":251,"__hash__":252},"docs\u002Finternal\u002Farchitecture\u002Fevent-sourcing.md","Event sourcing",{"type":42,"value":43,"toc":238},"minimark",[44,57,62,73,151,154,179,194,198,201,221,225,234],[45,46,47,48,52,53,56],"p",{},"A write never updates a table directly. It goes through an ",[49,50,51],"strong",{},"aggregate",". The aggregate checks the rules, then emits one or more ",[49,54,55],{},"events",". The event stream is the source of truth. Read models are built from it.",[58,59,61],"h2",{"id":60},"the-write-path","The write path",[45,63,64,65,69,70,72],{},"Every domain write calls the aggregate's ",[66,67,68],"code",{},"Try"," method. ",[66,71,68],{}," validates the command against the current state, then records the events.",[74,75,80],"pre",{"className":76,"code":77,"language":78,"meta":79,"style":79},"language-go shiki shiki-themes github-light github-dark","\u002F\u002F The command runs through the aggregate. On success it emits an event.\nif err := account.Try(cmd, chronicler.WithActor(actor), chronicler.WithChronicle(id)); err != nil {\n    return err\n}\n","go","",[66,81,82,91,136,145],{"__ignoreMap":79},[83,84,87],"span",{"class":85,"line":86},"line",1,[83,88,90],{"class":89},"sJ8bj","\u002F\u002F The command runs through the aggregate. On success it emits an event.\n",[83,92,94,98,102,105,108,111,114,117,120,123,126,129,133],{"class":85,"line":93},2,[83,95,97],{"class":96},"szBVR","if",[83,99,101],{"class":100},"sVt8B"," err ",[83,103,104],{"class":96},":=",[83,106,107],{"class":100}," account.",[83,109,68],{"class":110},"sScJk",[83,112,113],{"class":100},"(cmd, chronicler.",[83,115,116],{"class":110},"WithActor",[83,118,119],{"class":100},"(actor), chronicler.",[83,121,122],{"class":110},"WithChronicle",[83,124,125],{"class":100},"(id)); err ",[83,127,128],{"class":96},"!=",[83,130,132],{"class":131},"sj4cs"," nil",[83,134,135],{"class":100}," {\n",[83,137,139,142],{"class":85,"line":138},3,[83,140,141],{"class":96},"    return",[83,143,144],{"class":100}," err\n",[83,146,148],{"class":85,"line":147},4,[83,149,150],{"class":100},"}\n",[45,152,153],{},"Two rules hold here, and they are not optional.",[155,156,157,167],"ul",{},[158,159,160,166],"li",{},[49,161,162,163,165],{},"Never wrap the error from ",[66,164,68],{},"."," Return it as it is. The caller and the tests match on the exact error.",[158,168,169,172,173,175,176,178],{},[49,170,171],{},"Always add the injectors."," ",[66,174,116],{}," records who acted. ",[66,177,122],{}," scopes the event to its world.",[180,181,184],"callout",{"title":182,"tone":183},"Do not wrap Try errors","warning",[45,185,186,187,190,191,193],{},"Wrapping the error with ",[66,188,189],{},"fmt.Errorf"," breaks the callers and the tests that match on it. Return the error from ",[66,192,68],{}," directly.",[58,195,197],{"id":196},"why-events-not-rows","Why events, not rows",[45,199,200],{},"The event stream keeps the full history of every change. That gives Chronicler three things a row-update model cannot.",[155,202,203,209,215],{},[158,204,205,208],{},[49,206,207],{},"Replay."," A read model can be rebuilt from the events at any time.",[158,210,211,214],{},[49,212,213],{},"Audit."," Who changed what, and when, is a fact in the stream, not a guess.",[158,216,217,220],{},[49,218,219],{},"New views."," A new read model reads the same events and projects its own shape.",[58,222,224],{"id":223},"what-comes-next","What comes next",[45,226,227,228,233],{},"The events feed the read models. That is the ",[229,230,232],"a",{"href":231},"\u002Finternal\u002Farchitecture\u002Fprojections","Projections"," pattern.",[235,236,237],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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":79,"searchDepth":93,"depth":93,"links":239},[240,241,242],{"id":60,"depth":93,"text":61},{"id":196,"depth":93,"text":197},{"id":223,"depth":93,"text":224},"Every write to the domain goes through an aggregate. The aggregate emits events. The events are the source of truth. This is how it works in Chronicler.","md","Architecture",{},{"title":40},"\u002Finternal\u002Farchitecture\u002Fevent-sourcing",{"title":40,"description":243},null,"internal\u002Farchitecture\u002Fevent-sourcing","SULyVj61bYtjlJPFHlLDMFX6X28yUEOXFMi3zLUY-TM",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":254},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m21.73 18l-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4m0 4h.01\"\u002F>",1788784066565]