[{"data":1,"prerenderedAt":873},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Fdomain-events":103,"\u002Fguides\u002Fdomain-events-surround":868},[4,9,31,87,98],{"title":5,"path":6,"stem":7,"icon":8},"Getting started","\u002Fgetting-started","01.getting-started","i-tabler-rocket",{"title":10,"icon":11,"path":12,"stem":13,"children":14,"page":30},"Concepts","i-tabler-code","\u002Fconcepts","02.concepts",[15,20,25],{"title":16,"path":17,"stem":18,"icon":19},"Architecture","\u002Fconcepts\u002Farchitecture","02.concepts\u002Farchitecture","i-tabler-sitemap",{"title":21,"path":22,"stem":23,"icon":24},"Metadata and registry","\u002Fconcepts\u002Fmetadata-and-registry","02.concepts\u002Fmetadata-and-registry","i-tabler-schema",{"title":26,"path":27,"stem":28,"icon":29},"Query Engine","\u002Fconcepts\u002Fquery-engine","02.concepts\u002Fquery-engine","i-tabler-engine",false,{"title":32,"icon":33,"path":34,"stem":35,"children":36,"page":30},"Guide","i-tabler-arrow-ramp-right","\u002Fguides","03.guides",[37,42,47,52,57,62,67,72,77,82],{"title":38,"path":39,"stem":40,"icon":41},"Audit Log","\u002Fguides\u002Faudit-log","03.guides\u002Faudit-log","i-tabler-history",{"title":43,"path":44,"stem":45,"icon":46},"Cursor pagination","\u002Fguides\u002Fcursor-pagination","03.guides\u002Fcursor-pagination","i-tabler-arrow-bar-to-down",{"title":48,"path":49,"stem":50,"icon":51},"Domain Events","\u002Fguides\u002Fdomain-events","03.guides\u002Fdomain-events","i-tabler-broadcast",{"title":53,"path":54,"stem":55,"icon":56},"Field visibility","\u002Fguides\u002Ffield-visibility","03.guides\u002Ffield-visibility","i-tabler-eye-off",{"title":58,"path":59,"stem":60,"icon":61},"Lifecycle hooks","\u002Fguides\u002Flifecycle-hooks","03.guides\u002Flifecycle-hooks","i-tabler-arrows-split",{"title":63,"path":64,"stem":65,"icon":66},"Production playground","\u002Fguides\u002Fplayground","03.guides\u002Fplayground","i-tabler-flask",{"title":68,"path":69,"stem":70,"icon":71},"Queries and filters","\u002Fguides\u002Fqueries-and-filters","03.guides\u002Fqueries-and-filters","i-tabler-filter",{"title":73,"path":74,"stem":75,"icon":76},"Relations","\u002Fguides\u002Frelations","03.guides\u002Frelations","i-tabler-link",{"title":78,"path":79,"stem":80,"icon":81},"Schema consistency","\u002Fguides\u002Fschema-consistency","03.guides\u002Fschema-consistency","i-tabler-database-search",{"title":83,"path":84,"stem":85,"icon":86},"Validation","\u002Fguides\u002Fvalidation","03.guides\u002Fvalidation","i-tabler-checkup-list",{"title":88,"icon":89,"path":90,"stem":91,"children":92,"page":30},"Adapters","i-tabler-plug","\u002Fadapters","04.adapters",[93],{"title":94,"path":95,"stem":96,"icon":97},"Drizzle adapter","\u002Fadapters\u002Fdrizzle","04.adapters\u002Fdrizzle","i-simple-icons-drizzle",{"title":99,"path":100,"stem":101,"icon":102},"Current limitations","\u002Fcurrent-limitations","05.current-limitations","i-tabler-circle-dashed-x",{"id":104,"title":48,"body":105,"description":861,"extension":862,"links":863,"meta":864,"navigation":865,"path":49,"seo":866,"stem":50,"__hash__":867},"docs\u002F03.guides\u002Fdomain-events.md",{"type":106,"value":107,"toc":855},"minimark",[108,125,131,136,291,298,302,625,635,639,801,804,826,830,838,851],[109,110,111,112,116,117,120,121,124],"p",{},"A Domain Event describes a business fact that already happened:\n",[113,114,115],"code",{},"candidate.hired",", ",[113,118,119],{},"job.published",", or ",[113,122,123],{},"application.rejected",".",[109,126,127,128,124],{},"Persistence stores the fact in a transactional outbox. External publication is\nhandled later by an ",[113,129,130],{},"OutboxProcessor",[132,133,135],"h2",{"id":134},"configure-the-outbox","Configure the outbox",[137,138,143],"pre",{"className":139,"code":140,"language":141,"meta":142,"style":142},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const outboxMetadata = createOutboxMetadata()\nadapter.buildTable(outboxMetadata)\n\nconst outbox = createDatabaseOutboxWriter('outboxEvents')\n\nconst engine = createQueryEngine(\n  registry,\n  adapter,\n  hooks,\n  serializer,\n  audit,\n  outbox\n)\n","ts","",[113,144,145,169,183,190,218,223,239,248,256,264,272,280,286],{"__ignoreMap":142},[146,147,150,154,158,162,166],"span",{"class":148,"line":149},"line",1,[146,151,153],{"class":152},"spNyl","const",[146,155,157],{"class":156},"sTEyZ"," outboxMetadata ",[146,159,161],{"class":160},"sMK4o","=",[146,163,165],{"class":164},"s2Zo4"," createOutboxMetadata",[146,167,168],{"class":156},"()\n",[146,170,172,175,177,180],{"class":148,"line":171},2,[146,173,174],{"class":156},"adapter",[146,176,124],{"class":160},[146,178,179],{"class":164},"buildTable",[146,181,182],{"class":156},"(outboxMetadata)\n",[146,184,186],{"class":148,"line":185},3,[146,187,189],{"emptyLinePlaceholder":188},true,"\n",[146,191,193,195,198,200,203,206,209,213,215],{"class":148,"line":192},4,[146,194,153],{"class":152},[146,196,197],{"class":156}," outbox ",[146,199,161],{"class":160},[146,201,202],{"class":164}," createDatabaseOutboxWriter",[146,204,205],{"class":156},"(",[146,207,208],{"class":160},"'",[146,210,212],{"class":211},"sfazB","outboxEvents",[146,214,208],{"class":160},[146,216,217],{"class":156},")\n",[146,219,221],{"class":148,"line":220},5,[146,222,189],{"emptyLinePlaceholder":188},[146,224,226,228,231,233,236],{"class":148,"line":225},6,[146,227,153],{"class":152},[146,229,230],{"class":156}," engine ",[146,232,161],{"class":160},[146,234,235],{"class":164}," createQueryEngine",[146,237,238],{"class":156},"(\n",[146,240,242,245],{"class":148,"line":241},7,[146,243,244],{"class":156},"  registry",[146,246,247],{"class":160},",\n",[146,249,251,254],{"class":148,"line":250},8,[146,252,253],{"class":156},"  adapter",[146,255,247],{"class":160},[146,257,259,262],{"class":148,"line":258},9,[146,260,261],{"class":156},"  hooks",[146,263,247],{"class":160},[146,265,267,270],{"class":148,"line":266},10,[146,268,269],{"class":156},"  serializer",[146,271,247],{"class":160},[146,273,275,278],{"class":148,"line":274},11,[146,276,277],{"class":156},"  audit",[146,279,247],{"class":160},[146,281,283],{"class":148,"line":282},12,[146,284,285],{"class":156},"  outbox\n",[146,287,289],{"class":148,"line":288},13,[146,290,217],{"class":156},[109,292,293,294,297],{},"Create the physical ",[113,295,296],{},"outbox_events"," table with migrations. The metadata helper\ndefines pending, processing, published and failed states plus retry fields.",[132,299,301],{"id":300},"emit-inside-a-use-case","Emit inside a use case",[137,303,305],{"className":139,"code":304,"language":141,"meta":142,"style":142},"await engine.transaction(context, async tx => {\n  const application = await tx.updateOne(\n    'applications',\n    byId(applicationId),\n    { status: 'hired' }\n  )\n\n  if (!application) throw new Error('Application not found')\n\n  tx.events.emit(\n    'candidate.hired',\n    {\n      candidateId: application.candidateId,\n      applicationId: application.id\n    },\n    {\n      aggregate: { type: 'application', id: application.id },\n      correlationId: context.requestId,\n      version: 1\n    }\n  )\n})\n",[113,306,307,340,364,376,391,413,418,422,459,463,480,490,495,511,526,532,537,576,594,606,612,617],{"__ignoreMap":142},[146,308,309,313,316,318,321,324,327,330,334,337],{"class":148,"line":149},[146,310,312],{"class":311},"s7zQu","await",[146,314,315],{"class":156}," engine",[146,317,124],{"class":160},[146,319,320],{"class":164},"transaction",[146,322,323],{"class":156},"(context",[146,325,326],{"class":160},",",[146,328,329],{"class":152}," async",[146,331,333],{"class":332},"sHdIc"," tx",[146,335,336],{"class":152}," =>",[146,338,339],{"class":160}," {\n",[146,341,342,345,348,351,354,356,358,361],{"class":148,"line":171},[146,343,344],{"class":152},"  const",[146,346,347],{"class":156}," application",[146,349,350],{"class":160}," =",[146,352,353],{"class":311}," await",[146,355,333],{"class":156},[146,357,124],{"class":160},[146,359,360],{"class":164},"updateOne",[146,362,238],{"class":363},"swJcz",[146,365,366,369,372,374],{"class":148,"line":185},[146,367,368],{"class":160},"    '",[146,370,371],{"class":211},"applications",[146,373,208],{"class":160},[146,375,247],{"class":160},[146,377,378,381,383,386,389],{"class":148,"line":192},[146,379,380],{"class":164},"    byId",[146,382,205],{"class":363},[146,384,385],{"class":156},"applicationId",[146,387,388],{"class":363},")",[146,390,247],{"class":160},[146,392,393,396,399,402,405,408,410],{"class":148,"line":220},[146,394,395],{"class":160},"    {",[146,397,398],{"class":363}," status",[146,400,401],{"class":160},":",[146,403,404],{"class":160}," '",[146,406,407],{"class":211},"hired",[146,409,208],{"class":160},[146,411,412],{"class":160}," }\n",[146,414,415],{"class":148,"line":225},[146,416,417],{"class":363},"  )\n",[146,419,420],{"class":148,"line":241},[146,421,189],{"emptyLinePlaceholder":188},[146,423,424,427,430,433,436,439,442,445,448,450,452,455,457],{"class":148,"line":250},[146,425,426],{"class":311},"  if",[146,428,429],{"class":363}," (",[146,431,432],{"class":160},"!",[146,434,435],{"class":156},"application",[146,437,438],{"class":363},") ",[146,440,441],{"class":311},"throw",[146,443,444],{"class":160}," new",[146,446,447],{"class":164}," Error",[146,449,205],{"class":363},[146,451,208],{"class":160},[146,453,454],{"class":211},"Application not found",[146,456,208],{"class":160},[146,458,217],{"class":363},[146,460,461],{"class":148,"line":258},[146,462,189],{"emptyLinePlaceholder":188},[146,464,465,468,470,473,475,478],{"class":148,"line":266},[146,466,467],{"class":156},"  tx",[146,469,124],{"class":160},[146,471,472],{"class":156},"events",[146,474,124],{"class":160},[146,476,477],{"class":164},"emit",[146,479,238],{"class":363},[146,481,482,484,486,488],{"class":148,"line":274},[146,483,368],{"class":160},[146,485,115],{"class":211},[146,487,208],{"class":160},[146,489,247],{"class":160},[146,491,492],{"class":148,"line":282},[146,493,494],{"class":160},"    {\n",[146,496,497,500,502,504,506,509],{"class":148,"line":288},[146,498,499],{"class":363},"      candidateId",[146,501,401],{"class":160},[146,503,347],{"class":156},[146,505,124],{"class":160},[146,507,508],{"class":156},"candidateId",[146,510,247],{"class":160},[146,512,514,517,519,521,523],{"class":148,"line":513},14,[146,515,516],{"class":363},"      applicationId",[146,518,401],{"class":160},[146,520,347],{"class":156},[146,522,124],{"class":160},[146,524,525],{"class":156},"id\n",[146,527,529],{"class":148,"line":528},15,[146,530,531],{"class":160},"    },\n",[146,533,535],{"class":148,"line":534},16,[146,536,494],{"class":160},[146,538,540,543,545,548,551,553,555,557,559,561,564,566,568,570,573],{"class":148,"line":539},17,[146,541,542],{"class":363},"      aggregate",[146,544,401],{"class":160},[146,546,547],{"class":160}," {",[146,549,550],{"class":363}," type",[146,552,401],{"class":160},[146,554,404],{"class":160},[146,556,435],{"class":211},[146,558,208],{"class":160},[146,560,326],{"class":160},[146,562,563],{"class":363}," id",[146,565,401],{"class":160},[146,567,347],{"class":156},[146,569,124],{"class":160},[146,571,572],{"class":156},"id",[146,574,575],{"class":160}," },\n",[146,577,579,582,584,587,589,592],{"class":148,"line":578},18,[146,580,581],{"class":363},"      correlationId",[146,583,401],{"class":160},[146,585,586],{"class":156}," context",[146,588,124],{"class":160},[146,590,591],{"class":156},"requestId",[146,593,247],{"class":160},[146,595,597,600,602],{"class":148,"line":596},19,[146,598,599],{"class":363},"      version",[146,601,401],{"class":160},[146,603,605],{"class":604},"sbssI"," 1\n",[146,607,609],{"class":148,"line":608},20,[146,610,611],{"class":160},"    }\n",[146,613,615],{"class":148,"line":614},21,[146,616,417],{"class":363},[146,618,620,623],{"class":148,"line":619},22,[146,621,622],{"class":160},"}",[146,624,217],{"class":156},[109,626,627,630,631,634],{},[113,628,629],{},"emit()"," only collects the event. The outer transaction writes every event after\nthe callback succeeds. Emitting without a configured ",[113,632,633],{},"OutboxWriter"," rejects the\ntransaction.",[132,636,638],{"id":637},"publish-pending-events","Publish pending events",[137,640,642],{"className":139,"code":641,"language":141,"meta":142,"style":142},"const processor = createOutboxProcessor(\n  adapter,\n  {\n    async publish(event) {\n      await messageBroker.publish(event.type, event)\n    }\n  },\n  {\n    batchSize: 100,\n    maxAttempts: 5,\n    processingTimeoutMs: 5 * 60_000\n  }\n)\n\nconst result = await processor.processBatch()\n",[113,643,644,658,664,669,686,715,719,724,728,740,752,767,772,776,780],{"__ignoreMap":142},[146,645,646,648,651,653,656],{"class":148,"line":149},[146,647,153],{"class":152},[146,649,650],{"class":156}," processor ",[146,652,161],{"class":160},[146,654,655],{"class":164}," createOutboxProcessor",[146,657,238],{"class":156},[146,659,660,662],{"class":148,"line":171},[146,661,253],{"class":156},[146,663,247],{"class":160},[146,665,666],{"class":148,"line":185},[146,667,668],{"class":160},"  {\n",[146,670,671,674,677,679,682,684],{"class":148,"line":192},[146,672,673],{"class":152},"    async",[146,675,676],{"class":363}," publish",[146,678,205],{"class":160},[146,680,681],{"class":332},"event",[146,683,388],{"class":160},[146,685,339],{"class":160},[146,687,688,691,694,696,699,701,703,705,708,710,713],{"class":148,"line":220},[146,689,690],{"class":311},"      await",[146,692,693],{"class":156}," messageBroker",[146,695,124],{"class":160},[146,697,698],{"class":164},"publish",[146,700,205],{"class":363},[146,702,681],{"class":156},[146,704,124],{"class":160},[146,706,707],{"class":156},"type",[146,709,326],{"class":160},[146,711,712],{"class":156}," event",[146,714,217],{"class":363},[146,716,717],{"class":148,"line":225},[146,718,611],{"class":160},[146,720,721],{"class":148,"line":241},[146,722,723],{"class":160},"  },\n",[146,725,726],{"class":148,"line":250},[146,727,668],{"class":160},[146,729,730,733,735,738],{"class":148,"line":258},[146,731,732],{"class":363},"    batchSize",[146,734,401],{"class":160},[146,736,737],{"class":604}," 100",[146,739,247],{"class":160},[146,741,742,745,747,750],{"class":148,"line":266},[146,743,744],{"class":363},"    maxAttempts",[146,746,401],{"class":160},[146,748,749],{"class":604}," 5",[146,751,247],{"class":160},[146,753,754,757,759,761,764],{"class":148,"line":274},[146,755,756],{"class":363},"    processingTimeoutMs",[146,758,401],{"class":160},[146,760,749],{"class":604},[146,762,763],{"class":160}," *",[146,765,766],{"class":604}," 60_000\n",[146,768,769],{"class":148,"line":282},[146,770,771],{"class":160},"  }\n",[146,773,774],{"class":148,"line":288},[146,775,217],{"class":156},[146,777,778],{"class":148,"line":513},[146,779,189],{"emptyLinePlaceholder":188},[146,781,782,784,787,789,791,794,796,799],{"class":148,"line":528},[146,783,153],{"class":152},[146,785,786],{"class":156}," result ",[146,788,161],{"class":160},[146,790,353],{"class":311},[146,792,793],{"class":156}," processor",[146,795,124],{"class":160},[146,797,798],{"class":164},"processBatch",[146,800,168],{"class":156},[109,802,803],{},"The processor:",[805,806,807,811,814,817,820,823],"ul",{},[808,809,810],"li",{},"loads due pending events in occurrence order;",[808,812,813],{},"claims each record for one worker;",[808,815,816],{},"marks successful events as published;",[808,818,819],{},"retries failures with configurable exponential backoff;",[808,821,822],{},"marks exhausted events as failed;",[808,824,825],{},"releases stale processing claims after a timeout.",[132,827,829],{"id":828},"delivery-guarantee","Delivery guarantee",[109,831,832,833,837],{},"The outbox provides ",[834,835,836],"strong",{},"at-least-once delivery",". A worker may publish an event and\nstop before marking it as published. Consumers must therefore be idempotent,\nusually by storing processed event IDs.",[839,840,844],"callout",{"color":841,"icon":842,"variant":843},"info","i-tabler-plug-connected","subtle",[109,845,846,847,850],{},"Persistence defines ",[113,848,849],{},"EventPublisher","; it does not depend on Kafka, RabbitMQ,\nRedis, webhooks or any other transport.",[852,853,854],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":142,"searchDepth":149,"depth":171,"links":856},[857,858,859,860],{"id":134,"depth":171,"text":135},{"id":300,"depth":171,"text":301},{"id":637,"depth":171,"text":638},{"id":828,"depth":171,"text":829},"Persist typed business events atomically and publish them from an outbox.","md",null,{},{"icon":51},{"title":48,"description":861},"G7ewyFZ594cYB8Uc9kwCZulY5D5TzAjeS1yu-lzd_oE",[869,871],{"title":43,"path":44,"stem":45,"description":870,"icon":46,"children":-1},"Page through changing datasets with stable keyset filters.",{"title":53,"path":54,"stem":55,"description":872,"icon":56,"children":-1},"Remove hidden and context-sensitive fields from every engine result.",1783784235117]