[{"data":1,"prerenderedAt":758},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Fevents":193,"\u002Fguides\u002Fevents-surround":753},[4,27,49,99,149,169,183],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Getting Started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,14,18,22],{"title":11,"path":12,"stem":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction",{"title":15,"path":16,"stem":17},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation",{"title":19,"path":20,"stem":21},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start",{"title":23,"path":24,"stem":25},"Existing Application","\u002Fgetting-started\u002Fexisting-application","1.getting-started\u002F4.existing-application",false,{"title":28,"icon":29,"path":30,"stem":31,"children":32,"page":26},"Concepts","i-lucide-layers","\u002Fconcepts","2.concepts",[33,37,41,45],{"title":34,"path":35,"stem":36},"Layers","\u002Fconcepts\u002Flayers","2.concepts\u002F1.layers",{"title":38,"path":39,"stem":40},"Buckets","\u002Fconcepts\u002Fbuckets","2.concepts\u002F2.buckets",{"title":42,"path":43,"stem":44},"Boundaries","\u002Fconcepts\u002Fboundaries","2.concepts\u002F3.boundaries",{"title":46,"path":47,"stem":48},"Service Providers","\u002Fconcepts\u002Fservice-providers","2.concepts\u002F4.service-providers",{"title":50,"icon":51,"path":52,"stem":53,"children":54,"page":26},"Guides","i-lucide-book-marked","\u002Fguides","3.guides",[55,59,63,67,71,75,79,83,87,91,95],{"title":56,"path":57,"stem":58},"Add a Domain","\u002Fguides\u002Fadd-a-domain","3.guides\u002F01.add-a-domain",{"title":60,"path":61,"stem":62},"Share Code Between Layers","\u002Fguides\u002Fshare-code-between-layers","3.guides\u002F02.share-code-between-layers",{"title":64,"path":65,"stem":66},"Routes","\u002Fguides\u002Froutes","3.guides\u002F03.routes",{"title":68,"path":69,"stem":70},"Views and Components","\u002Fguides\u002Fviews-and-components","3.guides\u002F04.views-and-components",{"title":72,"path":73,"stem":74},"Seeders","\u002Fguides\u002Fseeders","3.guides\u002F05.seeders",{"title":76,"path":77,"stem":78},"Configuration","\u002Fguides\u002Fconfiguration","3.guides\u002F06.configuration",{"title":80,"path":81,"stem":82},"Events","\u002Fguides\u002Fevents","3.guides\u002F07.events",{"title":84,"path":85,"stem":86},"Tests and CI","\u002Fguides\u002Ftesting-and-ci","3.guides\u002F08.testing-and-ci",{"title":88,"path":89,"stem":90},"Production","\u002Fguides\u002Fproduction","3.guides\u002F09.production",{"title":92,"path":93,"stem":94},"Remove a Layer","\u002Fguides\u002Fremoving-a-layer","3.guides\u002F10.removing-a-layer",{"title":96,"path":97,"stem":98},"Multi-tenancy","\u002Fguides\u002Fmulti-tenancy","3.guides\u002F11.multi-tenancy",{"title":100,"icon":101,"path":102,"stem":103,"children":104,"page":26},"Commands","i-lucide-terminal","\u002Fcommands","4.commands",[105,109,113,117,121,125,129,133,137,141,145],{"title":106,"path":107,"stem":108},"Overview","\u002Fcommands\u002Foverview","4.commands\u002F01.overview",{"title":110,"path":111,"stem":112},"osdd:start","\u002Fcommands\u002Fosdd-start","4.commands\u002F02.osdd-start",{"title":114,"path":115,"stem":116},"osdd:layer","\u002Fcommands\u002Fosdd-layer","4.commands\u002F03.osdd-layer",{"title":118,"path":119,"stem":120},"osdd:list","\u002Fcommands\u002Fosdd-list","4.commands\u002F04.osdd-list",{"title":122,"path":123,"stem":124},"osdd:check","\u002Fcommands\u002Fosdd-check","4.commands\u002F05.osdd-check",{"title":126,"path":127,"stem":128},"osdd:graph","\u002Fcommands\u002Fosdd-graph","4.commands\u002F06.osdd-graph",{"title":130,"path":131,"stem":132},"osdd:seed","\u002Fcommands\u002Fosdd-seed","4.commands\u002F07.osdd-seed",{"title":134,"path":135,"stem":136},"osdd:phpunit","\u002Fcommands\u002Fosdd-phpunit","4.commands\u002F08.osdd-phpunit",{"title":138,"path":139,"stem":140},"osdd:remove","\u002Fcommands\u002Fosdd-remove","4.commands\u002F09.osdd-remove",{"title":142,"path":143,"stem":144},"osdd:cache","\u002Fcommands\u002Fosdd-cache","4.commands\u002F10.osdd-cache",{"title":146,"path":147,"stem":148},"Generators","\u002Fcommands\u002Fmake-commands","4.commands\u002F11.make-commands",{"title":150,"icon":151,"path":152,"stem":153,"children":154,"page":26},"API Reference","i-lucide-book-open","\u002Fapi-reference","5.api-reference",[155,159,162,166],{"title":156,"path":157,"stem":158},"LayerServiceProvider","\u002Fapi-reference\u002Flayer-service-provider","5.api-reference\u002F1.layer-service-provider",{"title":34,"path":160,"stem":161},"\u002Fapi-reference\u002Flayers","5.api-reference\u002F2.layers",{"title":163,"path":164,"stem":165},"SeederRegistry","\u002Fapi-reference\u002Fseeder-registry","5.api-reference\u002F3.seeder-registry",{"title":76,"path":167,"stem":168},"\u002Fapi-reference\u002Fconfiguration","5.api-reference\u002F4.configuration",{"title":170,"icon":171,"path":172,"stem":173,"children":174,"page":26},"Integrations","i-lucide-puzzle","\u002Fintegrations","6.integrations",[175,179],{"title":176,"path":177,"stem":178},"Laravel Boost","\u002Fintegrations\u002Flaravel-boost","6.integrations\u002F1.laravel-boost",{"title":180,"path":181,"stem":182},"Tinker and IDE Helper","\u002Fintegrations\u002Ftinker-and-ide-helper","6.integrations\u002F2.tinker-and-ide-helper",{"title":184,"icon":185,"path":186,"stem":187,"children":188,"page":26},"Upgrade","i-lucide-arrow-up-circle","\u002Fupgrade","7.upgrade",[189],{"title":190,"path":191,"stem":192},"Upgrade from 2.x","\u002Fupgrade\u002Ffrom-2x","7.upgrade\u002F1.from-2x",{"id":194,"title":80,"body":195,"description":746,"extension":747,"links":748,"meta":749,"navigation":336,"path":81,"seo":750,"sitemap":751,"stem":82,"__hash__":752},"docs\u002F3.guides\u002F07.events.md",{"type":196,"value":197,"toc":740},"minimark",[198,207,212,227,279,282,286,317,466,476,509,519,522,547,551,558,669,683,687,705,722,736],[199,200,201,202,206],"p",{},"Laravel discovers the listeners of ",[203,204,205],"code",{},"app\u002FListeners"," on its own. It guesses each class name from the file path under the project root, so it skips the listeners of a layer. Turn on OSDD's discovery to register them too.",[208,209,211],"h2",{"id":210},"turning-it-on","Turning it on",[199,213,214,215,218,219,222,223,226],{},"Set ",[203,216,217],{},"osdd.events.discover"," to ",[203,220,221],{},"true"," in ",[203,224,225],{},"technical\u002Fosdd\u002Fconfig\u002Fosdd.php",":",[228,229,234],"pre",{"className":230,"code":231,"filename":225,"language":232,"meta":233,"style":233},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","'events' => [\n    'discover' => true,\n],\n","php","",[203,235,236,257,273],{"__ignoreMap":233},[237,238,241,245,249,251,254],"span",{"class":239,"line":240},"line",1,[237,242,244],{"class":243},"sMK4o","'",[237,246,248],{"class":247},"sfazB","events",[237,250,244],{"class":243},[237,252,253],{"class":243}," =>",[237,255,256],{"class":243}," [\n",[237,258,260,263,266,268,270],{"class":239,"line":259},2,[237,261,262],{"class":243},"    '",[237,264,265],{"class":247},"discover",[237,267,244],{"class":243},[237,269,253],{"class":243},[237,271,272],{"class":243}," true,\n",[237,274,276],{"class":239,"line":275},3,[237,277,278],{"class":243},"],\n",[199,280,281],{},"The value must be a real boolean: anything else throws when the application boots. Discovery is off by default.",[208,283,285],{"id":284},"what-is-discovered","What is discovered",[199,287,288,289,292,293,296,297,300,301,304,305,308,309,312,313,316],{},"Every class in a layer's ",[203,290,291],{},"Listeners"," folder, under its source directory (",[203,294,295],{},"src\u002FListeners"," for a layer mapped to ",[203,298,299],{},"src\u002F","), sub-folders included. OSDD names each file through the layer's ",[203,302,303],{},"autoload.psr-4",", then applies Laravel's own rules: each public ",[203,306,307],{},"handle*()"," or ",[203,310,311],{},"__invoke()"," method listens to the event class of its first parameter, union types included, and ",[203,314,315],{},"ShouldBeDiscovered"," is honoured.",[228,318,321],{"className":230,"code":319,"filename":320,"language":232,"meta":233,"style":233},"\u003C?php\n\nnamespace Functional\\Billing\\Listeners;\n\nuse Functional\\Orders\\Events\\OrderPlaced;\n\nclass SendInvoice\n{\n    public function handle(OrderPlaced $event): void\n    {\n        \u002F\u002F ...\n    }\n}\n","functional\u002Fbilling\u002Fsrc\u002FListeners\u002FSendInvoice.php",[203,322,323,332,338,361,366,390,395,405,411,441,447,454,460],{"__ignoreMap":233},[237,324,325,328],{"class":239,"line":240},[237,326,327],{"class":243},"\u003C?",[237,329,331],{"class":330},"sTEyZ","php\n",[237,333,334],{"class":239,"line":259},[237,335,337],{"emptyLinePlaceholder":336},true,"\n",[237,339,340,344,348,351,354,356,358],{"class":239,"line":275},[237,341,343],{"class":342},"sbssI","namespace",[237,345,347],{"class":346},"sBMFI"," Functional",[237,349,350],{"class":243},"\\",[237,352,353],{"class":346},"Billing",[237,355,350],{"class":243},[237,357,291],{"class":346},[237,359,360],{"class":243},";\n",[237,362,364],{"class":239,"line":363},4,[237,365,337],{"emptyLinePlaceholder":336},[237,367,369,372,374,376,379,381,383,385,388],{"class":239,"line":368},5,[237,370,371],{"class":342},"use",[237,373,347],{"class":330},[237,375,350],{"class":243},[237,377,378],{"class":330},"Orders",[237,380,350],{"class":243},[237,382,80],{"class":330},[237,384,350],{"class":243},[237,386,387],{"class":330},"OrderPlaced",[237,389,360],{"class":243},[237,391,393],{"class":239,"line":392},6,[237,394,337],{"emptyLinePlaceholder":336},[237,396,398,402],{"class":239,"line":397},7,[237,399,401],{"class":400},"spNyl","class",[237,403,404],{"class":346}," SendInvoice\n",[237,406,408],{"class":239,"line":407},8,[237,409,410],{"class":243},"{\n",[237,412,414,417,420,424,427,429,432,435,438],{"class":239,"line":413},9,[237,415,416],{"class":400},"    public",[237,418,419],{"class":400}," function",[237,421,423],{"class":422},"s2Zo4"," handle",[237,425,426],{"class":243},"(",[237,428,387],{"class":346},[237,430,431],{"class":243}," $",[237,433,434],{"class":330},"event",[237,436,437],{"class":243},"):",[237,439,440],{"class":342}," void\n",[237,442,444],{"class":239,"line":443},10,[237,445,446],{"class":243},"    {\n",[237,448,450],{"class":239,"line":449},11,[237,451,453],{"class":452},"sHwdD","        \u002F\u002F ...\n",[237,455,457],{"class":239,"line":456},12,[237,458,459],{"class":243},"    }\n",[237,461,463],{"class":239,"line":462},13,[237,464,465],{"class":243},"}\n",[199,467,468,471,472,475],{},[203,469,470],{},"OrderPlaced::dispatch($order)"," now runs ",[203,473,474],{},"SendInvoice::handle()",". Generate a listener in a layer with:",[228,477,481],{"className":478,"code":479,"language":480,"meta":233,"style":233},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","php artisan osdd:listener SendInvoice --event='\\Functional\\Orders\\Events\\OrderPlaced' --layer=functional\u002Fbilling\n","bash",[203,482,483],{"__ignoreMap":233},[237,484,485,487,490,493,496,499,501,504,506],{"class":239,"line":240},[237,486,232],{"class":346},[237,488,489],{"class":247}," artisan",[237,491,492],{"class":247}," osdd:listener",[237,494,495],{"class":247}," SendInvoice",[237,497,498],{"class":247}," --event=",[237,500,244],{"class":243},[237,502,503],{"class":247},"\\Functional\\Orders\\Events\\OrderPlaced",[237,505,244],{"class":243},[237,507,508],{"class":247}," --layer=functional\u002Fbilling\n",[199,510,511,514,515,518],{},[203,512,513],{},"--event=OrderPlaced"," names an event of the layer itself (",[203,516,517],{},"Functional\\Billing\\Events\\OrderPlaced","); start the name with a backslash for an event of another layer.",[199,520,521],{},"A file that does not declare the class its path names is skipped.",[523,524,525],"note",{},[199,526,527,530,531,534,535,222,537,540,541,546],{},[203,528,529],{},"functional\u002Fbilling"," uses an event of ",[203,532,533],{},"functional\u002Forders"," here: require ",[203,536,533],{},[203,538,539],{},"functional\u002Fbilling\u002Fcomposer.json",", or ",[542,543,544],"a",{"href":123},[203,545,122],{}," reports it.",[208,548,550],{"id":549},"listeners-registered-by-hand","Listeners registered by hand",[199,552,553,554,557],{},"The discovered listeners are registered once the application has booted, after every provider's ",[203,555,556],{},"boot()",". A listener already registered for the same event and the same method is skipped, so these run once:",[228,559,561],{"className":230,"code":560,"language":232,"meta":233,"style":233},"Event::listen(OrderPlaced::class, SendInvoice::class);\nEvent::listen(OrderPlaced::class, SendInvoice::class.'@handle');\nEvent::listen(OrderPlaced::class, [SendInvoice::class, 'handle']);\n",[203,562,563,594,628],{"__ignoreMap":233},[237,564,565,568,571,574,576,578,580,582,585,587,589,591],{"class":239,"line":240},[237,566,567],{"class":346},"Event",[237,569,570],{"class":243},"::",[237,572,573],{"class":422},"listen",[237,575,426],{"class":243},[237,577,387],{"class":346},[237,579,570],{"class":243},[237,581,401],{"class":342},[237,583,584],{"class":243},",",[237,586,495],{"class":346},[237,588,570],{"class":243},[237,590,401],{"class":342},[237,592,593],{"class":243},");\n",[237,595,596,598,600,602,604,606,608,610,612,614,616,618,621,624,626],{"class":239,"line":259},[237,597,567],{"class":346},[237,599,570],{"class":243},[237,601,573],{"class":422},[237,603,426],{"class":243},[237,605,387],{"class":346},[237,607,570],{"class":243},[237,609,401],{"class":342},[237,611,584],{"class":243},[237,613,495],{"class":346},[237,615,570],{"class":243},[237,617,401],{"class":342},[237,619,620],{"class":243},".'",[237,622,623],{"class":247},"@handle",[237,625,244],{"class":243},[237,627,593],{"class":243},[237,629,630,632,634,636,638,640,642,644,646,649,652,654,656,658,661,664,666],{"class":239,"line":275},[237,631,567],{"class":346},[237,633,570],{"class":243},[237,635,573],{"class":422},[237,637,426],{"class":243},[237,639,387],{"class":346},[237,641,570],{"class":243},[237,643,401],{"class":342},[237,645,584],{"class":243},[237,647,648],{"class":243}," [",[237,650,651],{"class":346},"SendInvoice",[237,653,570],{"class":243},[237,655,401],{"class":342},[237,657,584],{"class":243},[237,659,660],{"class":243}," '",[237,662,663],{"class":247},"handle",[237,665,244],{"class":243},[237,667,668],{"class":243},"]);\n",[199,670,671,672,674,675,678,679,682],{},"in a provider's ",[203,673,556],{},", or in the ",[203,676,677],{},"$listen"," array of an event service provider. A listener registered later, in a ",[203,680,681],{},"booted()"," callback or at runtime, is not seen and runs twice. Remove the hand-written registrations when you turn discovery on.",[208,684,686],{"id":685},"in-production","In production",[199,688,689,692,693,696,697,700,701,704],{},[203,690,691],{},"php artisan event:cache",", which ",[203,694,695],{},"php artisan optimize"," runs, caches the layer listeners with the application's ones, so a request never scans the folders. They are stored under the ",[203,698,699],{},"Lomkit\\Osdd\\Events\\LayerEventServiceProvider"," key of ",[203,702,703],{},"bootstrap\u002Fcache\u002Fevents.php","; OSDD registers that provider for you.",[199,706,707,708,710,711,714,715,717,718,721],{},"As with ",[203,709,205],{},", a listener added after ",[203,712,713],{},"event:cache"," stays unregistered until ",[203,716,713],{}," runs again, and ",[203,719,720],{},"event:clear"," goes back to scanning. Check the result with:",[228,723,725],{"className":478,"code":724,"language":480,"meta":233,"style":233},"php artisan event:list\n",[203,726,727],{"__ignoreMap":233},[237,728,729,731,733],{"class":239,"line":240},[237,730,232],{"class":346},[237,732,489],{"class":247},[237,734,735],{"class":247}," event:list\n",[737,738,739],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":233,"searchDepth":240,"depth":259,"links":741},[742,743,744,745],{"id":210,"depth":259,"text":211},{"id":284,"depth":259,"text":285},{"id":549,"depth":259,"text":550},{"id":685,"depth":259,"text":686},"Register the listeners of every layer without Event::listen(), like the ones of app\u002FListeners.","md",null,{},{"title":80,"description":746},{"loc":81},"g2YrgV-Ts9rA1Jxc1VUOKCrQUv5AyF5PR1dWFnNko-A",[754,756],{"title":76,"path":77,"stem":78,"description":755,"children":-1},"Give a layer its own config file, and override the config of Laravel or any package from a layer.",{"title":84,"path":85,"stem":86,"description":757,"children":-1},"Give each layer its own test suite, run one layer's tests, and fail pull requests that cross a boundary.",1794437211549]