{
  "schemaVersion": 1,
  "packageName": "marionette",
  "packageVersion": "5.0.0-beta.1",
  "channel": "next",
  "publication": "beta (published on npm)",
  "sourceRepository": "https://github.com/marionettejs/marionette",
  "sourceRevision": "b06750c507494441f0b2298766b70087e45346a2",
  "sourceDirty": false,
  "sourceContentSha256": "3fe8788a771994d9effd124fee94d7444637a27ec974a5b520ccbf43b55bbec9",
  "publicationEditsSha256": "b52572096cfa1a8dfe8ceaacf72fe7f378f26208fe946f2cb6ad612598ebd64b",
  "documents": [
    {
      "id": "docs/readme.md",
      "title": "Documentation",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/",
      "markdownUrl": "https://marionettejs.com/docs/index.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/readme.md",
      "sourceSha256": "53351f26653e57cdb5acd0b68e84e7b427055a61bdbdec18d026a3fb4f52c5c7",
      "sha256": "7f73d9a4ff2f5ec0af5843ea7b954c0afc6160d925850f54e98cc702e060a668",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 53351f26653e57cdb5acd0b68e84e7b427055a61bdbdec18d026a3fb4f52c5c7. -->\n\n# Build your first piece of UI\n\nA View handles a piece of the interface. A Region puts it on the page and cleans\nit up when it is replaced. Start there; add the other pieces when you need them.\n\n## Where do you want to start?\n\n- **[Build something](/docs/installation.md#quick-start)** — set up Marionette and show your first View.\n- **[Work with an agent](/docs/agents.md)** — give your agent the right contract and a concrete task.\n- **[Look up an API](/docs/public-api.md)** — find the class, method, or integration you need.\n\n## A button that does something\n\nWith a [matching v5 build](/docs/installation.md#install) installed, add a place for the\nView in your HTML:\n\n```html\n<main id=\"app\"></main>\n```\n\nThen run this module in your application:\n\n<!-- executable-example: first-view-counter -->\n```javascript\nimport { Region, View } from 'marionette';\n\nconst Counter = View.extend({\n  initialize() { this.count = 0; },\n  template: ({ count }) => `<button type=\"button\">Count: <span>${count}</span></button>`,\n  templateContext() { return { count: this.count }; },\n  events: { 'click button': 'increment' },\n  increment() {\n    this.count += 1;\n    this.el.querySelector('span').textContent = String(this.count);\n  }\n});\n\nexport const region = new Region({ el: '#app' });\nregion.show(new Counter());\n```\n\nClick the button: **Count: 0 → Count: 1 → Count: 2**. The View handles the click\nand updates the number in place. The button stays the same DOM element.\n\nWhen that part of the screen is finished, `region.empty()` destroys the View and\nremoves its event handlers. The `#app` mount remains, ready for the next View.\n\n## Give it a little more to do\n\n| You want to… | Next step |\n| --- | --- |\n| Show a list that changes | [Render children with CollectionView](/docs/collection-view.md) |\n| Open a detail screen | [Show and replace a View](/docs/region.md) |\n| Save a form without losing a draft | [Forms and accessibility](/docs/forms-and-accessibility.md) |\n| Connect an existing router or data source | [Choose integrations](/docs/choosing-integrations.md) |\n| Check that it works | [Test an application](/docs/testing.md) |\n\nYou can keep Backbone models, an existing router, or a preferred template system.\nChoose each integration for the job it does; the button above needs none of them.\n\nFor versions before v5, see the [backbone.marionette repository](https://github.com/marionettejs/backbone.marionette).\n\n\n[Canonical source](/docs/markdown/docs/readme.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/installation.md",
      "title": "Install and show a View",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/installation/",
      "markdownUrl": "https://marionettejs.com/docs/installation.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/installation.md",
      "sourceSha256": "54ce13baa827d4d776eca1dd8db948c5227d20460dad672e6483aea0c49dcaa9",
      "sha256": "fdd88cef2835ae795727e379c4d6e928eb88292020a0fc57c0ffb5a7e8808b77",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 54ce13baa827d4d776eca1dd8db948c5227d20460dad672e6483aea0c49dcaa9. -->\n\n# Installing Marionette\n\nInstall the core package, show a View, then add the integrations your application\nneeds. Native DOM APIs, plain objects, and function templates work out of the box.\n\nThis guide covers the published Marionette 5.0.0-beta.1 package and its matching companion packages.\n\n## Documentation Index\n\n* [Install](#install)\n* [Peer dependencies](#peer-dependencies)\n* [Quick start](#quick-start)\n* [TypeScript](#typescript)\n* [Independent runtimes](#independent-runtimes)\n* [Observable data sources](#observable-data-sources)\n* [Distribution formats](#distribution-formats)\n* [Backbone is optional](#backbone-is-optional)\n* [jQuery DOM adapter is optional](#jquery-dom-adapter-is-optional)\n* [DOM content adapters are optional](#dom-content-adapters-are-optional)\n* [Current v5 documentation](/docs/index.md)\n\n## Install\n\nThe v5 package name is `marionette`.\n\n```bash\nnpm install marionette@5.0.0-beta.1\n```\n\nThe beta is available on npm. Pin this exact version and use the matching documentation. For unreleased changes, build and pack a known source revision separately.\n\n> The v4 package name has changed. See the [upgrade guide](/docs/upgrade-guide.md)\n> for migration guidance from earlier releases.\n\nCore and `@mnjs/data` automatically install the matching `@mnjs/utils`\nversion. Applications do not need a separate install unless they import helpers\ndirectly. During prereleases, keep Marionette packages on the same version. See the\n[shared helpers](/docs/common.md#shared-helpers) for reusable component helpers.\n\n## Peer dependencies\n\nMarionette v5 core has no peer dependencies. The separate\n`@mnjs/adapters` package requires the matching Marionette version and\ndeclares the integration-specific peers as optional.\n\n| Peer | Required? | When you need it |\n|---|---|---|\n| `marionette` `5.0.0-beta.1` | Required | The matching core runtime configured with an adapter. |\n| `backbone` `^1.4.0` | Optional | Only if your app imports `@mnjs/adapters/backbone`. See [Backbone is optional](#backbone-is-optional). |\n| `@types/backbone` `^1.4.23` | Optional | TypeScript declarations for `@mnjs/adapters/backbone`. JavaScript consumers do not need it. |\n| `jquery` `^4.0.0` | Optional | Only if your app uses the `@mnjs/adapters/dom/jquery` adapter. See [jQuery DOM adapter is optional](#jquery-dom-adapter-is-optional). |\n| `@types/jquery` `^4.0.1` | Optional | TypeScript declarations for `@mnjs/adapters/dom/jquery`. JavaScript consumers do not need it. |\n| `morphdom` `^2.7.8` | Optional | Only if your app imports `@mnjs/adapters/dom/morphdom`. |\n| `lit-html` `^3.3.3` | Optional | Only if your app imports `@mnjs/adapters/dom/lit-html`. |\n\nOptional peers are installed only when you opt into them:\n\n```bash\n# Only if you use the Backbone integration\nnpm install @mnjs/adapters@5.0.0-beta.1 backbone\n\n# Only if you use the jQuery DomApi adapter\nnpm install @mnjs/adapters@5.0.0-beta.1 jquery\n\n# Only if you use XState actors\nnpm install @mnjs/adapters@5.0.0-beta.1 xstate\n```\n\nThe XState actor adapter does not import or declare XState as a peer. Install\nXState alongside the adapter; the adapter consumes its public actor shape.\n\nNpm does not install missing optional peers. TypeScript consumers of an optional\nsubpath must install its matching type package explicitly:\n\n```bash\n# Only if TypeScript imports @mnjs/adapters/backbone\nnpm install --save-dev @types/backbone@^1.4.23\n\n# Only if TypeScript imports @mnjs/adapters/dom/jquery\nnpm install --save-dev @types/jquery@^4.0.1\n```\n\nMarionette core does not import or require Underscore. Install it as an\napplication dependency only when your own code uses it, such as an `_.template`\nused by a View.\n\n## Quick start\n\nMarionette v5 exposes its public API through named ESM imports. There is no\ndefault-namespace export; use named imports only. Add a mount element to the page\nbefore running the module:\n\n```html\n<div id=\"app\"></div>\n```\n\n```js\nimport { Application, View } from 'marionette';\n\nconst RootView = View.extend({\n  template: () => '<div>Hello, Marionette.</div>'\n});\n\nconst app = new Application({\n  region: document.getElementById('app'),\n  onStart() {\n    this.showView(new RootView());\n  }\n});\n\nawait app.start();\n```\n\n`View` and `CollectionView` accept a DOM element for `el`. They do not resolve\nselector strings — pass `document.querySelector('#root')` at the call site. See\nthe [upgrade guide](/docs/upgrade-guide.md) for the migration entry. `Region` continues\nto accept selector strings.\n\n## TypeScript\n\nMarionette 5.0.0-beta.1 includes declarations for TypeScript 6 and 7, with ESM and\nCommonJS entrypoints. Core needs no separate `@types` package. Annotate `initialize`\nto describe a View's application options; TypeScript uses that signature to check\nconstruction and `this.options`.\n\n```ts\nimport { View } from 'marionette';\n\nconst MessageView = View.extend({\n  template: false,\n  initialize(options: { message: string }) {\n    this.el.textContent = options.message;\n  },\n  message(): string {\n    return this.options.message;\n  }\n});\n\nconst view = new MessageView({ message: 'Hello, Marionette.' });\ndocument.body.append(view.render().el);\n```\n\nThis View requires a string `message`. Missing options or a numeric message are\ncompile errors. `template: false` preserves the text set during initialization.\n\nNamed imports work with `NodeNext` or bundler module resolution. The\n[consumer TypeScript guide](/docs/typescript.md) covers application options,\nDOM events, module resolution, and inheritance choices. Optional\nintegrations may need their own type packages, listed above.\n\n## Independent runtimes\n\nThe named root exports form one default runtime. Use `createMarionette()` only when\nindependent applications in the same process need isolated classes, adapters,\nrenderer configuration, or Radio channels:\n\n```javascript\nimport { createMarionette } from 'marionette';\n\nconst isolated = createMarionette();\nconst IsolatedView = isolated.View.extend({ template: () => 'Independent' });\n```\n\nSee [Runtime isolation](/docs/runtime-isolation.md) for composition and ownership rules.\n\n## Observable data sources\n\nCore's default DataApi supports plain objects and static arrays without a required\ndependency. Backbone Models and Collections are observable sources too; retain\nthem through the [Backbone adapter](/docs/backbone.md) when the application\nalready uses them. For a new application needing observable Model and ordered\nCollection sources, the optional `@mnjs/data` package is the native choice:\n\n```bash\nnpm install @mnjs/data@5.0.0-beta.1\n```\n\nConfigure its adapters before constructing owners. See the\n[`@mnjs/data` guide](/docs/data-api.md#optional-mnjsdata-sources) for a\ncomplete adapter setup and rendered list example.\n\nApplications using XState actors can select an ordered array of child actor\nreferences through `@mnjs/adapters/xstate`. See\n[XState actors](/docs/data-api.md#xstate-actors).\n\n## Distribution formats\n\nES modules are the canonical path for new applications. Use `import` syntax so\npackage export conditions select the ESM entry, and use Marionette's named exports.\n\nMarionette also ships compatibility distributions throughout v5:\n\n- CommonJS supports legacy Node and build-tool consumers through\n  `require('marionette')`.\n- Unminified and minified UMD builds support no-bundler, AMD, and\n  `Marionette`-global consumers.\n\nAll four ESM, CommonJS, unminified UMD, and minified UMD outputs remain supported\nand distribution-validated for v5. Marionette will not add another format or switch\nto unbundled source modules without measured consumer benefit. Six months after\nv5.0.0 is published, the distribution review is an evidence checkpoint for a\nfuture major version, not a removal commitment.\n\n## Backbone is optional\n\nStarting with v5, Marionette core does not depend on Backbone at runtime. Plain\nobjects and arrays use the default DataApi. Applications passing Backbone Models\nor Collections to Marionette must configure the Backbone DataApi before\nconstructing those consumers:\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport { setDataApi } from 'marionette';\n\nsetDataApi(BackboneApi);\n```\n\nThis configures model and collection use. Select the StateApi role separately\nwhen an owner uses Backbone state; see [Optional Backbone](/docs/backbone.md).\n[Data API](/docs/data-api.md) describes the neutral runtime contract.\n\n## jQuery DOM adapter is optional\n\nMarionette v5 core is jQuery-free. The default DOM API uses native browser\nmethods, and `view.$(selector)` returns a `NodeList`.\n\nApplications that want jQuery-shaped results from Marionette's DOM helpers —\nfor example, `view.$(selector)` returning a jQuery collection — can opt into\nthe optional `@mnjs/adapters/dom/jquery` adapter at app boot:\n\n```javascript\nimport { setDomApi } from 'marionette';\nimport JQueryDomApi from '@mnjs/adapters/dom/jquery';\n\nsetDomApi(JQueryDomApi);\n```\n\nThe adapter imports `jquery`, so this integration requires `jquery` only when you\nselect that adapter. If existing code also uses `$el`, assign `this.$el = $(this.el)` in\nits View, CollectionView, or Behavior `initialize()` method. See the [upgrade guide](/docs/upgrade-guide.md) for the migration entries on jQuery DOM\ncompatibility and the `detachContents` policy.\n\n## DOM content adapters are optional\n\nUse the same `@mnjs/adapters` package for incremental rendering. Install\nonly the DOM library you select:\n\n```bash\nnpm install @mnjs/adapters@5.0.0-beta.1 morphdom\n# or\nnpm install @mnjs/adapters@5.0.0-beta.1 lit-html\n```\n\nImport `MorphdomDomApi` from `@mnjs/adapters/dom/morphdom`, or\n`LitDomApi` from `@mnjs/adapters/dom/lit-html`, and pass it to\n`ViewClass.setDomApi()` before creating instances. Each adapter preserves unrelated\nDOM operations. Lit supplies the attachment hooks its directives need. DataApi and StateApi\nconfiguration remains explicit and separate.\n\nSee [Rendering to DOM](/docs/rendering.md#rendering-to-dom)\nfor examples and lifecycle requirements.\n\n## Getting Started\n\n[Choose a class for the job](/docs/classes.md), or learn the\n[shared configuration patterns](/docs/basics.md).\n\n\n[Canonical source](/docs/markdown/docs/installation.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/beta.md",
      "title": "Try the beta candidate",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/beta/",
      "markdownUrl": "https://marionettejs.com/docs/beta.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/beta.md",
      "sourceSha256": "f5ccc6d0dcfa278a26c6f2616d07dda2b33a620eb46f932549cd2d12442e9f32",
      "sha256": "136904dde3bd7dd4f0888a6c6fed9fb0297d2dc1eb3e4e7936ec4797d3a6040a",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 f5ccc6d0dcfa278a26c6f2616d07dda2b33a620eb46f932549cd2d12442e9f32. -->\n\n# Try Marionette v5 beta\n\n`5.0.0-beta.1` is published on npm and ready for application trials. Install the exact registry version. A locally built artifact with the same version string may differ from the published release.\n\n## What beta means\n\nThe intended architecture is ready for application trials: named core imports,\nView and Region ownership, synchronous UI lifecycle, Application asynchronous\ncoordination, optional data/state providers, and first-party package declarations.\nUse those documented public contracts. Beta feedback can still change an API before\nstable; record any change in migration guidance and the release notes.\n\nThis beta makes no comparative agent-effectiveness claim. The public corpus remains\nan unscored prototype. Architecture lint, generated method metadata, development\ninspection, and additional test helpers are separate work, not installed features.\n\nCore is `marionette`. The companion packages are `@mnjs/utils`,\n`@mnjs/radio`, `@mnjs/data`, and `@mnjs/adapters`. Keep all package\nversions aligned; install optional providers only when needed. See\n[the migration ledger](/docs/migration-from-v4.md) and [upgrade guide](/docs/upgrade-guide.md).\nOlder registry alphas are different implementations and do not define this beta's API.\n\n## Start in an empty directory\n\nInstall core and the optional native data package explicitly:\n\n```sh\nmkdir my-marionette-app\ncd my-marionette-app\nnpm init -y\nnpm install marionette@5.0.0-beta.1 @mnjs/data@5.0.0-beta.1\ncp -R node_modules/marionette/dist/docs/starter ./starter\ncd starter\nnpm install marionette@5.0.0-beta.1 @mnjs/data@5.0.0-beta.1\nnpm test\nnpm run build\nnpm run dev\n```\n\nThe starter README explains its files and trial steps. It is also available in the\n[source tree](https://github.com/marionettejs/marionette/tree/master/test/fixtures/data-package-starter).\nCopying uses a new directory and preserves existing application files. The commands\nabove use a POSIX shell; on Windows, copy the same folder using your file manager.\n\nBefore publication, replace each runtime install with one `npm install` invocation\ncontaining all five absolute candidate tarball paths. The required companions are\nnot assumed to exist on npm. Use artifacts from the same `release-evidence.json`;\nkeep their SHA-512 checksums and source commit with your trial report. Do not use\n`npm link`, a Git dependency, or source imports as proof of the published install path.\n\nThe starter has editable rows, asynchronous local selection, deliberate cancellation,\nand teardown. It has no backend, persistence, or URL router. Connect its `navigate`\nfunction to the application's chosen router when URLs are needed. See\n[routing](/docs/routing.md) for loader failure, navigation away, and stop/restart rules.\nUse [TypeScript guidance](/docs/typescript.md) when adding typed application code.\n\n## Check a real feature\n\n1. Edit a row title without opening it. Reverse rows; the draft should survive.\n2. Open the slow first note, then immediately open the second. The second should remain.\n3. Change a module during `npm run dev`. The old workspace should release its handlers.\n4. Run `npm test` and `npm run build`. Add a regression for your application's behavior.\n5. Test keyboard focus and selection in a real browser using the actual DOM adapter.\n6. Install the [consumer agent skill](/docs/agent-tools.md) if useful, then ask it to locate\n   the installed docs and identify the component responsible for cancellation.\n\nThe installed-consumer fixture checks the starter outside the repository against\ncandidate tarballs. The browser release matrix checks its draft, focus, selection,\nstale-load suppression, and handler cleanup in Chromium, Firefox, and WebKit.\nThose checks do not establish accessibility for an entire application or a router's\nhistory/deployment behavior.\n\n## Report feedback\n\n[Open a reproducible issue](https://github.com/marionettejs/marionette/issues/new/choose)\nwith the exact package versions/source revision, selected providers, browser and\nbundler, expected behavior, actual behavior, and a minimal anonymous reproduction.\nPrioritize installation problems, incorrect declarations, lost editable state,\nlate navigation commits, leaked subscriptions, and confusing documentation.\nDo not include private application code or customer data.\n\n## Before publication\n\nA beta needs verified scope/publisher access for all five packages, a clean candidate\ncommit, and the full [exact-artifact validation](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/docs/release-promotion.md#dry-run).\nReview the beta notes, migration guidance and installed starter together. Record\nknown failures instead of claiming the beta is stable. Registry installation must\nbe checked immediately after publication; local tarball tests cannot prove npm\npermission, propagation, or trusted-publisher configuration.\n\n## If the beta fails in your application\n\nPin your previous working dependency versions and restore the matching application\ncode and lockfile. The old `marionette@5.0.0-alpha.2` is not an API-compatible rollback\nfor this candidate; there is currently no previous published matching five-package\nrelease. Existing v4 applications should retain their pre-migration revision and\n`backbone.marionette` lockfile until their beta trial succeeds.\n\nMaintainers must not overwrite a published beta version. Withdraw its recommendation,\ndeprecate a broken version with a specific reason, and publish a corrected beta.\nMove `next` only to a verified compatible prior release; if beta.1 is the first one,\nthere is no earlier beta to select. Preserve exact artifacts and failure evidence.\nSee [release recovery](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/docs/release-promotion.md#recovery-and-rollback).\n\n\n[Canonical source](/docs/markdown/docs/beta.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/agents.md",
      "title": "Build with an agent",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/agents/",
      "markdownUrl": "https://marionettejs.com/docs/agents.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/agents.md",
      "sourceSha256": "b72d3deaf8a4f9cb46a57f666f7a8f98d6ea0ffd6ca81ccbedf118a1e5d5d228",
      "sha256": "9911ce2b807e2139c7120e3486c768b60df95e34d85a7fc0b785cae8d33d1ecb",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 b72d3deaf8a4f9cb46a57f666f7a8f98d6ea0ffd6ca81ccbedf118a1e5d5d228. -->\n\n# Build with Marionette\n\nUse this guide when an agent is building or maintaining an application with\nMarionette. It links each decision to the same contracts a human reviewer uses.\nFor changes to Marionette itself, use the [maintainer guide](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/docs/maintainers/readme.md).\n\n## Establish the installed contract\n\nBefore choosing an API, inspect the application's package manifest, lockfile,\ninstalled declarations, and existing Marionette configuration. Record:\n\n- the installed `marionette` version and matching optional package versions;\n- whether the dependency comes from a published package, Git commit, or local build;\n- the source revision for a checkout or custom artifact;\n- the selected renderer, data/state sources, DOM integrations, and router.\n\nThis documentation matches the published Marionette 5.0.0-beta.1 package. A website example, a copied prompt, or a third-party search result is not proof that another installed version has that API. Check the installed version, exports, and declarations; reproduce uncertain behavior with a small test against that package.\n\nFor a fresh application, follow [installation](/docs/installation.md). For a v4\napplication, use the [migration guide](/docs/migration-from-v4.md) and\n[upgrade guide](/docs/upgrade-guide.md) before applying current patterns. Do not\nsilently upgrade dependencies to make an example fit.\n\n## Read for the task\n\n| Task | Start here | Verify |\n| --- | --- | --- |\n| Show or update a piece of UI | [View](/docs/view.md), [rendering](/docs/rendering.md) | The intended element and content change; relevant handlers still work after rendering. |\n| Replace part of a screen | [Region](/docs/region.md), [View lifecycle](/docs/lifecycle.md) | The outgoing View is cleaned up and the new View owns the intended mount. |\n| Render a changing list | [CollectionView](/docs/collection-view.md), [DataApi](/docs/data-api.md) | Stable item identity, correct ordering, removal cleanup, and preservation of surviving edits. |\n| Coordinate a feature or navigate | [Application](/docs/application.md), [routing](/docs/routing.md) | Startup success, stale navigation, failure, stop, and destruction. |\n| Choose data, state, rendering, or DOM integration | [Choosing integrations](/docs/choosing-integrations.md) | The chosen capability matches the source; configuring one integration does not implicitly configure another. |\n| Add local or shared state | [State sources](/docs/state.md) | The correct observer updates; destroying one borrower does not dispose shared state. |\n| Handle DOM or component events | [DOM interactions](/docs/dom-interactions.md), [events](/docs/events.md) | One intended response per interaction and no response after teardown. |\n| Diagnose a framework error | [Diagnostic catalog](/docs/diagnostics.md) | The invariant associated with the diagnostic code; do not match only error-message text. |\n\nRead the relevant page and its direct references. Load the full documentation only\nwhen the task requires a broader API review.\n\n## Choose the smallest supported pattern\n\nKeep the application's established integrations unless the task requires changing\nthem. For new code, start with the built-in defaults: native DOM APIs, function\ntemplates, and plain objects or arrays. Plain sources are not observable; update\nthe UI explicitly or select an observable integration when the task needs one.\n\nChoose data, state, rendering, and DOM capabilities independently. Follow the\n[integration decision order](/docs/choosing-integrations.md) before writing a custom\nadapter. Record the chosen provider and its registration point once in the\napplication's own architecture notes so later agents do not choose again.\n\nUse a View for interface ownership, a Region for placement, and a CollectionView\nfor repeated children. Use an Application when work has an asynchronous feature\nlifecycle. A plain function or class is enough when it needs none of these\ncontracts. The [class guide](/docs/classes.md) explains the boundaries.\n\nConfigure the selected runtime before creating its consumers. The default named\nexports share a runtime. Use [runtime isolation](/docs/runtime-isolation.md) when\nindependent configurations must coexist; do not create a runtime per View.\n\n## Make ownership and cancellation explicit\n\nFor each resource, name the owner and the operation that releases it. Let the\nowning Region or CollectionView manage its child Views through public APIs.\nUse [View lifecycle hooks](/docs/lifecycle.md) for external listeners, timers,\nand widgets according to their actual render, attachment, and destruction lifetime.\nA rerender must not accumulate resources; destroying a View must not leave them\nrunning.\n\nA supplied `state` source is borrowed. A `createState()` result is owned and uses\nthe configured StateApi's optional disposal hook when its owner is destroyed.\nMarionette does not infer ownership from which object first reads a source.\n\nAwait Application lifecycle operations when later work depends on their result.\nThey return `Promise<boolean>`: `true` means the target state was reached; `false`\nmeans the request was superseded. A current readiness failure rejects. Keep those\noutcomes distinct. Constructor hooks run synchronously, and completion hooks are synchronous\nnotifications; returning a Promise from them does not add readiness.\n\nPass the readiness hook's signal to cancellable work. After an asynchronous step,\ncheck that it still belongs to the active operation before committing application\nside effects. Marionette suppresses stale lifecycle completion; it cannot undo an\narbitrary write made by application code. Follow the complete\n[routing pattern](/docs/routing.md) for navigation and feature startup.\n\n## Prove the behavior in the application\n\nUse the application's existing test runner, scripts, and package manager. Library\nmaintenance commands are not a consumer project's test strategy.\n\nTest the successful interaction and the boundary most likely to break. For an\nasynchronous screen, navigate away while work is pending and ensure its stale\nresult cannot replace the current screen. For a list, edit a surviving row while\ninserting, removing, or reordering another row. For a subscription, destroy one\nconsumer and confirm the remaining consumer still receives updates.\n\nUse a real browser when correctness depends on focus, attachment, DOM event\npropagation, or editable state. A build or screenshot alone does not prove those\ninteractions. Use documented public APIs for assertions rather than private\nframework fields.\n\nWhen reporting a change, name the behavior, the tested package/source, the exact\ncommands or interactions performed, and any untested boundary. Keep changes\nfocused and avoid introducing runtime instrumentation merely to help an agent\nunderstand the code.\n\n## Use agent tools as another way to read the same docs\n\nFollow [Set up an agent](/docs/agent-tools.md) to install the consumer skill and read\nversion-matched packaged docs. Adapt the [application instruction template](/docs/application-agent-template.md)\nto preserve this project's actual decisions across tasks.\n\nA Markdown page or versioned documentation index can be read directly. A service\nsuch as Context7 can help locate the relevant passage, but verify its library and\nversion selection before using the result. When retrieval is unavailable, use the\nsame source documents in the repository or the matching documentation artifact.\n\nA documentation index does not install instructions into every agent. An\napplication's own agent instructions should link to this guide and record its\ninstalled version and architecture choices. They should not copy this entire guide\nor use this library's maintainer instructions as application policy.\n\nUse playground tools only to examine the example they control. Their results do\nnot establish behavior in your application. No hosted AI service or MCP server is\nrequired to use Marionette or follow this workflow.\n\n\n[Canonical source](/docs/markdown/docs/agents.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/classes.md",
      "title": "Choose a class",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/classes/",
      "markdownUrl": "https://marionettejs.com/docs/classes.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/classes.md",
      "sourceSha256": "b432d207b275e514a8c22614d66c9e72965ecf6aff5fd160daff0c5ecb7ad8db",
      "sha256": "e55e03ae39732d7b536522e0f38c71ce4179b21b14e8ed05970eb4f84cd02a7b",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 b432d207b275e514a8c22614d66c9e72965ecf6aff5fd160daff0c5ecb7ad8db. -->\n\n# Marionette Classes\n\nEach Marionette class has a job: render a piece of interface, manage where it goes,\nrepeat it, share an interaction, or coordinate a feature. Start with the job you\nneed, then follow the reference for its options and lifecycle.\n\nThe classes share [configuration and inheritance patterns](/docs/basics.md#class-based-inheritance)\nand a [common set of methods](/docs/common.md).\n\n## [Marionette.View](/docs/view.md)\n\nA `View` owns a piece of interface through its root element, `el`. It renders a\ntemplate, handles DOM interactions, and can divide a screen into Regions for child\nViews. Plain objects and function templates work with the default configuration.\n\n`View` includes:\n- [The DOM API](/docs/dom-api.md)\n- [Class Events](/docs/class-events.md#view-events)\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Child Event Bubbling](/docs/events.md#event-bubbling)\n- [Entity Events](/docs/entity-events.md)\n- [View Rendering](/docs/rendering.md)\n- [Prerendered Content](/docs/prerendered-dom.md)\n- [View Lifecycle](/docs/lifecycle.md)\n\nA `View` can have [`Region`s](#marionetteregion) and [`Behavior`s](#marionettebehavior)\n\n## [Marionette.CollectionView](/docs/collection-view.md)\n\nA `CollectionView` manages an ordered set of child Views inside its root element.\nUse it for rows, cards, or other repeated content. A plain array supplies a static\ncollection; an observable data integration can notify it of changes. You can also\nmanage child Views directly without supplying a collection.\n\n`CollectionView` includes:\n- [The DOM API](/docs/dom-api.md)\n- [Class Events](/docs/class-events.md#collectionview-events)\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Child Event Bubbling](/docs/events.md#event-bubbling)\n- [Entity Events](/docs/entity-events.md)\n- [View Rendering](/docs/rendering.md)\n- [Prerendered Content](/docs/prerendered-dom.md)\n- [View Lifecycle](/docs/lifecycle.md)\n\nA `CollectionView` can have [`Behavior`s](#marionettebehavior).\n\n## [Marionette.Region](/docs/region.md)\n\nA `Region` gives a View a place to appear. Showing a new View renders and attaches\nit; replacing or emptying the Region destroys its current View by default.\n\n`Region` includes:\n- [Class Events](/docs/class-events.md#region-events)\n- [The DOM API](/docs/dom-api.md)\n\n## [Marionette.Behavior](/docs/behavior.md)\n\nA `Behavior` shares interaction logic between Views, such as keyboard shortcuts or\na reusable button action. The host View constructs and cleans up its Behaviors.\n\n`Behavior` includes:\n- [Class Events](/docs/class-events.md#behavior-events)\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Entity Events](/docs/entity-events.md)\n\n## [Marionette.Application](/docs/application.md)\n\nAn `Application` coordinates a feature's asynchronous start, stop, restart, and\ndestruction. It can own child Applications and display a View through an optional\nRegion. Use it for work that should start and stop together.\n\n`Application` includes:\n- [Class Events](/docs/class-events.md#application-events)\n- [Radio API](/docs/radio.md#marionette-integration)\n- [Common Marionette Functionality](/docs/common.md)\n- [State API](/docs/state.md)\n\nAn `Application` can have a single [region](/docs/application.md#application-region).\n\n## [Marionette.MnObject](/docs/mn-object.md)\n\n`MnObject` gives a nonvisual object initialization, events, options, and cleanup.\nUse it when those conventions are useful without an element or an Application's\nasynchronous lifecycle.\n\n`MnObject` includes:\n- [Class Events](/docs/class-events.md#mnobject-events)\n- [Radio API](/docs/radio.md#marionette-integration).\n\n## [State sources and StateApi](/docs/state.md)\n\nGive a feature or View its own state, or pass in a source it should share.\n`StateApi` connects that source's notifications and cleanup to its owner.\n\n## Routing in Marionette\n\nChoose a router that fits your application. Route handlers can start an Application\nor show a View using ordinary application code.\n\n[Continue Reading](/docs/routing.md) about routing in Marionette.\n\n\n[Canonical source](/docs/markdown/docs/classes.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/basics.md",
      "title": "Configuration and inheritance",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/basics/",
      "markdownUrl": "https://marionettejs.com/docs/basics.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/basics.md",
      "sourceSha256": "3c4d2b2db02e5b83235bb223451236d37be9251ec7c8b29e9c32d83923463d32",
      "sha256": "38df7b22ced5ac44884ecb3f86cec653e494afa002ae2ae9592a072f2f32302a",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 3c4d2b2db02e5b83235bb223451236d37be9251ec7c8b29e9c32d83923463d32. -->\n\n# Common Marionette Concepts\n\nLearn the configuration patterns once, then use them across Marionette's classes.\nEach class's reference explains when it reads an option and whether it reads it\nagain. For checked application options, see the\n[TypeScript example](/docs/installation.md#typescript).\n\n## Documentation Index\n\n* [Importing Marionette](#importing-marionette)\n* [Class-based Inheritance](#class-based-inheritance)\n  * [Value Attributes](#value-attributes)\n  * [Functions Returning Values](#functions-returning-values)\n  * [Binding Attributes on Instantiation](#binding-attributes-on-instantiation)\n* [Common Marionette Functionality](/docs/common.md)\n\n## Importing Marionette\n\nInstall the v5 `marionette` package and use named imports:\n\n```javascript\nimport { Application, View } from 'marionette';\n\nconst view = new View();\nconst app = new Application();\n```\n\nV5 has no default namespace export. The separate `@mnjs/adapters` package\nprovides optional integration subpaths; see [Installing Marionette](/docs/installation.md)\nfor the entrypoints and their dependencies.\n\nExisting no-bundler applications may serve the published\n`dist/marionette.umd.js` artifact. It exposes the named API on the global\n`Marionette` object and supports `Marionette.noConflict()`. Package-based named\nimports are the canonical path for new applications.\n\n## Class-based Inheritance\n\nLike [Backbone](http://backbonejs.org/#Model-extend), Marionette provides a\npseudo-class `extend` method. [All built-in classes](/docs/classes.md), such as\n`View` and `MnObject`, provide this method.\n\nThe `protoProps` and `staticProps` hashes passed to `extend` contribute their own\nenumerable string and symbol keys. Non-enumerable and inherited input properties\nare ignored, except that an own `constructor` selects the child constructor even\nwhen it is non-enumerable. Enumerable string statics from the parent, including\ninherited ones, are copied to the child constructor.\n\nIn the example below, we create a new pseudo-class called `MyView`:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({});\n```\n\nYou can now create instances of `MyView` with JavaScript's `new` keyword:\n\n```javascript\nconst view = new MyView();\n```\n\n### Value Attributes\n\nWhen we extend classes, we can provide class attributes with specific values by\ndefining them in the object we pass as the `extend` parameter:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  className: 'bg-success',\n\n  template: () => '<div class=\"my-region\"></div>',\n\n  regions: {\n    myRegion: '.my-region'\n  },\n\n  modelEvents: {\n    change: 'removeBackground'\n  },\n\n  removeBackground() {\n    this.el.classList.remove('bg-success');\n  }\n});\n```\n\nWhen `MyView` creates its element, the element receives the `bg-success` class.\nWhen the View renders, the `myRegion` Region targets `.my-region` within that\nelement. Entity-event behavior is documented separately because it depends on\nan attached entity.\n\n### Functions Returning Values\n\nMany configuration attributes accept either a value or a function returning\nthat value. Attributes documented as value callbacks call the function with\nthe Marionette instance as `this`. A `template` function is the renderer itself\nand instead receives serialized data as its argument; it does not receive the\nView as `this`. Resolution timing is part of each attribute's contract; do not\nassume every function runs during construction or that every result is cached\nfor the object's lifetime.\n\n<!-- executable-example: basics-class-configuration -->\n```javascript\nimport { View } from 'marionette';\n\nlet cancelCalls = 0;\nlet defaultCalls = 0;\nlet overrideCalls = 0;\nlet templateContext;\nlet templateData;\n\nconst MyView = View.extend({\n  options() {\n    this.optionsResolutionCount = (this.optionsResolutionCount || 0) + 1;\n    return {\n      count: 1,\n      enabled: true,\n      label: 'default',\n      tone: 'quiet'\n    };\n  },\n\n  className() {\n    this.classNameResolutionCount = (this.classNameResolutionCount || 0) + 1;\n    return `notice-${this.getOption('tone')}`;\n  },\n\n  template(data) {\n    templateContext = this;\n    templateData = data;\n    return '<button class=\"save\">Save</button><button class=\"cancel\">Cancel</button>';\n  },\n\n  triggers: {\n    'click .cancel': 'cancel:default',\n    'click .save': 'save:default'\n  },\n});\n\nconst view = new MyView({\n  count: 0,\n  enabled: false,\n  label: null,\n  tone: 'urgent',\n  triggers: {\n    'click .save': 'save:override'\n  },\n});\n\nconst classNameBeforeRender = view.el.className;\n\nview.on('cancel:default', () => {\n  cancelCalls += 1;\n});\n\nview.on('save:default', () => {\n  defaultCalls += 1;\n});\n\nview.on('save:override', () => {\n  overrideCalls += 1;\n});\n\nview.render();\nview.el.querySelector('.save').click();\nview.el.querySelector('.cancel').click();\n\nexport {\n  cancelCalls,\n  classNameBeforeRender,\n  defaultCalls,\n  overrideCalls,\n  templateContext,\n  templateData,\n  view\n};\n```\n\nHere `options()` supplies class defaults, the constructor's `tone` wins, and\n`className()` resolves while the View creates its element. The constructor's\n`triggers` map replaces the class map rather than merging with it.\n\n### Function Context\n\nUse a normal method when a configuration callback needs the instance context.\nAn arrow function retains its surrounding lexical `this`, so it is appropriate\nonly when the callback does not need the Marionette instance.\n\n### Binding Attributes on Instantiation\n\nThe documented constructor options for each class can replace matching values\ndefined on its prototype. This supports runtime configuration such as a View's\nevents, triggers, model, collection, and Region definitions:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: () => '<a href=\"#details\">Details</a>'\n});\n\nconst myView = new MyView({\n  triggers: {\n    'click a': 'show:link'\n  }\n});\n```\n\nThis will set a trigger called `show:link` that will be fired whenever the user\nclicks an `<a>` inside the view.\n\nConstructor values replace matching class values; map options are not\nimplicitly deep-merged. For example:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: () => '<button class=\"save\">Save</button><a href=\"#details\">Details</a>',\n\n  triggers: {\n    'click @ui.save': 'save:form'\n  }\n});\n\nconst myView = new MyView({\n  triggers: {\n    'click a': 'show:link'\n  }\n});\n```\n\nIn this example, `show:link` is the only configured trigger. The constructor's\n`triggers` object completely replaces the class-defined object.\n\n## Setting Options\n\nEvery Marionette class stores its merged class defaults and constructor values\non `this.options`. `getOption(name)` reads a defined value from `this.options`\nbefore falling back to the instance. A constructor value of `false`, `null`, or\n`0` therefore remains an intentional override; only `undefined` falls through.\n\nResolved class defaults and constructor option hashes contribute their own\nenumerable string and symbol properties when Marionette builds `options`.\nInherited and non-enumerable properties are ignored. `mergeOptions` copies only\nthe requested own enumerable string options onto an instance.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  checkOption() {\n    console.log(this.getOption('foo'));\n  }\n});\n\nconst view = new MyView({\n  foo: 'some text'\n});\n\nview.checkOption();  // prints 'some text'\n```\n\nConstructor/default option merges use own enumerable string and symbol properties. See\n[`getOption` and `mergeOptions`](/docs/common.md#getoption) for the exact lookup and\ncopying boundaries.\n\n## Common Marionette Functionality\n\nMarionette has a few methods and core functionality that are common to [all classes](/docs/classes.md).\n\n[Continue Reading...](/docs/common.md).\n\n\n[Canonical source](/docs/markdown/docs/basics.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/terminology.md",
      "title": "Terminology",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/terminology/",
      "markdownUrl": "https://marionettejs.com/docs/terminology.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/terminology.md",
      "sourceSha256": "fcbcd95c6da1a64664fa7d4ad8c274b5aa648db94648b1d60434d47d71de7c21",
      "sha256": "7f32fedf7105689e6873026e967d7bc061b117def920c7f3b55c99b877aee44e",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 fcbcd95c6da1a64664fa7d4ad8c274b5aa648db94648b1d60434d47d71de7c21. -->\n\n# Terms used in these guides\n\nThese names describe what a value does, where it belongs, and who cleans it up.\nThe distinctions matter when connecting data, composing Views, or waiting for an\nApplication to finish starting.\n\n## Models, template data, and state\n\nA **model** is one value displayed by a View or represented by a CollectionView's\nchild View. It may be a plain object or a value from your chosen data library.\nAn **ordered model snapshot** is the current sequence returned by\n`DataApi.models(collection)`. Collection change records refer to those original\nmodels through `added`, `removed`, `previous`, and `current`.\n\n**Serialized data** is the value prepared for a template. The default\n`serializeCollection()` returns each model's serialized value; it does not return\nthe raw model snapshot. An override may return another shape. When the View has\nno model, its template receives that collection serialization result as `models`.\nSee [Rendering](/docs/rendering.md).\n\nA **state source** holds state for an Application, MnObject, View, CollectionView,\nor Behavior. `getState()` returns the source itself, with its own values and\nmethods. State is configured separately from the model or collection a View\ndisplays. See [State sources](/docs/state.md).\n\n| API | What it connects |\n| --- | --- |\n| [`DataApi`](/docs/data-api.md) | Model reads, template serialization, collection order, and data events. |\n| [`StateApi`](/docs/state.md#stateapi) | State events and cleanup of owned state. |\n| [`DomApi`](/docs/dom-api.md) | Element creation, selection, content, and attachment. |\n\nAn **adapter** implements the methods for one or more of these APIs using your\nchosen tools. Installing an integration package makes its adapter available;\nconfigure it on the runtime or class that will use it. DataApi, StateApi, and\nDomApi support partial overlays: supplied methods replace the corresponding\nmethods, while omitted methods remain inherited. An EventDelegator is a complete\nreplacement. See [Choosing integrations](/docs/choosing-integrations.md) before\nselecting or implementing an adapter.\n\n## Ownership and cleanup\n\nA Behavior's **host View** is the View it is attached to. A **child View** is shown\nby a Region or managed by a CollectionView. These names describe relationships;\na particular child might be a row, a card, or another item in your interface.\n\nA **parent Application** owns its registered child Applications. Parents locate\nand control children; children receive the collaborators they need explicitly.\nThe Application at the top of that hierarchy is its **root Application**.\n\nFor state, **borrowed** and **owned** describe who is responsible for disposal:\n\n- A supplied or declared `state` is borrowed. Destroying an owner releases that\n  owner's subscriptions and leaves the source available to other users.\n- A `createState()` result is owned. Destroying the owner releases its\n  subscriptions, then calls the selected StateApi's optional `disposeOwned()`.\n\nA **cleanup function** releases a subscription or other resource. **Idempotent**\nmeans repeated calls have the same effect as one call. Adapters must return\nidempotent subscription cleanup functions; core does not wrap each returned\ncleanup to establish that property.\n\n## Default and isolated runtimes\n\nThe named exports from `marionette` belong to the **default runtime**.\n`createMarionette()` returns an **isolated runtime** with its own classes,\nadapter and renderer configuration, and Radio channels. Choose one runtime's\nclasses and setters when composing that part of the application. See\n[Runtime isolation](/docs/runtime-isolation.md).\n\nA state source created for one owner is still an owned state source; it does not\ncreate another runtime. Current package imports use `marionette`; historical\nmigration guides may refer to the old `backbone.marionette` package name.\n\n## Application lifecycle and readiness\n\n`start()`, `stop()`, `restart()`, and `destroy()` are Application **lifecycle\noperations**. A **readiness hook** is one of `onBeforeStart`, `onBeforeStop`, or\n`onBeforeDestroy`. Marionette awaits a Promise returned by one of those hooks\nbefore completing that phase.\n\nThe corresponding `before:*` event listeners are synchronous notifications;\ntheir return values are not awaited. `onStart`, `onStop`, `onDestroy`, and their\nmatching events are **completion notifications** and are not awaited either.\nSee [Application lifecycle](/docs/application.md) for ordering,\ncancellation, and the readiness `AbortSignal`.\n\n\n[Canonical source](/docs/markdown/docs/terminology.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/agent-tools.md",
      "title": "Set up an agent",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/agent-tools/",
      "markdownUrl": "https://marionettejs.com/docs/agent-tools.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/agent-tools.md",
      "sourceSha256": "b9c15b709e30f4e670f65684743d51793ad041eb6de04f37b7be732dd04c0425",
      "sha256": "84ebeff9b9ed3660c3aa94a245ce5cf2ee82a981982ed802b133dcb86e2b1e92",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 b9c15b709e30f4e670f65684743d51793ad041eb6de04f37b7be732dd04c0425. -->\n\n# Set up an agent\n\nUse the installed package's documentation and a small application instruction file\nfirst. The optional Marionette skill helps an agent select those documents and\napply their lifecycle and integration rules. None of these resources requires an\naccount, network access, hosted model, or shared API key to read.\n\n## Install the consumer skill\n\nBuilds containing these resources ship `dist/agent-skill/` and `dist/docs/` inside\nthe `marionette` package. Check that both exist in your installed package before\nfollowing these steps; earlier artifacts do not contain them. Do not upgrade an\napplication just to install instructions.\n\nCopy the whole `dist/agent-skill/` directory, including `scripts/`, into the skill\nlocation supported by your agent client, naming the copied folder `marionette`.\nUse the client's documented installation mechanism; installing an npm dependency\ndoes not automatically activate an agent skill. For a source checkout, the same\nskill lives in `skills/marionette/`. Use the checkout matching the package's known\nsource revision.\n\nFor a client configured to read project skills from `.agents/skills`, run this\nfrom your application directory when that destination does not already exist:\n\n```sh\nmkdir -p .agents/skills\ncp -R node_modules/marionette/dist/agent-skill .agents/skills/marionette\n```\n\nAdapt the source path for a hoisted dependency or package manager without\n`node_modules`. When updating an existing copy, review its local changes and\nreplace it deliberately; do not create nested copies. Keep the skill in the\napplication's repository if the team should share it. Update it alongside the\npackage, reviewing any project-specific edits. Agent clients differ in discovery\nand reload behavior; follow the client's setup instructions and confirm that it\nlists `marionette` before relying on automatic selection.\n\nIn a client supporting named skill invocation, try:\n\n```text\nUse $marionette to inspect this application's installed version and integrations.\nFind the matching routing guide and explain which component owns cancellation.\nDo not change the application yet.\n```\n\nA successful activation identifies the installed package, reports its documentation\nrevision, reads the relevant page, and distinguishes the router from Marionette's\nlifecycle. A response that only repeats the prompt has not demonstrated retrieval.\nIf the client cannot load skills, give it [Build with Marionette](/docs/agents.md) and\nthe matching task guide directly; the skill is an optional entry point.\n\n## Read matching docs locally\n\nThe skill bundles a read-only helper requiring Node 24 or later. It addresses a\nspecific retrieval problem: the copied skill must locate the application's\ninstalled docs, including hoisted dependencies, without importing application code.\nIt does not add a server, registry, or production dependency.\n\n```sh\nnode .agents/skills/marionette/scripts/docs.mjs --project . --list\nnode .agents/skills/marionette/scripts/docs.mjs --project . --page docs/routing.md\n```\n\n`--list` returns JSON with absolute page paths, version, source revision, local\nchange status, and content digest. `--page` accepts an exact `source` path from\nthat list and prints one provenance record followed by the page's Markdown. Run\nfrom the application workspace, not a neighboring package with a different\nMarionette dependency. `--project` defaults to the current directory.\n\nFor a package manager without a physical `node_modules` tree, find that\napplication's physical package directory using its package manager and supply\n`--package-root /path/to/marionette`. The helper does not execute resolver hooks or\ninstall packages to guess that path. Exit status `1` indicates missing docs,\ninvalid arguments, a version mismatch, or inconsistent files; it does not silently\nswitch to a different source.\n\nThe helper validates documentation hashes and their package version. This proves\nthat the files agree with their manifest, not that an arbitrary custom runtime was\nbuilt from that revision. Check installed exports and test uncertain behavior. For local builds, the\nversion alone cannot identify a source commit; `sourceDirty: true` means\nlocal changes are included. Older packages without docs require an exact release\nor known source checkout, not an automatic fallback to today's website.\n\n## Record the application decisions\n\nAdapt the [application instruction template](/docs/application-agent-template.md).\nRecord actual integration choices, initialization points, resource owners, and\nworking test commands. Keep those decisions in the application. The library's\nmaintainer `AGENTS.md` describes changing Marionette itself and should not be\ncopied into a consumer application.\n\n## Choose an optional service only for a specific need\n\n| Resource | Useful for | Boundary |\n| --- | --- | --- |\n| Packaged Markdown and manifest | Reading the contract shipped with an installed package | Available offline; verify custom runtime provenance separately. |\n| Website Markdown and `llms.txt` | Discovering pages and reading a published snapshot | An index is a set of links, not automatic instruction installation. Check version and source metadata. |\n| Context7 | Finding relevant excerpts through a supported agent integration | Optional third-party retrieval; results can omit setup or mix versions. Verify against the exact source. |\n| Local skill helper | Finding and checking packaged docs from a consumer workspace | Reads files only; no network, project-code execution, or automatic fallback. |\n| Website WebMCP tools | Operating the website's interactive example | Controls that example, not the consumer application. It is not a remote documentation server. |\n\nFor Context7, use the public `marionettejs/marionette` library and the client's\nContext7 setup instructions. Each developer uses their own account and limits.\nDo not put a maintainer's API key in a website, repository, or shared public proxy.\nIf a free quota is exhausted, read the static or installed docs directly; do not\nenable paid overages. Check the current [Context7 plans](https://context7.com/plans)\nand [documentation](https://context7.com/docs) before configuring an account.\nPublic indexing does not prove that the latest source configuration is active.\n\nMarionette does not require a custom MCP server, a hosted AI chat, or a WebMCP\nconnection to build an application. A future local MCP wrapper would need to solve\na demonstrated client integration gap beyond reading these files. Keep tooling\noutside the production import graph and avoid duplicating the contract in tool\nprompts. The same documentation remains available to human readers.\n\n\n[Canonical source](/docs/markdown/docs/agent-tools.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/application-agent-template.md",
      "title": "Application agent instructions",
      "section": "Start here",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/application-agent-template/",
      "markdownUrl": "https://marionettejs.com/docs/application-agent-template.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/application-agent-template.md",
      "sourceSha256": "33e10afa4db7cf6bdf8e1bea95b5f810f0d69419e017408415ee269c2e5091de",
      "sha256": "97316b5362ca10cd602e4274854b9db9f080d89854fd758bb5c028f227245021",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 33e10afa4db7cf6bdf8e1bea95b5f810f0d69419e017408415ee269c2e5091de. -->\n\n# Record an application's agent instructions\n\nUse this template to record decisions an agent cannot safely infer from Marionette\nalone. It belongs in the application repository's instruction file, usually\n`AGENTS.md` when supported by the agent client. Merge it with existing instructions\ninstead of replacing unrelated project policy.\n\nFill each field from the installed package, lockfile, configuration, and actual\ntest scripts. Delete irrelevant fields. A question still being decided should be\nmarked unresolved, with the constraint that blocks the decision; do not turn a\nplaceholder into an invented default. Never put credentials or private customer\ndata in these instructions.\n\n```markdown\n# Marionette application context\n\n## Installed contract\n\n- Application workspace: [directory containing this application's manifest].\n- Marionette package/version and install source: [lockfile and resolved package].\n- Documentation: [installed dist/docs path or exact release/source snapshot].\n- Source revision and local changes, when known: [manifest provenance].\n- Optional Marionette packages: [actual versions, or none].\n\nUse matching documentation. Check the installed exports before adopting an API\nfrom an external example. Do not change dependency versions to make a snippet fit.\n\n## Integration decisions\n\n- Runtime and registration point: [actual module; shared or isolated and why].\n- Renderer/templates: [actual choice and setup module].\n- Data sources and DataApi: [actual choice, observability, registration or default].\n- State sources and StateApi: [actual choice, ownership, registration or default].\n- DomApi and EventDelegator: [actual choices or defaults].\n- Router: [actual library or none; URL/history owner].\n- Navigation/loading: [controller or feature owner; stale-result policy].\n\nPreserve compatible established choices. Select these capabilities independently;\na router choice does not imply a data, state, renderer, or DOM adapter change.\n\n## Ownership and verification\n\n- Root mount and View/Region owner: [actual entry point].\n- Shared resources and disposal owners: [actual subscriptions/state/widgets].\n- Unit/component check: [existing command and working directory].\n- Browser interaction check: [existing command and working directory].\n- Build/type check: [existing command and working directory].\n- Relevant existing patterns: [a few actual source or test paths].\n\nFor the changed behavior, verify the appropriate interaction and cleanup boundary.\nReport the checks actually run and anything left untested. Update this file when\nan application decision changes; keep the API reference in the matching docs.\n```\n\nKeep the completed file short. Link to substantial project architecture or test\nguides rather than copying them. The purpose is to preserve the application's\nchoices across tasks, not to prescribe a new router, test runner, or framework.\nFor skill installation and optional services, see [Set up an agent](/docs/agent-tools.md).\n\n\n[Canonical source](/docs/markdown/docs/application-agent-template.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.view.md",
      "title": "View",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/view/",
      "markdownUrl": "https://marionettejs.com/docs/view.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.view.md",
      "sourceSha256": "b7b5871b0b56474cc3bc2513c2e2c4fdabdafcd724bfbaa8076ea7eee40d5ab5",
      "sha256": "fa47943dac17b3812086bb370caef231c6c4ae13552a53583eb1f0d8b3c0b6f8",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 b7b5871b0b56474cc3bc2513c2e2c4fdabdafcd724bfbaa8076ea7eee40d5ab5. -->\n\n# Marionette.View\n\nA `View` manages one part of a screen: its content, DOM interactions, and child\nviews. Give it a template and data, and it renders into a root element, `el`.\nPlain objects and native DOM methods work by default.\n\nUse named [Regions](/docs/region.md) to give child views a place within\nthat element, and [Behaviors](/docs/behavior.md) to share interaction\nlogic across views.\n\n`View` includes:\n- [The DOM API](/docs/dom-api.md)\n- [Class Events](/docs/class-events.md#view-events)\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Child Event Bubbling](/docs/events.md#event-bubbling)\n- [Entity Events](/docs/entity-events.md)\n- [View Rendering](/docs/rendering.md)\n- [Prerendered Content](/docs/prerendered-dom.md)\n- [View Lifecycle](/docs/lifecycle.md)\n\nA `View` can have [`Region`s](/docs/region.md) and [`Behavior`s](/docs/behavior.md)\n\n## Documentation Index\n\n* [Instantiating a View](#instantiating-a-view)\n* [Method results and side effects](#method-results-and-side-effects)\n* [Rendering a View](#rendering-a-view)\n  * [Using a View Without a Template](#using-a-view-without-a-template)\n  * [Refreshing Root Attributes](#refreshing-root-attributes)\n* [View Lifecycle and Events](#view-lifecycle-and-events)\n* [Entity Events](#entity-events)\n* [DOM Interactions](#dom-interactions)\n* [Behaviors](#behaviors)\n* [Managing Children](#managing-children)\n  * [Laying Out Views - Regions](#laying-out-views---regions)\n  * [Showing a Child View](#showing-a-child-view)\n  * [Accessing a Child View](#accessing-a-child-view)\n  * [Detaching a Child View](#detaching-a-child-view)\n  * [Destroying a Child View](#destroying-a-child-view)\n  * [Region Availability](#region-availability)\n* [Efficient Nested View Structures](#efficient-nested-view-structures)\n* [Listening to Events on Children](#listening-to-events-on-children)\n\n## Instantiating a View\n\nWhen instantiating a `View` there are several properties, if passed,\nthat will be attached directly to the instance:\n`attributes`, `behaviors`, `childViewEventPrefix`, `childViewEvents`,\n`childViewTriggers`, `className`, `collection`, `collectionEvents`, `el`,\n`events`, `id`, `model`, `modelEvents`, `regionClass`, `regions`, `stateEvents`,\n`tagName`, `template`, `templateContext`, `triggers`, `ui`\n\n```javascript\nimport { View } from 'marionette';\n\nconst myView = new View({ template: () => '<p>Content</p>' });\n```\n\nThese properties are defined by Marionette's standalone `View` constructor.\nWhen Marionette creates the View's element, it copies own enumerable\n`attributes` properties, including symbols. The default DomApi applies string\nattribute names only; inherited and non-enumerable properties are not copied. When applied, `id` and `className` assignments occur\nafterward and override the corresponding `attributes` keys. See the\n[`DomApi.setAttributes` contract](/docs/dom-api.md#setattributesel-attrs).\n\n## Method results and side effects\n\nThese operations run synchronously. Use lifecycle hooks for additional work;\nreturning a Promise from a View hook does not delay rendering or destruction.\n\n| Method | Result | Effect |\n| --- | --- | --- |\n| `render()` | This View | Evaluates the template, updates contents and UI bindings. Rendering again resets its Regions and destroys their current children. `template: false` and a destroyed View make this a no-op. |\n| `renderAttributes()` | This View | Refreshes root attributes without rendering contents or recreating children. |\n| `destroy(options)` | This View | Removes the root element, destroys owned Regions/children and Behaviors, releases subscriptions and owned State. Repeated destruction is a no-op. |\n| `isRendered()`, `isAttached()`, `isDestroyed()` | Boolean | Read lifecycle state without rendering. Attachment is Marionette's tracked state; see [monitoring](/docs/lifecycle.md). |\n| `hasRegion(name)`, `getRegion(name)` | Boolean or Region/`undefined` | Read a named registration without rendering the parent. |\n| `getRegions()` | New name-to-Region object | Read registrations; changing this object does not change ownership. |\n| `showChildView(name, view, options)` | Supplied child View | Renders the parent if needed, then delegates to the named Region. The result alone does not establish adoption when `allowMissingEl` permits a missing mount. |\n| `getChildView(name)` | Current child or `undefined` | Renders the parent if needed before reading the named Region. |\n| `detachChildView(name)` | Detached child or `undefined` | Renders the parent if needed, then transfers a live child to the caller. |\n| `addRegion(name, definition)` | Registered Region | Constructs or registers a Region without rendering the parent. |\n| `addRegions(definitions)` | Map of added Regions, or `undefined` for no entries | Registers the batch; see [ownership constraints](/docs/region.md#reading-region-ownership). |\n| `removeRegion(name)` | Removed Region | Destroys that Region and its current child. |\n| `removeRegions()` | Map of removed Regions | Destroys every registered Region and its current child. |\n| `emptyRegions()` | Map of Regions | Renders the parent if needed, destroys current children, and keeps the Regions available. |\n\n`getChildView`, `showChildView`, `detachChildView`, and `removeRegion` require a\nregistered name and throw [`MN0020`](/errors/MN0020.md) when it is absent.\n`getRegion` returns `undefined` for an absent valid name. Region names must be non-empty strings; an empty string throws\n[`MN0032`](/errors/MN0032.md).\n\nA supplied `state` is borrowed rather than copied as a normal constructor\noption. See [State ownership](/docs/state.md#borrowed-and-owned-sources)\nfor `getState()`, `createState()`, subscriptions, and disposal.\n\n## Rendering a View\n\nThe Marionette View implements a powerful render method which, given a\n[`template`](/docs/rendering.md#setting-a-view-template), will build your\nHTML from that template, mixing in `model` or `collection` data and any\nextra [template context](/docs/rendering.md#adding-context-data).\n\nMarionette `View` defines `render`, and this method should not be overridden.\nTo add functionality around rendering, use the\n[`render` and `before:render` events](/docs/class-events.md#render-and-beforerender-events).\n\n\nFor more detail on how to render templates, see\n[View Template Rendering](/docs/rendering.md).\n\n### Using a View Without a Template\n\nWith [`template: false`](/docs/rendering.md#using-a-view-without-a-template),\n`render()` returns the View without changing its contents or running\n`before:render` and `render`. Other View events and DOM interactions remain\navailable. Use this for [`prerendered content`](/docs/prerendered-dom.md) that the\nView should preserve.\n\n### Refreshing Root Attributes\n\n`renderAttributes()` reevaluates a View's declarative `attributes`, `className`,\nand `id`, then applies those values to its existing root element. The method is\nalso available on `CollectionView`.\n\n<!-- executable-example: view-render-attributes -->\n```javascript\nimport { View } from 'marionette';\n\nconst SelectableRow = View.extend({\n  tagName: 'tr',\n\n  attributes() {\n    return {\n      'aria-selected': this.isSelected ? 'true' : 'false'\n    };\n  },\n\n  className() {\n    return this.isSelected ? 'danger' : null;\n  },\n\n  template: false,\n\n  setSelected(isSelected) {\n    this.isSelected = isSelected;\n    return this.renderAttributes();\n  }\n});\n\nconst row = new SelectableRow();\nconst rootElement = row.el;\n\nrow.setSelected(true);\n\nexport { rootElement, row };\n```\n\nWith the default DomApi, only an explicit `null` removes an attribute.\nAn `undefined` value or omitted key leaves the existing attribute untouched;\nMarionette does not retain the names returned by an earlier call. Other values,\nincluding `false`, `0`, and an empty string, use the browser's attribute string\nconversion. For boolean HTML attributes, declare `disabled: isDisabled ? '' : null`;\n`disabled: false` still creates a present attribute and disables the element.\n`id` and `className` continue to override matching keys from `attributes` when\nthey are declared. Live form properties such as `input.value` and `input.checked`\nshould be updated explicitly, separately from their default-value attributes.\n\nUse `className` as the View-level class declaration, as shown above. The\n`attributes` map continues to use raw DOM attribute names for lower-level cases.\nMarionette normalizes the View declaration to the `class` attribute before\ncalling the DomApi, including for a supplied SVG root.\n\n`renderAttributes()` returns the View. It does not call the template, emit the\nrender lifecycle, replace the root element, rebind `ui` or DOM events, or reset\nRegions. It is not called automatically by `render()`. Calls after destruction\nbegins are no-ops and do not resolve the attribute declarations.\n\nWhen a View uses a supplied `el`, construction still leaves that element's\nattributes unchanged. A later `renderAttributes()` call applies only the keys\nin the current declaration, so unrelated host attributes remain caller-owned.\n\n## View Lifecycle and Events\n\nAn instantiated `View` is aware of its lifecycle state and will throw events related to when that state changes.\n\nThe view states indicate whether the view is rendered, attached to the DOM, or destroyed.\n\nRead More:\n- [View Lifecycle](/docs/lifecycle.md)\n- [View DOM Change Events](/docs/class-events.md#dom-change-events)\n- [View Destroy Events](/docs/class-events.md#destroy-events)\n\n## Entity Events\n\nA `View` subscribes to its `model` and `collection` through the configured\n[DataApi](/docs/data-api.md). Event names and callback arguments belong to that data\nprovider. Plain objects and arrays do not emit changes; declaring entity event\nmaps for unobservable values throws `MN0037`.\n\nRead More:\n- [Entity Events](/docs/entity-events.md)\n\n## DOM Interactions\n\n`View` provides `events`, `triggers`, and `ui` for DOM interactions.\n\nRead More:\n- [DOM Interactions](/docs/dom-interactions.md)\n\n## Behaviors\n\nA `Behavior` provides a clean separation of concerns to your view logic,\nallowing you to share common user-facing operations between your views.\n\nRead More:\n- [Using `Behavior`s](/docs/behavior.md#using-behaviors)\n\n## Managing Children\n\n`View` provides a simple interface for managing child-views with\n[`showChildView`](#showing-a-child-view), [`getChildView`](#accessing-a-child-view), and\n[`detachChildView`](#detaching-a-child-view).\nThese methods all access `regions` within the view.\nWe will cover this here but for more advanced information, see the\n[documentation for regions](/docs/region.md).\n\n### Laying Out Views - Regions\n\nThe `View` class lets us manage a hierarchy of views using `regions`.\nRegions are a hook point that lets us show views inside views, manage the\nshow/hide lifecycles, and act on events inside the children.\n\n**This Section only covers the basics. For more information on regions, see the\n[Regions Documentation.](/docs/region.md)**\n\nRegions are ideal for rendering application layouts by isolating concerns inside\nanother view. This is especially useful for independently re-rendering chunks\nof your application without having to completely re-draw the entire screen every\ntime some data is updated.\n\nRegions can be added to a View at class definition, with [`regions`](/docs/region.md#defining-regions),\nor at runtime using [`addRegion`](/docs/region.md#adding-regions).\n\nWhen you extend `View`, we use the `regions` attribute to point to the selector\nwhere the new view will be displayed:\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template(`\n    <div id=\"first-region\"></div>\n    <div id=\"second-region\"></div>\n    <div id=\"third-region\"></div>\n  `),\n  regions: {\n    firstRegion: '#first-region',\n    secondRegion: '#second-region'\n  }\n});\n```\n\n\nWhen we show views in the region, the contents of `#first-region` and\n`#second-region` will be replaced with the root element of the child View we show. The\nstring values in this example are CSS selectors scoped to the `View`'s `el`.\n\n### Showing a Child View\n\nTo show a view inside a region, simply call `showChildView(regionName, view)`. This\nwill handle rendering the view's HTML and attaching it to the DOM for you:\n\n<!-- executable-example: view-child-region -->\n```javascript\nimport { View } from 'marionette';\n\nconst ChildView = View.extend({\n  template() {\n    return '<p class=\"content\">Content</p>';\n  }\n});\n\nconst ParentView = View.extend({\n  template() {\n    return `\n      <div class=\"first-region\"></div>\n      <div class=\"second-region\"></div>\n    `;\n  },\n\n  regions: {\n    firstRegion: '.first-region',\n    secondRegion: '.second-region'\n  }\n});\n\nexport function runViewChildRegionLifecycle() {\n  const parentView = new ParentView();\n\n  parentView.showChildView('firstRegion', new ChildView());\n  const childView = parentView.getChildView('firstRegion');\n\n  parentView.detachChildView('firstRegion');\n  parentView.showChildView('secondRegion', childView);\n  parentView.getRegion('secondRegion').empty();\n\n  return parentView;\n}\n```\n\nNote: If `view.showChildView(region, subView)` is invoked before the `view` has been rendered, it will automatically render the `view` so the Region's `el` exists within the parent root; the root may still be detached.\n\n### Accessing a Child View\n\nTo access the child view of a `View` - use the `getChildView(regionName)` method.\nThis will return the view instance that is currently being displayed at that\nregion. The example gets the exact `ChildView` shown in `firstRegion` before\nmoving it.\n\nIf the named Region exists but has no current View, `getChildView` returns\n`undefined`.\n\n### Detaching a Child View\n\nYou can detach a child view from a Region through `detachChildView(regionName)`.\nIt returns the same live, rendered View so that it can be shown again without\nrendering a second time. In the example, the parent detaches its child from\n`firstRegion` before showing that same child in `secondRegion`. This is a proxy\nfor [Region `detachView()`](/docs/region.md#detaching-existing-views).\n\n### Destroying a Child View\n\nTo destroy and clear a child owned by a View, empty its owning Region. The\nexample calls `parentView.getRegion('secondRegion').empty()`, which destroys the\ncurrent child and leaves `secondRegion` empty and available for another View.\n\n### Region Availability\n\nDefined regions are registered during `View` construction. `hasRegion(name)`,\n`getRegion(name)`, and `getRegions()` query the View's own Region registry\nwithout rendering, including when the View is unrendered or destroyed.\n`getRegions()` returns a fresh, safe own-key snapshot. Child View operations\nsuch as `showChildView`, `detachChildView`, and `getChildView` still render a\nlive, unrendered View before dispatching through any `getRegion` override.\n`emptyRegions()` likewise renders before calling the overridable `getRegions()`\nand emptying its returned snapshot.\n\nCalling `getRegion(name)` does not render the parent or resolve the Region\nelement. Calling the returned Region's `show(view)` resolves its element but does\nnot render the parent. Use `showChildView`, or\nrender the parent first, when showing a child into a declared selector Region.\n\n`getRegion(name)` and `hasRegion(name)` support optional lookup: an unknown name\nreturns `undefined` or `false`, respectively. Operations that require a Region —\n`showChildView`, `detachChildView`, `getChildView`, and `removeRegion` — throw a\n`RegionError` with code [`MN0020`](/errors/MN0020.md) when the named Region does not\nexist. Region names must be non-empty strings. The public types require strings;\nan empty name throws a `RegionError` with code [`MN0032`](/errors/MN0032.md).\nChild View operations reject empty names before rendering the parent.\n\n## Efficient Nested View Structures\n\nShow a parent's Region children in `onRender` when they should be recreated\nwith that parent's template. During initial display, this builds the nested\nView tree before the owning Region attaches the parent. Keep independently\neditable content in child Views and update those children without re-rendering\nthe parent when their state must survive.\n\n```javascript\nimport { View } from 'marionette';\n\nconst ParentView = View.extend({\n  // ...\n  onRender() {\n    this.showChildView('header', new HeaderView());\n    this.showChildView('footer', new FooterView());\n  }\n});\n\nmyRegion.show(new ParentView());\n```\n\nChild Views can show their own Region children in `onRender` too. Marionette\ncoordinates the render and attachment lifecycles; browser layout and paint\ncounts depend on the DOM, styles, and application callbacks. Measure those costs\nin the running application when they matter.\n\n## Listening to Events on Children\n\nUsing regions lets you listen to the events that fire on child views - views\nattached inside a region. This lets a parent view take action depending on what\nevents are triggered in views it directly owns.\n\nRead More:\n- [Child Event Bubbling](/docs/events.md#event-bubbling)\n\n\n[Canonical source](/docs/markdown/docs/marionette.view.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.region.md",
      "title": "Region",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/region/",
      "markdownUrl": "https://marionettejs.com/docs/region.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.region.md",
      "sourceSha256": "ac3ddce3ccc4a5ba6980986cec0ca6cfacb7ff9271e11bf3f21593636e1e94ce",
      "sha256": "fc4d0668c1d52763debb29380efbdadb42c3f989d351314e3cb3fd4dfc97b3c7",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 ac3ddce3ccc4a5ba6980986cec0ca6cfacb7ff9271e11bf3f21593636e1e94ce. -->\n\n# Marionette.Region\n\nA `Region` gives a changing part of the screen a place to live. Show a view,\nreplace it with another, or empty the Region when that part of the interface\nis no longer needed. By default, replacing or emptying a view destroys it;\nthe Region remains available for the next view.\n\n`Region` includes:\n- [Common Marionette Functionality](/docs/common.md)\n- [Class Events](/docs/class-events.md#region-events)\n- [The DOM API](/docs/dom-api.md)\n\nSee the documentation for [laying out views](/docs/view.md#laying-out-views---regions) for an introduction in\nmanaging regions throughout your application.\n\nRegions maintain the [View's lifecycle](/docs/lifecycle.md) while showing or emptying a view.\n\n## Documentation Index\n\n* [Instantiating a Region](#instantiating-a-region)\n* [Reading Region ownership](#reading-region-ownership)\n* [Lifecycle transition contract](#lifecycle-transition-contract)\n* [Defining the Application Region](#defining-the-application-region)\n* [Defining Regions](#defining-regions)\n  * [String Selector](#string-selector)\n  * [Additional Options](#additional-options)\n  * [Specifying `regions` as a Function](#specifying-regions-as-a-function)\n  * [Using a RegionClass](#using-a-regionclass)\n  * [Referencing UI in `regions`](#referencing-ui-in-regions)\n* [Adding Regions](#adding-regions)\n* [Removing Regions](#removing-regions)\n* [Using Regions on a view](#using-regions-on-a-view)\n* [Showing a View](#showing-a-view)\n  * [Checking whether a region is showing a view](#checking-whether-a-region-is-showing-a-view)\n  * [Wrapping a non-Marionette view](#wrapping-a-non-marionette-view)\n* [Emptying a Region](#emptying-a-region)\n  * [Preserving Existing Views](#preserving-existing-views)\n  * [Detaching Existing Views](#detaching-existing-views)\n* [`reset` A Region](#reset-a-region)\n* [`destroy` A Region](#destroy-a-region)\n* [Check If View Is Being Swapped By Another](#check-if-view-is-being-swapped-by-another)\n* [Set How View's `el` Is Attached and Detached](#set-how-views-el-is-attached-and-detached)\n* [Configure How To Remove View](#configure-how-to-remove-view)\n\n## Instantiating a Region\n\nA `Region` accepts `el`, `parentEl`, `allowMissingEl`, and `replaceElement`.\n`el` is a native element or a selector; selector resolution is deferred until an\noperation needs the element. `parentEl` limits selector lookup and may be an\nelement, document, or function returning one. `allowMissingEl` and\n`replaceElement` may also be functions; a boolean supplied to `show(view,\noptions)` overrides the corresponding Region setting for that call.\n\n```javascript\nimport { Region } from 'marionette';\n\nconst myRegion = new Region({ el: '#content' });\n```\n\nWhile regions may be instantiated and useful on their own, their primary use case is through\nthe [`Application`](#defining-the-application-region) and [`View`](#defining-regions) classes.\n\n## Reading Region ownership\n\nA Region registered on a View exposes that existing relationship through pure,\nread-only queries. `getOwner()` returns the owning View and `getName()` returns\nthe Region's name within that View. Neither query renders the View, resolves the\nRegion element, or changes ownership. A standalone Region returns `undefined`\nfrom both methods. Removing a registered Region or completing its destruction\nclears both values. A throwing lifecycle hook interrupts teardown without\nrolling back ownership or retrying destruction.\n\nA Region has one authoritative registration. Re-adding that same Region instance\nunder its current owner and name returns it without lifecycle events or ownership changes.\nRegistering it under a different owner or name, registering a Region whose\ndestruction has begun or completed, or replacing an occupied Region name through\n`addRegion` throws [`MN0030`](/errors/MN0030.md) before committing the conflicting\nregistration. A conflict found before `addRegions` starts rejects the whole batch.\nLifecycle hooks must not re-register the Region or occupy its registration name\nwhile registration is in progress. Failed batch registration is not rolled back.\nRemove an existing named Region before replacing it, and use a fresh Region instance\nwhen another View needs a Region.\n\n```javascript\nconst contentRegion = myView.getRegion('content');\n\ncontentRegion.getOwner() === myView; // true\ncontentRegion.getName(); // 'content'\n```\n\n## Lifecycle transition contract\n\nA Region owns at most one current View. Its public lifecycle\nstate can be read without changing it:\n\n| State | `hasView()` | `isDestroyed()` | `currentView` |\n| --- | --- | --- | --- |\n| Empty | `false` | `false` | `undefined` |\n| Occupied | `true` | `false` | The View shown by the Region |\n| Destroyed | `false` | `true` | `undefined` |\n\n`isSwappingView()` is a temporary operation flag rather than a fourth stable state.\nIt is `true` while one occupied Region replaces its current View with another,\nincluding the Region's `before:show`, `before:empty`, `empty`, and `show` callbacks.\nIt returns to `false` when `show` completes. `isReplaced()` independently reports\nwhether `replaceElement` has temporarily replaced the Region element; it does not\nchange which lifecycle operations are valid.\n\n| Operation | Empty Region | Occupied Region | Destroyed Region |\n| --- | --- | --- | --- |\n| `show(view)` when the Region element resolves | Renders the View if needed, shows it, and enters occupied. | Showing the same View is a no-op. Showing a different View destroys the old View and swaps to the new one. | Returns the Region without inspecting or changing the caller-owned View or resolving the element. |\n| `detachView()` | Returns `undefined`; state is unchanged. | Detaches and returns the live View, then enters empty. | Returns `undefined` without changing state or DOM or emitting lifecycle events. |\n| `empty()` | Returns the Region and, when its element resolves, removes unmanaged contents from that element. | Destroys the current View, clears `currentView`, and enters empty. | Returns the Region without resolving the element or changing lifecycle state or DOM. |\n| `reset()` | Empties the Region and resets its element reference. | Destroys the current View, enters empty, and resets the element reference. | Returns the Region without resolving the element or changing lifecycle state, DOM, or element caches. |\n| Current View is destroyed externally | No effect. | Runs the Region's empty lifecycle once, clears `currentView`, and enters empty. | No effect. |\n| `destroy()` | Runs the destroy lifecycle and enters destroyed. | Emits `before:destroy`, destroys and empties the current View, enters destroyed, then emits `destroy`. | Returns the Region without repeating cleanup or lifecycle events. |\n\nSuccessful `show`, `empty`, and `destroy` calls return the Region when their\noperation completes. With `allowMissingEl: true`, `show` instead returns `undefined`\nand leaves the current View unchanged when its element does not resolve. A View returned\nby `detachView()` remains the caller's responsibility until the same or another Region shows it\nor it is destroyed. After destruction, `show()`, `empty()`, and `reset()` return\nthe Region without changing it, and `detachView()` returns `undefined`.\nAs soon as destruction begins, `show()`, `detachView()`, and recursive `destroy()`\ncalls are no-ops. `empty()` and `reset()` remain available during cleanup.\nA View passed to `show()` during or after destruction remains caller-owned and\nunchanged. A destroyed Region cannot be reused.\n\nWhen its current View destroys itself, the Region clears that View's ownership\nand releases the owning parent View's subscriptions to it. Later events on the\ndestroyed child are no longer forwarded to the parent.\n\nThe following example preserves a View by detaching it before showing it again.\nCalling `empty()` afterward destroys the View and returns the Region to its empty state.\n\n<!-- executable-example: region-lifecycle -->\n```javascript\nimport { Region, View } from 'marionette';\n\nexport function runRegionLifecycle() {\n  const region = new Region({ el: '#content' });\n  const contentView = new View({\n    template() {\n      return '<p>Content</p>';\n    }\n  });\n\n  region.show(contentView);\n  const detachedView = region.detachView();\n  region.show(detachedView);\n  region.empty();\n\n  return region;\n}\n```\n\n## Defining the Application Region\n\nThe Application defines a single region `el` using the `region` attribute. This\ncan be accessed through `getRegion()` or have a view displayed directly with\n`showView()`. Below is a short example:\n\n```javascript\nimport { Application } from 'marionette';\nimport SomeView from './view';\n\nconst MyApp = Application.extend({\n  region: '#main-content',\n\n  onStart() {\n    const mainRegion = this.getRegion();  // Has all the properties of a `Region`\n    mainRegion.show(new SomeView());\n  }\n});\n```\n\n\nFor more information, see the\n[Application docs](/docs/application.md#application-region).\n\n## Defining Regions\n\nIn Marionette you can define a region with a string selector or an object literal\non your `Application` or `View`. This section will document the two types as applied\nto `View`, although they will work for `Application` as well - just replace `regions`\nwith `region` in your definition.\n\nRegion declaration maps, including maps passed to `addRegions`, use own enumerable\nstring keys in standard JavaScript own-key order. Inherited, symbol, and\nnon-enumerable properties are ignored, and a numeric `length` property is an\nordinary Region name rather than an array-like signal. Arrays, sparse arrays, and\nother array-like values are not supported as Region declaration maps.\n\nNamed View Region operations require a non-empty string name. `addRegion`,\n`removeRegion`, `hasRegion`, `getRegion`, `showChildView`, `detachChildView`, and\n`getChildView` throw [`MN0032`](/errors/MN0032.md) for an empty name. The public\ntypes require strings; unsupported shapes have no guaranteed diagnostic.\nOrdinary collision names such as `constructor`,\n`toString`, and `__proto__` remain valid when explicitly registered.\n\n### String Selector\n\nYou can use a CSS selector string to define regions.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  regions: {\n    mainRegion: '#main'\n  }\n});\n```\n\n`Region#getEl(selector)` resolves the selector within `parentEl`, or within the\ndocument when no parent is defined, and returns the first matching native DOM\nelement. A custom `getEl` override must preserve that native-element return\ncontract; do not return a `NodeList` or jQuery collection. To customize selector\nlookup through the DOM adapter, implement `findEl(context, selector)` instead.\nThe v4 `DomApi#getEl` method is not part of the v5 DOM API.\n\nSelector lookup is deferred until a DOM operation such as `show()` needs it. During construction, `initialize` observes the configured\nselector string in `this.el`; constructing a Region does not query the document\nor dispatch through a `getEl` override.\n\n### Additional Options\n\nYou can define regions with an object literal. Object literal definitions expect\nan `el` property - the selector string to hook the region into. With this\nformat is possible to define whether showing the region overwrites the `el` or\njust overwrites the content (the default behavior).\n\nRegion defaults and object-literal definitions contribute their own enumerable\nproperties, including symbols, through object spread. Inherited and\nnon-enumerable properties are ignored when Marionette builds the Region options.\n\nTo replace the Region's placeholder with the child View's root element, use\n`replaceElement: true`:\n\n<!-- executable-example: region-replace-element -->\n```javascript\nimport { View } from 'marionette';\n\nconst ReplacementView = View.extend({\n  className: 'new-class',\n  template: () => '<p>Replacement content</p>'\n});\n\nconst Layout = View.extend({\n  template: () => '<div class=\"overwrite-me\"></div>',\n  regions: {\n    main: {\n      el: '.overwrite-me',\n      replaceElement: true\n    }\n  }\n});\n\nexport const view = new Layout().render();\nexport const placeholder = view.el.querySelector('.overwrite-me');\nexport const replacement = new ReplacementView();\n\n// Rendering the parent creates the placeholder. Showing the child replaces it.\nview.showChildView('main', replacement);\n\nview.$('.overwrite-me').length; // 0\nview.$('.new-class').length; // 1\n```\n\n`showChildView()` replaces `.overwrite-me` with the child's `el`; rendering the\nparent alone does not. The `className` option takes a class name, without the\n`.` used in CSS selectors. Emptying the Region destroys its current child and\nrestores the original placeholder. The parent View's own root remains unchanged.\n\nThis is useful when a container requires particular direct children, such as a\n`table` body containing rows. Choose a child `tagName` valid for that container.\n\n\n```js\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  regions: {\n    regionDefinition: {\n      el: '.bar',\n      replaceElement: true\n    }\n  }\n});\n```\n\n**Errors** An operation that needs the element throws `MN0004` when no `el`\nis configured, or `MN0005` when a selector finds no element and\n`allowMissingEl` is false. Construction alone does not resolve the selector.\n\n### Specifying `regions` as a Function\n\nOn a `View` the `regions` attribute can also be a\n[function returning an object](/docs/basics.md#functions-returning-values):\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  regions(){\n    return {\n      firstRegion: '#first-region'\n    };\n  }\n});\n```\n\n### Using a RegionClass\n\nIf you've created a custom region class, you can use it to define your region.\n\n```javascript\nimport { Application, Region, View } from 'marionette';\n\nconst MyRegion = Region.extend({\n  onShow(){\n    // Scroll to the middle\n    const viewHeight = this.currentView.el.getBoundingClientRect().height;\n    const regionHeight = this.el.getBoundingClientRect().height;\n    this.el.scrollTop = viewHeight / 2 - regionHeight / 2;\n  }\n});\n\nconst MyApp = Application.extend({\n  regionClass: MyRegion,\n  region: '#first-region'\n})\n\nconst MyView = View.extend({\n  regionClass: MyRegion,\n  regions: {\n    firstRegion: {\n      el: '#first-region',\n      regionClass: Region // Don't scroll this to the top\n    },\n    secondRegion: '#second-region'\n  }\n});\n```\n\n\n### Referencing UI in `regions`\n\nThe UI attribute can be useful when setting region selectors - simply use\nthe `@ui.` prefix:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  ui: {\n    region: '#first-region'\n  },\n  regions: {\n    firstRegion: '@ui.region'\n  }\n});\n```\n\n\n## Adding Regions\n\nTo add regions to a view after it has been instantiated, simply use the\n`addRegion` method:\n\n```javascript\nimport MyView from './myview';\n\nconst myView = new MyView();\nmyView.addRegion('thirdRegion', '#third-region');\n```\n\nNow we can access `thirdRegion` as we would the others.\n\nYou can also add multiple regions using `addRegions`.\n\n```javascript\nimport MyView from './myview';\n\nconst myView = new MyView();\nmyView.addRegions({\n  main: {\n    el: '.overwrite-me',\n    replaceElement: true\n  },\n  sidebar: '.sidebar'\n});\n```\n\n\n## Removing Regions\n\nYou can remove all of the regions from a view by calling `removeRegions` or you can remove a\nregion by name using `removeRegion`. When a region is removed the region will be destroyed.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  regions: {\n    main: '.main',\n    sidebar: '.sidebar',\n    header: '.header'\n  }\n});\n\nconst myView = new MyView();\n\n// remove only the main region\nconst mainRegion = myView.removeRegion('main');\n\nmainRegion.isDestroyed(); // -> true\n\n// remove all regions\nmyView.removeRegions();\n```\n\n## Using Regions on a view\n\nIn addition to adding and removing regions there are a few methods to help\nutilize regions. `hasRegion` and `getRegion` are pure own-registry queries, and\n`getRegions` returns a pure snapshot; none renders. Child View operations and\n`emptyRegions` first render a live, unrendered View before resolving or mutating\nRegions.\n\n- `getRegion(name)` - Request an own registered Region without rendering.\n- `getRegions()` - Return a fresh own-key snapshot of registered Regions without rendering.\n- `hasRegion(name)` - Check if a View has an own registered Region without rendering.\n- `emptyRegions()` - Render when needed, then empty all Regions returned by `getRegions()`.\n\n## Showing a View\n\nOnce a region is defined, you can call its `show` method to display the view:\n\n```javascript\nconst myView = new MyView();\nconst childView = new MyChildView();\nmyView.render();\nconst mainRegion = myView.getRegion('main');\n\n// render and display the child View\nmainRegion.show(childView, { fooOption: 'bar' });\n```\n\nThe parent View must already be rendered before calling a selector Region's\n`show` directly. Use `showChildView('main', childView)` to render the parent when\nneeded before showing the child.\n\nThis is equivalent to a view's `showChildView` which can be used as:\n\n```javascript\nconst myView = new MyView();\nconst childView = new MyChildView();\n\n// render and display the view\nmyView.showChildView('main', childView, { fooOption: 'bar' });\n```\n\nBoth forms require a Marionette View instance. Construct a `View` explicitly\nwhen displaying a template or static content; Regions do not allocate hidden Views\nfrom View classes, functions, strings, or option objects. The\n[wrapper pattern](#wrapping-a-non-marionette-view) provides explicit ownership for legacy integrations.\n\n```javascript\nimport { View } from 'marionette';\n\nmyView.showChildView('header', new View({\n  template: () => 'Welcome to the site'\n}));\n```\n\nThe argument after the View instance in `Region#show(view, options)` and\n`View#showChildView(name, view, options)` is a separate show-options object passed\nto the [events fired during `show`](/docs/class-events.md#show-and-beforeshow-events).\n\nFor more information on `showChildView` and `getChildView`, see the\n[Documentation for Views](/docs/view.md#managing-children)\n\n**Errors**\n- A destroyed View throws `MN0007`. Other input shapes are unsupported; core\n  does not guarantee a Marionette diagnostic for an invalid value.\n- An error will be thrown if the view is already managed by a Region or CollectionView,\n  including a filtered or deferred CollectionView child. Detach it from that owner first.\n\n### Checking whether a region is showing a view\n\nIf you wish to check whether a region has a view, you can use the `hasView`\nfunction. This will return a boolean value depending whether or not the region\nis showing a view.\n\n```javascript\nconst myView = new MyView();\nmyView.render();\nconst mainRegion = myView.getRegion('main');\n\nmainRegion.hasView() // false\nmainRegion.show(new OtherView());\nmainRegion.hasView() // true\n```\n\nIf you show a view in a region with an existing view, Marionette will\n[remove the existing View](#emptying-a-region) before showing the new one.\n\n### Wrapping a non-Marionette view\n\nRegions and CollectionViews manage Marionette Views. They do not synthesize\nrender or destroy events for Backbone Views or fall back to a `remove()` method.\nKeep a legacy integration inside a Marionette owner:\n\n```javascript\nimport { View } from 'marionette';\nimport LegacyView from './legacy-view.js';\n\nconst LegacyWrapper = View.extend({\n  template: () => '<div class=\"legacy\"></div>',\n  onRender() {\n    this.legacy?.remove();\n    this.legacy = new LegacyView({ el: this.$('.legacy')[0] });\n    this.legacy.render();\n  },\n  onDestroy() {\n    this.legacy?.remove();\n  }\n});\n```\n\nShow `new LegacyWrapper()` in the Region. The wrapper owns the legacy instance\nand translates its actual rendering and cleanup API. No global prototype mixin\nor compatibility flags are needed.\n\n## Emptying a Region\n\nYou can remove a view from a region (effectively \"unshowing\" it) with\n`region.empty()` on a region:\n\n```javascript\nconst myView = new MyView();\n\nmyView.showChildView('main', new OtherView());\nconst mainRegion = myView.getRegion('main');\nmainRegion.empty();\n```\n\nThis will destroy the view, clean up any event handlers and remove it from\nthe DOM. When a region is emptied [empty events are triggered](/docs/class-events.md#empty-and-beforeempty-events).\nCalling `empty()` after Region destruction completes returns the Region without\nresolving its element, changing the DOM, or emitting empty lifecycle events.\n\n**NOTE** If the region does _not_ currently contain a View it will detach\nany HTML inside the region when emptying. If the region _does_ contain a\nView, any HTML that doesn't belong to the View will remain.\n\n### Preserving Existing Views\n\nIf you replace the current view with a new view by calling `show`, it will\nautomatically destroy the previous view. You can prevent this behavior by\n[detaching the view](#detaching-existing-views) before showing another one.\n\n### Detaching Existing Views\n\nIf you want to detach an existing view from a region, use `detachView`.\n\n```javascript\nconst myView = new MyView();\n\nconst myOtherView = new MyView();\n\nconst childView = new MyChildView();\n\n// render and display the view\nmyView.showChildView('main', childView);\n\n// ... somewhere down the line\nmyOtherView.showChildView('main', myView.getRegion('main').detachView());\n```\n\n**Note** Detaching transfers responsibility for the live View to the caller.\nShow it again in the same emptied Region or another Region when needed, or call\n`destroy()` when finished with it.\n\n## `reset` A Region\n\nResetting a live Region destroys its current View and restores its original\n`el` reference. An original selector is queried again by the next operation that\nneeds it; an original DOM element is reused without a selector query.\n\n```javascript\nconst myView = new MyView();\nmyView.showChildView('main', new OtherView());\nconst myRegion = myView.getRegion('main');\nmyRegion.reset();\n```\n\nThis can be useful in unit testing your views.\nCalling `reset()` after Region destruction completes returns the Region without\nchanging its element reference or cache.\n\n## `destroy` A Region\n\nA region can be destroyed which will `reset` the region, destroy its current View,\nremove it from any parent View's Region lookups, and stop any internal Region listeners.\nReentrant Region destruction from `before:destroy` or `destroy`, repeated calls,\nand later destruction of the parent View do not repeat the child or Region teardown.\nA throwing lifecycle hook stops destruction. Later `destroy()` calls do not\nretry hooks or resume partial teardown. Discard the Region after a cleanup error;\nits remaining state is not a reusable lifecycle state.\n`isDestroyed()` becomes `true` after `reset()` finishes, before the `destroy`\nevent. It remains `false` in `before:destroy`, `before:empty`, and `empty` handlers\ncalled during teardown.\n\n`destroy()` calls the overridable `reset()` method, which calls `empty()`.\nOverrides can use this ordinary synchronous chain while cleanup is in progress.\nAn override that does not delegate to the base method owns the corresponding\ncleanup; for example, a custom `reset()` can call `this.empty()` and reset its own\nelement reference. Nested `empty()` or `reset()` calls from lifecycle handlers\nare ordinary calls, so handlers must avoid recursive loops.\n\nAfter destruction completes, `empty()` and `reset()` return the Region without\nchanging its element or DOM. `show()` and `detachView()` already stop accepting\nViews or transferring ownership as soon as destruction begins.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  regions: {\n    mainRegion: '#main'\n  }\n});\n\nconst myView = new MyView();\nmyView.render();\n\nconst myRegion = myView.getRegion('mainRegion');\n\nmyRegion.show(new ChildView());\n\nmyRegion.destroy();\n\nmyRegion.isDestroyed(); // true\nmyRegion.hasView(); // false\nmyView.hasRegion('mainRegion'); // false\n```\n\n## Check If View Is Being Swapped By Another\n\nThe `isSwappingView` method returns if a view is being swapped by another one. It's useful\ninside region lifecycle events / methods.\n\nThe example will show an message when the region is empty:\n\n```javascript\nimport { Region } from 'marionette';\n\nconst EmptyMsgRegion = Region.extend({\n  onEmpty() {\n    if (!this.isSwappingView()) {\n      this.el.append('Empty Region');\n    }\n  }\n});\n```\n\n## Set How View's `el` Is Attached and Detached\n\nOverride the region's `attachHtml` method to change how the view is attached\nto the DOM (when not using `replaceElement: true`). This method receives one\nparameter - the view to show.\n\nThe default implementation of `attachHtml` is essentially:\n\n```javascript\nimport { Region } from 'marionette';\n\nRegion.prototype.attachHtml = function(view){\n  this.el.appendChild(view.el);\n}\n```\n\nSimilar to `attachHtml`, override `detachHtml` to determine how the region detaches\nthe contents from its `el`. This method receives no parameters.\n\nFor most cases you will want to use the [DOM API](/docs/dom-api.md) to determine how\na region html is attached, but in some cases you may want to override a single Region\nclass for situations like animation where you want to control both attaching and\n[view removal](#configure-how-to-remove-view).\n\nThis example will make a view slide down from the top of the screen instead of just\nappearing in place:\n\n```javascript\nimport $ from 'jquery';\nimport { Region, View } from 'marionette';\n\nconst ModalRegion = Region.extend({\n  attachHtml(view){\n    // Some effect to show the view:\n    const $el = $(this.el);\n    $el.empty().append(view.el);\n    $el.hide().slideDown('fast');\n  }\n});\n\nconst MyView = View.extend({\n  regions: {\n    mainRegion: '#main-region',\n    modalRegion: {\n      regionClass: ModalRegion,\n      el: '#modal-region'\n    }\n  }\n});\n```\n\n## Configure How To Remove View\n\nOverride the region's `removeView` method to change how and when the view is destroyed / removed\nfrom the DOM. This method receives one parameter - the view to remove.\n\nThe default implementation of `removeView` is:\n\n```javascript\nimport { Region } from 'marionette';\n\nRegion.prototype.removeView = function(view){\n  this.destroyView(view);\n}\n```\n\n`destroyView(view)` destroys a Marionette View and returns it. It forwards the\nRegion owner's lifecycle-monitoring policy; it does not adapt a Backbone View\nor fall back to `remove()`. Keep this helper when overriding `removeView`.\n\nRegion operations are synchronous. A `removeView` override must complete cleanup\nbefore returning if callers should observe the normal empty/destroy contract.\nReturning a Promise does not delay Region lifecycle completion. For an exit\nanimation, finish the animation in the application before calling `empty()` or\nshowing the replacement, and let the Region perform its normal synchronous\nteardown. The application owns cancellation when navigation or destruction\ninterrupts that animation.\n\n\n[Canonical source](/docs/markdown/docs/marionette.region.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.collectionview.md",
      "title": "CollectionView",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/collection-view/",
      "markdownUrl": "https://marionettejs.com/docs/collection-view.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.collectionview.md",
      "sourceSha256": "5af1ed04daaf0e976fdd0538b0931fd370fd09167079d0c21b01195f8628cefe",
      "sha256": "cf11a246ff891a207873733884de682c188895c5d1ca138168760c61d4ea4cd1",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 5af1ed04daaf0e976fdd0538b0931fd370fd09167079d0c21b01195f8628cefe. -->\n\n# Marionette.CollectionView\n\nA `CollectionView` manages repeated parts of a screen: rows, cards, or any\nordered set of child views within a root element, `el`. It creates children\nfrom a `collection`, or lets you add and remove child views yourself.\n\nPlain arrays work with the default [Data API](/docs/data-api.md). Use an adapter\nwhen your collection needs to notify the view about changes; mutating a plain\narray does not send those notifications.\n\n`CollectionView` includes:\n- [The DOM API](/docs/dom-api.md)\n- [Class Events](/docs/class-events.md#collectionview-events)\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Child Event Bubbling](/docs/events.md#event-bubbling)\n- [Entity Events](/docs/entity-events.md)\n- [View Rendering](/docs/rendering.md)\n- [Prerendered Content](/docs/prerendered-dom.md)\n- [View Lifecycle](/docs/lifecycle.md)\n\nA `CollectionView` can have [`Behavior`s](/docs/behavior.md).\n\n## Documentation Index\n\n* [Instantiating a CollectionView](#instantiating-a-collectionview)\n* [Rendering a CollectionView](#rendering-a-collectionview)\n  * [Rendering a Template](#rendering-a-template)\n  * [Defining the `childViewContainer`](#defining-the-childviewcontainer)\n  * [Re-rendering the CollectionView](#re-rendering-the-collectionview)\n* [View Lifecycle and Events](#view-lifecycle-and-events)\n* [Entity Events](#entity-events)\n* [DOM Interactions](#dom-interactions)\n* [Behaviors](#behaviors)\n* [Managing Children](#managing-children)\n  * [Attaching `children` within the `el`](#attaching-children-within-the-el)\n  * [Destroying All `children`](#destroying-all-children)\n* [CollectionView's `childView`](#collectionviews-childview)\n  * [Building the `children`](#building-the-children)\n  * [Passing Data to the `childView`](#passing-data-to-the-childview)\n* [CollectionView's `emptyView`](#collectionviews-emptyview)\n  * [CollectionView's `getEmptyRegion`](#collectionviews-getemptyregion)\n  * [Passing Data to the `emptyView`](#passing-data-to-the-emptyview)\n  * [Defining When an `emptyView` shows](#defining-when-an-emptyview-shows)\n* [Accessing a Child View](#accessing-a-child-view)\n  * [CollectionView `children` Iterators And Collection Functions](#collectionview-children-iterators-and-collection-functions)\n* [Listening to Events on the `children`](#listening-to-events-on-the-children)\n* [Self Managed `children`](#self-managed-children)\n  * [Adding a Child View](#adding-a-child-view)\n  * [Removing a Child View](#removing-a-child-view)\n  * [Detaching a Child View](#detaching-a-child-view)\n  * [Swapping Child Views](#swapping-child-views)\n* [Sorting the `children`](#sorting-the-children)\n  * [Defining the `viewComparator`](#defining-the-viewcomparator)\n  * [Maintaining the `collection`'s sort](#maintaining-the-collections-sort)\n* [Filtering the `children`](#filtering-the-children)\n  * [Defining the `viewFilter`](#defining-the-viewfilter)\n\n## Instantiating a CollectionView\n\nWhen instantiating a `CollectionView` there are several properties, if passed,\nthat will be attached directly to the instance:\n`attributes`, `behaviors`, `childView`, `childViewContainer`, `childViewEventPrefix`,\n`childViewEvents`, `childViewOptions`, `childViewTriggers`, `className`, `collection`,\n`collectionEvents`, `el`, `emptyView`, `emptyViewOptions`, `events`, `id`, `model`,\n`modelEvents`, `sortWithCollection`, `stateEvents`, `tagName`, `template`, `templateContext`,\n`triggers`, `ui`, `viewComparator`, `viewFilter`\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst myCollectionView = new CollectionView();\n```\n\n`CollectionView` composes the same visual, event, and State contracts as `View`,\nbut does not inherit View's named-Region methods. Use `getEmptyRegion()` for its\nempty View; put a CollectionView inside a parent View when a layout needs\nadditional named Regions. A supplied `state` follows the\n[State ownership contract](/docs/state.md#borrowed-and-owned-sources).\n\n## Rendering a CollectionView\n\nThe `render` method of the `CollectionView` is primarily responsible\nfor rendering the entire collection. It loops through each of the\nchildren in the collection and renders them individually as a\n`childView`.\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst MyCollectionView = CollectionView.extend({});\n\n// all of the children views will now be rendered.\nnew MyCollectionView().render();\n```\n\n### Rendering a Template\n\nIn addition to rendering children, the `CollectionView` may have a\n`template`.  The child views can be rendered within a DOM element of\nthis template. The `CollectionView` will serialize either the `model`\nor `collection` along with context for the `template` to render.\n\nFor more detail on how to render templates, see\n[View Template Rendering](/docs/rendering.md).\n\n### Defining the `childViewContainer`\n\nBy default the `CollectionView` will render the children into the `el`\nof the `CollectionView`. If you are rendering a template you will want\nto set the `childViewContainer` to be a selector for an element within\nthe template for child view attachment.\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst MyCollectionView = CollectionView.extend({\n  childViewContainer: '.js-widgets',\n  template: () => '<h1>Widgets</h1><ul class=\"js-widgets\"></ul>'\n});\n```\n\n**Errors** An error will throw if the childViewContainer can not be found.\n\n### Re-rendering the CollectionView\n\nIf you need to re-render the entire collection or the template, you can call the\n`collectionView.render` method. This method will destroy all of\nthe child views that may have previously been added.\n\n## View Lifecycle and Events\n\nLike `View`, a `CollectionView` exposes its lifecycle as the independent\n`isRendered()`, `isAttached()`, and `isDestroyed()` state values. Its managed\nchildren have their own View lifecycle state. Existing contents in the\n`CollectionView` element do not make the `CollectionView` rendered; rendering\nmeans its child set has been built and inserted into its element.\n\nThe table describes the default rendered and monitored path. Passing\n`{ preventRender: true }` to `addChildView` still renders the parent when\nneeded, but manages the supplied child without rendering it; detaching that\nchild returns it in its current lifecycle state. Setting\n`monitorViewEvents: false` on the `CollectionView` intentionally disables child\nattachment events and automatic child `isAttached()` updates.\n\nDisabling monitoring does not make child destruction clear surrounding template\ncontent. Bulk removal is used only when the child container contains those Views'\nroot elements and optional formatting whitespace.\n\n| Operation | CollectionView state | Managed child state |\n| --- | --- | --- |\n| Construct | Starts not rendered and not destroyed. It is attached only when its element is already in the document. | No children have been built. |\n| `render()` | Enters rendered and preserves its attached state. Repeated render stays rendered. | Builds and renders the current children. Repeated render destroys the previous children before building replacements. |\n| A rendered collection resets | Remains rendered and preserves its attached state. | Destroys the previous children and builds replacements for the reset collection. |\n| `addChildView(view)` | Renders first when needed, then remains rendered. | Renders and manages the added View. |\n| `detachChildView(view)` | State is unchanged. | Removes and returns the live View in a detached state. The caller becomes responsible for it. |\n| `removeChildView(view)` or external child destruction | State is unchanged. | Removes the child from the managed set. `removeChildView` destroys it; an externally destroyed child is removed once. |\n| The owning Region detaches and re-shows the CollectionView | Remains rendered while attached changes to `false`, then back to `true`. | Live children follow the parent's detached and attached state. |\n| `destroy()` | Detaches, becomes not rendered, and enters destroyed. Repeated destroy returns the CollectionView without repeating lifecycle events. | Detaches and destroys every still-managed child after the parent element is removed. |\n| `render()` after destruction | Returns the same CollectionView and remains not rendered and destroyed. Repeated calls are no-ops. | Does not recreate or render children. |\n| `addChildView(view)` once destruction begins | Returns the supplied View without inspecting it, the index, or options or changing events, ownership, DOM, or lifecycle state. Calls during `before:destroy` and repeated calls after destruction are the same no-op. | The supplied View remains unchanged and can be added to a live owner. |\n\nCollection `sort`, `reset`, and `update` events raised reentrantly during destruction\ndo not rebuild, add, remove, sort, render, or destroy additional child Views.\n\nA View returned by `detachChildView()` is no longer managed by the\n`CollectionView`; another owner may show it, or the caller must destroy it.\nOther operations on an already destroyed `CollectionView` remain outside this\nlifecycle contract until their invalid-transition behavior is made consistent.\n\nRead More:\n- [View Lifecycle](/docs/lifecycle.md)\n- [View DOM Change Events](/docs/class-events.md#dom-change-events)\n- [View Destroy Events](/docs/class-events.md#destroy-events)\n\n## Entity Events\n\nA `CollectionView` subscribes to its `model` and `collection` through the\nconfigured [DataApi](/docs/data-api.md). Event names and callback arguments belong\nto that data provider. Plain objects and arrays do not emit changes; declaring\nentity event maps for unobservable values throws `MN0037`.\n\nRead More:\n- [Entity Events](/docs/entity-events.md)\n\n## DOM Interactions\n\n`CollectionView` uses the same native [`events`, `triggers`, and `ui`\ncontracts](/docs/dom-interactions.md) as `View`. Keep parent selectors and handlers\nspecific to DOM that the `CollectionView` itself owns. Delegation is rooted at\nthe parent `el`, so a broad selector can also match child-owned descendants; do\nnot rebind the parent's `ui` to reach into child View DOM.\n\nAfter application code places parent-owned DOM inside a template-less\n`CollectionView`, call `bindUIElements()` before reading it with `getUI()`. Use\nthat method only to bind the CollectionView's own DOM, not child View DOM.\nCalling `getUI()` without a declared `ui` map or while UI elements are unbound throws\n[`MN0023`](/errors/MN0023.md).\n\nWhen parent code needs a child, [retrieve the child View through the public\n`children` lookup APIs](#accessing-a-child-view) and call an intentional public\nmethod on that View. For communication initiated by a child, use\n[`childViewEvents` or `childViewTriggers`](/docs/events.md#child-view-events), or an\nexplicit public [`listenTo`](/docs/events.md#listening-to-events) subscription,\ninstead of querying or mutating the child's DOM from the parent.\n\nRead More:\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Listening to Events on Children](#listening-to-events-on-the-children)\n\n## Behaviors\n\nA `Behavior` provides a clean separation of concerns to your view logic,\nallowing you to share common user-facing operations between your views.\n\nRead More:\n- [Using `Behavior`s](/docs/behavior.md#using-behaviors)\n\n## Managing Children\n\nChildren are automatically managed once the `CollectionView` is\n[rendered](#rendering-a-collectionview). For each model within the\n`collection` the `CollectionView` will build and store a `childView`\nwithin its `children` object. This allows you to easily access\nthe views within the collection view, iterate them, find them by\na given indexer such as the view's model or id and more.\n\nDuring its first render, the `CollectionView` subscribes through\n`DataApi.observeCollection()` to normalized update, reset, and reorder\nnotifications. The configured provider owns the source event vocabulary;\n[Backbone](/docs/backbone.md) is one supported observable integration.\n\nWhen the `collection` for the view is `reset`, the view will destroy all\nchildren and re-render the entire collection.\n\nWhen the adapter reports a model addition, the `CollectionView` constructs its\nchild and renders it if it passes the presentation filter.\n\nWhen a model is removed from the `collection` (or destroyed / deleted), the `CollectionView`\nwill destroy and remove that model's child view.\n\nCollection updates, `sort()`, and `filter()` use the same child-rendering path.\nSurviving visible children keep their elements mounted, including when a\n`viewFilter` or custom `viewComparator` is active. New or newly visible children\nare attached through `attachHtml`; existing elements move only when their order\nneeds to change. Removal alone does not move or rerender surviving children. See\n[DOM movement](/docs/dom-api.md#moveelel-parent-before) for focus and text-selection\npreservation and the browser fallback behavior.\n\nThe `before:render:children` and `render:children` events receive all visible\nchildren. This describes the render pass, not a list of children whose templates\nwere rerendered. Already-rendered children reuse their contents unless the data\nadapter reports them as updated.\n\nOverriding `sort()` or `filter()` replaces that part of the flow. Call the parent\nmethod to retain its behavior; CollectionView does not force a render after an\noverride that deliberately skips it.\n\nWhen the `collection` for the view is sorted, the view by default reconciles its child\nviews to the collection's source order unless the `sortWithCollection` attribute on the\n`CollectionView` is set to `false`. Setting `viewComparator: false` disables a separate\npresentation sort; it does not disable keyed source-order reconciliation.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst collection = new Backbone.Collection();\n\nconst MyChildView = View.extend({\n  template: false\n});\n\nconst MyCollectionView = CollectionView.extend({\n  childView: MyChildView,\n  collection,\n});\n\nconst myCollectionView = new MyCollectionView();\n\n// Collection view will not re-render as it has not been rendered\ncollection.reset([{foo: 'foo'}]);\n\nmyCollectionView.render();\n\n// Collection view will effectively re-render displaying the new model\ncollection.reset([{foo: 'bar'}]);\n```\n\nWhen the children are rendered the\n[`render:children` and `before:render:children` events](/docs/class-events.md#renderchildren-and-beforerenderchildren-events)\nwill trigger.\n\nWhen a childview is added to the children\n[`add:child` and `before:add:child` events](/docs/class-events.md#addchild-and-beforeaddchild-events)\nwill trigger\n\nWhen a childview is removed from the children\n[`remove:child` and `before:remove:child` events](/docs/class-events.md#removechild-and-beforeremovechild-events)\nwill trigger.\n\n### Attaching `children` within the `el`\n\nThe `CollectionView` places new or newly visible child root elements into a\n`DocumentFragment`, then calls `attachHtml(fragment, container)` to insert that\nbatch. Already mounted children remain in place or move only as needed to match\nthe presentation order; they are not all removed and appended on each pass.\n\nYou can override this by specifying an `attachHtml` method in your\nview definition. This method takes two parameters and has no return value.\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nCollectionView.extend({\n\n  // The default implementation:\n  attachHtml(els, container) {\n    // Unless childViewContainer is set, container === this.el\n    this.Dom.appendContents(container, els);\n  }\n});\n```\n\nThe first parameter is the DOM fragment containing child root elements, and the second parameter\nis the native DOM container for the children which by default equates\nto the view's `el` unless a [`childViewContainer`](#defining-the-childviewcontainer)\nis set.\n\n### Destroying All `children`\n\n`CollectionView` implements a `destroy` method which automatically\ndestroys its children and cleans up listeners.\n\nWhen a nonempty owned child set is destroyed, the\n[`destroy:children` and `before:destroy:children` events](/docs/class-events.md#destroychildren-and-beforedestroychildren-events)\nwill trigger.\n\nRead More:\n- [View Destroy Events](/docs/class-events.md#destroy-events)\n\n## CollectionView's `childView`\n\nWhen using a `collection` to manage the children of `CollectionView`,\nspecify a Marionette `View` or `CollectionView` class as `childView`, rather\nthan an instance. A plain Backbone View is not a supported child;\n[wrap it in a Marionette View](/docs/region.md#wrapping-a-non-marionette-view)\nwhen integrating a legacy component.\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nconst MyChildView = View.extend({});\n\nconst MyCollectionView = CollectionView.extend({\n  childView: MyChildView\n});\n```\n\n**Errors** When Marionette needs to construct a collection-backed child and\n`childView` is missing, it throws `MN0011`. An empty CollectionView or a\nCollectionView with only manually added children does not require `childView`.\n\nYou can also define `childView` as a function. In this form, the value\nreturned by this method is the `ChildView` class that will be instantiated\nwhen a `Model` needs to be initially rendered. This method also gives you\nthe ability to customize per `Model` `ChildViews`.\n\n```javascript\nimport _ from 'underscore';\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst FooView = View.extend({\n  template: _.template('foo')\n});\n\nconst BarView = View.extend({\n  template: _.template('bar')\n});\n\nconst MyCollectionView = CollectionView.extend({\n  collection: new Backbone.Collection(),\n  childView(model) {\n    // Choose which view class to render,\n    // depending on the properties of the model\n    if  (model.get('isFoo')) {\n      return FooView;\n    }\n    else {\n      return BarView;\n    }\n  }\n});\n\nconst collectionView = new MyCollectionView().render();\n\nconst foo = new Backbone.Model({\n  isFoo: true\n});\n\nconst bar = new Backbone.Model({\n  isFoo: false\n});\n\n// Renders a FooView\ncollectionView.collection.add(foo);\n\n// Renders a BarView\ncollectionView.collection.add(bar);\n```\n\nA resolver must return a Marionette View class. Core trusts that result;\nunsupported returns can fail later during construction or child setup.\n\n### Building the `children`\n\nThe `buildChildView` method is responsible for taking the ChildView class and\ninstantiating it with the appropriate data. This method takes three\nparameters and returns a view instance to be used as the child view.\n\n```javascript\nbuildChildView(child, ChildViewClass, childViewOptions){\n  // build the final list of options for the childView class\n  const options = { model: child, ...childViewOptions };\n  // create the child view instance\n  const view = new ChildViewClass(options);\n  // return it\n  return view;\n},\n```\n\nOverride this method when you need a more complicated build, but use [`childView`](#collectionviews-childview)\nif you need to determine _which_ View class to instantiate.\n\n```javascript\nimport _ from 'underscore';\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi } from 'marionette';\nimport MyListView from './my-list-view';\nimport MyView from './my-view';\n\nsetDataApi(BackboneApi);\n\nconst MyCollectionView = CollectionView.extend({\n  childView(child) {\n    if (child.get('type') === 'list') {\n      return MyListView;\n    }\n\n    return MyView;\n  },\n  buildChildView(child, ChildViewClass, childViewOptions) {\n    let options;\n\n    if (child.get('type') === 'list') {\n      const childList = new Backbone.Collection(child.get('list'));\n      options = _.extend({collection: childList}, childViewOptions);\n    } else {\n      options = _.extend({model: child}, childViewOptions);\n    }\n\n    // create the child view instance\n    const view = new ChildViewClass(options);\n    // return it\n    return view;\n  }\n});\n```\n\n### Passing Data to the `childView`\n\nThere may be scenarios where you need to pass data from your parent\ncollection view in to each of the childView instances. To do this, provide\na `childViewOptions` definition on your collection view as an object\nliteral. This will be passed to the constructor of your childView as part\nof the `options`.\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nconst ChildView = View.extend({\n  initialize(options) {\n    console.log(options.foo); // => \"bar\"\n  }\n});\n\nconst MyCollectionView = CollectionView.extend({\n  childView: ChildView,\n\n  childViewOptions: {\n    foo: 'bar'\n  }\n});\n```\n\nYou can also specify the `childViewOptions` as a function, if you need to\ncalculate the values to return at runtime. The model will be passed into\nthe function should you need access to it when calculating\n`childViewOptions`. The function may return an object, `null`, or `undefined`. The attributes\nof a returned object will be copied to the `childView` instance's options. Whether\nprovided directly or returned by a function, the object's own enumerable\nproperties, including symbols, are copied by object spread. `null` or `undefined`\nadds no extra options. A supplied `model` option overrides the source model;\nuse that only when the child deliberately represents different data.\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst MyCollectionView = CollectionView.extend({\n  childViewOptions(model) {\n    // do some calculations based on the model\n    return {\n      foo: 'bar'\n    };\n  }\n});\n```\n\n## CollectionView's `emptyView`\n\nWhen a collection has no children, and you need to render a view other than\nthe list of childViews, you can specify an `emptyView` attribute on your\ncollection view. The `emptyView`, like the\n[`childView`](#collectionviews-childview), can be passed as an option on\ninstantiation. It must be a `View` class or a resolver that returns a `View`\nclass. Marionette calls resolvers with the `CollectionView` as `this`; arrow and\nbound functions retain their normal JavaScript `this` semantics.\n\nIf the resolved `emptyView` property is `undefined`, `null`, or `false`, no\nempty view is rendered. Because an `undefined` constructor option does not\nreplace an inherited value, use `null` or `false` to disable an inherited\ndefinition. A resolver may return a `View` class or `undefined`, `null`, or\n`false` to disable the empty view. The public types describe these alternatives;\nMarionette trusts the result when the collection is empty. Errors thrown by a\nresolver propagate unchanged.\n\nWhen the empty collection is rendered or filtered again, a disabled result also\nremoves any empty View already shown.\n\n```javascript\nimport _ from 'underscore';\nimport { View, CollectionView } from 'marionette';\n\nconst MyEmptyView = View.extend({\n  template: _.template('Nothing to display.')\n});\n\nconst MyCollectionView = CollectionView.extend({\n  // ...\n\n  emptyView: MyEmptyView\n});\n```\n\n### CollectionView's `getEmptyRegion`\n\nWhen a `CollectionView` is instantiated it creates a region for showing the [`emptyView`](#collectionviews-emptyview).\nThis region can be requested using the `getEmptyRegion` method. It uses the\nresolved `childViewContainer` when present, otherwise the CollectionView's `el`,\nand is shown with [`replaceElement: false`](/docs/region.md#additional-options).\n\n**Note** The `CollectionView` expects to be the only entity managing the region.\nShowing things in this region directly is not advised.\n\n```javascript\nconst isEmptyShowing = myCollectionView.getEmptyRegion().hasView();\n```\n\nThis region can be useful for handling the\n[EmptyView Region Events](/docs/class-events.md#collectionview-emptyview-region-events).\n\n### Passing Data to the `emptyView`\n\nSimilar to [`childView`](#collectionviews-childview) and [`childViewOptions`](#passing-data-to-the-childview),\nthere is an `emptyViewOptions` property that will be passed to the `emptyView` constructor.\nIt can be provided as an object literal or as a function.\n\nIf `emptyViewOptions` aren't provided, the `CollectionView` falls back to\n`childViewOptions`. A callable definition receives no model argument and runs\nwith the CollectionView as `this`; it must support that empty-view call.\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nconst EmptyView = View.extend({\n  initialize(options){\n    console.log(options.foo); // => \"bar\"\n  }\n});\n\nconst MyCollectionView = CollectionView.extend({\n  emptyView: EmptyView,\n\n  emptyViewOptions: {\n    foo: 'bar'\n  }\n});\n```\n\n### Defining When an `emptyView` shows\n\nIf you want to control when the empty view is rendered, you can override\n`isEmpty`:\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst MyCollectionView = CollectionView.extend({\n  isEmpty() {\n    // some logic to calculate if the view should be rendered as empty\n    return this.collection.length < 2;\n  }\n});\n```\n\nThe default implementation of `isEmpty` returns `!this.children.length`.\n\nUse `getEmptyRegion().hasView()` to determine whether an empty View is actually\nshown. `isEmpty()` alone does not establish that an `emptyView` was configured:\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst MyCollectionView = CollectionView.extend({\n  // ...\n  onRenderChildren() {\n    if (this.getEmptyRegion().hasView()) { console.log('Empty View Shown'); }\n  }\n});\n```\n\n## Accessing a Child View\n\nYou can retrieve a view by a number of methods. If the findBy* method cannot find the view,\nit will return `undefined`.\n\n**Note** `children` is the current presentation container. It can include\nunrendered children added with `preventRender` until the next render/filter\npass; filtered-out children remain owned but are absent from this container.\n\n### CollectionView `children`'s: `findByCid`\nFind a view by its cid.\n\n```javascript\nconst bView = myCollectionView.children.findByCid(buttonView.cid);\n```\n\n### CollectionView `children`'s: `findByModel`\nFind a view by `DataApi.key(model)`. With the default DataApi this is the\nmodel object identity. An adapter may use a stable key so that a new model\nobject representing the same item resolves the currently indexed child. This\nlookup does not promise child retention when a collection observation replaces\nthe model object; see [collection observations](/docs/data-api.md#collection-observations).\n\n```javascript\nconst bView = myCollectionView.children.findByModel(buttonView.model);\n```\n\n### CollectionView `children`'s: `findByKey`\n\n`children.findByKey(key)` returns the View indexed by the exact key produced by\nits DataApi, or `undefined` when absent. Do not assume this key is the model's\n`id`: native Marionette and Backbone models use their provider's identity\ncontract, while snapshot adapters can use an application-selected key.\n\n`children.hasView(view)` checks that the exact View instance is present under\nits `cid`; `children.contains(view)` checks instance membership as well.\nThese lookups refer to the public presentation container. A filtered-out child\ncan remain owned by the CollectionView without appearing in `children`. Keep\nan explicit reference when an application needs to detach such a child; do not\nreach into private containers.\n\n### CollectionView `children`'s: `findByIndex`\n\nFind by numeric index (unstable)\n\n```javascript\nconst bView = myCollectionView.children.findByIndex(0);\n```\n\n### CollectionView `children`'s: `findIndexByView`\n\nFind the index of the exact View inside `children`, or `-1` when absent.\n\n```javascript\nconst index = myCollectionView.children.findIndexByView(bView);\n```\n\n### CollectionView `children` Iterators And Collection Functions\n\nThe container is iterable: `for (const child of list.children)` visits the\ncurrent presentation order. Use `children.toArray()` when you need a separate\narray before changing membership.\n\nThe container owns the following iteration and collection functions:\n\n* `each`\n* `map`\n* `reduce`\n* `find`\n* `filter`\n* `reject`\n* `every`\n* `some`\n* `contains`\n* `invoke`\n* `toArray`\n* `first`\n* `initial`\n* `rest`\n* `last`\n* `without`\n* `isEmpty`\n* `pluck`\n* `partition`\n\nThese methods can be called directly on the container, to iterate and process\nthe views held by the container.\n\n`each`, `map`, `reduce`, `find`, `filter`, `reject`, `every`, `some`, and\n`partition` require callback functions. The public types enforce that contract;\nunsupported JavaScript callback shapes have no guaranteed Marionette diagnostic.\nString, object, and null iteratee shorthand is not supported. Structurally adding, removing, or\nreordering children while a callback runs is unsupported, and these methods do\nnot promise call-start snapshot semantics. Mutating ordinary properties on a\nchild View remains valid.\n\n`each(callback, context)` visits every child View in order, calls `callback` as\n`(view, index)`, binds `this` to `context` when provided, and returns the\n`children` container. An empty container returns itself without calling the\ncallback.\n\n`map(callback, context)` calls `(view, index)` for every child View and returns a\nnew ordered array of callback results. An empty container returns a new `[]`.\nUse `map(view => view.id)` or `pluck('id')` instead of property-name shorthand.\n\n`reduce(callback, initialValue, context)` calls\n`(accumulator, view, index)` in container order and binds optional `context`.\nWhen `initialValue` is supplied, every child View is visited; an empty container\nreturns that exact value without calling the callback. When it is omitted, the\nfirst child View becomes the accumulator and traversal starts at index `1`. An\nempty container without an initial value throws [`MN0024`](/errors/MN0024.md).\n\n`pluck(key)` reads `key` directly from each child View. For example,\n`children.pluck('model')` returns the child Views' model objects, and a child\nwithout a model contributes `undefined`. It does not read model attributes; use\nan explicit callback such as `children.map(view => view.model?.get('status'))`\nfor those values. Array-form deep paths are not traversed; replace\n`children.pluck(['model', 'cid'])` with\n`children.map(view => view.model?.cid)`. An empty container returns `[]`.\n\n`contains(value)` checks for the exact child View instance. A child View's model\nor another object with the same properties is not considered contained. An empty\ncontainer returns `false`.\n\n`find`, `filter`, `reject`, `every`, `some`, and `partition` call their predicate\nwith `(view, index)` and set `this` to optional `context`.\n\n`find(predicate, context)` returns the first child View for which the predicate\nis truthy, preserving View identity, and stops iterating at that match. It\nreturns `undefined` when no View matches or the container is empty.\n\n`filter(predicate, context)` and `reject(predicate, context)` visit every child\nView and return new ordered arrays containing the Views for which the predicate\nis truthy or falsey, respectively. Changing a returned array does not change the\ncontainer. An empty container returns `[]` without calling the predicate.\n\n`every(predicate, context)` returns `false` and stops at the first falsey result;\notherwise it returns `true`. `some(predicate, context)` returns `true` and stops\nat the first truthy result; otherwise it returns `false`. For an empty container,\n`every` returns `true` and `some` returns `false`, without calling the predicate.\n\n`partition(predicate, context)` visits every child View and returns\n`[matchingViews, rejectedViews]`. Both members are new arrays that preserve the\ncontainer order and contain the exact child View instances. An empty container\nreturns `[[], []]` without calling the predicate.\n\n`invoke(methodName, ...args)` requires a direct string method name, invokes that\nmethod with each child View as `this`, forwards `args`, and returns a new ordered\narray of results. TypeScript restricts the name to callable child methods and\nchecks their arguments and result types. Function-form and deep-path method\nnames are not supported. An empty container returns `[]`.\n\n`toArray()` returns a new array containing the current child Views in container\norder. Changing the returned array's membership or order does not change the\ncontainer. An empty container returns `[]`.\n\nWithout a count, `first()` and `last()` return the first or last child View. With\na nonnegative integer count, they return a new ordered array containing up to\nthat many Views from the corresponding end of the container. A count of `0`\nreturns `[]`. For an empty container, the no-count forms return `undefined` and\nthe count forms return `[]`.\n\n`initial(count = 1)` and `rest(count = 1)` return new ordered arrays after\nexcluding `count` Views from the end or start of the container, respectively.\nThe count is a nonnegative integer: `0` returns a new array of every child View,\nand a count greater than or equal to the container length returns `[]`. An empty\ncontainer also returns `[]`. `first`, `initial`, `rest`, and `last` throw\n[`MN0024`](/errors/MN0024.md) when a supplied count is not a nonnegative integer.\n\n`without(...views)` returns a new ordered array excluding the exact child View\ninstances supplied. Models and lookalike objects do not exclude their associated\nViews. With no arguments it returns a new array of every child View. Changing the\nreturned array's membership or order does not change the container. An empty\ncontainer returns `[]`.\n\n`children.isEmpty()` reports whether the child container currently has zero\nViews. It is distinct from the overridable `CollectionView#isEmpty()` method,\nwhich controls whether a CollectionView renders its `emptyView`.\n\nThe child container is iterable. `for...of`, spread, destructuring, and\n`Array.from(children)` yield the exact child View instances in container order.\nThe iterator is defined once on the prototype rather than allocated as an own\nproperty on every container.\n\nThe former undocumented Underscore aliases `forEach`, `detect`, `select`, `all`,\n`any`, and `include` are not part of the v5 container. Use `each`, `find`,\n`filter`, `every`, `some`, and `contains`, respectively.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst collectionView = new CollectionView({\n  collection: new Backbone.Collection()\n});\n\ncollectionView.render();\n\n// iterate over all of the views and process them\ncollectionView.children.each(function(childView) {\n  // process the `childView` here\n});\n```\n\n## Listening to Events on the `children`\n\nThe `CollectionView` can take action depending on what\nevents are triggered in its `children`.\n\nRead More:\n- [Child Event Bubbling](/docs/events.md#event-bubbling)\n\n## Self-Managed `children`\n\nIn addition to children added by Marionette matching the model of a `collection`,\nthe `children` of the `CollectionView` can be manually managed.\n\n### Adding a Child View\n\nThe `addChildView` method can be used to add a view that is independent of your\ncollection source. This method takes three parameters, the child view instance,\noptionally the index for where it should be placed within the\n[CollectionView's `children`](#managing-children), and an options hash.\nIt returns the added view.\n\n<!-- executable-example: collectionview-child-ownership -->\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst ChildView = View.extend({\n  tagName: 'li',\n  template() {\n    return 'Model';\n  }\n});\n\nexport function runChildOwnershipLifecycle() {\n  const collectionView = new CollectionView({ tagName: 'ul' });\n  const reusableChild = new ChildView();\n  const remainingChild = new ChildView();\n\n  collectionView.render();\n  collectionView.addChildView(reusableChild);\n\n  const detachedChild = collectionView.detachChildView(reusableChild);\n  collectionView.addChildView(detachedChild);\n  collectionView.removeChildView(detachedChild);\n\n  collectionView.addChildView(remainingChild);\n  collectionView.destroy();\n}\n```\n\n`detachChildView()` returns the same live View and transfers responsibility to\nthe caller. That View may be added again without rendering it a second time.\n`removeChildView()` destroys the removed View, while destroying the\n`CollectionView` destroys every child that it still manages.\n\nAn omitted or `null` index appends the child before sorting and filtering.\nThe options-only form follows the same rule; use a numeric `index` to choose\nan insertion position.\n\nA numeric index bypasses sorting and filtering for that addition only. A later\n`sort()` or `filter()` processes the child normally. The numeric `index` in an\noptions object takes precedence over the separate positional argument.\n\n**Errors** Adding a View that is still managed by a Region or\n`CollectionView` throws [`MN0003`](/errors/MN0003.md). Detach the View from its\ncurrent owner before transferring it.\n\nFiltering a child out or adding it with `preventRender` still leaves it managed\nby that CollectionView. Use `detachChildView()` to transfer it to another owner.\n\n#### `preventRender` option\n\nIf you wish to add a child view to the children without the collectionview rendering\nthe children use the `preventRender` option.\n\n```javascript\nimport { CollectionView } from 'marionette';\nimport ButtonView from './button-view';\n\nconst myCollectionView = new CollectionView();\n\nconst insertIndex = 0; // Add to the top\n\nmyCollectionView.addChildView(new ButtonView(), { preventRender: true, index: insertIndex });\nmyCollectionView.addChildView(new ButtonView(), insertIndex, { preventRender: true });\nmyCollectionView.addChildView(new ButtonView());  // renders all three children\n```\n\n### Removing a Child View\n\nThe `removeChildView` method is useful if you need to remove and destroy a view from\nthe `CollectionView` without affecting the view's collection.  In most cases it is\nbetter to use the data to determine what the `CollectionView` should display.\n\nThis method accepts the child view instance to remove as its parameter. It returns\nthe removed view.\n\nLater updates to the retained model do not recreate its removed View. Rendering\nthe CollectionView again or resetting its collection rebuilds its children from\nthe current collection.\n\n```javascript\nimport { CollectionView } from 'marionette';\n\n// Fragment for a collection using the Backbone DataApi.\nconst MyCollectionView = CollectionView.extend({\n  childViewEvents: { 'foo:event': 'onChildViewFooEvent' },\n  onChildViewFooEvent(childView, model) {\n    // NOTE: we must wait for the server to confirm\n    // the destroy PRIOR to removing it from the collection\n    model.destroy({wait: true});\n\n    // but go ahead and remove it visually\n    this.removeChildView(childView);\n  }\n});\n```\n\n### Detaching a Child View\n\nThe `detachChildView` method is the same as [`removeChildView`](#removing-a-child-view)\nwith the exception that the removed view is not destroyed.\n\n### Swapping Child Views\n\nSwap the location of two views in the `CollectionView` `children` and in the `el`.\nThis can be useful when sorting is arbitrary or is not performant.\n\n**Errors** If either of the two views aren't part of the `CollectionView` an error will be thrown.\n\nIf only one of the two children is in the presentation `children` container,\n[filter](#filtering-the-children) is called after swapping their owned order.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi } from 'marionette';\nimport MyChildView from './my-child-view';\n\nsetDataApi(BackboneApi);\n\nconst collection = new Backbone.Collection([\n  { name: 'first' },\n  { name: 'middle' },\n  { name: 'last' }\n]);\n\nconst myColView = new CollectionView({\n  collection: collection,\n  childView: MyChildView\n});\n\nmyColView.render();\nmyColView.swapChildViews(myColView.children.first(), myColView.children.last());\n\nmyColView.children.first().model.get('name'); // \"last\"\nmyColView.children.last().model.get('name'); // \"first\"\n```\n\n## Sorting the `children`\n\nThe `sort` method will loop through the `CollectionView` `children` prior to filtering\nand sort them with the [`viewComparator`](#defining-the-viewcomparator).\nBy default, if a `viewComparator` is not set, the `CollectionView` will sort\nthe views by the order of the models in the `collection`. If set to `false`,\npresentation sorting is disabled. Normalized collection observations still reconcile\nthe keyed children to source order when `sortWithCollection` is enabled.\n\nThis method is called internally when rendering.\n[`sort` and `before:sort` events](/docs/class-events.md#sort-and-beforesort-events)\nfire when owned children exist and a comparator is active.\n\nBy default the `CollectionView` will maintain a sorted collection's order\nin the DOM. This behavior can be disabled by specifying `{sortWithCollection: false}`\non initialize.\n\nDefault source ordering uses each notification's captured snapshot. A nested\nnotification waits for the current sort, filter, and render pass to finish.\nCalling `sort()` outside a collection notification reads the current source\nafter `before:sort`. With the default comparator, manually added children whose\nmodels are absent from the source stay before the source children.\n\nCustom comparators still determine their own order and data reads. With\n`sortWithCollection` enabled, source order breaks ties and manually added\nchildren follow source children on ties. With it disabled, ties retain the\nexisting child order.\n\n### Defining the `viewComparator`\n\n`CollectionView` allows for a custom `viewComparator` option if you want your\n`CollectionView`'s children to be rendered with a different sort order than the\nunderlying collection uses.\n\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst RowView = View.extend({ template: ({ rank }) => String(rank) });\nconst myCollectionView = new CollectionView({\n  collection: [{ rank: 2 }, { rank: 1 }],\n  childView: RowView,\n  viewComparator: 'rank'\n});\n```\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst RowView = View.extend({ template: ({ id }) => String(id) });\n\nconst myCollection = new Backbone.Collection([\n  { id: 1 },\n  { id: 4 },\n  { id: 3 },\n  { id: 2 }\n]);\n\nmyCollection.comparator = 'id';\n\nconst myDescendingView = new CollectionView({\n  childView: RowView,\n  collection: myCollection,\n  viewComparator: childView => -childView.model.id\n});\n\nconst mySourceOrderView = new CollectionView({\n  childView: RowView,\n  collection: myCollection,\n  viewComparator: false\n});\n\nmyDescendingView.render(); // 4 3 2 1\nmySourceOrderView.render(); // 1 4 3 2\n\nmyCollection.sort();\n// myDescendingView remains 4 3 2 1\n// mySourceOrderView reconciles to source order: 1 2 3 4\n```\n\nA `viewComparator` can be a one-argument criterion function, a two-argument\ncomparison function, or a string naming a model attribute read through DataApi.\nFunctions receive child Views, not models, and run with the CollectionView as\n`this`. These forms do not require Backbone.\n\nA string or single-argument comparator evaluates one criterion per child View and\nsorts stably. Equal, `NaN`, or otherwise incomparable criteria retain their existing\norder, while `undefined` criteria sort last. A string comparator therefore places a\nchild without a model last. Two-argument comparators retain native `Array#sort`\nsemantics. Sorting keeps the same `children` container in use. If evaluating or\ncomparing a single-argument criterion throws, the error propagates without changing\nthe child order.\n\n#### `getComparator`\n\nOverride this method to determine which `viewComparator` to use.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport { CollectionView, setDataApi } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst MyCollectionView = CollectionView.extend({\n  sortAsc(view) {\n    return view.model.get('order');\n  },\n  sortDesc(view) {\n    return -view.model.get('order');\n  },\n  getComparator() {\n    // The collectionView's model\n    if (this.model.get('sorted') === 'ASC') {\n      return this.sortAsc;\n    }\n\n    return this.sortDesc;\n  }\n});\n```\n\n#### `setComparator`\n\nThe `setComparator` method updates `viewComparator` and calls `sort()` when the\nvalue changes. `{ preventRender: true }` defers that sort/filter/child-render\npass. It returns the CollectionView and does not run the parent\n`before:render`/`render` lifecycle. Call it after initial rendering, or defer the\npass until the initial `render()`.\n\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst RowView = View.extend({ template: ({ orderBy }) => String(orderBy) });\nconst cv = new CollectionView({\n  collection: [{ orderBy: 2 }, { orderBy: 1 }],\n  childView: RowView\n});\n\ncv.render();\n\n// Note: the setComparator is preventing the automatic re-render\ncv.setComparator('orderBy', { preventRender: true });\n\n// Apply the order without rebuilding the children or parent template\ncv.sort();\n```\n\n#### `removeComparator`\n\nThis function is actually an alias of `setComparator(null, options)`. It is useful\nfor removing the comparator. `removeComparator` also accepts `preventRender` as a option.\n\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst RowView = View.extend({ template: ({ orderBy }) => String(orderBy) });\nconst cv = new CollectionView({\n  collection: [{ orderBy: 2 }, { orderBy: 1 }],\n  childView: RowView\n});\n\ncv.render();\n\ncv.setComparator('orderBy');\n\n//Remove the current comparator without rendering again.\ncv.removeComparator({ preventRender: true });\n```\n\n### Maintaining the `collection`'s sort\n\nBy default the `CollectionView` will maintain a sorted collection's order\nin the DOM. This behavior can be disabled by specifying `{sortWithCollection: false}`\non initialize or on the view definiton.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst RowView = View.extend({ template: ({ id }) => String(id) });\n\nconst myCollection = new Backbone.Collection([\n  { id: 1 },\n  { id: 4 },\n  { id: 3 },\n  { id: 2 }\n]);\n\nmyCollection.comparator = 'id';\n\nconst mySortedColView = new CollectionView({\n  childView: RowView,\n  collection: myCollection\n});\n\nconst myUnsortedColView = new CollectionView({\n  childView: RowView,\n  collection: myCollection,\n  sortWithCollection: false\n});\n\nmySortedColView.render(); // 1 4 3 2\nmyUnsortedColView.render(); // 1 4 3 2\n\nmyCollection.sort();\n// mySortedColView auto-renders 1 2 3 4\n// myUnsortedColView has no change\n```\n\n## Filtering the `children`\n\nThe `filter` method will loop through the `CollectionView`'s sorted `children`\nand test them against the [`viewFilter`](#defining-the-viewfilter).\nThe views that pass the `viewFilter` are rendered if necessary and attached\nto the CollectionView and the views that are filtered out will be detached.\nAfter filtering the `children` will only contain the views to be attached.\n\nIf owned children exist and an active `viewFilter` is applied, the\n[`filter` and `before:filter` events](/docs/class-events.md#filter-and-beforefilter-events)\nwill trigger.\n\nThe CollectionView refilters during normalized collection updates and sorting.\nAn arbitrary child property change does not itself trigger filtering; call\n`filter()` when application-owned presentation criteria change.\n\n**Note** This is a presentation functionality used to easily filter in and out\nconstructed children. All children of a `collection` will be instantiated once\nregardless of their filtered status. If you would prefer to manage child view\ninstantiation, you should filter the `collection` itself.\n\n### Defining the `viewFilter`\n\n`CollectionView` allows for a custom `viewFilter` option if you want to prevent\nsome of the underlying `children` from being attached to the DOM.\nA `viewFilter` can be a function, predicate object, or string. Use `null` or\n`false` to disable it. Other shapes are unsupported; core does not guarantee\na diagnostic for an invalid filter.\n\n#### `viewFilter` as a function\n\nThe `viewFilter` function takes a view from the `children` and returns a truthy\nvalue if the child should be attached, and a falsey value if it should not.\nIt runs with the `CollectionView` as `this` and receives the child View, index,\nand the live backing child array. A filter pass captures the array's initial\nlength, visits every index densely, and does not visit entries appended during\nthat pass.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst SomeChildView = View.extend({ template: ({ value }) => String(value) });\nconst SomeEmptyView = View.extend({ template: () => 'No matches' });\n\nconst cv = new CollectionView({\n  childView: SomeChildView,\n  emptyView: SomeEmptyView,\n  collection: new Backbone.Collection([\n    { value: 1 },\n    { value: 2 },\n    { value: 3 },\n    { value: 4 }\n  ]),\n\n  // Only show views with even values\n  viewFilter(view, index, children) {\n    return view.model.get('value') % 2 === 0;\n  }\n});\n\n// renders the views with values '2' and '4'\ncv.render();\n```\n\n#### `viewFilter` as a predicate object\n\nThe `viewFilter` predicate object will filter against the view's model attributes.\nEach filter pass snapshots the predicate's own enumerable string keys and values\nin standard JavaScript own-key order. Inherited, symbol, and non-enumerable keys\nare ignored. Every predicate key must exist in the model attributes and its value\nmust compare strictly equal; nested objects therefore match by identity. Arrays\nare not predicate objects.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst SomeChildView = View.extend({ template: ({ value }) => String(value) });\nconst SomeEmptyView = View.extend({ template: () => 'No matches' });\n\nconst cv = new CollectionView({\n  childView: SomeChildView,\n  emptyView: SomeEmptyView,\n  collection: new Backbone.Collection([\n    { value: 1 },\n    { value: 2 },\n    { value: 3 },\n    { value: 4 }\n  ]),\n\n  // Only show views with value 2\n  viewFilter: { value: 2 }\n});\n\n// renders the view with values '2'\ncv.render();\n```\n\n#### `viewFilter` as a string\n\nThe `viewFilter` string represents the view's model attribute and will filter\ntruthy values.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst SomeChildView = View.extend({ template: ({ value }) => String(value) });\nconst SomeEmptyView = View.extend({ template: () => 'No matches' });\n\nconst cv = new CollectionView({\n  childView: SomeChildView,\n  emptyView: SomeEmptyView,\n  collection: new Backbone.Collection([\n    { value: 0 },\n    { value: 1 },\n    { value: 2 },\n    { value: null },\n    { value: 4 }\n  ]),\n\n  // Only show views 1,2, and 4\n  viewFilter: 'value'\n});\n\n// renders the view with values '1', '2', and '4'\ncv.render();\n```\n\n#### `getFilter`\n\nOverride this function to programatically decide which\n`viewFilter` to use when `filter` is called.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport { CollectionView, setDataApi } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst MyCollectionView = CollectionView.extend({\n  summaryFilter(view) {\n    return view.model.get('type') === 'summary';\n  },\n  getFilter() {\n    if (this.collection.length > 100) {\n      return this.summaryFilter;\n    }\n    return this.viewFilter;\n  }\n});\n```\n\n#### `setFilter`\n\nThe `setFilter` method updates `viewFilter` and calls `filter()` when the value\nchanges. `{ preventRender: true }` defers that filter/child-render pass. It\nreturns the CollectionView without running the parent render lifecycle. Call\nit after initial rendering, or defer the pass until the initial `render()`.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst RowView = View.extend({ template: ({ value }) => String(value) });\nconst cv = new CollectionView({\n  collection: new Backbone.Collection([{ value: 1 }, { value: 2 }]),\n  childView: RowView\n});\n\ncv.render();\n\nconst newFilter = function(view, index, children) {\n  return view.model.get('value') % 2 === 0;\n};\n\n// Note: the setFilter is preventing the automatic re-render\ncv.setFilter(newFilter, { preventRender: true });\n\n// Apply the new filter while retaining surviving child instances.\ncv.filter();\n```\n\n#### `removeFilter`\n\nThis function is actually an alias of `setFilter(null, options)`. It is useful\nfor removing filters. `removeFilter` also accepts `preventRender` as a option.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { CollectionView, setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\nconst RowView = View.extend({ template: ({ value }) => String(value) });\nconst cv = new CollectionView({\n  collection: new Backbone.Collection([{ value: 1 }, { value: 2 }]),\n  childView: RowView\n});\n\ncv.render();\n\ncv.setFilter(function(view, index, children) {\n  return view.model.get('value') % 2 === 0;\n});\n\n// Remove the current filter without rendering again.\ncv.removeFilter({ preventRender: true });\n```\n\n\n[Canonical source](/docs/markdown/docs/marionette.collectionview.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.application.md",
      "title": "Application",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/application/",
      "markdownUrl": "https://marionettejs.com/docs/application.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.application.md",
      "sourceSha256": "0c820bfdad7a67a5f0697aca747da3f8c8354246ddc0882aba7675bac5c48ddc",
      "sha256": "11b56bbb20e7d69fd623a56103d865d4e28299d34e0cda6cc778e8d14ffea8a8",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 0c820bfdad7a67a5f0697aca747da3f8c8354246ddc0882aba7675bac5c48ddc. -->\n\n# Marionette.Application\n\nAn `Application` gives a feature a place to start, stop, restart, and clean up.\nIt coordinates asynchronous work and child Applications, with an optional\nRegion for the feature's view tree.\n\n`Application` includes:\n- [Common Marionette Functionality](/docs/common.md)\n- [Class Events](/docs/class-events.md#application-events)\n- [Radio API](/docs/radio.md#marionette-integration)\n- [State API](/docs/state.md#borrowed-and-owned-sources)\n\n`Application` is an independent class. It does not inherit from `MnObject` and\ndoes not add an element or render method.\n\nThe `Application` `cidPrefix` is `mna`.\n\n## Documentation Index\n\n* [Instantiating An Application](#instantiating-an-application)\n* [Application Lifecycle](#application-lifecycle)\n* [Application Ownership](#application-ownership)\n* [Application and root View communication](#application-and-root-view-communication)\n* [Application State](#application-state)\n* [Application Region](#application-region)\n* [Application Region Methods](#application-region-methods)\n\n## Instantiating an Application\n\nWhen instantiating an `Application` there are several properties, if passed,\nthat will be attached directly to the instance:\n`channelName`, `radioEvents`, `radioRequests`, `region`, `regionClass`,\n`stateEvents`\n\n```javascript\nimport { Application } from 'marionette';\n\nconst myApplication = new Application();\n```\n\n### Initialization hooks\n\n`preinitialize(options)` runs after `options` and `cid` are assigned, before\nMarionette sets up the Region, Radio, and State. Use it to prepare instance\nconfiguration those steps depend on. `initialize(options)` runs after that\nsetup, before State event subscriptions are connected. Owned State is still\ncreated lazily when `getState()` is first called.\n\n```javascript\nconst FeatureApplication = Application.extend({\n  preinitialize(options) {\n    this.channelName = options.featureName;\n    this.region = { el: options.element };\n  },\n  initialize() {\n    // The configured Region and Radio channel are now available.\n  }\n});\n```\n\nBoth hooks receive the original constructor arguments and run synchronously;\nreturned Promises are not awaited. Use `onBeforeStart` for asynchronous startup\nreadiness.\n\nConstructor errors propagate to the caller. Marionette does not undo partially\ncompleted initialization or automatically release resources from a constructor\nthat throws. See the shared [synchronous failure boundary](/docs/lifecycle.md#synchronous-failures).\nApplication's asynchronous lifecycle has its own cancellation and failure contract,\ndescribed below.\n\n## Application Lifecycle\n\n`start`, `stop`, `restart`, and `destroy` return a `Promise<boolean>`. The\nPromise resolves `true` when the requested target state is reached, including\nan idempotent call when that state is already current. It resolves `false` when\na later incompatible operation supersedes the request. `false` is cancellation,\nnot failure. A current lifecycle hook failure rejects its operation Promise.\n\nCompatible repeated calls share the in-flight Promise. Before destruction\nbegins, the latest incompatible operation wins: for example, `stop()` during\nstartup resolves the earlier `start()` as `false`, completes the stop lifecycle,\nand prevents a stale `start` event. A `start()` that supersedes an in-flight\nstop waits for the already-running `onBeforeStop` readiness hook before beginning startup;\nit does not emit the invalidated `stop` completion. Once destruction begins it is terminal;\n`start()` and `restart()` resolve `false`, while `stop()` follows the active\nteardown until it has reached a stopped or destroyed state. Completion of an\ninvalidated asynchronous hook cannot change the Application's running or\ndestroyed state or emit the invalidated success event.\n\n`isRunning()` is `true` only after startup readiness completes and while the\nApplication is running. It is `false` before the first start, during lifecycle\ntransitions, after stop, and after destroy.\n\n### Lifecycle operations\n\n| Current condition | Operation | Lifecycle | Result |\n| --- | --- | --- | --- |\n| Not running | `start(options)` | `before:start`, await readiness, `start` | `true` when running |\n| Running | `start(options)` | No-op | `true` |\n| Running or starting | `stop(options)` | Invalidates startup when needed, then `before:stop`, `stop` | `true` when stopped; the invalidated start resolves `false` |\n| Stopped | `stop(options)` | Empty a root View shown outside startup; otherwise no-op | `true` |\n| Any live, non-destroying state | `restart(options)` | Stop when needed, then start | `true` when running |\n| Running or starting | `destroy(options)` | Stop when needed, then `before:destroy`, `destroy` | `true` when destroyed |\n| Stopped | `destroy(options)` | `before:destroy`, `destroy` | `true` when destroyed |\n| Destroying | repeated `destroy()` | Shares the active destroy lifecycle | Same in-flight Promise |\n| Destroying | `start()` or `restart()` | Terminal no-op | `false` |\n| Destroying | `stop()` | Follows active teardown without interrupting it | `true` once stopped or destroyed; rejects if teardown fails before stopping |\n| Destroyed | `start()` or `restart()` | Terminal no-op | `false` |\n| Destroyed | `stop()` or `destroy()` | Terminal no-op | `true` |\n\nThe `onBeforeStart`, `onBeforeStop`, and `onBeforeDestroy` methods may return a\nPromise. Their corresponding `before:*` events still fire synchronously, but\nevent-listener return values are not readiness inputs. `onStart`, `onStop`,\n`onDestroy`, and their matching events are completion notifications and are not\nawaited. A `before:*` method must not await the same operation whose readiness it\nis defining. `restart` composes the stop and start lifecycles; it does not add a\nparallel restart hook path.\n\nEach readiness hook and `before:*` event receives the Application, the\noperation options, and a context object with an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal):\n`(application, options, { signal })`. When a later operation invalidates\nreadiness, Marionette aborts its signal before starting replacement readiness.\nThe signal makes cancellation cooperative; the invalidated operation still\nresolves `false` even when a handler ignores it. When a start, restart, or\ndestroy operation adopts an in-flight stop phase, it also adopts that phase's\noriginal options and context, and does not abort its signal.\n\nIf a replacement start has already canceled the remaining child stops, that\nstop phase is no longer adopted. A later `stop()`, `restart()`, or `destroy()`\nbegins a fresh stop phase with its own options and context.\n\nThe context belongs to the readiness phase rather than to one caller's Promise.\nCompletion methods and events receive only `(application, options)`.\n\nOwned child Applications participate in the same operation. After the owner's\n`before:start` readiness, children start sequentially in registration order\nbefore the owner reaches running and emits `start`. After `before:stop`\nreadiness, children stop in that order before the owner reaches stopped and\nemits `stop`. Restart and destroy compose those same phases.\n\nIf a direct child operation supersedes an owner-requested child start or stop,\nthe owner operation resolves `false`, retains its prior stable state, and does\nnot emit its completion event. Children that already reached the requested\nstate remain there. `isRunning()` describes that Application, not an aggregate\nof every descendant state; callers receiving `false` can inspect child state\nthrough the public hierarchy. Once owner destruction begins, descendant `start`\nand `restart` calls resolve `false` so they cannot interrupt terminal teardown.\n\n### Starting an Application\n\nOnce configured, await `start(options)` before dispatching work that requires a\nrunning Application. The optional argument is passed to the lifecycle methods\nand events.\n\nThe application below loads a session before showing its root View. The supplied\n`loadSession({ signal })` function returns a Promise for an object with a\n`name` string. It can use `fetch`, a cache, or the project's existing data layer.\n\n<!-- executable-example: application-bootstrap-readiness -->\n```javascript\nimport { Application, View } from 'marionette';\n\nconst SessionView = View.extend({\n  template: () => '<h1></h1>',\n  onRender() {\n    this.el.querySelector('h1').textContent = this.model.name;\n  }\n});\n\nexport function createSessionApplication({ el, loadSession }) {\n  const SessionApplication = Application.extend({\n    async onBeforeStart(app, options, { signal }) {\n      const session = await loadSession({ signal });\n      if (signal.aborted) return;\n      this.session = session;\n    },\n    onStart() {\n      this.showView(new SessionView({ model: this.session }));\n    }\n  });\n\n  return new SessionApplication({ region: { el } });\n}\n```\n\nCreate and start it at the application entry point:\n\nServe this application and its API over HTTPS in production; relative requests\nuse the application origin.\n\n```javascript\nconst app = createSessionApplication({\n  el: document.querySelector('#root-element'),\n  async loadSession({ signal }) {\n    const response = await fetch('/api/bootstrap', { signal });\n    if (!response.ok) throw new Error(`Session request failed: ${response.status}`);\n    return response.json();\n  }\n});\n\nconst started = await app.start();\nif (started) {\n  // Dispatch work that requires the running feature.\n}\n```\n\nCheck the readiness signal after asynchronous work and before mutating\napplication state. Marionette prevents a canceled operation from emitting its\nsuccess event, but cannot undo a stale assignment inside application code.\nA current loader failure rejects `start()`; handle it at the application entry\npoint. Route registration and browser-history startup belong to the router's\nowner, outside a feature's restartable `onStart` hook. See\n[router integration](/docs/routing.md) for per-navigation loading and cancellation.\n\n## Application Ownership\n\nAn Application may own named child Applications. Ownership is one-way: an\nApplication locates and controls its children, while children receive required\ncollaborators explicitly. Internal parent references exist only to enforce\nlifecycle and unlink children safely; upward lookup is not public API.\n\n`addChildApp(name, application)` registers an existing live,\nparentless Application instance under a non-empty string name and returns that\ninstance. Registration does not construct or implicitly start the child. Use\n`hasChildApp(name)` before constructing a dynamic child when duplicate\nallocation matters. Registering the same instance again under its existing\nowner and name is an idempotent no-op. A conflicting owner, name, runtime, or cyclic ownership relationship throws\n[`MN0031`](/errors/MN0031.md).\n\nCalls to `addChildApp` after the owner's destruction begins return the supplied\nvalue without inspecting or adopting it. A child from the same runtime whose\ndestruction has begun is also returned without registration. Live registrations\nrequire the owner and child to belong to the same Marionette runtime.\n\n```javascript\nconst root = new Application();\n\nif (!root.hasChildApp('search')) {\n  root.addChildApp('search', new SearchApplication());\n}\n\nconst search = root.getChildApp('search');\n\nsearch.getName(); // 'search'\nroot.getChildApps(); // { search }\n```\n\n`getChildApps()` returns a fresh snapshot. Changing the snapshot does\nnot change ownership. Child lookup methods are reads; they do not start, render,\nor otherwise mutate an Application.\n\nOwner lifecycle options are forwarded to each child. A child failure rejects\nthe owner operation and leaves the owner in its last committed stable state.\nChildren that already reached the requested state remain there; retry visits\nthe same registration order, where completed child operations are idempotent.\nAn owner transition completes only after every child remains in the requested\nstable state. A direct opposing child operation cancels the owner transition,\nand superseding the owner from `before:start` or `before:stop` prevents the\nstale transition from changing any further children.\n\n`removeChildApp(name, options)` destroys the named child and resolves\nwith it after destruction. An unknown name resolves with `undefined`. A child\nalso removes itself from its parent's child hierarchy when destroyed directly. A\nrunning parent stops its children before `before:destroy`, then destroys owned\nchildren in registration order and finally emits the parent's `destroy`\ncompletion. A parent's `onBeforeDestroy` readiness hook can therefore inspect its\nstopped, live children. A stopped parent also stops any child that was\nstarted directly before entering destroy readiness. A concurrent direct child\ndestroy joins terminal teardown and may remove that child before parent\nreadiness. If child stop or destroy readiness fails, the parent returns to its\nlast committed stable state and retains that child so destruction can be retried.\n\nThe canonical child-Application pattern is explicit construction followed by\nownership registration. Registration means lifecycle ownership; it is not a\ndormant service registry and it has no per-child lifecycle flags. Put a service\nthat must outlive an Application under a longer-lived owner and pass it to the\nshorter-lived child as a dependency.\n\n<!-- executable-example: application-child-ownership -->\n```javascript\nimport { Application } from 'marionette';\n\nexport const lifecycle = [];\n\nconst SearchApplication = Application.extend({\n  onBeforeStart(app, options) {\n    lifecycle.push(`search:before:start:${ options.source }`);\n  },\n\n  onStart(app, options) {\n    lifecycle.push(`search:start:${ options.source }`);\n  },\n\n  onBeforeStop(app, options) {\n    lifecycle.push(`search:before:stop:${ options.source }`);\n  },\n\n  onStop(app, options) {\n    lifecycle.push(`search:stop:${ options.source }`);\n  },\n\n  onDestroy() {\n    lifecycle.push('search:destroy');\n  }\n});\n\nconst RootApplication = Application.extend({\n  onBeforeStart(app, options) {\n    lifecycle.push(`root:before:start:${ options.source }`);\n  },\n\n  onStart(app, options) {\n    lifecycle.push(`root:start:${ options.source }`);\n  },\n\n  onBeforeStop(app, options) {\n    lifecycle.push(`root:before:stop:${ options.source }`);\n  },\n\n  onStop(app, options) {\n    lifecycle.push(`root:stop:${ options.source }`);\n  },\n\n  onDestroy() {\n    lifecycle.push('root:destroy');\n  }\n});\n\nexport const root = new RootApplication();\nexport const search = root.addChildApp('search', new SearchApplication());\n\nexport const started = await root.start({ source: 'owner' });\nexport const stopped = await root.stop({ source: 'owner' });\n```\n\n## Application and root View communication\n\nKeep the ownership direction visible. The Application constructs the root View,\npasses dependencies and initial values down through its options or public methods,\nand listens to semantic View events for messages back up. The View should not find\nits Application through DOM ancestry or private ownership fields. Use Radio only\nwhen the sender and receiver do not share this direct ownership boundary.\n\n<!-- executable-example: application-root-view-communication -->\n```javascript\nimport { Application, View } from 'marionette';\n\nexport const refreshes = [];\n\nconst DashboardView = View.extend({\n  initialize(options) {\n    this.initialStatus = options.initialStatus;\n  },\n\n  template() {\n    return '<button class=\"refresh\">Refresh</button><p class=\"status\"></p>';\n  },\n\n  events: {\n    'click .refresh': 'requestRefresh'\n  },\n\n  onRender() {\n    this.showStatus(this.initialStatus);\n  },\n\n  requestRefresh() {\n    this.trigger('refresh:requested', this, { source: 'button' });\n  },\n\n  showStatus(status) {\n    this.el.querySelector('.status').textContent = status;\n  }\n});\n\nconst DashboardApplication = Application.extend({\n  region: '#dashboard',\n\n  onStart() {\n    const view = new DashboardView({ initialStatus: 'Idle' });\n    this.listenTo(view, 'refresh:requested', this.refreshDashboard);\n    this.showView(view);\n  },\n\n  refreshDashboard(view, request) {\n    refreshes.push(request);\n    view.showStatus('Updated');\n  }\n});\n\nexport const dashboard = new DashboardApplication();\nawait dashboard.start();\nexport const dashboardView = dashboard.getView();\n```\n\n## Application state\n\nAn Application may compose one [state source](/docs/state.md). A supplied\n`state` is borrowed; a `createState(options)` result is owned. `getState()`\nreturns the exact source, and `stateEvents` are installed through the selected\nStateApi after `initialize`.\n\nApplication state persists across stop and restart. Destruction releases its\nsubscriptions, then disposes its owned state source through StateApi.\nStateless Applications allocate no source or subscription. Asynchronous startup\nwork must use the readiness context's abort signal before committing values so\ninvalidated startup cannot apply stale changes.\n\n## Application Region\n\nAn `Application` coordinates one root View through a single\n[region](/docs/region.md). The `region` property can be\n[defined in multiple ways](/docs/region.md#defining-regions).\n\n```javascript\nimport { Application } from 'marionette';\nimport RootView from './views/root';\n\nconst MyApp = Application.extend({\n  region: '#root-element',\n\n  onStart() {\n    this.showView(new RootView());\n  }\n});\n\nconst myApp = new MyApp();\nawait myApp.start();\n```\n\nThe `onStart` callback synchronously renders and shows `RootView`.\n`before:render` and `render` run for its template; `before:attach` and `attach`\nalso run when the Region is attached to a document and lifecycle monitoring is\nenabled. `start()` itself remains asynchronous.\n\n`region` can also be passed as an option during instantiation.\n\nThe Application owns a Region that it constructs from a selector, Region class,\nor definition object. Passing an existing Region instance instead borrows that\nhost. Stopping the Application empties the Region's current View, including one\nshown directly through the Region. Destroying the Application also destroys a Region it\nconstructed, but never destroys a borrowed Region.\n\nThe Application's View is whatever its Region currently shows. Showing a View\nthrough either `app.showView(view)` or `app.getRegion().show(view)` updates what\n`app.getView()` returns. Emptying or detaching the Region leaves no current View\nwithout stopping the Application. Restart removes the current View before\n`onStart` may show a new View. If the Region has no View, stopping the Application\nleaves any unmanaged HTML alone.\n\n### `regionClass`\n\nBy default the [`Region`](/docs/region.md) is used to instantiate the `Application`'s region.\nAn extended Region can be provided to the `Application` definition to override the default.\n\n```javascript\nimport { Application, Region } from 'marionette';\n\nconst MyRegion = Region.extend({\n  isSpecial: true\n});\n\nconst MyApp = Application.extend({\n  regionClass: MyRegion\n});\n\nconst myApp = new MyApp({ region: '#foo' });\n\nmyApp.getRegion().isSpecial; // true\n```\n\n`regionClass` can also be passed as an option during instantiation.\n\n## Application Region Methods\n\nThe Marionette Application provides helper methods for managing its attached region.\n\n### `getRegion()`\n\nReturn the current host [region object](/docs/region.md) for the\nApplication, or `undefined` if none was configured. This synchronous query does\nnot resolve its element or render a View. The host reference is released when\nthe Application is destroyed.\n\n### `showView(view, options)`\n\nDisplay a `View` instance in the Region attached to the Application. This runs the\n[`View lifecycle`](/docs/lifecycle.md). The Application itself is never passed\nto `Region#show` and does not become renderable.\n\nThis method is synchronous and returns the supplied View, forwarding `options`\nto `Region#show`. Configure a Region before calling it. It does not call\n`start()` or wait for Application readiness. Once destruction begins it returns\nthe supplied View without displaying or adopting it. A missing element allowed\nby `allowMissingEl` also leaves the View caller-owned; use `getView() === view`\nto check that it was shown.\n\n### `getView()`\n\nReturn the Region's `currentView`, including a View shown directly through the\nRegion or before Application startup. Returns `undefined` when the Region has no\ncurrent View or the Application has no Region.\n\n\n[Canonical source](/docs/markdown/docs/marionette.application.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.behavior.md",
      "title": "Behavior",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/behavior/",
      "markdownUrl": "https://marionettejs.com/docs/behavior.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.behavior.md",
      "sourceSha256": "bf002b5ba380cf1bb1054b98f9813d89b4aef16ba6495d02b823ed178ab3f0c4",
      "sha256": "7bdf6ecba5120701c4500a6d104817365230b455c183b811bbc1aae34fce7457",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 bf002b5ba380cf1bb1054b98f9813d89b4aef16ba6495d02b823ed178ab3f0c4. -->\n\n# Marionette.Behavior\n\nA `Behavior` shares interaction logic across views. It uses its host view's\nDOM and can handle DOM, model, and collection events without giving each\nview another copy of the same handlers.\n\n`Behavior` includes:\n- [Common Marionette Functionality](/docs/common.md)\n- [Class Events](/docs/class-events.md#behavior-events)\n- [DOM Interactions](/docs/dom-interactions.md)\n- [Entity Events](/docs/entity-events.md)\n\n[Attach a Behavior class to a view](#using-behaviors) through its `behaviors`\ndefinition. The view constructs the Behavior and manages its lifetime.\n\n## Documentation Index\n\n* [Instantiating a Behavior](#instantiating-a-behavior)\n* [Using Behaviors](#using-behaviors)\n  * [Defining and Attaching Behaviors](#defining-and-attaching-behaviors)\n  * [Behavior Options](#behavior-options)\n* [Nesting Behaviors](#nesting-behaviors)\n* [The Behavior's `view`](#the-behaviors-view)\n* [Host Communication and Event Proxies](#host-communication-and-event-proxies)\n  * [Host and Behavior Events](#host-and-behavior-events)\n  * [Proxy Handlers](#proxy-handlers)\n  * [Initialize Order](#initialize-order)\n  * [Using `ui`](#using-ui)\n  * [Host DOM Boundary](#host-dom-boundary)\n* [Behavior Lifecycle](#behavior-lifecycle)\n* [Destroying a Behavior](#destroying-a-behavior)\n\n\n## Instantiating a Behavior\n\nUnlike other [Marionette classes](/docs/classes.md), `Behavior`s are not meant to\nbe instantiated except by a view.\n\n## Using Behaviors\n\nThe easiest way to see how to use the `Behavior` class is to take an example\nview and factor out common behavior to be shared across other views.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template() {\n    return '<button class=\"destroy-btn\" type=\"button\">Destroy</button>';\n  },\n\n  ui: {\n    destroy: '.destroy-btn'\n  },\n\n  events: {\n    'click @ui.destroy': 'warnBeforeDestroy'\n  },\n\n  warnBeforeDestroy() {\n    alert('This view will be removed.');\n    this.destroy();\n  },\n\n  onRender() {\n    this.getUI('destroy')[0].title = 'What a nice mouse you have.';\n  }\n});\n```\n\nInteraction points, such as tooltips and warning messages, are generic concepts.\nThere is no need to recode them within your Views so they are prime candidates\nto be extracted into `Behavior` classes.\n\n### Defining and Attaching Behaviors\n\n<!-- executable-example: behavior-defining-attaching -->\n```javascript\nimport { Behavior, View } from 'marionette';\n\nconst DestroyWarn = Behavior.extend({\n  // You can set default options\n  // They will be overridden if you pass in an option with the same key.\n  options: {\n    message: 'You are destroying!'\n  },\n\n  ui: {\n    destroy: '.destroy-btn'\n  },\n\n  // Behaviors have events that are bound to the view's DOM.\n  events: {\n    'click @ui.destroy': 'warnBeforeDestroy'\n  },\n\n  warnBeforeDestroy() {\n    const message = this.getOption('message');\n    window.alert(message);\n    // Every Behavior has a hook into the\n    // view that it is attached to.\n    this.view.destroy();\n  }\n});\n\nconst ToolTip = Behavior.extend({\n  options: {\n    text: 'Tooltip text'\n  },\n\n  ui: {\n    tooltip: '.tooltip'\n  },\n\n  onRender() {\n    this.getUI('tooltip')[0].title = this.getOption('text');\n  }\n});\n\nexport const MyView = View.extend({\n  template() {\n    return [\n      '<button class=\"destroy-btn\" type=\"button\">Destroy</button>',\n      '<span class=\"tooltip\">More information</span>'\n    ].join('');\n  },\n\n  behaviors: [DestroyWarn, ToolTip]\n});\n```\n\nEach behavior will now be able to respond to user interactions as though the\nevent handlers were attached to the view directly. In addition to using array\nnotation, Behaviors can be attached using an object:\n\n```javascript\nconst MyView = View.extend({\n  behaviors: {\n    destroy: DestroyWarn,\n    tooltip: ToolTip\n  }\n});\n```\n\nArrays are the only supported list form for `behaviors`. Object maps use own\nenumerable string keys in standard JavaScript own-key order. Inherited, symbol,\nand non-enumerable properties are ignored, and a numeric `length` property is\nan ordinary map entry rather than an array-like signal.\n\n#### Behavior Options\n\nWhen we attach behaviors to views, we can also pass in options to add to the\nbehavior. This tends to be static information relating to what the behavior\nshould do. In our above example, we want to override the message to our\n`DestroyWarn` and `Tooltip` behaviors to match the original message on the View:\n\n```javascript\nconst MyView = View.extend({\n  behaviors: [\n    {\n      behaviorClass: DestroyWarn,\n      message: 'You are about to destroy all your data!'\n    },\n    {\n      behaviorClass: ToolTip,\n      text: 'What a nice mouse you have.'\n    }\n  ]\n});\n```\n\nThere are several properties, if passed, that will be attached directly to the instance:\n`collectionEvents`, `events`, `modelEvents`, `stateEvents`, `triggers`, `ui`\n\nUsing an object, we must define the `behaviorClass` attribute to refer to our\nbehaviors and then add any extra options with keys matching the option we want\nto override. Any passed options will override the values from `options` property.\n\nBehavior options can also provide collaborators that the Behavior needs. These\nvalues are selected during construction and retained by reference. Read an\narbitrary collaborator with `getOption()` so that a class default and an\nattachment override follow the same option precedence; arbitrary option names\nare not copied directly onto the Behavior instance. A host can explicitly pass\nan injected service through a `behaviors()` function:\n\n`initialize(options, hostView)` receives the same host View exposed as\n`this.view`.\n\n<!-- executable-example: behavior-collaborator -->\n```javascript\nimport { Behavior, View } from 'marionette';\n\nconst SelectionBehavior = Behavior.extend({\n  initialize() {\n    this.listenTo(\n      this.getOption('service'),\n      'selection:change',\n      this.onSelectionChange\n    );\n  },\n\n  onSelectionChange(selection) {\n    this.view.showSelection(selection);\n  }\n});\n\nexport const SelectionView = View.extend({\n  template() {\n    return '<output class=\"selection\"></output>';\n  },\n\n  ui: {\n    selection: '.selection'\n  },\n\n  behaviors() {\n    return [{\n      behaviorClass: SelectionBehavior,\n      service: this.getOption('selectionService')\n    }];\n  },\n\n  showSelection(selection) {\n    this.getUI('selection')[0].textContent = selection.label;\n  }\n});\n```\n\n`getOption()` does not fall back to options on the host. Use `this.view` for\ndependencies owned by the host, such as its model or collection. A nested\nBehavior receives its own definition options while sharing the same host View\nas the Behavior that declared it.\n\nWhen a Behavior is removed directly or its host is destroyed, Marionette removes\nsubscriptions created by that Behavior with `listenTo()`. It does not destroy or\ndispose arbitrary values passed through Behavior options, and unrelated listeners\non those collaborators remain active.\n\n**Errors** An error will be thrown if the `Behavior` class is not passed.\n\n## Nesting Behaviors\n\nIn addition to extending a `View` with `Behavior`, a `Behavior` can itself use\nother Behaviors. The syntax is identical to that used for a `View`:\n\n```javascript\nimport { Behavior } from 'marionette';\n\nconst Modal = Behavior.extend({\n  behaviors: [\n    {\n      behaviorClass: DestroyWarn,\n      message: 'Whoa! You sure about this?'\n    }\n  ]\n});\n```\n\nNesting groups Behavior declarations; it does not transfer cleanup ownership to\nthe declaring Behavior. Nested Behaviors act as direct Behaviors of the same host\nview, so destroying the declarer leaves them active until they are removed\ndirectly or the host is destroyed.\n\n## The Behavior's `view`\nThe `view` is a reference to the `View` instance that the `Behavior` is attached to.\n\n```javascript\nimport { Behavior } from 'marionette';\n\nBehavior.extend({\n  handleDestroyClick() {\n    this.view.destroy();\n  }\n});\n```\n\n## Host Communication and Event Proxies\n\nA Behavior is an event-capable object attached to one host View. It can handle\nhost events, DOM events, and host entity events while keeping its own events\nseparate from the host.\n\n### Host and Behavior Events\n\nWhen the host calls `triggerMethod()`, the host's corresponding `onEvent` method\nruns first. The event is then broadcast with the same arguments to every attached\nBehavior, where the corresponding method runs with that Behavior as its context.\nNested Behaviors participate directly in the same host broadcast. Calling the\nhost's `trigger()` also broadcasts to Behaviors, but does not call the host's `onEvent`\nmethod. Do not rely on an ordering among Behavior handlers.\n\nHost and Behavior DOM declarations are delegated independently. If multiple\nBehaviors or the host declare the same event and selector, every matching\ndeclaration runs once. Do not use declaration collisions to establish\nprecedence or suppress another handler.\n\nHost broadcasts include events produced by:\n\n* Calls to `triggerMethod()`\n* DOM `triggers`\n* `childViewTriggers`\n* Child events forwarded through a non-false `childViewEventPrefix`\n\n`childViewEvents` calls the configured host handler directly. It becomes a host\nbroadcast only if that handler explicitly calls `triggerMethod()`.\n\nA call to `behavior.triggerMethod()` stays local to that Behavior. It does not\ninvoke the host or sibling Behaviors. To request host work, call an appropriate\npublic host method or explicitly use `this.view.triggerMethod()`. The latter is a\nhost broadcast, so every attached Behavior receives it, including the Behavior\nthat sent it. Do not re-emit the same host event from that Behavior's corresponding\nhandler, as doing so would recurse.\n\n<!-- executable-example: behavior-host-communication -->\n```javascript\nimport { Behavior, View } from 'marionette';\n\nconst SaveBehavior = Behavior.extend({\n  ui: {\n    save: '.save'\n  },\n\n  events: {\n    'click @ui.save': 'requestSave'\n  },\n\n  requestSave() {\n    this.view.requestSave();\n  }\n});\n\nexport const FormView = View.extend({\n  behaviors: [SaveBehavior],\n\n  template() {\n    return '<button class=\"save\" type=\"button\">Save</button>';\n  },\n\n  requestSave() {\n    this.triggerMethod('save:requested', this);\n  }\n});\n```\n\nBehavior DOM queries and delegation stay scoped to the host View. A matching\nelement outside the host does not participate. Literal configuration errors fail\neagerly: an undeclared `@ui` reference throws [MN0018](/docs/diagnostics.md#look-up-a-code), and a\nstring handler that does not resolve to a callable method throws\n[MN0019](/docs/diagnostics.md#look-up-a-code). For example, declaring the event above without\n`ui.save`, or naming `requestSave` without defining that method, is invalid.\n\nA Behavior's DOM [`triggers`](/docs/dom-interactions.md#view-triggers) are emitted on\nthe host automatically. The host method runs first, and all attached Behaviors,\nincluding the Behavior that declared the trigger, receive the broadcast.\n\nFor general event naming and handler conversion, see\n[`triggerMethod`](/docs/events.md#triggermethod).\n\n### Proxy Handlers\n\nBehaviors provide proxies to a number of the view event handling attributes\nincluding:\n\n* [`events`](/docs/dom-interactions.md#view-events)\n* [`triggers`](/docs/dom-interactions.md#view-triggers)\n* [`modelEvents`](/docs/entity-events.md)\n* [`collectionEvents`](/docs/entity-events.md)\n\n```javascript\nimport { Behavior } from 'marionette';\n\nBehavior.extend({\n  events: {\n    'click .foo-button': 'onClickFooButton'\n  },\n  triggers: {\n    'click .bar-button': 'click:barButton'\n  },\n  modelEvents: {\n    'change': 'onChangeModel'\n  },\n  collectionEvents: {\n    'change': 'onChangeCollection'\n  },\n  onClickFooButton(evt) {\n    // ..\n  },\n  onClickBarButton(view, evt) {\n    // ..\n  },\n  onChangeModel(model, opts) {\n    // ..\n  },\n  onChangeCollection(model, opts) {\n    // ..\n  }\n});\n```\n\n### Initialize Order\n\nThe View + Behavior initialize process is as follows:\n\n1. View construction begins and the View's `preinitialize` runs\n2. Behavior is constructed\n3. Behavior is initialized with view property set\n4. Callable Behavior `events` and `triggers` are resolved and delegated\n5. View is initialized\n6. View triggers an `initialize` event on the behavior.\n\nThis means that the behavior can access the view during its own `initialize` method.\nIt can also access state established by the View's `preinitialize` method.\nCallable `events` and `triggers` may use state established by that method before\nthe View initializes.\nThe View's `initialize` is called later with its original constructor arguments.\nIt can observe Behavior-driven state only when a Behavior explicitly sets that\nstate or calls a host method; Marionette does not inject Behavior information.\nThe `initialize` event is triggered on the behavior indicating that the view is fully initialized.\n\n#### Using `ui`\n\nAs in views, `events` and `triggers` can use the `ui` references in their\nlisteners. For more details, see the [`ui` documentation](/docs/dom-interactions.md#organizing-a-view-with-ui).\nThese can be defined on either the Behavior or the View. The fragment below\nassumes a Backbone model with `save()` and a configured\n[Backbone DataApi](/docs/backbone.md):\n\n```javascript\nimport { Behavior } from 'marionette';\n\nconst MyBehavior = Behavior.extend({\n  ui: {\n    saveForm: '.btn-save'\n  },\n\n  events: {\n    'click @ui.saveForm': 'saveForm'\n  },\n\n  modelEvents: {\n    invalid: 'showError'\n  },\n\n  saveForm() {\n    this.view.model.save();\n  },\n\n  showError() {\n    alert('You have errors');\n  }\n});\n```\n\n### UI resolution and binding\n\nFor a host whose `el` is empty at construction, the host constructs each Behavior\nbefore the host's `initialize` and before binding UI elements. During that\nconstruction, the Behavior resolves its own `ui` declaration and the host's `ui`\ndeclaration into one selector map. When both declarations contain the same key, the\nhost's selector wins. This allows a Behavior to provide reusable defaults without\ndictating the host's markup. Marionette establishes this merged map before the\nBehavior's first DOM event and trigger delegation, so host-only keys and host\noverrides are available immediately.\n\nThe merged selector map is available to the Behavior's `initialize`, before either\nthe Behavior or host has bound UI elements. The map is captured for that Behavior\ninstance during construction; later changes to values returned by a `ui` function do\nnot replace its captured selectors. The host evaluates its own `ui` again when it\nbinds. If a stateful host `ui` function returns a different selector then, the host\nbinds the later selector while the Behavior continues to bind its construction-time\nselector. Keep `ui` functions deterministic when the host and Behavior share keys.\n\nThe Behavior's `el` is also available during `initialize`. Behaviors\ncan initialize their own `$el` wrapper with `$(this.el)` at this point. DOM event and trigger declarations are delegated only after `initialize`\nreturns, so callable declarations may safely depend on state established there.\n\nBefore binding, `behavior.ui` contains selector strings. A template-rendered `View`\nbinds those selectors during render, after which the values are array-like element\ncollections found only within the host's `el`. Its rerender replaces the contents and\nrebinds the same Behavior to the replacement elements. Code must read the current\n`behavior.ui` or call `behavior.getUI(name)` after binding instead of retaining an\nelement collection from an earlier render. Calling `getUI()` without a declared\n`ui` map, before binding, or after unbinding throws [`MN0023`](/errors/MN0023.md).\n\nA `CollectionView` also binds Behavior UI automatically when its render processes a\ntemplate. Without a template, `CollectionView#render` leaves Behavior UI as selector\nstrings; call `collectionView.bindUIElements()` after the expected elements exist to\nbind them explicitly.\n\nOnce the owning View or CollectionView starts destruction, its base\n`bindUIElements()` method and direct `bindUIElements()` calls on a Behavior owned by\nor retained from that host are chainable no-ops. They do not resolve host UI or query\nthe retained root element. `unbindUIElements()` remains available for cleanup, and\n`getUI()` continues to throw [`MN0023`](/errors/MN0023.md) while UI is unbound. Reusing\na Behavior after calling `Behavior#destroy()` while its host remains live is outside\nthis terminal-host contract.\n\nA `View` initialized around pre-rendered content binds its own UI before it\nconstructs Behaviors. This contract pins only that construction ordering. It\nintentionally leaves the mixed Behavior UI representation for that path unresolved;\ndo not infer the selector-before-binding sequence above or rely on that representation.\n\n<!-- executable-example: behavior-ui-resolution -->\n```javascript\nimport { Behavior, View } from 'marionette';\n\nconst SaveBehavior = Behavior.extend({\n  ui: {\n    save: '.btn-save'\n  },\n\n  events: {\n    'click @ui.save': 'requestSave'\n  },\n\n  requestSave() {\n    this.getUI('save')[0].classList.add('is-saving');\n    this.view.requestSave();\n  }\n});\n\nexport const FormView = View.extend({\n  behaviors: [SaveBehavior],\n\n  template() {\n    return [\n      '<button class=\"btn-save\" type=\"button\">Default save</button>',\n      '<button class=\"btn-primary\" type=\"button\">Save</button>'\n    ].join('');\n  },\n\n  ui: {\n    save: '.btn-primary'\n  },\n\n  requestSave() {\n    this.triggerMethod('save:requested', this);\n  }\n});\n```\n\n### Host DOM boundary\n\nThe host View or CollectionView owns the DOM boundary for each attached\nBehavior. A Behavior's `el` is the host's current `el`, and its `$()` lookup\ndelegates to the host so that results stay scoped to that element. Native core\ndoes not create `$el`. With the optional\n[jQuery adapter](/docs/dom-api.md#optional-jquery-adapter), application code can\nassign `this.$el = $(this.el)` once in `initialize()`.\n\nThe host and its Behaviors keep the same root for their lifetime. Rendering can\nreplace its contents, and `delegateEvents()` refreshes View and Behavior handlers.\nDestroying the host removes those handlers. Behaviors do not own or replace the root.\n\nEach Behavior can also reference its host through the `view` attribute. Read\nmodel values through the host's selected DataApi so the same code works with plain\nobjects and configured observable providers:\n\n```javascript\nimport { Behavior } from 'marionette';\n\nconst ViewBehavior = Behavior.extend({\n  onRender() {\n    const shouldHighlight = this.view.Data.get(this.view.model, 'selected');\n    this.el.classList.toggle('highlight', shouldHighlight);\n    Array.from(this.$('.view-class')).forEach(element => {\n      element.classList.add('highlighted-icon');\n    });\n  }\n});\n```\n\n## Behavior Lifecycle\n\nA `Behavior` has a host-managed lifetime rather than the independent rendered,\nattached, and destroyed state exposed by a View. In this table, the host view is\neither a `View` or `CollectionView`. It constructs its Behaviors, keeps the same\ninstances through render and attachment transitions, and cleans them up when it\nis destroyed. Nested Behaviors participate as Behaviors of the same host view.\n\n| Operation | Host view | Behavior |\n| --- | --- | --- |\n| Construct the View | Constructs each Behavior before the View's `initialize`. | Receives its `view` and runs its own `initialize`; after the View initializes, receives the View's `initialize` notification. |\n| Render or re-render the View | Runs each View lifecycle callback first. | The same instance receives the corresponding lifecycle callback after the View. |\n| Show, detach, or re-show the host through a Region with lifecycle monitoring enabled | Changes the host's attachment state. | The same instance receives the corresponding attachment lifecycle after the host. |\n| First direct `behavior.destroy()` while the View is alive | Remains alive without the removed Behavior. | Undelegates its events, stops listening, removes itself from the View, and deletes its entity-event handlers. It receives no later host lifecycle notifications. |\n| Destroy the View | Runs `before:destroy`, tears down the View, and runs its `destroy` callback. Repeated View destruction is a no-op. | Receives `before:destroy` while the View is alive, is cleaned up after the View enters destroyed, then receives `destroy` after the View's callback. Nested Behaviors follow the same ordering. |\n\n`Behavior` does not expose an independent `isDestroyed()` state. Repeated direct\n`behavior.destroy()` calls, reuse after direct cleanup, and other post-cleanup\noperations are outside this lifecycle contract. Dependency access, invalid\nreferences, and dynamic replacement semantics are separate Behavior contract\ndecisions; this table does not add an Application or State lifecycle to Behavior.\n\nIf a Region's owning view sets `monitorViewEvents: false`, the shown host does not\nreceive attachment lifecycle notifications, so its Behaviors do not receive them\neither. Separately, setting `monitorViewEvents: false` on the host itself does not\nby itself suppress Region attachment lifecycle. It suppresses the host's\n`dom:refresh` and `dom:remove` notifications, so its Behaviors do not receive those\nnotifications.\n\n## Destroying a Behavior\n\n`myBehavior.destroy()` synchronously returns the Behavior after removing its\nDOM and entity subscriptions, releasing its State subscriptions and owned State,\ncalling `stopListening()`, and removing it from the host. It does not emit an\nindependent destroy lifecycle or await Promises. Errors propagate and can leave\ncleanup incomplete; the host itself remains alive.\n\n\n[Canonical source](/docs/markdown/docs/marionette.behavior.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/view.lifecycle.md",
      "title": "Lifecycle and cleanup",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/lifecycle/",
      "markdownUrl": "https://marionettejs.com/docs/lifecycle.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/view.lifecycle.md",
      "sourceSha256": "2cc29e59e056174bb2fcbd2888ee508ff6fb044b86e9fcacd1025c1f4e036133",
      "sha256": "978b05fb72fbffe2d124f1e257cb7d9b06cb66a28f1d339f61ef074888120080",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 2cc29e59e056174bb2fcbd2888ee508ff6fb044b86e9fcacd1025c1f4e036133. -->\n\n# View Lifecycle\n\nBoth [`View` and `CollectionView`](/docs/classes.md) are aware of their lifecycle state\nwhich indicates whether the View is rendered, attached, or destroyed.\n\n## Documentation Index\n\n* [View Lifecycle](#view-lifecycle)\n* [Lifecycle State Methods](#lifecycle-state-methods)\n  * [`isRendered()`](#isrendered)\n  * [`isAttached()`](#isattached)\n  * [`isDestroyed()`](#isdestroyed)\n* [Instantiating a View](#instantiating-a-view)\n  * [A fixed root element](#a-fixed-root-element)\n* [Rendering a View](#rendering-a-view)\n  * [`View` Rendering](#view-rendering)\n  * [`CollectionView` Rendering](#collectionview-rendering)\n* [Rendering Children](#rendering-children)\n* [Attaching a View](#attaching-a-view)\n* [Detaching a View](#detaching-a-view)\n* [Destroying a View](#destroying-a-view)\n* [Synchronous failures](#synchronous-failures)\n* [Destroying Children](#destroying-children)\n\n## Lifecycle State Methods\n\nBoth `View` and `CollectionView` share methods for checking lifecycle state.\n\n### `isRendered()`\n\nReturns a boolean value reflecting if the view is considered rendered.\n\n### `isAttached()`\n\nReturns a boolean value reflecting if the view is considered attached to the DOM.\n\n### `isDestroyed()`\n\nReturns a boolean value reflecting if the view has been destroyed.\n\n### State vectors\n\nThe three lifecycle methods are independent observations, not one linear state enum.\n`View` construction can therefore produce any of the four alive render/attachment vectors:\n\n| Initial `el` | `isRendered()` | `isAttached()` | `isDestroyed()` |\n| --- | --- | --- | --- |\n| Empty and detached | `false` | `false` | `false` |\n| Empty and in the document | `false` | `true` | `false` |\n| Populated and detached | `true` | `false` | `false` |\n| Populated and in the document | `true` | `true` | `false` |\n\n`CollectionView` starts unrendered regardless of its initial contents and has its own\n[lifecycle transition table](/docs/collection-view.md#view-lifecycle-and-events).\n\nWith lifecycle monitoring enabled, Marionette-managed operations preserve the\nfollowing observable transitions:\n\n| Operation | Result | Repeated call |\n| --- | --- | --- |\n| `View#render()` with a template function while alive | Runs `before:render` and `render`; rendered becomes `true`; attachment is unchanged | Renders again and runs the render lifecycle again |\n| `View#render()` with `template: false` while alive | Returns the View without running the render lifecycle or changing contents or state | Repeated calls are the same no-op |\n| `CollectionView#render()` while alive | Runs `before:render` and `render`, rebuilds its children, and becomes rendered; attachment is unchanged | Rebuilds the children and runs the render lifecycle again |\n| `view.renderAttributes()` while alive | Applies the current root attribute declarations without changing contents, children, lifecycle events, or state | Reevaluates and applies the declarations again |\n| `region.show(view)` | Ensures the view is rendered; attached becomes `true` only when the Region is in the document | Showing the current view is a no-op |\n| `region.detachView()` | Rendered is preserved; attached becomes `false`; destroyed stays `false` | Returns `undefined` with no transition |\n| Re-show a detached view | Rendered stays `true`; attachment reflects the Region | Does not render the view again |\n| `region.empty()` or `view.destroy()` | Rendered and attached become `false`; destroyed becomes `true` | Repeated destroy is a no-op |\n| `view.render()` after destruction | Returns the same View with rendered and attached `false` and destroyed `true` | Repeated calls are no-ops |\n| `view.renderAttributes()` once destruction begins | Returns the same View before resolving declarations or changing the root element or lifecycle state | Repeated calls are no-ops |\n| `CollectionView#addChildView(view, ...)` once destruction begins | Returns the supplied child before inspecting or taking ownership of it; the caller remains responsible for that child | Repeated calls are no-ops for the destroyed CollectionView |\n| `view.delegateEvents()` or `view.undelegateEvents()` once destruction begins | Returns the same View without changing View or Behavior DOM delegation | Repeated calls are no-ops |\n| `view.bindUIElements()` once destruction begins | Returns the same View without resolving host UI, querying DOM, or binding View or Behavior UI | Repeated calls are no-ops |\n\nSetting `monitorViewEvents: false` on a Region's owning view intentionally disables\nattachment events and automatic `isAttached()` updates for the shown view.\n\nThis table specifies the managed and terminal operations listed above. Do not\ninfer behavior for other calls on a destroyed View; custom overrides also own\ntheir behavior unless they delegate to a guarded base method.\n\n## Instantiating a View\n\nEvery Marionette `View` and `CollectionView` has a native DOM element in `el`.\nPass an existing element with `el: document.querySelector('.foo-selector')`, or\ncreate one first with `document.createElement()`. Selector strings and jQuery\ncollections are not valid View `el` values.\n\nWhen `el` is omitted, Marionette creates the root element from `tagName` (a\n`div` by default) and applies the resolved `id`, `className`, and `attributes`.\nThe element remains the View's root for its entire lifetime. Native core does not create `$el`;\napplications can initialize their own wrapper when using the\n[jQuery adapter](/docs/dom-api.md#optional-jquery-adapter).\n\nMarionette determines whether the initial root is already\n[rendered](#rendering-a-view) or [attached](#attaching-a-view). If a View starts\nrendered or attached, its [state](#lifecycle-state-methods) reflects that status, but the\n[related events](/docs/class-events.md#dom-change-events) will not have fired.\nAn element owned by template content is detached while that owner document has no\ndocument element. Showing its View later through an attached Region runs the managed\nattachment lifecycle once for the View and its existing children.\n\nFor more information on instantiating a view with pre-rendered DOM, see\n[Pre-rendered Content](/docs/prerendered-dom.md).\n\n### A fixed root element\n\nChoose the root with the constructor's `el` option, or let Marionette create it.\nA View and its Behaviors keep that element for their lifetime. `el` is readonly\nin the public instance types; assigning another element directly is unsupported.\nThere is no public `setElement()` method.\n\nRendering changes the root's contents. Moving or detaching a View through a\nRegion preserves its root and its child ownership. If another system replaces\nthe root, destroy the old View and construct a new View with the new element.\nKeep state that must survive that replacement outside the View.\n\n## Rendering a View\n\nIn Marionette [rendering a view](/docs/rendering.md) is changing a view's `el`'s contents.\n\nWhat rendering indicates varies slightly between the two Marionette views.\n\n**Note** A completed render leaves the View rendered until destruction. During\na normalized collection update, CollectionView may mark an updated child\nunrendered before rendering it again; a filtered child can remain unrendered\nuntil it becomes visible.\n\n### `View` Rendering\n\nFor [`View`](/docs/view.md), rendering with a template function runs the\n`before:render` lifecycle, serializes the View's data, passes it to the template,\nplaces the result in `el`, binds UI, marks the View rendered, and then runs the\n`render` lifecycle. A newly constructed `View` is already considered rendered if\nits initial `el` contains content. A later template may produce empty content;\nthe completed render still leaves the View rendered.\n\n`template: false` is different from a template that returns an empty value.\nCalling `View#render()` with `template: false` returns the View without running\nthe render lifecycle, changing the DOM, or changing its rendered state.\n\n### `CollectionView` Rendering\n\nFor [`CollectionView`](/docs/collection-view.md), every live `render()` is\nbracketed by `before:render` and `render`. After it completes, collection-backed\nchildren have been rebuilt, the optional template and visible children have\nbeen rendered, and the CollectionView is rendered. Any children the\nCollectionView owned before that render have been destroyed.\n\nInserting a child element into the CollectionView is not itself an attachment\ntransition. When the CollectionView is monitored as attached, rendering marks\nand notifies the inserted children as attached; when the parent is detached or\nchild lifecycle monitoring is disabled, their monitored attachment state remains\ndetached even though their elements are inside the parent element.\n\nA CollectionView with no children is still rendered, with or without an\n[`emptyView`](/docs/collection-view.md#collectionviews-emptyview). Its own\ntemplate controls the container markup but does not determine rendered state.\n\n## Rendering Children\n\nRendering child views is often best accomplished after the View renders, as the first render typically happens before\nthe View enters the DOM. This helps to prevent unnecessary repaints and reflows by making the DOM insertion at the\nhighest practical View in the view tree.\n\nThe exception is Views with [pre-rendered content](/docs/prerendered-dom.md). When a View is instantiated\nrendered, child Views are best managed in the View's [`initialize`](/docs/common.md#initialize).\n\n### `View` Children\n\nIn general the best method for adding a child view to a `View` is to use [`showChildView`](/docs/view.md#showing-a-child-view)\nin the [`render` event](/docs/class-events.md#render-and-beforerender-events).\n\nView Regions are emptied on each render, so Views shown outside of the `render` event still need to be shown again\non subsequent renders.\n\n### `CollectionView` Children\n\nThe primary use case for a `CollectionView` is maintaining collection-backed\nchild Views. Marionette creates and removes those children as the collection\nchanges.\n\n`addChildView()` can also add a child that is independent of the collection,\nbut that child is not unmanaged. The CollectionView owns it, includes it in its\nchild containers, and may sort or filter it. Rendering, collection reset, or\nCollectionView destruction destroys every child that is still owned, including\nmanually added children. `detachChildView()` is the explicit operation that\nremoves a child from ownership without destroying it and transfers cleanup\nresponsibility to the caller.\n\nSee [Self-Managed `children`](/docs/collection-view.md#self-managed-children)\nfor the supported add, remove, detach, sorting, and filtering contracts.\n\n## Attaching a View\n\n`isAttached()` is Marionette's monitored lifecycle state, not a live query of\nthe physical DOM on every call. Construction initializes it\nfrom the current root element, and Marionette-managed Region and CollectionView\noperations update it while attachment monitoring is enabled.\nThe [`attach` event](/docs/class-events.md#attach-and-beforeattach-events) is the\nappropriate place to add listeners to the root `el`. Render can replace the\ncontents while that root remains attached; use\n[`dom:refresh`](/docs/class-events.md#domrefresh-event) for listeners tied to those\nrendered descendants.\n\nMoving `view.el` directly with native DOM APIs, such as\n`document.body.append(view.el)`, changes its physical location without running\nMarionette attachment lifecycles or updating `isAttached()`. The same caveat\napplies when application code directly removes or moves an attached root.\nPrefer a Region or CollectionView for managed transitions; if application code\nmoves the element directly, it owns the resulting lifecycle mismatch.\n\nA child shown in a rendered but detached parent View's Region is rendered and remains\ndetached. When the parent is later shown in an attached Region, attachment propagates\nto its existing children. A child shown during the parent's `onAttach` is attached\nimmediately. Showing the same attached parent again is a no-op for both parent and child\nattachment lifecycles.\n\n## Detaching a View\n\nA managed View becomes detached when Marionette removes its `el` from the DOM\nand updates its monitored attachment state.\nUse the [`before:detach` event](/docs/class-events.md#detach-and-beforedetach-events)\nto clean up listeners added to the root `el`. Render can replace descendants\nwhile the root remains attached; use\n[`dom:remove`](/docs/class-events.md#domremove-event) to clean up listeners tied to\nthose rendered descendants.\n\nDetaching a parent View propagates detachment to its managed Region children while\npreserving their rendered state and ownership. Re-showing that parent attaches the same\nchildren again. Emptying the parent-owning Region then detaches and destroys the parent\nand its still-managed children once.\n\n## Destroying a View\n\nDestroying a View (for example, `myView.destroy()`) removes Marionette-owned\nresources: delegated View and Behavior DOM handlers, bound UI, outgoing\n`listenTo()` subscriptions, entity-event bookkeeping, Behaviors, Regions and\ntheir current Views, and CollectionView children that remain owned. It detaches\nthe root element and leaves the View rendered `false`, attached `false`, and\ndestroyed `true` after successful teardown.\n\nDestroy does not remove callbacks registered directly on the View with `on()`,\ndestroy its model, collection, or arbitrary option collaborators, or clean up\napplication resources Marionette does not own. Release those resources in the\nappropriate lifecycle callback.\n\nThe [`before:destroy` event](/docs/class-events.md#destroy-and-beforedestroy-events) is the best place to clean\nup any added listeners not related to the view's DOM.\n\nOnce destruction begins, reentrant `destroy()` calls from `before:destroy` or\n`destroy`, and later repeated calls, return the same View without restarting\nteardown. During a normal successful teardown, an attached parent and its owned\nchildren complete their detach and destroy lifecycles once.\n\nBase `View#bindUIElements()` and `CollectionView#bindUIElements()` calls are\nalso terminal no-ops once destruction begins. They do not resolve callable UI,\nquery the retained root element, or bind attached Behaviors. A direct\n`Behavior#bindUIElements()` call through a Behavior owned by or retained from\nthat host returns the Behavior without binding. `unbindUIElements()` remains\navailable for cleanup, and `getUI()` continues to throw `MN0023` when UI is\nunbound.\n\nErrors from lifecycle handlers propagate and stop the operation, as described\nunder [Synchronous failures](#synchronous-failures). A throwing `before:destroy`\nor later cleanup handler does not clear the destruction guard or make a later\n`destroy()` call resume teardown.\n\nSuccessful destruction retains the root `el` object but detaches it. Do not\ninfer that all of its contents are retained: owned child Views are removed as\nthey are destroyed, and Region or CollectionView cleanup can detach contents\nfrom managed containers. Marionette makes no general cleanup promise for\nunowned DOM outside those managed boundaries.\n\n## Synchronous failures\n\nMarionette expects valid adapters and working registration and cleanup callbacks.\nAn exception during synchronous registration, construction, rendering, or teardown\npropagates to the caller and aborts that operation. Completed work is not rolled\nback. Marionette does not promise to release every resource after a callback throws,\nrestore a partially initialized or rendered instance, or recover on the next call or\nsource notification. Fix the failing callback or adapter; do not rely on partial\ninstance state after a failure.\n\nSuccessful cleanup and the documented ownership and repeated-destruction rules still\napply. A callback that destroys or mutates an owner during an in-progress render does\nnot acquire additional recovery guarantees merely because it calls a public method;\nuse the documented lifecycle boundaries for that workflow.\n\nApplication's [asynchronous lifecycle](/docs/application.md#application-lifecycle)\nhas its own readiness, cancellation, rejection, and restart semantics. This synchronous\nfailure boundary does not replace those contracts or change ordinary supersession\ninto an error.\n\n## Destroying Children\n\nChildren still owned by a View's Region or a CollectionView are automatically\ndestroyed when their owner completes a re-render or is destroyed. A CollectionView also\ndestroys its currently owned children when its collection is reset before\nbuilding the replacement collection-backed children. A child returned by\n`detachView()` or `detachChildView()` is no longer owned and is not included in\nlater owner cleanup.\n\nDuring owner destruction, children are removed after the parent root is detached\nto avoid repeated reflows or repaints.\n\n\n[Canonical source](/docs/markdown/docs/view.lifecycle.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/view.rendering.md",
      "title": "Templates and rendering",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/rendering/",
      "markdownUrl": "https://marionettejs.com/docs/rendering.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/view.rendering.md",
      "sourceSha256": "6b397b0925b00c06ff644cd549b2273ba6235e1d6148ad6fa0514394f9c92df5",
      "sha256": "8214bfbec96f34c818764430b042fe18b18094ed6ba0d4e7c488de020b6a3877",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 6b397b0925b00c06ff644cd549b2273ba6235e1d6148ad6fa0514394f9c92df5. -->\n\n# View Template Rendering\n\nGive a view a template function, then call `render()` to put its result in the\nview's element. A plain function is enough to get started; template engines\nand custom renderers can fit the same workflow.\n\nThe renderer evaluates the template; DomApi applies the result to the element.\nProjects can configure template evaluation with `setRenderer()` directly. Lit\nand Morphdom are DOM adapters configured with `setDomApi()`.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  tagName: 'h1',\n  template: () => 'Contents'\n});\n\nconst myView = new MyView();\nmyView.render();\n```\n\nThis renders `<h1>Contents</h1>`, available at `myView.el`.\n\n## Documentation Index\n\n* [What is a template](#what-is-a-template)\n* [Setting a View Template](#setting-a-view-template)\n  * [Using a View Without a Template](#using-a-view-without-a-template)\n* [Rendering the Template](#rendering-the-template)\n  * [Using a Custom Renderer](#using-a-custom-renderer)\n  * [Rendering to HTML](#rendering-to-html)\n  * [Rendering to DOM](#rendering-to-dom)\n* [Serializing Data](#serializing-data)\n  * [Serializing a Model](#serializing-a-model)\n  * [Serializing a Collection](#serializing-a-collection)\n  * [Serializing with a `CollectionView`](#serializing-with-a-collectionview)\n* [Adding Context Data](#adding-context-data)\n  * [What is Context Data?](#what-is-context-data)\n\n## What is a template?\n\nA template is a function that given data returns either an HTML string or DOM.\n[The default renderer](#rendering-the-template) in Marionette expects the template to\nreturn an HTML string. If your application uses Underscore, its\n[template compiler](http://underscorejs.org/#template) can create that function.\nInstall Underscore as an application dependency to use the following example;\nMarionette does not include it.\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template('<h1>Hello, world</h1>')\n});\n```\nThis doesn't have to be an underscore template, you can pass your own rendering\nfunction:\n\n```javascript\nimport Handlebars from 'handlebars';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: Handlebars.compile('<h1>Hello, {{ name }}</h1>')\n});\n```\n\n\n## Setting a View Template\n\nMarionette views use the `getTemplate` method to determine which template to use for\nrendering into its `el`. By default `getTemplate` is predefined on the view as simply:\n\n```javascript\ngetTemplate() {\n  return this.template\n}\n```\n\nIn most cases by using the default `getTemplate` you can simply set the `template` on the\nview to define the view's template, but in some circumstances you may want to set the template\nconditionally.\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template('Hello World!'),\n  getTemplate() {\n    if (this.Data.has(this.model, 'user')) {\n      return _.template('Hello User!');\n    }\n\n    return this.template;\n  }\n});\n```\n\n\n### Using a View Without a Template\n\nBy default `CollectionView` has no defined `template` and will only attempt to render the `template`\nif one is defined. For `View` there may be some situations where you do not intend to use a `template`.\nPerhaps you only need the view's `el` or you are using [prerendered content](/docs/prerendered-dom.md).\n\nIn this case setting `template` to `false` will prevent the template render. In the case of `View`\nit will also prevent the [`render` events](/docs/class-events.md#render-and-beforerender-events).\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyIconButtonView = View.extend({\n  template: false,\n  tagName: 'button',\n  className: 'icon-button',\n  triggers: {\n    'click': 'click'\n  },\n  onRender() {\n    console.log('You will never see me!');\n  }\n});\n```\n\n## Rendering the Template\n\nEach view class has a renderer which by default passes the [view data](#serializing-data)\nto the template function and returns the html string it generates.\n\nThe current default renderer is essentially the following:\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nfunction renderer(template, data) {\n  return template(data);\n}\n\nView.setRenderer(renderer);\nCollectionView.setRenderer(renderer);\n```\n\nThe default expects a function template; it does not look up script elements\nby selector.\n\n### Using a Custom Renderer\n\nYou can set the renderer for a view class by using the class method `setRenderer`.\nThe renderer accepts two arguments. The first is the template passed to the view,\nand the second argument is the data to be rendered into the template. Marionette\ninvokes the renderer with the View as `this`, so use a regular function when the\nrenderer needs access to the View instance.\n\nRendering is synchronous. A renderer must return content supported by the\nchosen DomApi immediately; returning a Promise does not make `render()` await\nit. Complete asynchronous loading before rendering, or update the View when the\nresult becomes available under its owner's cancellation rules.\n\nMarionette passes the renderer's return value to\n[`attachElContent`](#customizing-attachelcontent), which calls `Dom.setContents`.\nThe renderer evaluates the template; the DOM adapter applies its result. The\nnative, jQuery, and Morphdom adapters treat `null` and `undefined` as empty\ncontents. Lit accepts these values as empty content too. Returning `undefined`\ndoes not bypass content attachment.\n\nHere's an example that allows for the `template` of a view to be an underscore template string.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport _ from 'underscore';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nView.setRenderer(function(template, data) {\n  return _.template(template)(data);\n});\n\nconst myView = new View({\n  template: 'Hello <%- name %>!',\n  model: new Backbone.Model({ name: 'World' })\n});\n\nmyView.render();\n\n// myView.el is <div>Hello World!</div>\n```\n\nThe renderer can also be customized separately on any extended View. This\nstandalone example uses the default plain-object DataApi and requires the\napplication to install Handlebars.\n\n```javascript\nimport Handlebars from 'handlebars';\nimport { View } from 'marionette';\n\nconst MyHBSView = View.extend();\n\n// Similar example as above but for handlebars\nMyHBSView.setRenderer(function(template, data) {\n  return Handlebars.compile(template)(data);\n});\n\nconst myHBSView = new MyHBSView({\n  template: 'Hello {{ name }}!',\n  model: { name: 'World' }\n});\n\nmyHBSView.render();\n\n// myHBSView.el is <div>Hello World!</div>\n```\n\n**Note** These examples while functional may not be ideal. If possible it is recommended to\nprecompile your templates which can be done for a number of templating engines using various plugins\nfor bundling tools such as [Browserify or Webpack](/docs/installation.md).\n\n### Rendering to HTML\n\nThe default Marionette renderer returns the HTML as a string. This string is passed to the view's\n`attachElContent` method which in turn uses the DOM API's [`setContents`](/docs/dom-api.md#setcontentsel-html)\nto set the contents of the view's `el` with DOM from the string.\n\n#### Customizing `attachElContent`\n\nYou can modify the way any particular view attaches a compiled template to the `el` by overriding `attachElContent`.\nThis method always receives the result of the view's renderer, including `undefined`.\n\nFor instance, perhaps for one particular view you need to bypass the [DOM API](/docs/dom-api.md) and set the html directly:\n\n```javascript\nattachElContent(html) {\n  this.Dom.setContents(this.el, html);\n}\n```\n\n### Rendering to DOM\n\nA DOM adapter can update existing content incrementally. The optional\n`@mnjs/adapters` package includes Morphdom and Lit HTML integrations.\nInstall only the DOM adapter peer your application uses and configure a View subclass\nbefore creating its instances. `setDomApi` overlays the supplied methods and\npreserves unrelated operations, including jQuery queries.\n\nFor HTML string templates:\n\n```javascript\nimport { View } from 'marionette';\nimport MorphdomDomApi from '@mnjs/adapters/dom/morphdom';\n\nconst MessageView = View.extend({\n  template: () => '<p id=\"message\">Hello again.</p>'\n});\nMessageView.setDomApi(MorphdomDomApi);\n```\n\nMorphdom updates the View's contents using its normal matching rules, including\nelement IDs. Empty roots take the direct HTML insertion path. For Lit templates,\nselect the Lit DOM adapter:\n\n```javascript\nimport { View } from 'marionette';\nimport { html } from 'lit-html';\nimport LitDomApi from '@mnjs/adapters/dom/lit-html';\n\nconst MessageView = View.extend({\n  template: ({ message }) => html`<p>${message}</p>`,\n  templateContext: { message: 'Hello again.' }\n});\nMessageView.setDomApi(LitDomApi);\n```\n\nBoth adapters apply template output through `Dom.setContents`. The root remains\nowned by the View; refresh its dynamic `className`, `id`, or `attributes` with\n[`renderAttributes()`](/docs/view.md#refreshing-root-attributes).\nA parent render still destroys its Region children. Keep Region placeholders\nempty so the renderer and Region do not manage the same contents.\n\nLit replaces preexisting contents on its first explicit render. Keep\n`monitorViewEvents` enabled and manage attachment through Regions so directives\nreceive connection changes through `Dom.notifyAttach(el)` and `Dom.notifyDetach(el)`.\nThe View keeps the same root throughout its lifetime. Automatic directive\nconnection management requires monitoring on the View and its ancestors. Lifecycle overrides must call their parent methods;\navoid independently replacing Lit's contents or switching DOM adapters after rendering.\nSee the [render adapter guide](/docs/adapters-package.md#dom-contents)\nfor installation, directive cleanup, and root ownership.\n\nRendering configuration is separate from data and state integration. Configure\n[`DataApi`](/docs/data-api.md) and [`StateApi`](/docs/state.md) explicitly when\nyour sources need them.\n\n## Serializing Data\n\nMarionette will automatically serialize the data from its `model` or `collection` through the configured\n[`DataApi`](/docs/data-api.md) for the template to use\nat [rendering](#rendering-the-template). You can override this logic and provide serialization of other\ndata with the `serializeData` method. The method is called with no arguments, but has the context of the\nview and should return a javascript object for the template to consume. If `serializeData` does not return\ndata the template may still receive [added context](#adding-context-data) or an empty object for rendering.\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template(`\n    <div><%- user.name %></div>\n    <ul>\n    <% _.each(groups, function(group) { %>\n      <li><%- group.name %></li>\n    <% }) %>\n    </ul>\n  `),\n  serializeData() {\n    // For this view I need both the\n    // model and collection serialized\n    return {\n      user: this.serializeModel(),\n      groups: this.serializeCollection(),\n    };\n  }\n});\n```\n\n**Note** You should not use this method to add arbitrary extra data to your template.\nInstead use `templateContext` to [add context data to your template](#adding-context-data).\n\n### Serializing a Model\n\nIf the view has a `model`, it passes `DataApi.serialize(model)` to the template.\nThe default adapter returns the original plain object.\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template('<h1>Hello, <%- name %></h1>')\n});\n\nconst myView = new MyView({ model: { name: 'world' } });\n```\n\n\nHow the `model` is serialized can also be customized per view.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport _ from 'underscore';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst MyView = View.extend({\n  serializeModel() {\n    const data = _.clone(this.Data.serialize(this.model));\n\n    // serialize a nested Backbone model through the configured adapter\n    data.subModel = this.Data.serialize(data.subModel);\n\n    return data;\n  }\n});\n```\n\n### Serializing a Collection\n\nIf the view does not have a `model` but has a `collection`, DataApi supplies its\nordered models and serializes each one into an array provided as a `models`\nattribute to the template. These are the results of calling `DataApi.serialize()`\nfor each model, not the raw model instances returned by `DataApi.models()`.\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template(`\n    <ul>\n    <% _.each(models, function(data) { %>\n      <li><%- data.name %></li>\n    <% }) %>\n    </ul>\n  `)\n});\n\nconst collection = [\n  {name: 'Steve'}, {name: 'Helen'}\n];\n\nconst myView = new MyView({ collection });\n```\n\n\nHow the `collection` is serialized can also be customized per view.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport _ from 'underscore';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst MyView = View.extend({\n  serializeCollection() {\n    return _.map(this.Data.models(this.collection), model => {\n      const data = _.clone(this.Data.serialize(model));\n\n      // serialize a nested Backbone model through the configured adapter\n      data.subModel = this.Data.serialize(data.subModel);\n\n      return data;\n    });\n  }\n});\n```\n\n### Serializing with a `CollectionView`\n\nIf you are using a `template` with a `CollectionView` that is not also given a `model`, your `CollectionView`\nwill [serialize the collection](#serializing-a-collection) for the template. This could be costly and unnecessary.\nIf your `CollectionView` has a `template` it is advised to either use an empty `model` or override the\n[`serializeData`](#serializing-data) method.\n\n## Adding Context Data\n\nMarionette views provide a `templateContext` attribute that is used to add\nextra information to your templates. This can be either an object, or a function\nreturning an object. The keys on the returned object will be mixed into the\nmodel or collection keys and made available to the template.\n\nWhen serialized data and template context are combined, each contributes its\nown enumerable properties, including symbols, through object spread. Inherited\nand non-enumerable properties are ignored. If only one object exists, Marionette passes that\noriginal object through unchanged.\n\n```javascript\nimport _ from 'underscore';\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: _.template('<h1>Hello, <%- name %></h1>'),\n  templateContext: {\n    name: 'World'\n  }\n});\n```\n\nAdditionally context data overwrites the serialized data\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport _ from 'underscore';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst MyView = View.extend({\n  template: _.template('<h1>Hello, <%- name %></h1>'),\n  templateContext() {\n    return {\n      name: this.Data.get(this.model, 'name').toUpperCase()\n    };\n  }\n});\n```\n\nYou can also define a template context value as a method. How this method is called is determined\nby your templating solution. For instance with handlebars a method is called with the context of\nthe data passed to the template.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Handlebars from 'handlebars';\nimport Backbone from 'backbone';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst MyView = View.extend({\n  template: Handlebars.compile(`\n    <h1{{#if isDr}} class=\"dr\"{{/if}}>Hello {{ fullName }}</h1>,\n  `),\n  templateContext: {\n    isDr() {\n      return (this.degree) === 'phd';\n    },\n    fullName() {\n      // Because of Handlebars `this` here is the data object\n      // passed to the template which is the result of the\n      // templateContext mixed with the serialized data of the view\n      return this.isDr() ? `Dr. ${this.name}` : this.name;\n    }\n  }\n});\n\nconst myView = new MyView({\n  model: new Backbone.Model({ degree: 'masters', name: 'Joe' })\n});\n```\n\n**Note** the data object passed to the template is not deeply cloned and in some cases is not cloned at all.\nTake caution when modifying the data passed to the template, that you are not also modifying your model's\ndata indirectly.\n\n### What is Context Data?\n\nWhile [serializing data](#serializing-data) deals more with getting the data belonging to the view\ninto the template, template context mixes in other needed data, or in some cases, might do extra\ncomputations that go beyond simply \"serializing\" the view's `model` or `collection`.\nThis fragment assumes an application-specific Backbone model with\n`getOrganization()` and `getFullName()` methods, and a Backbone collection of\ngroups; these helpers are not Marionette APIs.\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport _ from 'underscore';\nimport { CollectionView, setDataApi } from 'marionette';\nimport GroupView from './group-view';\n\nsetDataApi(BackboneApi);\n\nconst MyCollectionView = CollectionView.extend({\n  tagName: 'div',\n  childViewContainer: 'ul',\n  childView: GroupView,\n  template: _.template(`\n    <h1>Hello <%- name %> of <%- orgName %></h1>\n    <div>You have <%- stats.public ?? 0 %> group(s).</div>\n    <div>You have <%- stats.private ?? 0 %> group(s).</div>\n    <h3>Groups:</h3>\n    <ul></ul>\n  `),\n  templateContext() {\n    const user = this.model;\n    const organization = user.getOrganization();\n    const groups = this.collection;\n\n    return {\n      orgName: organization.get('name'),\n      name: user.getFullName(),\n      stats: groups.countBy('type')\n    };\n  }\n})\n```\n\n\n[Canonical source](/docs/markdown/docs/view.rendering.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/dom.interactions.md",
      "title": "DOM interactions",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/dom-interactions/",
      "markdownUrl": "https://marionettejs.com/docs/dom-interactions.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/dom.interactions.md",
      "sourceSha256": "81bd678c7d498e08c08c84cfc3bbe1d27451ef46ed521e67fff4f72450bdbadb",
      "sha256": "88731d52fd2f5ab76a53e14ee260c90a6a7a46b52d1d37d3297fddde44062095",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 81bd678c7d498e08c08c84cfc3bbe1d27451ef46ed521e67fff4f72450bdbadb. -->\n\n# DOM Interactions\n\nMarionette `View` and `CollectionView` instances manage DOM interactions through\na root DOM element, `el`. Core uses the browser DOM API by default: `view.$()`\nand bound `getUI()` values are native `NodeList` instances, and delegated\nhandlers receive native DOM events.\n\n`View`, `CollectionView`, and `Behavior` use the public EventDelegator runtime\nadapter described below. Core provides a native DOM adapter by default.\n\n## DOM Ownership Boundaries\n\nUse these boundaries when deciding where DOM work belongs:\n\n* The external shell chooses where a root View is mounted. Pass a concrete DOM\n  element as `el`, or append the View's generated `el` to the shell's mount.\n* A View owns its `el` and the nodes produced by its template.\n* A Behavior borrows its host View's DOM boundary. It does not own a separate\n  root; see [Behavior host communication](/docs/behavior.md#host-communication-and-event-proxies).\n* The external shell or owning View owns the DOM element used as a Region mount.\n  The Region manages the placement and lifecycle of its current child View at\n  that mount. Use the [View Region APIs](/docs/view.md#laying-out-views---regions)\n  to show, access, detach, or empty that child.\n* A child View owns its own `el` and handles interactions inside it.\n\nDOM scoping is structural, not ownership-aware. `view.$()`, `ui`, and delegated\nselectors are rooted at `view.el`, so they exclude matching elements outside\nthat root. They can still match a descendant owned by a child View. Do not use a\nparent query such as `parentView.$('.child-control')` to manipulate child-owned\nDOM. Give each owner distinct selectors and communicate across View boundaries\nthrough public View or Region APIs and\n[explicit child events](/docs/events.md#child-view-events).\n\n## Canonical View Interaction\n\nThe example below defines selectors once in `ui`, handles a save click through\n`events`, and translates a close click into the `form:close` View event through\n`triggers`.\n\n<!-- executable-example: view-dom-interactions -->\n```javascript\nimport { View } from 'marionette';\n\nexport const FormView = View.extend({\n  template() {\n    return `\n      <form>\n        <button class=\"save\" type=\"button\">Save</button>\n        <button class=\"close\" type=\"button\">Close</button>\n      </form>\n    `;\n  },\n\n  ui: {\n    save: '.save',\n    close: '.close'\n  },\n\n  events: {\n    'click @ui.save': 'onSave'\n  },\n\n  triggers: {\n    'click @ui.close': 'form:close'\n  },\n\n  onSave(event) {\n    const [saveButton] = this.getUI('save');\n\n    saveButton.disabled = true;\n    this.triggerMethod('form:save', this, event);\n  },\n\n  onFormClose(view) {\n    view.el.dataset.closed = 'true';\n  }\n});\n```\n\nCreate and render the View before accessing its bound UI elements:\n\n```javascript\nconst formView = new FormView();\n\nformView.render();\ndocument.querySelector('#form-host').append(formView.el);\n```\n\nThe shell owns `#form-host`; `formView` owns the generated `formView.el` inside\nit. Destroy the View when the shell is finished with it so delegated handlers\nand other owned resources are cleaned up.\n\n## View `events`\n\nThe `events` attribute delegates DOM events from the View's `el` to functions or\nmethods on the View. A key has this shape:\n\n```javascript\n'<dom event> [CSS selector]': 'methodName'\n```\n\nThe CSS selector is optional. Without one, the handler is bound to the View's\nroot `el`. Use `@ui.<name>` in place of a literal selector to reference a\ndeclared `ui` key, as the canonical example does with `@ui.save`.\n\nThe handler receives the native DOM event as its first argument and runs with\nthe View as its context. An `events` value must be a function or a string that\nresolves to a callable method. Invalid handlers throw `MarionetteError` with\ncode [`MN0019`](/errors/MN0019.md) before Marionette delegates any handler from\nthat event map.\n\nDelegation sees matching descendants throughout `el`. If a child View contains\nthe same selector, its bubbling DOM event can reach the parent handler. Prefer\nowner-specific selectors; use Marionette events for parent-child communication\ninstead of relying on DOM bubbling across ownership boundaries.\n\nCall `view.delegateEvents(events)` to refresh delegated DOM handlers after\nchanging a callable `events` or `triggers` definition. UI references use the\nView's current selector bindings; a Behavior retains the selector map captured\nat construction, as described in [Behavior UI resolution](/docs/behavior.md#ui-resolution-and-binding). A supplied event\nmap replaces only the View's configured `events` for that delegation pass;\nView triggers and Behavior events and triggers remain active. The method first\nremoves existing handlers, so repeated calls do not duplicate them.\n`view.undelegateEvents()` removes the View and Behavior DOM handlers. Both\nmethods return the View, and both are no-ops after destruction has started.\nConstruction calls `delegateEvents()`. A subclass override remains responsible\nfor delegating to the base method when it wants Marionette's cleanup and redelegation.\n\n## EventDelegator Adapter\n\nAn EventDelegator owns how one normalized `events` or `triggers` declaration is\nregistered and removed. Marionette still owns declaration resolution, handler\ncontext, UI normalization, and the timing of registration and cleanup.\n\nConfigure every View, CollectionView, and Behavior class with the root setter:\n\n```javascript\nimport { setEventDelegator } from 'marionette';\n\nsetEventDelegator(MyEventDelegator);\n```\n\nOr configure one class hierarchy through its static setter:\n\n```javascript\nconst InstrumentedView = View.extend({});\nInstrumentedView.setEventDelegator(MyEventDelegator);\n```\n\nThe supplied object is a complete adapter, not a partial overlay. It must\nprovide this method. This example retains native selector and focus behavior;\nan instrumentation adapter could record around the same registration:\n\n<!-- executable-example: event-delegator-adapter -->\n```javascript\nexport const CustomEventDelegator = {\n  delegate({ eventName, selector, handler, rootEl }) {\n    const capture = eventName === 'focus' || eventName === 'blur';\n    const listener = selector ? event => {\n      const target = event.target.nodeType === 1 ?\n        event.target : event.target.parentElement;\n      const match = target && target.closest(selector);\n\n      if (match && match !== rootEl && rootEl.contains(match)) {\n        event.delegateTarget = match;\n        return handler(event);\n      }\n    } : handler;\n\n    rootEl.addEventListener(eventName, listener, capture);\n    return () => rootEl.removeEventListener(eventName, listener, capture);\n  }\n};\n```\n\nThe arguments are:\n\n* `eventName`: the first token in the declaration key. Begin the key with the\n  event name, without leading whitespace.\n* `selector`: the remaining selector, or an empty string for a direct handler.\n* `handler`: Marionette's normalized callback. The adapter must preserve its\n  arguments and return behavior.\n* `rootEl`: the View or CollectionView's current `el`. A Behavior receives its\n  host View's current `el`.\n\n`delegate` must return an idempotent cleanup function that removes exactly the\nregistration it created, including its original root, listener, namespace, and\ncapture/options policy. Marionette owns and stores that opaque cleanup. The\nadapter must not mutate View internals.\n\nMarionette invokes the returned cleanups during redelegation or destruction,\nin reverse registration order. Registration and cleanup errors propagate to the\ncaller and stop the operation. Core does not roll back failed registration or\nattempt remaining cleanup after a callback throws. See the shared\n[synchronous failure boundary](/docs/lifecycle.md#synchronous-failures).\n\n`setEventDelegator` requires an adapter with a callable `delegate` method.\nEach registration must return a working cleanup. The TypeScript contract\nchecks these shapes; core trusts the configured adapter.\n\nAdapter selection occurs at registration time. Changing a global or per-class\nadapter does not reinterpret existing registrations; their original opaque\ncleanups remain authoritative. The newly configured adapter is used the next\ntime declarations are delegated, including a new instance, an explicit\n`delegateEvents()` call. A per-class setter creates an own\nadapter override for that class hierarchy, so a later root setter does not\nreplace it.\n\nThe native adapter uses `addEventListener`. Selector declarations walk from a\ntext or element target to the closest matching descendant of `rootEl` and set\n`event.delegateTarget` to that match. Native event names are literal:\nnamespaces such as `click.menu` are not interpreted, and non-bubbling events\nsuch as `mouseenter` are not emulated.\n\nDelegated native `focus` and `blur` use capture because those events do not\nbubble. The delegated handler therefore runs before a target-element listener.\nA Marionette trigger stops propagation by default, which prevents the event\nfrom reaching that target listener. Set `stopPropagation: false` on that\ntrigger when the target must also observe the focus or blur event; the\nMarionette trigger still runs first. Marionette does not silently translate\nthese declarations to `focusin` or `focusout`.\n\nA jQuery adapter can implement the same protocol with paired `.on()` and\n`.off()` calls. Compatibility tests exercise that protocol, but v5 does not yet\nship a jQuery EventDelegator. A custom adapter is needed only when the\napplication requires jQuery-specific namespaces, programmatic dispatch, and\ndelegated focus behavior without adding jQuery to the core production graph.\nReact and Vue normally own events within the subtree they\nrender; integrate those subtrees through explicit DOM and lifecycle ownership\nboundaries instead of replacing Marionette's EventDelegator with a React or Vue\nadapter.\n\n## View `triggers`\n\nThe `triggers` attribute translates a DOM event into a Marionette View event.\nIn the canonical example, clicking the close button emits exactly\n`form:close`. Listeners and the matching `onFormClose` method receive the\ntriggering View first, followed by the native DOM event.\n\nBy default, a trigger calls `preventDefault()` and `stopPropagation()` on the\nDOM event. Configure either behavior for one trigger with an object:\n\n```javascript\ntriggers: {\n  'click @ui.close': {\n    event: 'form:close',\n    preventDefault: true,\n    stopPropagation: false\n  }\n}\n```\n\nThese settings are local to the configured trigger. Selectors remain scoped only\nby the View's root `el`.\n\nFor a child owned through a Region, automatic parent handling and forwarding is\nopt-in. `childViewEvents` calls a configured parent handler,\n`childViewTriggers` re-emits a configured parent event, and a non-false\n`childViewEventPrefix` forwards prefixed events. A parent may instead subscribe\ndirectly with public [`listenTo(childView, ...)`](/docs/events.md#listening-to-events),\nbut that is an explicit subscription rather than automatic bubbling. See\n[Child View Events](/docs/events.md#child-view-events) for the configured contracts.\n\n## Organizing a View with `ui`\n\nThe `ui` attribute gives frequently used CSS selectors stable names:\n\n```javascript\nui: {\n  save: '.save',\n  close: '.close'\n}\n```\n\nWhen Marionette iterates a UI definition for binding, or a map passed to a UI\nnormalization helper, it uses own enumerable string keys in standard JavaScript\nown-key order. Inherited, symbol, and non-enumerable properties are ignored by\nthose iterations, and a numeric `length` is an ordinary key rather than an\narray-like signal. Arrays, sparse arrays, and other array-like values are not\nsupported as UI maps. A literal own `__proto__` key remains an own entry in\nnormalized and bound UI maps without changing either map's prototype. Direct\n`@ui.<name>` lookup follows the own-declaration contract described below and\ndoes not require the declared selector property to be enumerable.\n\nWhen the View renders, Marionette queries each selector within `view.el` and\nreplaces the configured string with the resulting collection. With the default\nDOM API, `view.getUI('save')` and `view.ui.save` are native `NodeList`\ninstances. Marionette rebinds those collections to replacement nodes after\neach render.\n\nUse `getUI(name)` after declaring a `ui` map and binding its elements when\napplication code needs a named element. Calling it without a declared map,\nbefore binding, or after unbinding throws\n`MarionetteError` with code [`MN0023`](/errors/MN0023.md). Once bound, a missing\nkey preserves the existing `undefined` result. Use the `@ui.<name>`\nform in `events`, `triggers`, Behaviors, and Regions so a selector change has one\nsource of truth.\n\nEvery `@ui.<name>` reference must contain a non-empty name for an own, declared\nkey in the applicable `ui` map. Missing or inherited keys throw\n`MarionetteError` with code [`MN0018`](/errors/MN0018.md) during normalization.\nSelector values must be strings. An own key with `undefined` is not diagnosed\nas missing by core; do not rely on a particular result for that unsupported value.\nAn explicitly declared empty selector is a known key, though the DOM API may\nreject it when the selector is used.\n\n## Optional jQuery DOM Adapter\n\nApplications that explicitly configure\n[`@mnjs/adapters/dom/jquery`](/docs/installation.md#jquery-dom-adapter-is-optional)\nbefore constructing Views receive jQuery collections from query methods. The\n[application-owned `$el` setup](/docs/dom-api.md#optional-jquery-adapter) can add a\nwrapper on View, CollectionView, and Behavior subclasses; no base-class helper\nis exported. Core examples use native\ncollections so the default package remains jQuery-free.\n\n\n[Canonical source](/docs/markdown/docs/dom.interactions.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/routing.md",
      "title": "Routing",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/routing/",
      "markdownUrl": "https://marionettejs.com/docs/routing.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/routing.md",
      "sourceSha256": "060d74831a1b5fca0cfc161cec5ebcc4abb8775a205189ef80c4405bcb466e3f",
      "sha256": "c174373b58f8d7a8125dd471219d93e4ee4454969cfb385fff40f61bbad4953b",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 060d74831a1b5fca0cfc161cec5ebcc4abb8775a205189ef80c4405bcb466e3f. -->\n\n# Connect routing to a feature\n\nKeep the project's existing router. A route handler can call an application\nfunction that loads data and shows a View. Marionette does not export a router\nor require a routing adapter.\n\n## Choose the boundary\n\n| Responsibility | Owner |\n| --- | --- |\n| Match URLs, parse parameters, update browser history | Your router |\n| Validate route input, load data, handle errors, cancel superseded navigation | Application code |\n| Display and replace the feature's View tree | A Marionette Region |\n| Start, stop, and destroy the feature | A Marionette Application |\n\nUse a Region directly when navigation only replaces Views. Add an Application\nwhen the feature also needs a start/stop boundary or owns other Applications.\nA route change does not inherently require a new Application instance.\n\nIf the project has no router, first determine whether it needs URLs at all.\nLocal selection can be ordinary application state. For URL navigation, choose a\nrouter against the required URL, history, and deployment behavior. That decision\nis independent of the [data, state, and DOM integrations](/docs/choosing-integrations.md).\n\n## Load the latest page and discard stale work\n\nThis example keeps one Application alive while routes replace its root View.\nIt retains the previous page during loading and on a current request failure.\nA later navigation aborts the previous request. Stopping or destroying the\nApplication also aborts pending work and removes its displayed View.\n\nSave this module as `page-navigation.js`. `loadPage(id, { signal })` is an\napplication dependency: it returns a Promise for an object with `title` and\n`body` strings. The element must already exist. No data adapter is needed for\nthese plain objects.\n\n<!-- executable-example: routing-latest-navigation -->\n```javascript\nimport { Application, View } from 'marionette';\n\nconst PageView = View.extend({\n  template: () => '<h1></h1><p></p>',\n  onRender() {\n    this.el.querySelector('h1').textContent = this.model.title;\n    this.el.querySelector('p').textContent = this.model.body;\n  }\n});\n\nexport async function createPageNavigation({ el, loadPage }) {\n  let pending;\n\n  function cancelPending() {\n    pending?.abort();\n    pending = undefined;\n  }\n\n  const Pages = Application.extend({\n    onBeforeStop: cancelPending,\n    onBeforeDestroy: cancelPending\n  });\n  const application = new Pages({ region: { el } });\n  await application.start();\n\n  async function navigate(id) {\n    if (!application.isRunning()) return false;\n\n    cancelPending();\n    const request = new AbortController();\n    pending = request;\n\n    try {\n      const page = await loadPage(id, { signal: request.signal });\n      if (request.signal.aborted || !application.isRunning()) return false;\n\n      application.showView(new PageView({ model: page }));\n      return true;\n    } catch (error) {\n      if (request.signal.aborted || !application.isRunning()) return false;\n      throw error;\n    } finally {\n      if (pending === request) pending = undefined;\n    }\n  }\n\n  return { application, navigate };\n}\n```\n\n`navigate()` resolves `true` after displaying the requested page and `false`\nwhen navigation was canceled or the Application was not running. A current\nload or render failure rejects. Catch that rejection at the route boundary and\nshow an error appropriate to the application. Render failures do not promise\nthat the previous View survives; Region replacement is not transactional.\n\nThe check after `await` is required even when the loader accepts an\n`AbortSignal`: a cache or another provider may finish work after cancellation.\nIt also prevents a stale rejection from becoming the current page's error.\nThe identity check in `finally` keeps an older request from clearing the newer\nrequest's cancellation handle.\n\nThis controller owns cancellation for page requests. It does not make every\nView lifecycle asynchronous. Use Application readiness hooks for work that\nmust finish before the *feature* can start; see\n[Application lifecycle](/docs/application.md#application-lifecycle).\nRepeated in-flight `start()` or `restart()` calls share their operation Promise,\nso changing their options is not a substitute for navigation cancellation.\n\n## Connect an existing router\n\nCreate the feature once, then call `navigate(id)` from the router's existing\nmatched-route handler. For an application already using `Backbone.Router`,\nthat can look like this:\n\nServe this application and its API over HTTPS in production; relative requests\nuse the application origin.\n\n```javascript\nimport Backbone from 'backbone';\nimport { createPageNavigation } from './page-navigation.js';\n\nconst status = document.querySelector('#route-status');\nconst { application, navigate } = await createPageNavigation({\n  el: document.querySelector('#page'),\n  async loadPage(id, { signal }) {\n    const response = await fetch(`/api/pages/${encodeURIComponent(id)}`, { signal });\n    if (!response.ok) throw new Error(`Page request failed: ${response.status}`);\n    return response.json();\n  }\n});\n\nconst Router = Backbone.Router.extend({\n  routes: { 'pages/:id': 'page' },\n  page(id) {\n    status.textContent = '';\n    void navigate(id).catch(() => {\n      status.textContent = 'Could not load this page. Try again.';\n    });\n  }\n});\n\nconst router = new Router();\nBackbone.history.start();\n\n// When the owning application leaves this feature:\n// await application.stop();\n// When that owner permanently releases it:\n// await application.destroy();\n```\n\nThe page supplies `<main id=\"page\"></main>` and\n`<p id=\"route-status\" role=\"status\"></p>`. The server supplies the page endpoint.\nRegister this route within the project's existing router when one is already\npresent; start browser history once at the application entry point. Route\nregistration and history teardown remain the router owner's responsibility.\nStop the feature on routes that leave it, and restart it with `start()` before\nsending it more navigation requests.\n\nUsing Backbone for routing alone does not require `BackboneApi`, `setDataApi`,\nor `setStateApi`. Configure those only when Marionette owners consume Backbone\ndata or state. Backbone's URL matching and history behavior remain\n[Backbone contracts](https://backbonejs.org/#Router).\n\n## Verify the integration\n\nCheck the behavior at the route boundary:\n\n- Navigate from a slow request to a fast one. The fast page must remain visible\n  when the slow request later resolves or rejects.\n- Navigate away or destroy the feature during loading. No late View may appear.\n- Fail the current load. Surface the error and allow a later navigation to succeed.\n- Replace a displayed page. Its old View must be destroyed through its Region.\n- Follow a direct URL and use browser back/forward. Those checks exercise the\n  router and hosting configuration, beyond the Marionette example.\n\nThe executable example fixture tests replacement, cancellation, load failure,\nstop/restart, and destruction using deferred loaders, including loaders that\nignore abort. It does not test a particular router or server deployment.\n\n\n[Canonical source](/docs/markdown/docs/routing.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/task-recipes.md",
      "title": "Common application tasks",
      "section": "Build interfaces",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/task-recipes/",
      "markdownUrl": "https://marionettejs.com/docs/task-recipes.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/task-recipes.md",
      "sourceSha256": "4477bf1b5b4fb57793663b32e34a330c424313ae785e108c2a8206df83a7e3a9",
      "sha256": "89bc04b44c3d8247b325c143fe00f9ddb8d55a4738327a70a8ca7a6a3bb920f1",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 4477bf1b5b4fb57793663b32e34a330c424313ae785e108c2a8206df83a7e3a9. -->\n\n# Task recipes\n\nStart with the resource that must survive or be cleaned up. These recipes use\nMarionette ownership to keep application behavior predictable. Preserve an\nexisting compatible integration; each task identifies when another one is needed.\n\n| Task | Start here | Owner and decision |\n| --- | --- | --- |\n| Save a draft without losing focus | [Forms](/docs/forms-and-accessibility.md) | The form View owns input DOM and its pending save; update status without rerendering. |\n| Change pages while requests overlap | [Routing](/docs/routing.md) | The application owns URL handling and cancellation; the Region owns the active page. |\n| Refresh a root class or ARIA state | [Root attributes](/docs/view.md#refreshing-root-attributes) | Call `renderAttributes()` when only declared root attributes changed. |\n| Keep surviving list rows editable | [Collection reconciliation](/docs/collection-view.md#managing-children) | Keep the observable collection and surviving source objects; do not rebuild the entire CollectionView on every change. |\n| Reuse server-provided markup | [Prerendered content](/docs/prerendered-dom.md) | Give an existing element to its View; establish child ownership explicitly. |\n| Observe a shared model | [DataApi](/docs/data-api.md) | Use the existing provider, or native observable data for a new application; plain objects do not emit changes. |\n| React to local owner state | [State](/docs/state.md) | Choose StateApi separately from DataApi; use owner cleanup for subscriptions. |\n| Wrap a widget that owns DOM | [The example below](#wrap-a-dom-owning-widget) | The View owns the widget handle and tears it down before DOM removal. |\n\n## Wrap a DOM-owning widget\n\nUse this seam for a chart, editor, map, or other widget that renders inside a\nMarionette-owned host. The widget factory receives a DOM element and returns a\nsynchronous `destroy()` handle. Its own library decides rendering and data updates.\nDo not let Marionette and the widget both own the same descendants.\n\n<!-- executable-example: widget-owned-lifecycle -->\n```javascript\nimport { View } from 'marionette';\n\nexport const WidgetView = View.extend({\n  template: () => '<div data-widget-host></div>',\n  initialize({ createWidget }) {\n    this.createWidget = createWidget;\n    this.widget = null;\n  },\n  onDomRefresh() {\n    if (!this.widget) {\n      this.widget = this.createWidget(this.el.querySelector('[data-widget-host]'));\n    }\n  },\n  releaseWidget() {\n    const widget = this.widget;\n    this.widget = null;\n    widget?.destroy();\n  },\n  onDomRemove() {\n    this.releaseWidget();\n  },\n  onBeforeDestroy() {\n    this.releaseWidget();\n  }\n});\n```\n\nHere is a complete factory for trying the ownership contract without installing\nanother library. A real widget adapter supplies the same handle.\n\n```javascript\nimport { Region } from 'marionette';\nimport { WidgetView } from './widget-view.js';\n\nconst mount = document.createElement('main');\ndocument.body.append(mount);\nconst region = new Region({ el: mount });\nregion.show(new WidgetView({\n  createWidget(host) {\n    const button = document.createElement('button');\n    button.type = 'button';\n    let count = 0;\n    button.textContent = 'Count: 0';\n    const increment = () => { button.textContent = `Count: ${++count}`; };\n    button.addEventListener('click', increment);\n    host.append(button);\n    return {\n      destroy() {\n        button.removeEventListener('click', increment);\n        button.remove();\n      }\n    };\n  }\n}));\n// When leaving: region.destroy(); mount.remove();\n```\n\nWith default lifecycle monitoring, `dom:refresh` runs after attached rendering\nand attachment of rendered content. `dom:remove` runs before that content is\nrerendered or detached. Thus a rerender destroys the previous widget before a new\nhost appears. Detaching destroys the widget but retains the View; showing that\nView again creates a fresh widget. Destruction releases any remaining handle.\n\nKeep `monitorViewEvents` enabled for this pattern and use Marionette-managed\nattachment. Direct `append()`/`remove()` calls outside the lifecycle do not become\nMarionette attachment events. If the widget must retain expensive state across\nnavigation, persist that state outside its disposable DOM handle or deliberately\nchoose a different attachment policy.\n\nThe factory must clean up partially acquired resources if initialization throws.\nAn asynchronous widget loader also needs a cancellation/generation check before\nit attaches; follow the [navigation cancellation pattern](/docs/routing.md). A View\nlifecycle callback does not automatically await arbitrary third-party promises.\n\nThe [executable fixture](/docs/source/test/fixtures/docs-application-guides/validate.mjs)\nchecks one widget per attachment, teardown before rerender, detach/reshow, and\nfinal destruction. See [lifecycle](/docs/lifecycle.md) for event ordering.\n\n## Preserve an edited row during collection changes\n\nA stable model object and a stable child View are different from matching IDs in a\nnew array. For an observable collection, perform the provider's supported\nincremental operations. Then verify the unaffected child View and its input node\nare the same objects. Avoid calling `collectionView.render()` after every provider\nnotification: that explicitly rebuilds children.\n\nIf data arrives as an immutable replacement, use a provider/reconciliation policy\nthat defines how source identity changes are handled. Do not assume `trackBy` or\nID matching preserves the existing View's `model` object under every adapter.\nThe [integration guide](/docs/choosing-integrations.md) identifies supported contracts;\n[testing](/docs/testing.md) explains the input identity and stale-subscription assertions\nthat catch this failure.\n\n\n[Canonical source](/docs/markdown/docs/task-recipes.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/typescript.md",
      "title": "TypeScript in applications",
      "section": "Application guides",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/typescript/",
      "markdownUrl": "https://marionettejs.com/docs/typescript.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/typescript.md",
      "sourceSha256": "47ec746e0dcc04cce56f6227f0645d4c777585a2ae797f00c4683b32585922f1",
      "sha256": "e473c57281ceee2796572fec6d928ae91120e61bb20479202ca298e24b396e42",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 47ec746e0dcc04cce56f6227f0645d4c777585a2ae797f00c4683b32585922f1. -->\n\n# TypeScript in an application\n\nUse the declarations shipped by the installed `marionette` package. Core does\nnot need `@types/backbone` or an additional Marionette type package. Install type\npackages for an optional integration only when your application imports it; see\n[installation](/docs/installation.md#peer-dependencies).\n\n## Match the compiler to the runtime\n\nFor a browser application whose existing bundler emits JavaScript, a minimal\nstarting configuration is:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2024\",\n    \"lib\": [\"ES2024\", \"DOM\", \"DOM.Iterable\"],\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Bundler\",\n    \"strict\": true,\n    \"noEmit\": true,\n    \"skipLibCheck\": false\n  },\n  \"include\": [\"src\"]\n}\n```\n\nRun the application's installed compiler with `npx tsc --noEmit`, then run its\nnormal bundler. This example assumes a toolchain supporting that target; it does\nnot supply browser polyfills. Preserve the application's existing target when it\nis constrained by its supported browsers.\n\nFor modules executed directly by Node, use `module: \"NodeNext\"` and\n`moduleResolution: \"NodeNext\"`. Mark ESM using `\"type\": \"module\"` in package.json\nor `.mts` files. Use `.cts` for explicit CommonJS. Select resolution according to\nthe program that loads the emitted modules, as described in the\n[TypeScript compiler guide](https://www.typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options).\n\nMarionette's declarations are checked with TypeScript 6 and 7 in the repository.\nThe [installed consumer fixture](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/test/fixtures/core-types/consumer.mts) covers\nstrict ESM, CommonJS, and bundler resolution. A successful source-only compiler run\nis not a substitute for checking the package your application actually installs.\n\n## Give application options a type\n\nAnnotate `initialize` when using `.extend`. The constructor and `this.options`\nthen share that application option contract. Use public methods to expose\napplication values rather than writing ad hoc properties through a cast.\n\n```ts\nimport { Region, View } from 'marionette';\n\nconst MessageView = View.extend({\n  template: () => '<p></p>',\n  initialize(options: { message: string }) {\n    // The annotation defines required application options.\n    void options;\n  },\n  onRender() {\n    const paragraph = this.el.querySelector('p');\n    if (!paragraph) throw new Error('Message template requires a paragraph');\n    paragraph.textContent = this.options.message;\n  },\n  message(): string {\n    return this.options.message;\n  }\n});\n\nconst mount = document.createElement('main');\ndocument.body.append(mount);\nconst region = new Region({ el: mount });\nregion.show(new MessageView({ message: 'Ready' }));\n// On feature removal: region.destroy(); mount.remove();\n```\n\n`new MessageView()` and `new MessageView({ message: 42 })` are compile errors.\nReturn-type annotations are useful on application methods that reference other\ninferred methods. Prefer one inheritance style within a View family. `.extend`\nuses a callable parent by default; blindly calling inherited `.extend()` on a\nnative JavaScript class is not equivalent to ordinary `class extends`.\nThe [implementation notes](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/docs/maintainers/types.md) document advanced constructor\nand mixed-inheritance boundaries for library authors.\n\n## Narrow the DOM at its use site\n\nA selector does not prove that a template contains a particular element type.\nCheck nullable query results. Native DOM event `target` can be a nested element;\nMarionette's `delegateTarget` is the matched delegated element.\n\nThis complete View narrows the matched element at the event boundary:\n\n```ts\nimport { View } from 'marionette';\nimport type { DelegatedEvent } from 'marionette';\n\nexport const SearchView = View.extend({\n  template: () => '<label>Search <input name=\"query\" type=\"search\"></label><p></p>',\n  events: { 'input input': 'showQuery' },\n  showQuery(event: DelegatedEvent) {\n    const input = event.delegateTarget;\n    const output = this.el.querySelector('p');\n    if (!(input instanceof HTMLInputElement) || !output) {\n      throw new Error('Search template is incomplete');\n    }\n    output.textContent = input.value;\n  }\n});\n```\n\nThe example checks the matched control rather than asserting that an arbitrary\nevent target is an input. For elements from another window, use that element's\nowner-document constructors or a suitable structural check. Do not use a broad\n`any` cast to hide a package-version mismatch.\n\n## Keep lifecycle result types distinct\n\n`View#destroy()` and `Region#destroy()` are synchronous. Application lifecycle\noperations return promises; await `app.start()`, `app.stop()`, and `app.destroy()`\nwhen later work depends on their completion. A `true` result means the requested state was reached, including an already-running\n`start()` or repeated `destroy()`. A superseded transition resolves `false`;\nstarting a destroyed application also resolves `false`. Rejection reports a\nfailed transition. See [Application](/docs/application.md) for exact states.\n\nTypes do not establish data validity at a network boundary, protect against stale\nasynchronous results, or demonstrate focus retention. Validate external data in\nthe application and test runtime behavior alongside the compiler.\n\n\n[Canonical source](/docs/markdown/docs/typescript.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/testing.md",
      "title": "Test an application",
      "section": "Application guides",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/testing/",
      "markdownUrl": "https://marionettejs.com/docs/testing.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/testing.md",
      "sourceSha256": "2af41bf009872459b8cd836384aae04ca5c34ff5eabc15e2ea45ba1357fb5fb9",
      "sha256": "c27414d49c5ff018afb7dc7e0e4c748c1d8d311f04a1e4c4cba720a9503893f9",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 2af41bf009872459b8cd836384aae04ca5c34ff5eabc15e2ea45ba1357fb5fb9. -->\n\n# Testing a Marionette application\n\nTest observable application behavior through the same package and integrations\nused in production. Keep fast View tests for local contracts, then use a real\nbrowser for focus, layout, navigation, and third-party DOM behavior. Marionette\ndoes not require a particular test runner or supply a browser environment.\n\n## A small View test\n\nThis complete example uses Node's test runner and a DOM supplied by `jsdom`.\nInstall `jsdom` as a development dependency and run `node --test counter.test.mjs`.\nKeep DOM-dependent modules inside the configured environment. The View uses no\nBackbone or jQuery adapter.\n\n```javascript\n// counter.test.mjs\nimport assert from 'node:assert/strict';\nimport test from 'node:test';\nimport { JSDOM } from 'jsdom';\n\ntest('a delegated button updates the existing screen and stops after destruction', async () => {\n  const dom = new JSDOM('<!doctype html><main></main>');\n  globalThis.window = dom.window;\n  globalThis.document = dom.window.document;\n  let region;\n  try {\n    const { Region, View } = await import('marionette');\n    const Counter = View.extend({\n      template: () => '<button type=\"button\"><span>Increment</span></button><output>0</output>',\n      events: { 'click button': 'increment' },\n      initialize() { this.count = 0; },\n      increment(event) {\n        assert.equal(event.delegateTarget.tagName, 'BUTTON');\n        this.count += 1;\n        this.el.querySelector('output').textContent = String(this.count);\n      }\n    });\n    region = new Region({ el: document.querySelector('main') });\n    const view = new Counter();\n    region.show(view);\n    const button = view.el.querySelector('button');\n    button.querySelector('span').click();\n    assert.equal(view.el.querySelector('output').textContent, '1');\n    assert.equal(view.el.querySelector('button'), button);\n    region.empty();\n    assert.equal(view.isDestroyed(), true);\n    button.click();\n    assert.equal(view.count, 1);\n    assert.equal(document.querySelector('main').children.length, 0);\n  } finally {\n    region?.destroy();\n    dom.window.close();\n    delete globalThis.window;\n    delete globalThis.document;\n  }\n});\n```\n\nRun tests that mutate global DOM objects in isolation, or use your runner's DOM\nenvironment and cleanup hooks. Configure adapters before constructing owners.\nUse `createMarionette()` for independent runtimes with different global defaults;\nit is not necessary for every test. Avoid test order dependence from shared Radio\nchannels or runtime configuration.\n\n## Assert resource ownership\n\n| Change under test | Assertions that establish behavior |\n| --- | --- |\n| Region replacement | The new View is current; the old one is destroyed exactly once; its subscriptions no longer fire. |\n| Deliberate detach | The View is alive and reusable; another owner eventually shows or destroys it. |\n| Collection update | Unaffected child View and input identities survive; draft, focus, and selection remain; removed children are destroyed. |\n| Provider/source replacement | Updates from the new source reach the owner; old source updates no longer do. |\n| Async navigation | Resolve the second request first; a late first success or failure cannot replace it. Test a client that ignores abort. |\n| Application shutdown | Await stop/destroy; pending work is canceled; no late DOM write occurs. |\n| Widget rendering | Acquire once per host; release before replacement and on final removal; no duplicate global listeners. |\n\nDo not prove teardown only by asserting that `destroy()` was called. Trigger the\nold source, click a retained detached node, or resolve the late promise and verify\nthat nothing commits. The [routing fixture](/docs/source/test/fixtures/docs-routing/validate.mjs)\nand [form/widget fixture](/docs/source/test/fixtures/docs-application-guides/validate.mjs)\nshow these assertions against the exact documented examples.\n\n## Use a real browser where it changes the conclusion\n\nA simulated DOM can establish event wiring and object identity. It cannot prove\nlayout, paint, native constraint-validation presentation, or announcements by\nassistive technology. In the browser, test keyboard submission, focus and selection\nthrough provider updates, direct navigation to a deep URL, and cleanup after\nleaving and returning to a feature. Exercise the actual selected DomApi and widget,\nnot a mock that always preserves nodes.\n\nObserve failures through the rendered UI and application API boundary. A green\ncompiler, coverage percentage, or matching screenshot alone does not establish\nthat the intended operation succeeded. Keep test data anonymous and deterministic.\n\n## Keep examples and evidence together\n\nFor repository contributions, an `executable-example` marker connects a canonical\nJavaScript fence to a fixture that extracts and executes it. The marker checker\nchecks the connection, not behavior. `npm run test:fixtures` builds and tests\ninstalled package artifacts; `npm run docs:check` verifies example markers and\ndocument links. Application projects should use their own package lock and CI\ncommands rather than copying Marionette's maintainer workflow wholesale.\n\n\n[Canonical source](/docs/markdown/docs/testing.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/forms-and-accessibility.md",
      "title": "Forms and accessibility",
      "section": "Application guides",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/forms-and-accessibility/",
      "markdownUrl": "https://marionettejs.com/docs/forms-and-accessibility.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/forms-and-accessibility.md",
      "sourceSha256": "4dfff93422b48001cef53f2d187c86bfb720dcb6cd51fdd22396ef441094e6d1",
      "sha256": "6befedf3629ad5bc6e1d0b571fe2fbb4b18cd70b1d43f5d66dd9898a0e9ce60c",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 4dfff93422b48001cef53f2d187c86bfb720dcb6cd51fdd22396ef441094e6d1. -->\n\n# Forms and accessible interactions\n\nUse native form controls and keep an unfinished draft in the existing input DOM.\nA Marionette View owns the form and its pending save; the application supplies the\npersistence operation. A DataApi or StateApi is not required for this local draft.\nChoose a shared observable source only when other owners need to observe it.\n\n## Save without replacing the user's input\n\nThis complete module uses the default DOM and event implementations. The template\ncontains only trusted, fixed markup. User data is assigned through `value` or\n`textContent`. Each instance gets its own label and message IDs.\n\n<!-- executable-example: accessible-form-save -->\n```javascript\nimport { View } from 'marionette';\n\nexport const ProfileForm = View.extend({\n  tagName: 'form',\n  attributes: { 'aria-label': 'Profile' },\n  templateContext() { return { id: this.cid }; },\n  template({ id }) {\n    return `<label for=\"${id}-name\">Display name</label>\n      <input id=\"${id}-name\" name=\"displayName\" required\n        autocomplete=\"nickname\" maxlength=\"80\"\n        aria-describedby=\"${id}-status\">\n      <button type=\"submit\">Save</button>\n      <p id=\"${id}-status\" role=\"status\" aria-live=\"polite\"></p>`;\n  },\n  events: { submit: 'onSubmit' },\n  initialize({ displayName, save }) {\n    this.initialName = displayName;\n    this.save = save;\n    this.pendingSave = null;\n  },\n  onRender() {\n    this.el.elements.namedItem('displayName').value = this.initialName;\n  },\n  onBeforeRender() {\n    this.cancelSave();\n  },\n  onSubmit(event) {\n    event.preventDefault();\n    return this.submit();\n  },\n  async submit() {\n    if (this.isDestroyed() || this.pendingSave) return false;\n    if (!this.el.reportValidity()) return false;\n    const input = this.el.elements.namedItem('displayName');\n    const button = this.el.querySelector('button');\n    const status = this.el.querySelector('[role=\"status\"]');\n    const request = new AbortController();\n    this.pendingSave = request;\n    input.readOnly = true;\n    button.disabled = true;\n    this.el.setAttribute('aria-busy', 'true');\n    status.textContent = 'Saving…';\n    const displayName = input.value;\n    try {\n      await this.save({ displayName }, { signal: request.signal });\n      if (request.signal.aborted || this.isDestroyed()) return false;\n      this.initialName = displayName;\n      status.textContent = 'Saved.';\n      return true;\n    } catch {\n      if (request.signal.aborted || this.isDestroyed()) return false;\n      status.textContent = 'Could not save. Your changes are still here. Try again.';\n      return false;\n    } finally {\n      if (this.pendingSave === request) {\n        this.pendingSave = null;\n        input.readOnly = false;\n        button.disabled = false;\n        this.el.removeAttribute('aria-busy');\n      }\n    }\n  },\n  cancelSave() {\n    this.pendingSave?.abort();\n    this.pendingSave = null;\n    this.el.removeAttribute('aria-busy');\n  },\n  onBeforeDestroy() {\n    this.cancelSave();\n  }\n});\n```\n\nMount it through a Region. This example's persistence is deliberately in memory;\nreplace `save` with the application's API client for durable storage.\n\n```javascript\nimport { Region } from 'marionette';\nimport { ProfileForm } from './profile-form.js';\n\nconst mount = document.createElement('main');\ndocument.body.append(mount);\nconst region = new Region({ el: mount });\nlet savedProfile = { displayName: 'Taylor' };\nregion.show(new ProfileForm({\n  ...savedProfile,\n  async save(profile, { signal }) {\n    signal.throwIfAborted();\n    savedProfile = profile;\n  }\n}));\n// When the feature is removed: region.destroy(); mount.remove();\n```\n\nThe submit event handles the button and keyboard submission. Native `required`\nvalidation prevents an empty save. While saving, the input is read-only and the\nbutton is disabled; duplicate programmatic submissions return `false`. A failure\nkeeps the same input, its value, and its selection. The live status announces the\noutcome without replacing the form or forcing focus elsewhere.\n\nDo not call `render()` for a status change. An explicit rerender is a reset to the\nlast saved value: it cancels a pending request before replacing the controls.\nDestruction also aborts the request. The signal check matters even if a client\nignores cancellation. Aborting does **not** prove a server rolled back a write;\nreconcile ambiguous writes through the application's API contract.\n\nFor server field validation, map known field errors to visible messages, set\n`aria-invalid=\"true\"`, and connect each message with `aria-describedby`. Clear\nthose errors when corrected. Keep an error summary focusable when the user needs\nto move among several invalid fields. Avoid displaying raw server errors.\n[WAI's form guidance](https://www.w3.org/WAI/tutorials/forms/) explains labels and\nstructure; its [notification guidance](https://www.w3.org/WAI/tutorials/forms/notifications/)\nexplains associating errors and communicating results.\n\n## Focus when a screen changes\n\nA Region owns destruction and insertion; it does not decide the application's\nnavigation focus policy. After a user-initiated route change has successfully\nshown the new screen, update `document.title` and focus a meaningful heading with\n`tabindex=\"-1\"`. Keep that operation after the current-navigation check in the\n[routing guide](/docs/routing.md). A stale response must neither replace the page nor\nmove focus. Background refreshes should normally leave focus where the user put it.\n\nPrefer `<button>` for actions and `<a href>` for navigation. A delegated click on a\n`<div>` does not supply native keyboard semantics. In delegated handlers,\n`event.delegateTarget` identifies the matched control; `event.target` may be its\nnested icon. See [DOM interactions](/docs/dom-interactions.md).\n\n## Verify the experience\n\nThe [executable form fixture](/docs/source/test/fixtures/docs-application-guides/validate.mjs)\nchecks unique labels, literal untrusted text, duplicate saves, retained input and\nfocus, errors, cancellation, and late results. It uses a simulated DOM; it does\nnot establish screen-reader announcements or native browser validation UI.\n\nIn the real application, tab through the form, submit with Enter, cause an API\nfailure, navigate away during a save, and confirm there is no unexpected focus\njump. Check labels and notifications with the assistive technology your users\nrely on. Automated accessibility checks supplement that interaction review.\n\n\n[Canonical source](/docs/markdown/docs/forms-and-accessibility.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/security.md",
      "title": "Render untrusted content safely",
      "section": "Application guides",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/security/",
      "markdownUrl": "https://marionettejs.com/docs/security.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/security.md",
      "sourceSha256": "a84617af6d01cb2267c085a47a2022c9a4e14fa6d26d3b4609bd841dea59db9d",
      "sha256": "2659923eb04da1c441d0f833cfa326e97827e0884a1fc7cd675c679b83d357e0",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 a84617af6d01cb2267c085a47a2022c9a4e14fa6d26d3b4609bd841dea59db9d. -->\n\n# Rendering and application security\n\nMarionette owns rendering and lifecycle. It does not authenticate requests,\nauthorize operations, sanitize arbitrary HTML, or make an application's API safe.\nKeep those boundaries explicit when choosing a renderer or adding a recipe.\n\nServe production applications and APIs over HTTPS. The same-origin URL helper\nbelow permits HTTP for local development; it is a destination check, not a TLS\nenforcement mechanism. Relative fetch examples inherit the application origin.\n\n## Treat template output as HTML\n\nThe default renderer evaluates a function template and the default DOM API inserts\nits output as HTML. Interpolating an untrusted value into a template string is\ntherefore an HTML injection boundary. A model, StateApi, or DataApi does not escape\nvalues simply because it supplied them.\n\nFor ordinary user text, use fixed markup and write `textContent` or an input's\n`value`. Here is a complete View definition:\n\n```javascript\nimport { View } from 'marionette';\n\nexport const CommentView = View.extend({\n  template: () => '<h2></h2><p></p>',\n  initialize({ author, body }) {\n    this.comment = { author, body };\n  },\n  onRender() {\n    this.el.querySelector('h2').textContent = this.comment.author;\n    this.el.querySelector('p').textContent = this.comment.body;\n  }\n});\n```\n\nA body such as `<img src=x onerror=alert(1)>` appears literally. Avoid constructing\nattributes, inline scripts, or URLs from that string. OWASP recommends safe DOM\nsinks such as `textContent` for this use case; escaping rules depend on the output\ncontext. [DOM XSS prevention](https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html)\n\nIf a feature truly requires rich HTML, define an allowlist and use a maintained\nsanitizer appropriate to that context before the value reaches an HTML sink.\nTest the actual renderer and DomApi combination; incremental patching is not\nsanitization. Do not assume a renderer's text interpolation protections extend to\nits raw-HTML escape hatch. [XSS prevention guidance](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html)\n\n## Validate link destinations separately\n\nAssigning `anchor.href` avoids attribute-string interpolation but does not decide\nwhether a URL's protocol or origin is acceptable. A same-origin application link\ncan use this complete helper:\n\n```javascript\nexport function applicationURL(value, base = window.location.href) {\n  const url = new URL(value, base);\n  const origin = new URL(base).origin;\n  if (!['https:', 'http:'].includes(url.protocol) || url.origin !== origin) {\n    throw new Error('Expected an HTTP(S) URL on this application origin');\n  }\n  return url.href;\n}\n```\n\nThis policy intentionally rejects external links. A feature supporting them needs\nits own explicit protocol/origin policy. URL acceptance does not establish that the\ncurrent user may access the destination. Router guards improve navigation behavior;\nserver authorization must enforce access for every protected operation.\n\n## Keep API responsibilities in the application\n\n- Validate external data before treating it as an application model. TypeScript\n  annotations do not validate a response body.\n- Keep credentials out of templates, public static assets, logs, and shared agent\n  prompts. Follow the authentication system's handling of cookies/tokens and CSRF.\n- Show a useful user-facing failure message; keep stack traces, credentials, and\n  raw backend responses out of the page.\n- Cancel obsolete requests and reject stale results before committing them.\n  Cancellation prevents a late UI write; it does not revoke server permission or\n  guarantee that an in-flight mutation was undone.\n\nMarionette has no built-in CSRF or authentication middleware. Follow the API's\nsecurity design; consult the [OWASP CSRF guidance](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html)\nfor cookie-authenticated requests.\n\n## Apply a deployment policy to the actual bundle\n\nA Content Security Policy belongs to the application response. Test the policy\nagainst the selected template compiler, renderer, scripts, and third-party assets.\nAvoid adding `unsafe-eval` merely to accommodate runtime template compilation when\nprecompiled templates can meet the requirement. CSP is additional protection,\nnot a replacement for safe rendering. [OWASP CSP guidance](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)\n\nThe [forms](/docs/forms-and-accessibility.md) and [routing](/docs/routing.md) fixtures check\nliteral text rendering and late results for their specific examples. They are not\na security audit of the reader's application or third-party integrations.\n\n\n[Canonical source](/docs/markdown/docs/security.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/production-and-performance.md",
      "title": "Production and performance",
      "section": "Application guides",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/production-and-performance/",
      "markdownUrl": "https://marionettejs.com/docs/production-and-performance.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/production-and-performance.md",
      "sourceSha256": "88e6ba4df31c5a9da1a0532a0c27aba902e9f2fed0920ea4f32282e48eb15e05",
      "sha256": "6dc73c692006201da43cf802409b53bc463c017d9cf51321452291d6aa794867",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 88e6ba4df31c5a9da1a0532a0c27aba902e9f2fed0920ea4f32282e48eb15e05. -->\n\n# Production and performance\n\nBuild and deploy Marionette as part of the application's existing browser\npipeline. Marionette does not require a server renderer, hosted runtime, or paid\nservice. Choose integrations for required behavior, then measure the resulting\napplication before changing them for speed.\n\n## Ship a reproducible application\n\n1. Pin the selected Marionette packages through the application lockfile. During\n   prereleases, align package versions. Record the exact source revision when using\n   locally packed builds; a local build may differ from the published package.\n2. Use named ESM imports with the application's bundler for a new browser app.\n   Import only optional adapter subpaths the application configures. Keep adapter\n   configuration before owner construction. Existing supported CommonJS and UMD\n   consumers can keep their documented format.\n3. Build and test the production artifact, including the actual renderer,\n   DataApi/StateApi, and DomApi. Development-server success does not prove the\n   published asset paths, CSP, or router fallback work.\n4. Serve content-hashed assets with the host's immutable-asset policy. Give the\n   HTML entry a policy that permits discovering new asset names. Retain referenced\n   assets across a deployment so a still-open page can load its chunks.\n5. Exercise startup, deep-link reload, navigation, API failure, and shutdown using\n   the deployed artifact. Keep the previous artifact available for a deliberate\n   rollback.\n\nCaching behavior depends on the application's server headers; MDN documents the\n[distinction between revalidation and immutable assets](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching).\n\n## Deploy the router's URL policy\n\nA history-based router needs the host to serve the application entry for valid\nclient routes on direct navigation. Missing static files and API paths should keep\ntheir own error behavior. A hash-based router has a different URL/hosting tradeoff.\nPreserve the application's existing router where it meets requirements; this\nchoice does not require changing Marionette's data or state integration.\n\nDo not copy a rewrite configuration from a different host without testing a real\ndeep URL. The [routing guide](/docs/routing.md) owns the boundary between URL handling,\nrequest cancellation, and Region replacement.\n\n## Measure the interaction that is slow\n\n| Observed problem | Check first | Candidate change |\n| --- | --- | --- |\n| Typing loses focus or becomes slow | Is a model event rerendering the whole form or collection? | Update the affected control/status; preserve the draft and input node. |\n| List refresh destroys unchanged rows | Is the caller invoking full `render()` or replacing source identities? | Use supported provider operations and verify surviving child/source identity. |\n| Large screens create too much work | How many Views and DOM nodes are actually needed at once? | Page or virtualize at the application boundary; define focus/selection and cleanup semantics. |\n| Root status updates rebuild descendants | Are only root classes/attributes changing? | Use `renderAttributes()` with the existing declarations. |\n| Navigation grows listeners/memory | Does each activation acquire resources that survive shutdown? | Release widget/global subscriptions and cancel application-owned work. |\n| Incremental rendering is attractive | Which DOM identity must survive, and does the selected adapter preserve it? | Test a supported DomApi on the real screen before adopting it. |\n\nUse browser performance recordings around the actual interaction. Record the\nsource revision, data size, browser, device, selected integrations, and whether\nlifecycle monitoring is enabled. Compare equivalent operations with repeated runs;\na small synthetic result does not establish every application's performance.\n[Browser performance measurement](https://developer.chrome.com/docs/devtools/performance/overview)\n\n## Keep optimizations inside the ownership contract\n\n`CollectionView#render()` rebuilds its child tree. An incremental collection event\nis a different operation and should not be benchmarked as if it did the same work.\nCheck input focus, selection, and draft retention alongside elapsed time.\n\nDisabling `monitorViewEvents` changes attachment tracking and events; widgets using\n`dom:refresh`/`dom:remove` depend on that contract. It is not a general-purpose\nspeed switch. Similarly, manually mutating owned descendants or skipping cleanup\nmay make a benchmark faster while invalidating application behavior.\n\nMarionette does not provide automatic list virtualization, request deduplication,\nor server rendering. Add an application policy when those capabilities are\nrequired. Keep each policy testable and avoid attributing its behavior to core.\nSee [task recipes](/docs/task-recipes.md) and [testing](/docs/testing.md) for the corresponding\nownership assertions.\n\n## Keep diagnostics useful\n\nCapture failures at the application's boundary with enough operation and version\ncontext to reproduce them. Preserve Marionette diagnostic codes so the linked\n[diagnostic catalog](/docs/source/config/diagnostics/catalog.json) can explain the contract.\nAvoid logging whole models or request bodies by default; they may contain user\ndata. Decide source-map visibility according to the application's debugging and\ninformation-exposure requirements.\n\n\n[Canonical source](/docs/markdown/docs/production-and-performance.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/choosing-integrations.md",
      "title": "Choose integrations",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/choosing-integrations/",
      "markdownUrl": "https://marionettejs.com/docs/choosing-integrations.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/choosing-integrations.md",
      "sourceSha256": "24ce6295dcc8cf8f587a52a935e2b351ebab4e9721e6ed311625c611eec0bc6c",
      "sha256": "8631640f38413a9035f386b1fb77c162b7c90b5777d8ebc7584b57dca004d684",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 24ce6295dcc8cf8f587a52a935e2b351ebab4e9721e6ed311625c611eec0bc6c. -->\n\n# Choose integrations without changing the whole stack\n\nAn adapter connects a specific capability to Marionette. It does not select the\nrest of your application architecture. Keep integrations that already satisfy\nthe task; add a dependency only when the required behavior needs it.\n\n## Make the decision in this order\n\n1. **Inspect the project.** Read its package versions, initialization code, View\n   subclasses, and existing adapter configuration. Follow its established\n   integrations unless the requested change includes replacing them.\n2. **Name the missing capability.** Examples: observe model changes, retain DOM\n   contents across a render, or subscribe to an actor snapshot. “Use an adapter”\n   is not itself a requirement.\n3. **Use the smallest matching integration.** Keep Marionette's defaults for\n   capabilities that do not need to change. Prefer an existing, verified adapter\n   over introducing a custom implementation of the same contract.\n4. **Check ownership and verification.** Identify who creates the source, who\n   releases subscriptions, and which behavior demonstrates that the integration\n   works. Configure it before constructing the affected owners.\n\nFor a new application with no integration requirements, start with plain\nobjects, arrays, native DOM operations, and template functions. Plain data is\nnot observable: explicitly update the UI when it changes. If the task requires\nobservable models and ordered collections without an existing provider,\nuse [`@mnjs/data`](/docs/data-package.md) as the starting choice.\nBackbone models and collections are also observable: keep them and select\n`BackboneApi` when the application already uses Backbone. “Optional” means\nBackbone is not required by core, not that its data is static.\n`@mnjs/data` includes DataApi and StateApi implementations; it does not add persistence\nor REST synchronization. Choose another provider when a requirement calls for\nits additional behavior, such as state-machine actors or an existing persistence\nlayer.\n\n## Select each capability independently\n\n| Capability | Default | Change it when | Contract |\n| --- | --- | --- | --- |\n| Read models, serialize data, track collection identity/order, observe entity changes | Plain objects and array snapshots | Views consume another provider's models or collections | [DataApi](/docs/data-api.md) |\n| Subscribe to an owner's state and dispose owned state sources | Plain objects with no subscriptions | `stateEvents` must observe a provider, or owned sources need disposal | [StateApi](/docs/state.md#stateapi) |\n| Create, query, attach, and update DOM elements | Native browser APIs | Required DOM operations or content updates differ | [DomApi](/docs/dom-api.md) |\n| Evaluate a template with serialized data | Call a template function | A template engine needs another evaluation function | [Renderer](/docs/rendering.md#using-a-custom-renderer) |\n| Bind View/Behavior `events` and `triggers` declarations | Native delegated DOM events | The binding mechanism itself needs replacement | [EventDelegator](/docs/dom-interactions.md#eventdelegator-adapter) |\n| Match URLs and control browser history | None | The application requires routing | [Router integration](/docs/routing.md) |\n\nA state source and a View's model can use different providers. A single provider\nmay implement both DataApi and StateApi, but configuring one does not configure\nthe other. Changing DomApi does not change EventDelegator. A template renderer\nproduces a value; DomApi applies that value to the element.\n\n## Match an existing provider\n\nThese entrypoints are supplied by this repository. Check their package and peer\nversions against the source revision or release you are using; an older alpha\npackage may not contain an entrypoint described by current source docs.\n\n| Existing requirement | Integration | Scope and consequence |\n| --- | --- | --- |\n| Backbone models or collections | `@mnjs/adapters/backbone` as DataApi | Observes Backbone model and collection events while preserving their native vocabulary |\n| Backbone state | The same `BackboneApi` object as StateApi | A separate configuration decision from model/collection data |\n| XState actor data or state | `@mnjs/adapters/xstate` | Select the actor snapshot event explicitly; collection selectors return stable child actor references |\n| jQuery DOM queries or attachment operations | `@mnjs/adapters/dom/jquery` | Does not install jQuery event delegation or create `$el` |\n| Morphdom updates to a View's HTML contents | `@mnjs/adapters/dom/morphdom` | Keeps the View root; does not preserve child Views owned by Regions across parent render |\n| Lit template results | `@mnjs/adapters/dom/lit-html` | Applies Lit results through DomApi; requires attachment monitoring for directive connection cleanup |\n\nRead the [adapter package guide](/docs/adapters-package.md) for exact\nimports, provider constraints, ownership, and setup examples. There is no root\n`@mnjs/adapters` export. Import the subpath you use; importing it does not\nconfigure Marionette or select any other adapter.\n\nFor example, a View may use Backbone data with native DOM operations and a\nplain template function. Adding Morphdom to its content updates would not\nrequire changing its models, state, or router.\n\n## Configure the narrowest appropriate scope\n\nConfigure a View subclass when the integration belongs to that component:\n\n```javascript\nimport { View } from 'marionette';\nimport BackboneApi from '@mnjs/adapters/backbone';\n\nconst AccountView = View.extend({\n  template: () => '<span class=\"name\"></span>',\n  modelEvents: { change: 'render' },\n  onRender() {\n    this.el.querySelector('.name').textContent = this.model.get('name');\n  }\n});\nAccountView.setDataApi(BackboneApi);\n```\n\nThis configures DataApi for `AccountView` and its subclasses. It does not choose\nStateApi or change sibling View classes. Use top-level setters when the whole\napplication intentionally shares that configuration. Use an\n[isolated runtime](/docs/runtime-isolation.md) when independently configured\napplication surfaces must coexist.\n\nSetters overlay supplied adapter methods. When composing DOM operations,\nconfigure a general adapter such as jQuery before an adapter that replaces\ncontent updates, such as Morphdom. Do not switch content adapters after a View\nhas rendered. Changing a live object's source contract is an application\nmigration, not a configuration shortcut.\n\n## Add a custom adapter only for an unmet contract\n\nBefore implementing one, write down:\n\n- The required methods and source event payloads, using the relevant contract.\n- Stable model identity and ordered collection snapshots, if it is a DataApi.\n- Borrowed versus owned sources, idempotent subscription cleanup, and which owner disposes each registration.\n- Failure behavior when subscription setup, rendering, or source updates throw.\n- A test with two consumers of one source, followed by destruction of one\n  consumer. The surviving consumer must keep working.\n\nFor editable collection children, also verify draft/focus retention when a\nmodel stays the same, and the documented destruction/recreation behavior when\nan immutable replacement supplies a different model with the same key.\nAn adapter's type declaration alone does not establish these runtime behaviors.\n\n## Explain choices to an agent or reviewer\n\nRecord the chosen integration once where the application configures it. A useful\ndecision states the capability, existing constraint, configuration scope, and\nverification, for example:\n\n> This feature already uses Backbone models. Configure BackboneApi on its View\n> subclasses, retain native DOM events, and verify that model changes render\n> once and that destroying one View leaves another observer subscribed.\n\nWhen several providers meet the same requirements, preserve the existing one.\nFor a new project, choose the simplest option that meets the stated capability;\nask for a preference only when the choice changes a meaningful product or\nmaintenance constraint. Do not introduce additional providers just because\nexamples for them appear beside each other in this guide.\n\n\n[Canonical source](/docs/markdown/docs/choosing-integrations.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.state.md",
      "title": "State sources",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/state/",
      "markdownUrl": "https://marionettejs.com/docs/state.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.state.md",
      "sourceSha256": "242b5a0d7e4bd99774c6f67c6152a218950f99a88ba962b2a9c4d6daab0a60ca",
      "sha256": "4fc7669d0f83247424ba50fefdc741db151703aec66c96d92284d1a51ea3471d",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 242b5a0d7e4bd99774c6f67c6152a218950f99a88ba962b2a9c4d6daab0a60ca. -->\n\n# State sources and StateApi\n\nKeep state with the part of the application that uses it. `Application`,\n`MnObject`, `View`, `CollectionView`, and `Behavior` can each hold one state\nsource. Marionette manages subscriptions and the cleanup described below; the\nsource provides its own values and mutation API. `Region` does not compose state.\n\n`getState()` always returns the exact source. Core never converts a plain object\ninto a model, record, Proxy, or observable object.\n\n```javascript\nimport { Application } from 'marionette';\n\nconst App = Application.extend({\n  createState() {\n    return { filter: '', selectedId: null };\n  }\n});\n\nconst app = new App();\napp.getState().filter = 'active';\n```\n\nWithout a supplied source or custom factory, the first `getState()` call lazily\ncreates an empty plain object. An owner that never supplies, declares, or asks\nfor state has no state-source property, subscription, or cleanup registration.\n\n## Borrowed and owned sources\n\nChoose how the state source is created and who disposes it:\n\n- `state` is an already-created, borrowed source. Several owners may borrow the\n  same source. Destroying one owner releases only its subscriptions and never\n  disposes the source.\n- `createState(options)` is a factory called with the owner as `this` and the\n  constructor options as its argument. Its result is owned. Owner destruction\n  releases subscriptions and then calls the selected StateApi's optional\n  `disposeOwned(source)` hook.\n\nA supplied function is a source, not a factory. Use `createState()` when a\nfunction must be invoked to create a source.\n\nState persists across View and CollectionView render. Application state\npersists across stop and restart. Behavior state lasts until that Behavior is\ndestroyed, and MnObject state lasts until the object is destroyed.\n\n## Plain-object state\n\nPlain objects are the dependency-free default and are intentionally\nnon-observable. Mutate them with ordinary JavaScript and explicitly render or\ncall an application method when the UI must update.\n\n<!-- executable-example: view-local-state -->\n```javascript\nimport { View } from 'marionette';\n\nexport const label = new View({\n  el: document.querySelector('#label'),\n  model: { name: 'Account' },\n  template: model => model.name\n}).render();\n\nconst Disclosure = View.extend({\n  el() { return document.querySelector('#disclosure'); },\n  template: () => '<button class=\"toggle\">Toggle</button>',\n  events: { 'click .toggle': 'toggle' },\n  createState() { return { open: false }; },\n  toggle() {\n    const state = this.getState();\n    state.open = !state.open;\n    this.render();\n  },\n  onRender() { this.el.dataset.open = String(this.getState().open); }\n});\n\nexport const disclosure = new Disclosure().render();\n```\n\n## StateApi\n\nThe public adapter contract is deliberately small:\n\n```javascript\nStateApi.subscribe(source, eventName, callback, context);\n// returns a cleanup function\n\nStateApi.disposeOwned?.(source);\n```\n\n`subscribe` registers handlers for future events. It receives each `stateEvents`\nname unchanged and calls the provided callback with the source's native payload.\nEvery call must return an idempotent cleanup function. Marionette retains it\noutside the owner's public event registry and invokes it during destruction.\nTherefore calling `owner.off()` cannot disable state-source cleanup.\nSubscription setup errors propagate to the caller; event-map registration is\nnot rolled back.\n\n`disposeOwned` is called only for a `createState()` result, after subscriptions\nare released. It is never called for a supplied or declared `state` source.\n\nThe default StateApi does not pretend a plain object is observable. Declaring\n`stateEvents` for a source it cannot observe throws `MN0037`.\n\nConfigure StateApi on the default runtime before constructing its consumers:\n\n```javascript\nimport { setStateApi } from 'marionette';\n\nsetStateApi({\n  subscribe(source, eventName, callback, context) {\n    return source.subscribe(eventName, (...args) => callback.apply(context, args));\n  },\n  disposeOwned(source) {\n    source.dispose();\n  }\n});\n```\n\n`Application.setStateApi()`, `MnObject.setStateApi()`, `View.setStateApi()`,\n`CollectionView.setStateApi()`, and `Behavior.setStateApi()` configure a class\nor subclass independently. Repeated configuration overlays only that receiving\nclass; it does not mutate its parent or sibling classes. StateApi selection is\nindependent of DataApi selection, though one object may implement both.\n\n## stateEvents\n\n`stateEvents` retains Marionette's declarative event-map shape. Handler names\nare resolved on the owner, while event vocabulary and callback arguments belong\nto the selected adapter.\n\n```javascript\nimport { View } from 'marionette';\n\n// Fragment: provide an actor source and its matching StateApi at construction.\nconst ActorView = View.extend({\n  stateEvents: {\n    'actor.transition': 'onTransition'\n  },\n  onTransition(snapshot) {\n    this.el.dataset.phase = snapshot.value;\n  }\n});\n```\n\nChanging from one state provider to another may require changing event names.\nMarionette does not add universal `get`, `set`, `reset`, `dispatch`, or `send`\nmethods to state owners.\n\n## Application lifetime\n\n<!-- executable-example: application-local-state -->\n```javascript\nimport { Application } from 'marionette';\n\nconst Session = Application.extend({\n  createState() { return { phase: 'stopped' }; },\n  onStart() { this.getState().phase = 'ready'; },\n  onStop() { this.getState().phase = 'stopped'; }\n});\n\nexport const session = new Session();\nexport const sessionState = session.getState();\nexport const started = await session.start();\nexport const stopped = await session.stop();\nexport const restarted = await session.restart();\n```\n\nApplication readiness remains the only asynchronous lifecycle boundary. Code\nthat mutates a state source after awaited work must still check the readiness\n`AbortSignal` before committing stale results.\n\n## Behavior lifetime\n\n<!-- executable-example: behavior-state-ownership -->\n```javascript\nimport { Behavior, View } from 'marionette';\n\nconst Disclosure = Behavior.extend({\n  events: { 'click .disclosure': 'toggleDisclosure' },\n  createState() { return { open: false }; },\n  toggleDisclosure() {\n    const state = this.getState();\n    state.open = !state.open;\n    this.view.render();\n  },\n  onRender() {\n    this.view.el.dataset.disclosureOpen = String(this.getState().open);\n  }\n});\n\nconst Settings = View.extend({\n  el() { return document.querySelector('#settings'); },\n  behaviors: [Disclosure],\n  events: { 'click .selection': 'toggleSelection' },\n  template: () => '<button class=\"disclosure\">Disclosure</button><button class=\"selection\">Selection</button>',\n  createState() { return { selected: false }; },\n  toggleSelection() {\n    const state = this.getState();\n    state.selected = !state.selected;\n    this.render();\n  },\n  onRender() {\n    this.el.dataset.selected = String(this.getState().selected);\n  }\n});\n\nexport const settings = new Settings().render();\n```\n\nA Behavior that receives its View's source through `state` borrows it. A\nBehavior-private `createState()` result is owned only by that Behavior.\n\n## Migration from the v5 alpha State\n\nThe experimental concrete `Marionette.State` export was removed from core. For\nnon-observable local values, return a plain object from `createState()` and use\nproperty access. For reactive values, supply the provider's real source and a\nmatching StateApi. Do not alias the removed State to another model type.\n\n```javascript\n// Before\nconst state = owner.getState();\nstate.set('open', true);\n\n```\n\n```javascript\n// Plain-object source\nconst state = owner.getState();\nstate.open = true;\n```\n\n\n[Canonical source](/docs/markdown/docs/marionette.state.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/data.api.md",
      "title": "Data and collections",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/data-api/",
      "markdownUrl": "https://marionettejs.com/docs/data-api.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/data.api.md",
      "sourceSha256": "73f0fa0c0ea339b15c07c17e8eee87d9cbbd8a2393195d777e3d4948f47e287f",
      "sha256": "1c38638bd95125841e3567665898932994feba558e097e09d0e5a567fd034378",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 73f0fa0c0ea339b15c07c17e8eee87d9cbbd8a2393195d777e3d4948f47e287f. -->\n\n# Data API\n\nDisplay plain objects and arrays directly, or connect your data library through\n`DataApi`. The adapter tells Marionette how to read models, obtain collection\norder, and observe changes. Core does not require Backbone-shaped `cid`,\n`attributes`, `get`, `models`, or collection event payloads.\n\nThe default adapter treats models as plain objects and collections as ordered\narrays. Plain arrays are static snapshots: mutating one does not notify\nMarionette. Call `render()` after changing a plain array. Declaring\n`modelEvents` or `collectionEvents` for an unobservable plain value throws\n`MN0037` instead of manufacturing an event system. Both Backbone models and\ncollections (through `BackboneApi`) and `@mnjs/data` models and collections\nare observable alternatives; preserve an existing provider that meets the task.\n\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst ChildView = View.extend({\n  tagName: 'li',\n  template: model => model.name\n});\n\nconst ListView = CollectionView.extend({ childView: ChildView });\nconst models = [{ name: 'one' }, { name: 'two' }];\nconst list = new ListView({ collection: models });\n\nlist.render();\n```\n\n## Adapter contract\n\nAn adapter supplies seven methods:\n\n| Method | Purpose |\n| --- | --- |\n| `key(model)` | Return a stable `Map` key used to associate a model with its child View. |\n| `get(model, attribute)` | Read one named value for string comparators and filters. |\n| `has(model, attribute)` | Distinguish a missing value from a present value of `undefined`. |\n| `serialize(model)` | Return the data passed to a template. |\n| `models(collection)` | Return the collection's current ordered model snapshot. |\n| `subscribe(entity, eventName, callback, context)` | Subscribe to an application entity event and return an idempotent cleanup function. |\n| `observeCollection(collection, callback, context)` | Observe structural collection changes and return an idempotent cleanup function. |\n\n`key()` must remain stable while a model belongs to a CollectionView and must be\nunique among the models currently owned by that CollectionView. The default\nadapter uses object identity. Adapters for immutable sources may use a stable\nsource identity instead.\n\n`models()` must return an ordered model snapshot after the source mutation is complete.\nMarionette does not mutate that array.\n\n`subscribe()` registers handlers for future events and preserves the source event's\narguments. It must return an idempotent cleanup function. Marionette invokes\nthat function during explicit undelegation or owner destruction. Subscription\nsetup errors propagate to the caller; event-map registration is not rolled back.\n\n`observeCollection()` also returns an idempotent cleanup function. Adapters are\nresponsible for fulfilling these contracts; core does not wrap or validate each\nreturned cleanup.\n\n`model` and `collection` are opaque adapter references. Only `null` and\n`undefined` mean no source; values such as `0`, `false`, and `''` can identify a\nsource when the configured adapter supports them. Prefer a stable reference\nwhose `get` and `serialize` methods read current values. Item changes can then\nnotify existing Views through `subscribe` without replacing their identity.\n\n## Collection observations\n\n`observeCollection()` reports one of three normalized records:\n\n```javascript\n{ kind: 'reorder' }\n{ kind: 'reset' }\n{\n  kind: 'update',\n  added: [],\n  removed: [],\n  updated: [\n    { previous: previousModel, current: currentModel }\n  ]\n}\n```\n\n`reorder` means model order changed without membership changing. `reset` means\nMarionette must rebuild every child. `update` supplies exact added and removed\nmodel instances. Each `updated` entry contains the previous and current model for\none stable key. For an in-place update, `previous === current`. For an immutable\nsame-key replacement, they are different objects. This distinction lets core\ndistinguish a safe in-place render from an identity replacement. Marionette\ndestroys and recreates the child View for an immutable same-key replacement so\nconstructor options, `initialize`, Behaviors, entity events, and other\nmodel-dependent state all belong to the current object. Marionette constructs\nevery same-key replacement View before removing any existing child. A\nreplacement-construction or rendering failure propagates to the caller. Core\ndoes not undo a partial update or promise recovery on the next notification. See\n[synchronous failures](/docs/lifecycle.md#synchronous-failures).\n\nAn in-place `updated` entry requests a child render. Adapters for mutable models\nwith their own change events can leave `updated` empty and let child\n`modelEvents` handle rendering. The Backbone adapter follows this approach:\nmerges still update collection order and filtering, without rendering children\nagain after their model events have run.\n\nIf a child was removed, detached, or destroyed while its model remained in the\nsource, updates for that model do not recreate its View. Other children continue\nto update. Rendering the CollectionView again or a source reset recreates children\nfrom the current source.\n\nAn immutable same-key replacement belongs only in `updated`, not in `removed`\nand `added`. Replacing a model with one that has a different stable key is a\nremoval plus an addition; changing the key of a retained model is invalid. The\npost-mutation `models()` snapshot is authoritative and must agree with the\nrecord. Missing, duplicate, or unstable snapshot keys throw `MN0039`. Adapters\nmust supply correct change records; core uses those records directly instead of\nrecalculating the change to validate them. Added children follow the current\nsnapshot order; removed children follow the previous snapshot order, regardless\nof their order in the change record.\n\nObservers may notify synchronously from CollectionView lifecycle hooks. Core\ncaptures each source snapshot and drains nested notifications in order, so each\nqueued update uses the source state that accompanied it.\n\nAll three record types enter one CollectionView reconciliation path. Additions\ncreate only their child Views; removals destroy only theirs; reorder moves\nsurvivor elements without rerendering them; and reset is the explicitly\ndestructive whole-list operation. Presentation comparators may sort the child\nViews independently of the source's canonical order.\n\n## Configuring an adapter\n\nConfigure the application before constructing Views. In this configuration\nfragment, `MyDataApi` is the adapter your application supplies:\n\n```javascript\nimport { setDataApi } from 'marionette';\n\nsetDataApi(MyDataApi);\n```\n\n`setDataApi()` overlays the supplied own enumerable methods onto both `View`\nand `CollectionView`. `View.setDataApi()` and `CollectionView.setDataApi()` can\nconfigure a subclass independently. A CollectionView and its child View class\nmust use compatible adapters.\n\nBehaviors use their owning View's adapter. Views and Behaviors work with the\noriginal model or collection, and event callbacks receive the source's native\narguments. DataApi does not wrap application sources. Templates receive the\ndata prepared by `serializeModel()` or `serializeCollection()`; see\n[Rendering](/docs/rendering.md).\n\nDataApi and [StateApi](/docs/state.md#stateapi) are selected\nindependently. One adapter object may implement both contracts, but configuring\none role never selects the other.\n\n## XState actors\n\n`@mnjs/adapters/xstate` supports a parent XState v5 actor whose selected\nordered collection contains stable child actor references. The adapter uses\nthe actor reference itself as `DataApi.key()`, reads and serializes the child\nactor's current `snapshot.context`, and observes the parent through its snapshot\nsubscription. A stopped and respawned actor is therefore a new model identity,\neven if it uses the same actor `id`.\n\nThe following configuration fragment assumes `parentActor` is an already-created\nactor whose `context.children` contains stable child actor references. The\napplication owns actor creation, startup, and eventual shutdown.\n\n```javascript\nimport createXStateActorApi from '@mnjs/adapters/xstate';\nimport { CollectionView, View } from 'marionette';\n\nconst XStateActorApi = createXStateActorApi({\n  select: snapshot => snapshot.context.children,\n  snapshotEvent: 'actor:snapshot'\n});\n\nconst ChildView = View.extend({\n  template: context => context.label,\n  modelEvents: {\n    'actor:snapshot': 'render',\n    announced: 'onAnnounced'\n  },\n  onAnnounced(event) {\n    console.log(event.label);\n  }\n});\nconst ListView = CollectionView.extend({ childView: ChildView });\nChildView.setDataApi(XStateActorApi);\nListView.setDataApi(XStateActorApi);\n\nconst view = new ListView({ collection: parentActor }).render();\n```\n\n`snapshotEvent` is optional and has no implicit default. When configured, that\nexact event-map name observes `actor.subscribe()` snapshots. Every other name\nis passed unchanged to `actor.on()` and observes an explicitly emitted event;\nevents sent to the actor are not surfaced automatically. The selected snapshot\narray should retain its reference for unrelated parent transitions. A newly\nsubscribed observer does not receive an already-started actor's current\nsnapshot, so initial template data comes from `getSnapshot()`.\n\n`select` is required when the result configures a CollectionView. Omit it when\nonly actor model reads, `modelEvents`, or `stateEvents` are needed; that result\ndoes not define the collection-only `models()` and `observeCollection()` methods.\n\nSet the same adapter on `StateApi` when `stateEvents` should use this event\nvocabulary. Supplied actors are borrowed and never stopped by Marionette. An\nactor returned from `createState()` is owned and is stopped only after its\nMarionette-managed subscriptions are released. The adapter never traverses or\nstops child actors.\n\n## Optional `@mnjs/data` sources\n\nInstall `@mnjs/data` with `marionette` when an application wants a small\nfirst-party observable Model and ordered Collection without Backbone:\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/data@5.0.0-beta.1\n```\n\n```javascript\nimport { CollectionView, setDataApi, setStateApi, View } from 'marionette';\nimport { Collection, DataApi, Model, StateApi } from '@mnjs/data';\n\nsetDataApi(DataApi);\nsetStateApi(StateApi);\n\nconst RowView = View.extend({\n  tagName: 'li',\n  template: () => '',\n  modelEvents: { change: 'render' },\n  onRender() {\n    this.el.textContent = this.model.get('label');\n  }\n});\nconst state = new Model({ selectedId: null });\nconst collection = new Collection([{ id: 1, label: 'one' }]);\nconst list = new CollectionView({\n  tagName: 'ul', childView: RowView, collection, state\n}).render();\n\n// Mount list.el in the application's chosen container.\ncollection.get(1).set('label', 'updated'); // The existing row now shows \"updated\".\n```\n\nUnless `{ silent: true }` is passed, the package Collection emits synchronous\n`update`, `sort`, and `reset` events. The adapter translates them directly to\nnormalized records. There is no separate observer queue, coalescing, or replay.\nFinish one structural mutation before starting another; schedule mutations from\ncollection listeners or child lifecycle handlers after the current notification\nreturns. Listener errors propagate and abort delivery.\n\n`move(modelOrId, index)` supports explicit list ordering without remove/add\nnotifications or child View recreation. It and `sort` emit `sort`. Ordinary\nattribute changes use `model.set()` and child `modelEvents` bindings.\n\nThe native adapter keys models by stable `cid`, so changing an application id\ndoes not replace its child View. Collection lookup uses current ids. Reset\nrejects duplicate instances and ids before changing membership; applications\nshould keep ids unique when changing them.\n\nLookup precedence is exact member instance, application id, then cid, regardless\nof collection order. Supplied native Model instances retain their identity even\nwhen the Collection configures a different model constructor; only raw attributes\nuse that constructor. Bulk removal resolves all identities against one current\nsnapshot, including ids changed with `{ silent: true }`.\n\n`Model.destroy()` and `Collection.destroy()` always emit their `destroy`\nlifecycle events, including with `{ silent: true }`. A destroyed model removes\nitself from each containing Collection through ordinary event subscriptions.\nDestroying a Collection releases its subscriptions without destroying its models.\n\nUse `Model.toObject()` for a shallow attribute copy and `Collection.toArray()`\nfor an array of plain attribute objects. Template serialization reads attributes\nindependently. The native package does not implement `toJSON`; pass these plain\nvalues to `JSON.stringify` explicitly.\n\nDefine Model subclass `defaults` on the prototype with `Model.extend`, a prototype\nmethod, or a prototype getter; a native class field initializes too late to seed\nthe base constructor. The package does not provide persistence, REST\nsynchronization, validation, or implicit Backbone behavior.\n\nNative Model writes use `Object.is` equality and report sparse `changed` and\n`previous` maps on their event options. Nested writes are independent synchronous\nchanges; use `options.changed` for the event being handled, since `model.changed`\nmay already describe a nested write. `has` tests own-property presence, including\nundefined values. Native collection sorting is explicit and `reset` rebuilds\nchildren; there is no automatic merge/reconcile operation. See the package's\n[mutation semantics](/docs/data-package.md#mutation-semantics) for details.\n\nApplications using Backbone should import the bundled integration instead of\nconfiguring these methods individually. See [Optional Backbone](/docs/backbone.md).\n\n\n[Canonical source](/docs/markdown/docs/data.api.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/dom.api.md",
      "title": "DOM API",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/dom-api/",
      "markdownUrl": "https://marionettejs.com/docs/dom-api.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/dom.api.md",
      "sourceSha256": "a697a637ae4c6cc92aa5d72850b404763f08e0417800feacc0b431ec073d3916",
      "sha256": "dea982ba190a485d792abec23e715bacab1a0bdd7dc1789dbff14785557c9709",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 a697a637ae4c6cc92aa5d72850b404763f08e0417800feacc0b431ec073d3916. -->\n\n# The DOM API\n\nMarionette uses a small DOM adapter for element creation, selection, attributes,\ncontent, and attachment operations. The default `DomApi` uses native browser\nAPIs and does not require Backbone or jQuery.\n\n`View`, `CollectionView`, and `Region` expose their adapter as `Dom`. A custom\nadapter can replace only the operations an application needs; all omitted\nmethods continue to use the inherited adapter.\n\nA renderer evaluates templates; `Dom.setContents` applies their output. The optional\n[Morphdom and Lit HTML DOM adapters](/docs/rendering.md#rendering-to-dom)\npreserve the selected DomApi; installing one does not select a data or state\nadapter.\n\n## Element and selector boundaries\n\n`View` and `CollectionView` own a concrete DOM element. Their `el` option must\nbe a DOM element. Resolve a selector\nat the call site when a View should reuse existing markup:\n\n```javascript\nimport { View } from 'marionette';\n\nconst view = new View({\n  el: document.querySelector('#content')\n});\n```\n\n`Region` retains selector resolution because a Region locates its managed\nelement relative to its `parentEl` or the document. `View#$()` and Region\nselector lookup both delegate to `DomApi.findEl`. With the native adapter,\n`View#$()` returns a `NodeList`. `Region#getEl` selects the first result and\nreturns that native DOM element. This Region return contract does not change\nwhen `findEl` is supplied by the optional jQuery adapter.\n\nThe v4 `DomApi#getEl` method is removed. DOM adapter overrides should implement\n`findEl(context, selector)` with an array-like result. Region `getEl` overrides\nare a separate extension point and must return one native DOM element.\n\n## Native API methods\n\nThe exported `DomApi` contains the following methods. This list is checked\nagainst the shipped package in CI.\n\n### `createElement(tagName)`\n\nCreates and returns a DOM element with `document.createElement(tagName)`.\nMarionette uses it when a View does not receive an `el`.\n\n### `createBuffer()`\n\nCreates and returns a `DocumentFragment` for collecting DOM nodes before one\nappend operation.\n\n### `getDocumentEl(el)`\n\nReturns `el.ownerDocument.documentElement`. Marionette uses that document root\nwhen determining whether a View is attached. Elements inside template content may\nhave an owner document without a document element; Marionette treats that missing\nroot as detached.\n\n### `findEl(el, selector)`\n\nFinds descendants of `el` matching `selector`. The native adapter returns the\n`NodeList` produced by `el.querySelectorAll(selector)`.\n\n### `hasEl(el, childEl)`\n\nReports whether `childEl` is attached beneath `el`. Marionette uses this for\nattachment-state checks.\n\n### `detachEl(el)`\n\nRemoves `el` from its parent when it has one. Native listeners attached to the\nelement remain on the detached element.\n\n### `replaceEl(newEl, oldEl)`\n\nReplaces `oldEl` with `newEl` when `oldEl` has a parent. Passing the same\nelement twice or an unattached `oldEl` is a no-op.\n\n### `moveEl(el, parent, before)`\n\nMoves `el` within `parent` before the optional reference node. The native\nadapter uses `moveBefore` for already-attached children when available so\nCollectionView reordering and swapping preserve focus, selection, media, and custom-element\nconnection state. It falls back to `insertBefore` for initial attachment and\nolder DOM implementations; the CollectionView render pass restores focused text selection after\nthat fallback, while older platforms may still run custom-element connection\ncallbacks for the move. `swapChildViews()` does not restore focus or selection\nwhen it uses the `insertBefore` fallback without a child-render pass.\n\n### `setContents(el, html)`\n\nReplaces the contents of `el` by assigning `html` to `el.innerHTML`.\n`null` and `undefined` produce empty contents.\n\n### `setAttributes(el, attrs)`\n\nApplies own enumerable string keys from `attrs` as DOM attributes using\n`setAttribute`. Use attribute names such as `class` and `for`. View-level\n`className` is converted to `class` before this method is called.\n\nAn explicit `null` removes an attribute. An `undefined` value or omitted key\nleaves the existing attribute untouched. Other values use the browser's string\nconversion, including `false`, `0`, and an empty string. For boolean HTML\nattributes, use `disabled: isDisabled ? '' : null`: the string `\"false\"` still\nmeans the attribute is present. ARIA and data attributes can use `false` to set\n`\"false\"`.\n\nThis method does not assign JavaScript properties. Set live form values or\ncustom element properties explicitly on the element; `value` and `checked`\nattributes describe input defaults. Attribute changes still have the browser's\nnormal effects on reflected properties.\n\nWhen `View` or `CollectionView` creates an element, `id` and `className`\ndeclarations override matching entries in `attributes`.\n[`View#renderAttributes()`](/docs/view.md#refreshing-root-attributes)\napplies the current declarations to an existing element without tracking prior\nkeys. Custom DomApi adapters must preserve explicit-null removal and leave\nundefined and omitted entries untouched.\n\n### `appendContents(el, contents)`\n\nAppends the DOM node or `DocumentFragment` in `contents` to `el`.\n\n### `hasContents(el)`\n\nReturns whether `el` exists and has child nodes.\n\n### `detachContents(el)`\n\nRemoves all children by assigning an empty string to `el.textContent`. This is\nthe fast, jQuery-free default.\n\n### `notifyAttach(el)`\n\nNotify the adapter that its element's contents are active. Called through View\nattachment monitoring and when construction adopts an attached root. The\nnative implementation does nothing; Lit reconnects its directives.\n\n### `notifyDetach(el)`\n\nNotify the adapter that its element's contents are inactive. Called through View\ndetachment monitoring. This notification does not remove or empty the element.\nThe native implementation does nothing; Lit disconnects its directives while retaining its rendered contents.\n\nThese hooks receive only the element. They follow the existing attachment\nmonitoring opt-out: with `monitorViewEvents: false` or monitoring handlers\nremoved, applications must deliver the notifications they need themselves.\nThis includes destruction: `destroy()` still removes the View and its owned\nresources, but does not separately disconnect adapter-managed contents when\nattachment monitoring is disabled. An application rendering Lit into an attached\nroot with monitoring disabled must notify `notifyDetach(el)` when releasing that root.\n`detachContents(el)` remains the operation for physically emptying an element.\n\n## Using the default API\n\nThe native adapter is exported for direct use and for restoring native methods\ninside a customized class:\n\n```javascript\nimport { DomApi, View } from 'marionette';\n\nconst NativeView = View.extend();\nNativeView.setDomApi(DomApi);\n```\n\n## Providing a custom API\n\nThe root `setDomApi` function overlays methods for `View`, `CollectionView`,\nand `Region`:\n\n```javascript\nimport { setDomApi } from 'marionette';\nimport MyDomApi from './my-dom-api.js';\n\nsetDomApi(MyDomApi);\n```\n\nUse a class setter when only one class or subclass needs the override. The\nsetter creates a shallow adapter overlay for that class, so a partial override\nretains every other currently configured method. The current adapter and supplied overlay\ncontribute own enumerable string and symbol properties. Inherited and\nnon-enumerable properties are ignored.\n\n<!-- executable-example: dom-api-partial-override -->\n```javascript\nimport { View } from 'marionette';\n\nexport const PlainTextView = View.extend({\n  template() {\n    return '<strong>Literal markup</strong>';\n  }\n});\n\nPlainTextView.setDomApi({\n  setContents(el, html) {\n    el.textContent = html;\n  }\n});\n\nexport function renderPlainText() {\n  const view = new PlainTextView();\n  view.render();\n  return view;\n}\n```\n\n`PlainTextView` uses the custom `setContents`, while `View` and unrelated View\nsubclasses retain their existing adapters. `CollectionView`, `Region`, and\n`View` each support this class-level pattern.\n\n## Optional jQuery adapter\n\nApplications that rely on jQuery DOM bookkeeping can install jQuery and opt in\nat application boot:\n\n```javascript\nimport { setDomApi } from 'marionette';\nimport JQueryDomApi from '@mnjs/adapters/dom/jquery';\n\nsetDomApi(JQueryDomApi);\n```\n\nThe optional adapter overrides `findEl`, `detachEl`, `setContents`,\n`appendContents`, and `detachContents`. `View#$()` consequently returns a jQuery\ncollection. If application code also needs `$el`, initialize it once:\n\n```javascript\nimport $ from 'jquery';\nimport { View } from 'marionette';\n\nconst JQueryView = View.extend({\n  initialize() {\n    this.$el = $(this.el);\n  }\n});\n```\n\nThe root is fixed at construction, so the wrapper remains valid through rendering\nand detach/reattach. CollectionViews and Behaviors can initialize `$el` the same\nway. `$el` is application-owned; the adapter has no wrapper or View setup API.\n\nThe native adapter does not create `$el`. The jQuery adapter does not replace\nMarionette's event delegator, restore Backbone.View inheritance, or allow\nselector strings as a View `el`. Configure those concerns separately when an\napplication actually requires them.\n\nPrefer the native adapter for new applications. Use\n`@mnjs/adapters/dom/jquery` only for an existing integration that depends on\njQuery selection, content, or detach semantics.\n\n\n[Canonical source](/docs/markdown/docs/dom.api.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/dom.prerendered.md",
      "title": "Pre-rendered DOM",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/prerendered-dom/",
      "markdownUrl": "https://marionettejs.com/docs/prerendered-dom.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/dom.prerendered.md",
      "sourceSha256": "61302b6f8fe83582cdb84bd06938a3fef150a67dfff63e77a2ce8b9d7a18aaeb",
      "sha256": "ebfe3cf3e97c1abb6295c03ad8734f9eba845c026e6fed9a548a64a42c34c2fd",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 61302b6f8fe83582cdb84bd06938a3fef150a67dfff63e77a2ce8b9d7a18aaeb. -->\n\n# Prerendered Content\n\nView classes can be initialized with pre-rendered DOM.\n\nThis can be HTML that's currently in the DOM:\n\n```javascript\nimport { View } from 'marionette';\n\nconst myView = new View({ el: document.querySelector('#foo-selector') });\n\nmyView.isRendered(); // true if '#foo-selector' exists and has content\nmyView.isAttached(); // true if '#foo-selector' is in the DOM\n```\n\nOr it can be DOM created in memory:\n\n```javascript\nimport { View } from 'marionette';\n\nconst inMemoryHtml = document.createElement('div');\ninMemoryHtml.textContent = 'Hello World!';\n\nconst myView = new View({ el: inMemoryHtml });\n```\n\n\nIn both of the cases at instantiation the view will determine\nits state as to whether the el is rendered\nor attached.\n\n**Note** `render` and `attach` events will not fire for the initial\nstate as the state is set already at instantiation and is not changing.\n\n## Managing `View` children\n\nWith `View`, the `render` event is usually the best place to show child views for\nefficient nested rendering.\n\nHowever with pre-rendered DOM you may need to show child views in `initialize`\nas the view will already be rendered.\n\n```javascript\nimport { View } from 'marionette';\nimport HeaderView from './header-view';\n\nconst MyBaseLayout = View.extend({\n  regions: {\n    header: '#header-region',\n    content: '#content-region'\n  },\n  el() {\n    return document.querySelector('#base-layout');\n  },\n  initialize() {\n   this.showChildView('header', new HeaderView());\n  }\n});\n```\n\n### Managing a Preexisting View Tree\n\nIt may be the case that you need child views of already existing DOM as well.\nQuery the existing DOM for each child's element. A Region declared with a\nselector may still hold that selector in `region.el` before its first show;\n`getRegion()` does not resolve it. Query from the owning View's concrete `el`:\n\nThe page contains this existing markup before the module runs:\n\n```html\n<main id=\"base-layout\">\n  <div id=\"header-region\"><header><h1>Existing account</h1></header></div>\n  <div id=\"content-region\"></div>\n</main>\n```\n\n<!-- executable-example: prerendered-owned-tree -->\n```javascript\nimport { View } from 'marionette';\n\nexport const HeaderView = View.extend({\n  tagName: 'header',\n  template: () => '<h1>Account</h1>'\n});\n\nexport const BaseLayout = View.extend({\n  regions: {\n    header: '#header-region',\n    content: '#content-region'\n  },\n  el() {\n    return document.querySelector('#base-layout');\n  },\n  initialize() {\n    this.showChildView('header', new HeaderView({\n      el: this.el.querySelector('#header-region').firstElementChild\n    }));\n  }\n});\n\nexport const layout = new BaseLayout();\n```\n\nThe child owns the existing `header` element. Its existing content is retained\nwhen shown because it is already rendered. Destroying the layout destroys its\nchild and removes the owned tree. The [fixture](/docs/source/test/fixtures/docs-prerendered-content/validate.mjs)\nchecks element identity, retained content, parent ownership, and cleanup.\n\n\nThe same can be done with `CollectionView`. This fragment assumes an existing\n`#base-table` with a `tbody` containing one row per item, in source order. Supply\nthe application's `someCollection` and configure its DataApi before construction\nwhen using an observable collection:\n\n```javascript\nimport { CollectionView } from 'marionette';\nimport RowView from './row-view';\n\nconst MyList = CollectionView.extend({\n  el() {\n    return document.querySelector('#base-table');\n  },\n  childView: RowView,\n  childViewContainer: 'tbody',\n  buildChildView(model, ChildView, childViewOptions) {\n    const index = this.Data.models(this.collection).indexOf(model);\n    const childEl = this.el.querySelector('tbody').children[index];\n\n    return new ChildView({\n      model,\n      ...childViewOptions,\n      el: childEl\n    });\n  }\n});\n\nconst myList = new MyList({ collection: someCollection });\n\n// Unlike `View`, `CollectionView` should be rendered to build the `children`\nmyList.render();\n```\n\n## Re-rendering children of a view with preexisting DOM\n\nYou may be instantiating a `View` with existing HTML, but if you re-render the view,\nlike any other view, your view will render the `template` into the view's `el` and\nany children will need to be re-shown.\n\nSo your view will need to be prepared to handle both scenarios.\n\n```javascript\nimport { View } from 'marionette';\nimport HeaderView from './header-view';\n\nconst MyBaseLayout = View.extend({\n  regions: {\n    header: '#header-region',\n    content: '#content-region'\n  },\n  el() {\n    return document.querySelector('#base-layout');\n  },\n  initialize() {\n    this.showChildView('header', new HeaderView({\n      el: this.el.querySelector('#header-region').firstElementChild\n    }));\n  },\n  template: () => '<div id=\"header-region\"></div><div id=\"content-region\"></div>',\n  onRender() {\n    this.showChildView('header', new HeaderView());\n  }\n});\n```\n\n\n[Canonical source](/docs/markdown/docs/dom.prerendered.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/optional-backbone.md",
      "title": "Backbone",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/backbone/",
      "markdownUrl": "https://marionettejs.com/docs/backbone.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/optional-backbone.md",
      "sourceSha256": "05bd7e97a8e76372aedcf05641184ec14ac1238bbc928723e2dc49cd3d73f854",
      "sha256": "f97ac7f920d23916d365f3ff1dac27c3cbcb45668fdd020af13cddcb1dc81b83",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 05bd7e97a8e76372aedcf05641184ec14ac1238bbc928723e2dc49cd3d73f854. -->\n\n# Optional Backbone\n\nUse Backbone models and collections with Marionette by installing the separate\nadapters package and selecting its Backbone integration. Marionette core does\nnot import Backbone. Backbone models and collections are observable sources;\n“optional” means Marionette does not require that provider. Plain objects and\narrays use the default [Data API](/docs/data-api.md) as static data.\n\n```sh\nnpm install @mnjs/adapters@5.0.0-beta.1 backbone\n```\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport { setDataApi } from 'marionette';\n\nsetDataApi(BackboneApi);\n```\n\nIf a Marionette owner also uses a Backbone source for `state` or `createState()`,\nselect the StateApi role separately:\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport { setStateApi } from 'marionette';\n\nsetStateApi(BackboneApi);\n```\n\nConfigure `BackboneApi` once at application boot before constructing Marionette\nconsumers or registering their subscriptions. Existing Backbone sources can be\npassed in; the adapter does not alter their construction or native events. For an isolated runtime, call\nthat runtime's `setDataApi()` and `setStateApi()` methods instead of the root\nsetters.\n\n## What the integration does\n\nThe integration supplies one combined adapter object for two related contracts:\n\n1. As a DataApi adapter, it translates Backbone data and structural\n   collection events.\n2. As a StateApi adapter, it subscribes to Backbone state events while leaving\n   owned Backbone state caller-controlled.\n\nThe data adapter maps:\n\n| Marionette operation | Backbone source |\n| --- | --- |\n| model identity | `model.cid` |\n| named value read | `model.get(attribute)` |\n| value presence and serialization | `model.attributes` |\n| ordered model snapshot | `collection.models` |\n| application entity events | `entity.on(...)` and `entity.off(...)` |\n| structural observations | `sort`, `reset`, and `update` collection events |\n\nBackbone's `sort`, `reset`, and `update` payloads are translated to the neutral\nrecords documented by [`DataApi.observeCollection()`](/docs/data-api.md#collection-observations).\nThose Backbone-specific shapes do not enter Marionette core.\n\nAs in Marionette v4, child `modelEvents` control rendering after model changes.\nFor example, `modelEvents: { change: 'render' }` renders a child when its model\nchanges. Collection merges still sort and filter children, but do not request\nanother render. Backbone also reports unchanged models as merged, so treating\nevery merge as a render request would redraw unchanged children.\n\nSort handling follows Marionette v4: the adapter skips `sort` events carrying\n`add`, `remove`, or `merge` flags and handles those mutations through `update`.\nExplicit `collection.sort()` calls still notify the View. The observer does not\nretain or scan a separate membership snapshot to distinguish these events.\n\nThis retains a v4 limitation: without a comparator, `collection.set()` that only\nreorders existing model instances emits a flagged `sort` but no `update`, so it\ndoes not automatically reorder the displayed children. Call the CollectionView's\n`render()` to refresh them after that operation.\n\nThe original Backbone model or collection remains the value stored on a View\nand passed to callbacks. The integration does not wrap entities or allocate a\nsecond model graph.\n\n## Native event identity and load order\n\nThe integration uses Backbone's native `on()`, `off()`, `listenTo()`, and\n`stopListening()` behavior. It does not modify the Backbone namespace,\nconstructors, prototypes, or event stores, and it does not add `triggerMethod`.\nListeners registered before adapter configuration continue to work afterward:\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { setDataApi } from 'marionette';\n\nconst model = new Backbone.Model();\nconst onChange = () => console.log('Model changed');\nmodel.on('change', onChange);\n\nsetDataApi(BackboneApi);\nmodel.set('ready', true); // onChange still runs\n```\n\nDestroying a Marionette owner unsubscribes its adapter-managed event handlers.\nThe adapter leaves an owned Backbone state source and its caller-owned listeners\nintact because Backbone has no source-wide disposal operation that can preserve\nthem. It does not call `stopListening()`, `off()`, or persistence-capable\n`Backbone.Model#destroy()` on that source.\n\n## Applications without Backbone\n\nDo not install or import Backbone solely for Marionette. Plain models and arrays\nwork with the default DataApi:\n\n```javascript\nconst model = { name: 'one' };\nconst collection = [model, { name: 'two' }];\n```\n\nFor observable data, use [Choosing integrations](/docs/choosing-integrations.md) to\nselect an existing integration first. If the application requires a custom\nintegration, implement the [DataApi contract](/docs/data-api.md) rather than\nmanufacturing Backbone-shaped `cid`, `attributes`, `models`, or event payloads.\n\n\n[Canonical source](/docs/markdown/docs/optional-backbone.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/runtime-isolation.md",
      "title": "Runtime isolation",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/runtime-isolation/",
      "markdownUrl": "https://marionettejs.com/docs/runtime-isolation.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/runtime-isolation.md",
      "sourceSha256": "e18927a5aa30558805018c9c28dffceaf02d953394efce8eaa7d35f0711de7f4",
      "sha256": "6634e384f01d333f27f08e0b4e9829b83eeeea3f9218806d0a2f055e8ec97582",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 e18927a5aa30558805018c9c28dffceaf02d953394efce8eaa7d35f0711de7f4. -->\n\n# Runtime isolation\n\nUse named imports from `marionette` when the application shares one configuration.\nThese exports belong to the default runtime:\n\n```javascript\nimport { View, Radio, setRenderer } from 'marionette';\n```\n\n`createMarionette()` creates an isolated runtime for applications that need\nmore than one Marionette configuration in the same JavaScript process. This\nconfiguration fragment assumes the application supplies the two renderers and\ntemplates:\n\n```javascript\nimport { createMarionette } from 'marionette';\n\nconst admin = createMarionette();\nconst storefront = createMarionette();\n\nadmin.setRenderer(adminRenderer);\nstorefront.setRenderer(storefrontRenderer);\n\nconst AdminView = admin.View.extend({ template: adminTemplate });\nconst StorefrontView = storefront.View.extend({ template: storefrontTemplate });\n```\n\nEach call returns its own `Application`, `Behavior`, `CollectionView`, `MnObject`,\n`Region`, and `View` classes. It also owns independent `DataApi`, `DomApi`,\n`StateApi`, EventDelegator configuration, renderer configuration, and `Radio`\nchannel registry. Changing one runtime does not change the default runtime or another\nisolated runtime.\n\nNew runtimes start from Marionette's built-in adapter and renderer defaults, not from\nlater configuration applied to the default runtime. Apply shared application\nconfiguration explicitly to each runtime that needs it.\n\nImplicit composition stays inside the selected runtime. Declarative Regions,\nCollectionView's empty Region, and Application's root Region use the owning runtime's\nclasses. A Region or child Application from another runtime is rejected as an ownership\nconflict; construct it from the receiver's runtime instead.\n\nIsolation controls implicit class composition and mutable runtime configuration. It\nis not a security boundary: explicitly showing a View-like object from another\nruntime remains allowed under the existing Region and CollectionView display\ncontracts.\n\nThe factory is optional. Calling it does not replace the default exports, and\nordinary imports do not create a runtime per View or Application instance. Class-level\nsetters remain subclass-local within either form.\n\nConfigure object-style adapters against the selected runtime's setters. For example,\npass the `@mnjs/adapters/dom/jquery` export to `isolated.setDomApi()`.\nLikewise, pass the `@mnjs/adapters/backbone` export to the isolated\nruntime's `setDataApi()` and `setStateApi()` methods when it consumes Backbone\ndata or state. No implicit adapter configuration crosses runtime boundaries.\n\n## Configuration method contract\n\nConfigure a runtime or subclass before creating its instances. The setters run\nsynchronously; they do not render Views or replace existing event subscriptions.\nChanging a class prototype during a live feature is not a coordinated migration\nof the feature's adapters or resources.\n\n| Setter | Classes configured by the root or runtime function | Update |\n| --- | --- | --- |\n| `setDataApi(api)` | `View`, `CollectionView` | Overlays own enumerable methods on each class's current DataApi. |\n| `setDomApi(api)` | `View`, `CollectionView`, `Region` | Overlays own enumerable methods on each class's current DomApi. |\n| `setStateApi(api)` | `Application`, `Behavior`, `CollectionView`, `MnObject`, `View` | Overlays own enumerable methods on each class's current StateApi. |\n| `setRenderer(renderer)` | `View`, `CollectionView` | Replaces template evaluation with the supplied function. |\n| `setEventDelegator(delegator)` | `Behavior`, `CollectionView`, `View` | Replaces the delegator with an object exposing `delegate(options)` that returns the cleanup function for that registration. |\n\nRoot and runtime setter functions return `undefined`. Corresponding class\nmethods, such as `CustomView.setDataApi(api)`, return that class and configure\nits prototype. Subclasses inherit configuration until they receive their own\noverride. An existing subclass override is not overwritten by subsequently\nconfiguring its parent class.\n\nOmitting an argument is not a reset operation. In particular, object API setters\nretain the current overlay, while `setRenderer(undefined)` removes the configured\nrenderer rather than restoring the default. Use a fresh `createMarionette()`\nwhen a new independent configuration should start from built-in defaults.\n\n\n[Canonical source](/docs/markdown/docs/runtime-isolation.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "packages/data/readme.md",
      "title": "Data package",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/data-package/",
      "markdownUrl": "https://marionettejs.com/docs/data-package.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/packages/data/readme.md",
      "sourceSha256": "fc111bfead076ede1d9cf00fe9cd7d02ef5aac4ab2317bffba529dcca850b360",
      "sha256": "19a48f6d3c5a5ff03415389c444f98e89cef4419370de4ee04d9b4c27d89be7d",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 fc111bfead076ede1d9cf00fe9cd7d02ef5aac4ab2317bffba529dcca850b360. -->\n\n# @mnjs/data\n\nDependency-light observable `Model` and ordered `Collection` sources for\nMarionette v5. The package depends only on `@mnjs/utils`; models and\ncollections can run without core or a DOM. Install `@mnjs/data` on its own\nfor standalone use. To use it with Marionette views, install both packages and\nconfigure the runtime before creating owners:\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/data@5.0.0-beta.1\n```\n\n```js\nimport { CollectionView, View } from 'marionette';\nimport { Collection, DataApi } from '@mnjs/data';\n\nconst Row = View.extend({\n  tagName: 'li',\n  template: () => '<span></span>',\n  modelEvents: { change: 'render' },\n  onRender() {\n    this.el.querySelector('span').textContent = this.model.get('label');\n  }\n});\nconst List = CollectionView.extend({ tagName: 'ul', childView: Row });\nRow.setDataApi(DataApi);\nList.setDataApi(DataApi);\n\nconst collection = new Collection([{ id: 1, label: 'one' }]);\nconst view = new List({ collection }).render();\n```\n\nThis setup selects data for the list and its child Views. State remains an\nindependent choice. If a View also uses a `Model` as observable state, configure\nStateApi on that class before construction. In the example above, place this\noptional setup before `new List(...)`, which constructs its children when rendered:\n\n```js\nimport { StateApi } from '@mnjs/data';\n\nRow.setStateApi(StateApi);\n```\n\nSupply an existing `Model` through `state`, or return an owned one from\n`createState()`. Declare `stateEvents` only for the changes the owner needs to\nobserve; the model's event names and payloads remain its own contract.\n\nUse top-level setters when all affected classes intentionally share the same\nprovider. Configure an existing isolated runtime through its corresponding\nsetters when needed; using this package does not require creating a new runtime.\n\n`Collection` reports synchronous `kind: 'update'`, `kind: 'reorder'`, and\n`kind: 'reset'` records through `DataApi.observeCollection()`. `Model` and\n`Collection` expose `on()`, `once()`, `off()`, `trigger()`, and\n`triggerMethod()` for Marionette entity event maps.\n`DataApi.models(collection)` returns the current ordered model snapshot.\n\n`Model` provides `get`, `has`, `set`, `unset`, `clear`, `reset`, `toObject`, and\n`destroy`. `Collection` provides ordered `at`, `get`, `indexOf`, iteration,\n`forEach`, `map`, `add`, `remove`, `reset`, `move`, `sort`, `toArray`, and `destroy` operations. Pass `{ silent: true }` to a\nstructural mutation to suppress its normalized record and entity events.\n`destroy()` is the exception and always emits its destruction event.\n\nDefine subclass `defaults` on the prototype, for example with `Model.extend`, a\nprototype method, or a prototype getter. Native class fields initialize after\n`super()` returns, so a `defaults = { ... }` field cannot seed construction.\n\n`move(modelOrId, index)` changes list order without removing and re-adding a\nmodel. This supports drag ordering while retaining child Views and their local\nstate. Both `move` and `sort` emit `sort`, translated to a DataApi reorder record.\nUpdate model attributes with `model.set()` and subscribe through `modelEvents`\nwhen a child should render after a change.\n\nThe native DataApi uses each model's stable `cid` as its key. Application ids may\nchange; Collection lookup reads the current ids. Duplicate instances or ids are\nrejected before a reset changes membership; `add` ignores an instance or id\nalready present. Applications should keep ids unique when changing them.\n`get`, `remove`, and `move` resolve an exact member instance first, then an\napplication id, then a cid. This precedence does not change when models move.\nBulk removal resolves its inputs against one current membership snapshot, including\nsilent id changes. It skips missing identities and repeated matches, returns\nremoved Models in input order, and keeps surviving Models in collection order.\nIf id writes temporarily create duplicates, id lookup selects the first current\nmember; applications should restore unique ids.\n\nSupplied native Model instances retain their identity, attributes, and subclass,\nincluding when the Collection has a different `model` constructor. That constructor\nis used only for raw attribute objects. Initial model instances do not configure\nthe constructor used for future raw additions.\n\nA model may belong to multiple Collections. Its `destroy` event removes it from\neach containing Collection, forwarding removal options such as `silent`.\nThe destroy event itself still fires. Destroying a Collection releases subscriptions; it\ndoes not destroy its models.\n\n`model.toObject()` returns a shallow attribute copy. `collection.toArray()` returns\nan array of those plain objects; use `collection.models.slice()` or iteration for\nmodel instances. Template serialization reads `model.attributes` independently of\nthese conversion methods. There is no automatic `toJSON` hook: to serialize the\nplain data, use `JSON.stringify(model.toObject())` or\n`JSON.stringify(collection.toArray())`.\n\nCollection observation uses ordinary synchronous `update`, `reset`, and `sort`\nevents. Notifications are not combined or replayed. Complete one structural\nmutation before starting another: schedule mutations from collection listeners\nor child lifecycle handlers after the current notification returns. Errors in\nlisteners propagate and abort delivery, as with ordinary model events.\n\nThe package does not provide persistence, REST synchronization, validation, or\nimplicit Backbone compatibility.\n\n## Mutation semantics\n\n`set` compares values with `Object.is`: a fresh object is a change even when its\ncontents match, while mutating a nested object in place is not observed. `has`\ntests own-property presence, including a present `undefined` or `null` value.\nSupplied attributes override defaults, including when their value is `undefined`.\nModel `reset` reapplies defaults and removes attributes absent from the result.\n\nChange callbacks receive `options.changed` and `options.previous`, sparse maps for\nthat mutation. For an attribute reported in `changed`, an absent own key in\n`previous` means it did not exist before the mutation; an own key with value\n`undefined` means it existed with that value. `previous` is\nnot a complete model snapshot. Removing an attribute reports `undefined` in\n`changed`; use `has` to check its current presence.\n\nNested Model writes complete synchronously as independent changes. Use the event's\n`options.changed` to inspect that event: `model.changed` reflects the latest write,\nwhich may be a nested mutation by the time an outer change callback runs. Silent\nwrites still update attributes and `changed`; no-op writes clear `changed`.\n\nCollection `add` and `remove` events originate on the Collection. Model events are\nforwarded by containing Collections. Sorting is explicit: a prototype comparator\nis used by `sort()`, but `add` and `reset` do not automatically sort. There is no\n`Collection.set()` merge/reconcile operation; update retained Models explicitly\nwhen refreshing a list whose child Views must retain local state. `reset` is the\ndeliberately destructive whole-list operation for CollectionView child Views;\nthe Collection retains supplied Model instances rather than destroying them.\n\n## TypeScript\n\nThe package includes ESM and CommonJS declarations and a TypeScript 4.6-compatible\nentry. `Model.extend` and `Collection.extend` retain added methods, descendants,\nstatic replacements, and their normal attribute/model constructor inference.\nEvent registration accepts typed callbacks and maps; event names do not validate\npayload types. A borrowed `triggerMethod` requires a receiver with a callable\n`trigger` method.\n\nA custom constructor must initialize the receiver itself. An explicit object\nreturn describes a replacement instance; an unknown result stays unknown. To\nreturn the initialized receiver while preserving methods added by descendants,\nstate that contract explicitly:\n\n```ts\nimport { Model } from '@mnjs/data';\n\nconst Named = Model.extend({\n  constructor: function<Receiver extends Model>(\n    this: Receiver, attributes: { label: string }\n  ): Receiver {\n    Model.call(this, attributes);\n    return this;\n  },\n  label() { return String(this.get('label')); }\n});\n```\n\nThe same form works with `Collection`. A constructor declared to return `void`\nor a primitive declares ordinary construction; the caller is responsible for\nhonoring that declaration. TypeScript's `void` return erasure can hide an object\nreturn, so the declarations cannot prove that contract from arbitrary constructor\nimplementations. An inferred fixed receiver return does not promise methods\nadded by later descendants.\n\nDirect native subclasses remain supported. Calling their inherited `.extend()`\nwithout an explicit constructor is rejected because that path calls the parent\nwith `apply`, which cannot invoke a native class. An explicit constructor skips\nthat forwarding path and owns its initialization or replacement result.\n\nTypeScript 4.6 narrows `instanceof` checks for the root constructors and ordinary\nmethod-only extensions. Its callable-intersection limitation prevents that\nnarrowing on extensions with custom statics; directly constructed instances and\nthose static members remain typed.\n\nCollection member types include both supplied Models and the constructor used for\nraw attributes. Constructor `options.model` replaces a prototype `model` factory;\nwithout either, raw attributes construct a base Model. Narrow an item with\n`instanceof ModelClass` before using subclass-specific methods. The instance\n`model` constructor has the same conservative member result type.\n\nModel attributes and `toObject()` are partial: construction, `unset`, and `clear`\ncan leave any attribute absent. Known string keys in `set(key, value)` use the same\nattribute value types as object-form writes; arbitrary dynamic keys remain open.\nAn explicitly typed Collection also checks raw attribute inputs against its model\nattribute shape. These are compile-time contracts, not runtime validation.\n\n\n[Canonical source](/docs/markdown/packages/data/readme.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "packages/adapters/readme.md",
      "title": "Adapters package",
      "section": "Choose integrations",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/adapters-package/",
      "markdownUrl": "https://marionettejs.com/docs/adapters-package.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/packages/adapters/readme.md",
      "sourceSha256": "2bdba0d62222d76124ce0e90fa2fe425cf16e3cf46b00a6ad7aaf33872f015b3",
      "sha256": "f26799985f8ac3ebab251a237ea840f876378dd0a8547667731b1948a8c5d4c5",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 2bdba0d62222d76124ce0e90fa2fe425cf16e3cf46b00a6ad7aaf33872f015b3. -->\n\n# @mnjs/adapters\n\nFirst-party optional integrations for Marionette v5. The package intentionally\nhas no root export: import only the adapter and optional peer your application\nuses. Installing this package does not install every provider. The adapters have\nseparate module graphs and no import-time installation; unused integrations stay\nout of the application bundle. Source is grouped into `data` and `dom`,\nwhile each integration remains an explicit package subpath.\n\n## Adapter conventions\n\n- `SomethingApi` is an object implementing an existing runtime contract.\n- `createSomethingApi(options)` returns that object when configuration is required.\n\nImports do not configure Marionette. Use the existing `setDomApi`, `setDataApi`,\nand `setStateApi` methods before constructing instances. An integration may\nsatisfy more than one contract: Backbone uses the same adapter object for both\ndata and state. Setters overlay supplied methods; the last supplied version of\na method wins. Configure content rendering after general DOM operations.\n\nAdapters use public APIs and document source ownership and cleanup below.\n\nTemplate evaluation is a function configured with `View.setRenderer()`. Projects\ncan supply that function directly; it does not need a packaged adapter. Lit and\nMorphdom belong to DomApi because they apply template results to the DOM.\n\n## Backbone\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/adapters@5.0.0-beta.1 backbone\n```\n\nConfigure DataApi before creating Views that consume Backbone models or\ncollections. The example below covers model-backed Views. For a CollectionView, configure\nDataApi on both its parent CollectionView class and its child View class before\nconstruction. For a feature-specific integration, configure its View subclass:\n\n```js\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport { View } from 'marionette';\n\nconst BackboneView = View.extend();\nBackboneView.setDataApi(BackboneApi);\n```\n\nUse the top-level `setDataApi(BackboneApi)` when the whole application shares\nthat data provider. Configure StateApi separately, only for owners whose state\nuses Backbone and needs subscriptions or owned-source cleanup:\n\n```js\nBackboneView.setStateApi(BackboneApi);\n```\n\nThe same adapter object can configure other state-owning classes, or the\ncorresponding setters on an existing isolated runtime. Choosing Backbone data\ndoes not require choosing Backbone state or creating an isolated runtime.\n\nThe adapter uses Backbone's native events and does not modify Backbone objects\nor prototypes. Releasing an owned Backbone state source removes only the\nadapter-managed owner subscriptions. The adapter leaves the source and its\ncaller-owned listeners intact; it does not call source-wide `stopListening()`,\n`off()`, or persistence-capable `Model#destroy()` methods.\n\n## XState actors\n\nUse the XState actor adapter when a parent actor snapshot contains stable child\nactor references. Actor-reference identity associates each child actor with its\nView; stopping and respawning an actor creates a different model identity even\nwhen the actors share an `id`. The adapter supports XState `^5.32.6`.\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/adapters@5.0.0-beta.1 xstate\n```\n\nThis configuration fragment assumes an application-owned `parentActor` whose\n`context.children` contains stable child actor references. Create and start the\nactors in the application's XState setup.\n\n```js\nimport createXStateActorApi from '@mnjs/adapters/xstate';\nimport { CollectionView, View } from 'marionette';\n\nconst XStateActorApi = createXStateActorApi({\n  select: snapshot => snapshot.context.children,\n  snapshotEvent: 'actor:snapshot'\n});\n\nconst ActorView = View.extend({\n  template: context => context.label,\n  modelEvents: {\n    'actor:snapshot': 'render',\n    announced: 'onAnnounced'\n  },\n  onAnnounced(event) {\n    console.log(event.label);\n  }\n});\nconst ActorList = CollectionView.extend({ childView: ActorView });\nActorView.setDataApi(XStateActorApi);\nActorList.setDataApi(XStateActorApi);\n\nconst view = new ActorList({ collection: parentActor }).render();\n```\n\nFor a CollectionView, the required selector receives the parent actor's\nsynchronous snapshot and returns its ordered child actor references. Omit\n`select` when configuring only actor models or state. Templates receive each child actor's current\n`snapshot.context`. Configure `snapshotEvent` only when declarative\n`modelEvents` or `stateEvents` should observe actor snapshots; the chosen name\nis reserved by that adapter instance. Every other event-map name is passed to\n`actor.on()` and therefore observes an explicitly emitted actor event, not an\nevent sent to the actor. Subscribing to an already-started actor does not replay\nits current snapshot, so initial rendering reads `getSnapshot()` directly.\n\nReplace the selected array when membership or order changes. Reusing an unchanged\narray lets the adapter skip comparison; a newly allocated array requires a keyed\nscan per observer, even if its contents are identical.\n\nSupplied parent, child, and state actors are borrowed. Destroying a Marionette\nowner releases its subscriptions and Views but does not stop those actors. An\nactor returned by an owner's `createState()` factory is owned; after releasing\nits subscriptions, Marionette calls this adapter's `disposeOwned()` and stops\nthat actor. The keyed snapshot helper is private implementation only;\nthere is no generic snapshot-source package export.\n\n## jQuery DomApi\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/adapters@5.0.0-beta.1 jquery\n```\n\n```js\nimport { View } from 'marionette';\nimport JQueryDomApi from '@mnjs/adapters/dom/jquery';\n\nconst JQueryView = View.extend();\nJQueryView.setDomApi(JQueryDomApi);\n```\n\nIf application code needs `$el`, initialize it once:\n\n```js\nimport $ from 'jquery';\nimport { View } from 'marionette';\nimport JQueryDomApi from '@mnjs/adapters/dom/jquery';\n\nconst JQueryView = View.extend({\n  initialize() { this.$el = $(this.el); }\n});\nJQueryView.setDomApi(JQueryDomApi);\n```\n\nViews, CollectionViews, and Behaviors keep their initial root. The application\nowns `$el`; no wrapper helper or extra package subpath is needed.\n\nImporting an adapter subpath does not load any other adapter or optional peer.\n\n## DOM contents\n\nThe Morphdom and Lit DOM adapters update a View's contents synchronously and keep its `el`\nin place. Marionette still owns View events, attachment, destruction, and\nRegions. A parent render still destroys its Region children before updating the\nparent template; incremental rendering does not preserve those child Views.\nKeep Region placeholders empty in your templates so the adapter and Region do\nnot both manage the same contents.\n\nConfigure these adapters through `ViewClass.setDomApi(adapter)` before creating\ninstances. The adapter overlays only its supplied methods, so unrelated DOM\noperations remain in place. Configure jQuery first if you need its query and\nattachment operations alongside Morphdom or Lit.\n\n### Morphdom\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/adapters@5.0.0-beta.1 morphdom\n```\n\n```js\nimport { View } from 'marionette';\nimport MorphdomDomApi from '@mnjs/adapters/dom/morphdom';\n\nconst MessageView = View.extend({\n  template: () => '<p id=\"message\">Hello again.</p>'\n});\nMessageView.setDomApi(MorphdomDomApi);\n```\n\nThe template returns an HTML string containing the View's contents. Morphdom\nmatches children using its normal rules, including element IDs. The adapter\ninstalls HTML directly into an empty root and morphs existing contents using\n`childrenOnly`, leaving the root's attributes under Marionette's control. Use\n`renderAttributes()` to refresh those attributes.\n\n### Lit HTML\n\n```sh\nnpm install marionette@5.0.0-beta.1 @mnjs/adapters@5.0.0-beta.1 lit-html\n```\n\n```js\nimport { View } from 'marionette';\nimport { html } from 'lit-html';\nimport LitDomApi from '@mnjs/adapters/dom/lit-html';\n\nconst MessageView = View.extend({\n  template: ({ message }) => html`<p>${message}</p>`,\n  templateContext: { message: 'Hello again.' }\n});\nMessageView.setDomApi(LitDomApi);\n```\n\nConfigure a View subclass before creating its instances. Further subclasses\ninherit the adapter. Neither DOM adapter modifies View methods or needs\na View reference: template evaluation stays in the renderer and the returned\nvalue goes to `Dom.setContents(el, value)`.\n\nLit async directives can own subscriptions and other resources. Marionette calls\n`Dom.notifyAttach(el)` and `Dom.notifyDetach(el)` through its existing attachment\nmonitoring. Lit translates these notifications to its directive connection API.\nDetaching and destroying a View disconnects its directives while preserving\nthe View root. A View keeps its initial element for its lifetime.\nDestroying an already constructed View also disconnects resources created before\nan explicit render failed. Failed construction does not roll back initialization.\n\nKeep `monitorViewEvents` enabled on the View and its ancestors and manage\nattachment through Regions. If you disable monitoring or remove its handlers\nwith `off()`, the application must call the adapter's attachment methods itself.\nThere is no separate hidden cleanup listener. Lifecycle overrides must call\nparent methods, as with other Marionette lifecycle overrides.\n\nThe first explicit render replaces preexisting contents; this is not hydration.\nSubsequent renders update Lit's marked range. A disconnected element can be\nadopted by another View using the same adapter without erasing its contents.\nRelease the previous owner first; one element cannot have two active View owners.\nLit event handlers use Lit's normal element receiver; use closures when a\nhandler needs application or View state. Do not independently replace Lit's\ncontents or switch content adapters after rendering.\n\n\n[Canonical source](/docs/markdown/packages/adapters/readme.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/common.md",
      "title": "Common methods",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/common/",
      "markdownUrl": "https://marionettejs.com/docs/common.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/common.md",
      "sourceSha256": "7187e547873539242ce1391e3d2af96c81a334c86900ba9a14c336e638775df6",
      "sha256": "db7325305bfd423933d588166774c1307172d38f160978df9386ee4984195440",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 7187e547873539242ce1391e3d2af96c81a334c86900ba9a14c336e638775df6. -->\n\n# Common Marionette Functionality\n\nMarionette classes share a small set of lifecycle, event, request, and option\nhelpers.\n\n## Documentation Index\n\n* [Shared helpers](#shared-helpers)\n* [initialize](#initialize)\n* [extend](#extend)\n* [Events API](#events-api)\n* [triggerMethod](#triggermethod)\n* [bindEvents](#bindevents)\n* [unbindEvents](#unbindevents)\n* [bindRequests](#bindrequests)\n* [unbindRequests](#unbindrequests)\n* [normalizeMethods](#normalizemethods)\n* [getOption](#getoption)\n* [mergeOptions](#mergeoptions)\n* [The `options` Property](#the-options-property)\n\n## Shared helpers\n\nThe reusable option, binding, and event helpers are also available from\n`@mnjs/utils` for components outside Marionette's classes:\n\n```javascript\nimport { getOption, normalizeMethods } from '@mnjs/utils';\n\nconst component = {\n  options: { label: 'Inbox' },\n  getOption,\n  normalizeMethods,\n  onOpen() {}\n};\n\ncomponent.getOption('label'); // 'Inbox'\ncomponent.normalizeMethods({ open: 'onOpen' });\n```\n\nInstall `@mnjs/utils` directly when importing it in an application. Use the\nsame version as Marionette during prereleases. Core and native data depend on this\npackage and use the same implementations. Helpers that read `this` can be mixed\ninto a component or invoked with `.call(component, ...)`.\n\n### `initialize`\n\n`initialize` is a no-op method that you can override on any Marionette class.\nIt is called when the class is instantiated and receives the constructor\narguments unchanged. The first argument is conventionally an options object.\nUse [`getOption`](#getoption) to read that object together with class defaults.\n\n```javascript\nimport { MnObject } from 'marionette';\n\nconst MyObject = MnObject.extend({\n  initialize(options, secondArgument) {\n    console.log(options.foo, this.getOption('foo'), secondArgument);\n  }\n});\n\nnew MyObject({ foo: 'bar' }, 'baz'); // logs \"bar\" \"bar\" \"baz\"\n```\n\n### `extend`\n\n`extend` is available on Marionette class definitions for\n[class-based inheritance](/docs/basics.md#class-based-inheritance).\n\n### Events API\n\nMarionette classes include Marionette's owned [Events API](/docs/events.md). Each\nclass can emit events and listen to other objects that implement the compatible\nevent interface, including native Backbone emitters. The separate\n[`Backbone integration`](/docs/events.md#backbone-interop) selects data reads and\ncollection observation; the core Events API does not require Backbone.\n\nThe Events API should not be confused with [view `events`](/docs/dom-interactions.md#view-events),\nwhich capture DOM events.\n\n### `triggerMethod`\n\n`triggerMethod` calls a matching method and then triggers an event on the\nobject. The first letter of each event-name segment is capitalized and `on` is\nprepended:\n\n* `triggerMethod('foo')` calls `onFoo` and triggers `foo`.\n* `triggerMethod('before:foo')` calls `onBeforeFoo` and triggers `before:foo`.\n\nArguments after the event name are passed to both the method and event. The\nmatching method is resolved through `getOption`, runs first with the Marionette\nobject as its context, and supplies the return value of `triggerMethod`. If that\nmethod throws, the event is not triggered.\n\n```javascript\nimport { MnObject } from 'marionette';\n\nconst MyObject = MnObject.extend({\n  onFoo(value) {\n    return value.toUpperCase();\n  }\n});\n\nconst object = new MyObject();\nobject.on('foo', value => console.log(value));\n\nobject.triggerMethod('foo', 'bar'); // logs \"bar\" and returns \"BAR\"\n```\n\nSee the [Marionette events documentation](/docs/events.md#triggermethod) for the\ncomplete event and method-handler contract.\n\n### `bindEvents`\n\n`bindEvents(entity, bindings)` uses the Marionette object's `listenTo` API to\nbind events from another compatible event emitter. The binding map associates\nevent names with functions or method names on the listening object. The method\nreturns the listening object.\n\nMarionette classes and [Radio](/docs/radio.md) channels implement the required\nevent interface. Backbone models, collections, and other Backbone emitters can\nparticipate directly through compatible `on` and `off` methods. Configure the\n[`Backbone integration`](/docs/events.md#backbone-interop) separately when a View\nalso needs Backbone data reads, serialization, or collection observation.\n\nBinding maps follow the declared object contract. An own enumerable `__proto__`\nevent name is rejected with code `MN0026` before any listener is added. This restriction applies only to entity-event maps;\nMarionette's direct Events API supports `__proto__` as an ordinary event name.\n\n### `unbindEvents`\n\n`unbindEvents(entity, bindings)` stops the subscriptions represented by a\nbinding map. Without a binding map, it stops every subscription that this\nMarionette object established to that entity. It does not remove listeners\nowned by other objects or direct handlers registered on the entity. The method\nreturns the listening object.\n\nWhen selectively unbinding with a map, an own enumerable `__proto__` event name\nis rejected with `MarionetteError` code `MN0026` before any listener is removed.\n\n### `bindRequests`\n\n`bindRequests(channel, bindings)` registers replies on a [Radio](/docs/radio.md)\nchannel. The binding map associates request names with functions or method names\non the Marionette object. Reply methods run with that object as their context,\nand `bindRequests` returns the object.\n\nBinding maps follow the declared object contract. String-named handlers must\nresolve to callable methods on the receiver.\n\n### `unbindRequests`\n\n`unbindRequests(channel, bindings)` removes the replies represented by a\nbinding map. Without a binding map, it removes every reply owned by this object\nfrom that channel. Replies owned by other objects remain registered. The method\nreturns the object.\n\n> **Warning:** Request bindings created manually retain their owner as reply\n> context. To avoid memory leaks, call `unbindRequests` in or before\n> `onBeforeDestroy`, and whenever a shorter binding lifetime ends.\n\n`MnObject` and `Application` instead support the declarative `channelName`,\n`radioEvents`, and `radioRequests` options; those owned bindings are cleaned up\nwhen the owner is destroyed. A `View` using `bindRequests` directly should call\n`unbindRequests` as part of its own cleanup.\n\nThe following example shows both event and request bindings remaining scoped to\ntheir owner.\n\n<!-- executable-example: common-owner-bindings -->\n```javascript\nimport { MnObject, Radio } from 'marionette';\n\nconst source = new MnObject();\nconst channel = Radio.channel('common-owner-bindings');\nconst unrelatedMessages = [];\n\nsource.on('status', value => unrelatedMessages.push(value));\nchannel.reply('status:other', () => 'other');\n\nconst Owner = MnObject.extend({\n  initialize() {\n    this.messages = [];\n    this.bindEvents(source, { status: 'onStatus' });\n    this.bindRequests(channel, { 'status:current': 'getStatus' });\n  },\n\n  onStatus(value) {\n    this.messages.push(value);\n  },\n\n  getStatus() {\n    return this.messages[this.messages.length - 1];\n  }\n});\n\nconst owner = new Owner();\nsource.trigger('status', 'ready');\nconst ownerReply = channel.request('status:current'); // \"ready\"\n\nowner.unbindEvents(source);\nowner.unbindRequests(channel);\nsource.trigger('status', 'after');\n\nconst ownerReplyAfterCleanup = channel.request('status:current'); // undefined\nconst unrelatedReplyAfterCleanup = channel.request('status:other'); // \"other\"\n\nexport {\n  Radio,\n  owner,\n  ownerReply,\n  ownerReplyAfterCleanup,\n  unrelatedMessages,\n  unrelatedReplyAfterCleanup\n};\n```\n\n### `normalizeMethods`\n\n`normalizeMethods(bindings)` returns a fresh map with method-name strings\nreplaced by function references from the Marionette object. Only the map's own\nenumerable string keys are normalized; inherited, symbol, and non-enumerable\nproperties are ignored. A literal own `__proto__` entry remains a handler key\nwithout changing the returned object's prototype.\n\nEvery supplied handler must be a function or a string that resolves to a\ncallable own or inherited method on the binding context. Otherwise Marionette\nthrows `MarionetteError` with code `MN0019`. This invariant also applies to\nevent and request binding maps, including their unbind operations, and to model,\ncollection, Radio, and child-view event bindings.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  initialize() {\n    this.normalizedActions = this.normalizeMethods({\n      'action:one': 'handleActionOne',\n      'action:two': this.handleActionTwo\n    });\n  },\n\n  handleActionOne() {\n    console.log('action:one');\n  },\n\n  handleActionTwo() {\n    console.log('action:two');\n  }\n});\n```\n\n### `getOption`\n\n`getOption(name)` first reads the named value from the merged `options` object.\nIf that value is `undefined`, it falls back to the same property on the\ninstance or its prototype. Explicit option values such as `null`, `false`, `0`,\nand an empty string are returned without falling back. Function values are\nreturned without being invoked.\n\n### `mergeOptions`\n\n`mergeOptions(options, keys)` copies selected option values directly onto the\nclass instance. `keys` must be an array when options are present. Only requested\nown enumerable string properties with values other than `undefined` are copied; inherited, symbol,\nand non-enumerable properties are ignored.\n\n### The `options` Property\n\nA class-level `options` property supplies defaults. Marionette creates a fresh\n`this.options` object for each instance by merging those defaults with the\nconstructor options; constructor values take precedence. The `options` argument\nreceived by `initialize` remains the raw object supplied by the caller, so use\n`getOption` when class defaults must be included.\n\n`mergeOptions` is separate: it copies only named values directly onto the\ninstance for APIs that need instance properties.\n\n<!-- executable-example: common-options -->\n```javascript\nimport { MnObject } from 'marionette';\n\nconst service = { name: 'example' };\nconst Example = MnObject.extend({\n  enabled: true,\n  options: {\n    mode: 'default'\n  },\n\n  initialize(options) {\n    this.rawMode = options.mode;\n    this.mergeOptions(options, ['service']);\n  }\n});\n\nconst example = new Example({\n  enabled: false,\n  service,\n  extra: 'kept only in this.options'\n});\nconst rawMode = example.rawMode; // undefined\n\nexample.getOption('mode'); // \"default\"\nexample.getOption('enabled'); // false\nexample.getOption('extra'); // \"kept only in this.options\"\nconsole.log(example.service === service); // true\n\nexport { example, rawMode, service };\n```\n\n## Marionette Classes\n\nMarionette provides classes for building a view tree and application structure.\n\n[Continue Reading...](/docs/classes.md).\n\n\n[Canonical source](/docs/markdown/docs/common.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/events.md",
      "title": "Events",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/events/",
      "markdownUrl": "https://marionettejs.com/docs/events.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/events.md",
      "sourceSha256": "ecc54967f0964ae721d16a769db30016986a252eb391da5f3380f7d3b6b5adc3",
      "sha256": "c3bd1948bed6caf6ac6e9a4eafa49f02072d3b9ed1980d7b23145c244faea4ac",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 ecc54967f0964ae721d16a769db30016986a252eb391da5f3380f7d3b6b5adc3. -->\n\n# Marionette Events\n\nMarionette provides its own `Events` primitive for communication between\nobjects. It is exported from `marionette`, mixed into every\n[Marionette class](/docs/classes.md), and does not require Backbone. These object\nevents are separate from [DOM events](/docs/dom-interactions.md#canonical-view-interaction).\n\n## Documentation Index\n\n* [Triggering and Listening to Events](#triggering-and-listening-to-events)\n  * [Events API](#events-api)\n  * [`triggerMethod`](#triggermethod)\n  * [Listening to Events](#listening-to-events)\n    * [`onEvent` Binding](#onevent-binding)\n  * [Backbone interop](#backbone-interop)\n  * [Private bookkeeping](#private-bookkeeping)\n  * [View events and triggers](#view-events-and-triggers)\n  * [View entity events](#view-entity-events)\n* [Child View Events](#child-view-events)\n  * [Event Bubbling](#event-bubbling)\n    * [Using CollectionView](#using-collectionview)\n  * [A Child View's Event Prefix](#a-child-views-event-prefix)\n  * [Explicit Event Listeners](#explicit-event-listeners)\n    * [Attaching Functions](#attaching-functions)\n    * [Using `CollectionView`'s `childViewEvents`](#using-collectionviews-childviewevents)\n  * [Triggering Events on Child Events](#triggering-events-on-child-events)\n    * [Using `CollectionView`'s `childViewTriggers`](#using-collectionviews-childviewtriggers)\n* [Lifecycle Events](#lifecycle-events)\n\n## Triggering and Listening to Events\n\nUse the `Events` export directly when a plain object needs Marionette's event\nAPI, or use the same methods already present on a Marionette class.\n\n```javascript\nimport { Events, MnObject } from 'marionette';\n\nconst emitter = Object.assign({}, Events);\nconst listener = new MnObject();\n\nlistener.listenTo(emitter, 'status:changed', status => {\n  console.log(status);\n});\n\nemitter.trigger('status:changed', 'ready');\nlistener.stopListening(emitter);\n```\n\n### Events API\n\n| Method | Purpose |\n| --- | --- |\n| `on(name, callback, context?)` | Register a callback on this object. |\n| `off(name?, callback?, context?)` | Remove matching callbacks registered with `on`. |\n| `trigger(name, ...args)` | Trigger one or more named events. |\n| `once(name, callback, context?)` | Register a callback that is removed after its first call. |\n| `listenTo(object, name, callback)` | Listen to another emitter while tracking the relationship on this object. |\n| `stopListening(object?, name?, callback?)` | Remove relationships created with `listenTo` or `listenToOnce`. |\n| `listenToOnce(object, name, callback)` | Listen to another emitter once. |\n| `triggerMethod(name, ...args)` | Trigger an event and call its matching `onEventName` method. |\n\n`trigger`, `on`, `off`, `once`, `listenTo`, `listenToOnce`, and\n`stopListening` accept space-separated event names. `triggerMethod` delegates\nto `trigger` for listener notification, but call it once per event when you\nneed matching `onEventName` methods. Object-form `trigger` maps each key to the\nsingle value passed to that event's handlers:\n\n```javascript\nemitter.on('start stop', value => console.log(value));\nemitter.trigger('start stop', 'manual');\n\nemitter.trigger({\n  start: 'automatic',\n  stop: 'complete'\n});\n```\n\nDuring a multi-name or mapped `trigger` call, calling `off()` from a handler\nremoves subscriptions for subsequent calls but does not cancel the remaining\nevent names in the current call. For example, `off()` inside a `start` handler\nstill allows the existing `stop` handlers in `trigger('start stop')` to run.\nCalling `off('stop', handler)` inside `start` instead removes that handler before\n`stop` is dispatched. A nested `trigger` call uses the current subscriptions.\n\n`once` registers its generated callback through the object's overridable\n`on` method, and `listenToOnce` registers through overridable `listenTo`.\nThis preserves the extension points used by event-lifecycle mixins. Likewise,\n`listenTo` and `stopListening` call an emitter's documented three-argument\n`on` and `off` methods exactly once per binding.\n\n### `triggerMethod`\n\n`triggerMethod` invokes the matching `onEventName` method when it exists, then\nfires the named event on the instance. If there are no listeners or\nmatching method, the call still succeeds. All arguments after the event name\nare passed to both the method and event handlers.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  callMethod(myString) {\n    console.log(myString + ' was passed');\n  }\n});\n\nconst myView = new MyView();\nmyView.on('something:happened', myView.callMethod);\n\n/* Calls callMethod('foo'); */\nmyView.triggerMethod('something:happened', 'foo');\n```\n\n**The `triggerMethod` method is available to [all Marionette classes](/docs/common.md#triggermethod).**\n\n### Listening to Events\n\nUse `on` to register a callback directly on an emitter:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  initialize() {\n    this.on('event:happened', this.logCall);\n  },\n\n  logCall(myVal) {\n    console.log(myVal);\n  }\n});\n```\n\nUse `listenTo` when the listener should own and later clean up the subscription:\n\n```javascript\nimport { View } from 'marionette';\n\nconst OtherView = View.extend({\n  initialize({ source }) {\n    this.listenTo(source, 'event:happened', this.logCall);\n  },\n\n  logCall(myVal) {\n    console.log(myVal);\n  }\n});\n\nconst MyView = View.extend();\n\nconst myView = new MyView();\n\nconst otherView = new OtherView({ source: myView });\n\nmyView.triggerMethod('event:happened', 'someValue'); // Logs 'someValue'\n```\n\n`listenTo` calls the callback with the listener as its context and records the\nrelationship for `stopListening`. A direct `on` subscription must be removed\nwith `off` when it is no longer needed. Marionette view lifecycles also clean up\ntheir tracked `listenTo` relationships during destruction.\n\n### Backbone interop\n\nBackbone models and collections are observable event sources. Marionette\n`listenTo` and `stopListening` work directly with their native event interface,\nwithout changing Backbone. Select the integration separately when a View needs\nBackbone model reads, serialization, or structural collection observation:\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst model = new Backbone.Model();\nconst view = new View({ model });\n\nview.listenTo(model, 'change', () => {\n  // ...\n});\n```\n\nThe integration subscribes through Backbone's native event methods. It does not\nmodify Backbone objects or prototypes, so existing listeners and Backbone's\nown listener bookkeeping remain intact. Marionette `listenTo` and\n`stopListening` interoperate with native Backbone objects, and Backbone can\nlikewise listen to Marionette evented objects.\n\n### Event names\n\nEvent callbacks are dispatched only when they were explicitly registered with\n`on`, `once`, `listenTo`, or `listenToOnce`. Names that also exist on\n`Object.prototype`, including `constructor`, `toString`, and `__proto__`, are\nordinary event names and do not affect the event store's prototype. Remove them\nthrough the corresponding `off` or `stopListening` API as with any other name.\n\n### Private bookkeeping\n\nMarionette stores event internals under `_rdEvents`, `_rdListeningTo`,\n`_rdListeners`, and `_rdListenId`. These fields are private and replace the\nBackbone-shaped `_events`, `_listeningTo`, and `_listenId` names. Plugins should\nuse `on`, `off`, `listenTo`, and `stopListening` instead of reading or writing\neither set of private fields.\n\n#### `onEvent` Binding\n\nIn addition to triggering listeners, `triggerMethod` can call specially named\nmethods on the instance. For\nexample, a view that has been rendered will internally fire `view.triggerMethod('render')`\nand call `onRender` - providing a handy way to add behavior to your views.\n\nDetermining what method an event will call is easy, we will outline this with an\nexample using `before:dom:refresh` though this also works with any custom events\nyou want to fire:\n\n1. Split the words around the `:` characters - so `before`, `dom`, `refresh`\n2. Capitalize the first letter of each word - `Before`, `Dom`, `Refresh`\n3. Add a leading `on` - `on`, `Before`, `Dom`, `Refresh`\n4. Mash it into a single call - `onBeforeDomRefresh`\n\nUsing this process, `before:dom:refresh` will call the `onBeforeDomRefresh`\nmethod. Let's see it in action with a custom event:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  onMyEvent(myVal) {\n    console.log(myVal);\n  }\n});\n\nconst myView = new MyView();\n\nmyView.triggerMethod('my:event', 'someValue'); // Logs 'someValue'\n```\n\nAs before, all arguments passed into `triggerMethod` after the event name will make\ntheir way into the event handler. `triggerMethod` does not establish or clean up subscriptions;\nuse `listenTo` and owner teardown, or explicit `off`, for listener cleanup.\n\n### View `events` and `triggers`\n\nViews can automatically bind DOM events to methods and View events with [`events`](/docs/dom-interactions.md#view-events)\nand [`triggers`](/docs/dom-interactions.md#view-triggers) respectively:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  events: {\n    'click a': 'showModal'\n  },\n\n  triggers: {\n    'keyup input': 'data:entered'\n  },\n\n  showModal(event) {\n    console.log('Show the modal');\n  },\n\n  onDataEntered(view, event) {\n    console.log('Data was entered');\n  }\n});\n```\n\nFor more information, see the [DOM interactions documentation](/docs/dom-interactions.md#canonical-view-interaction).\n\n### View entity events\n\nViews can automatically bind to its model or collection with [`modelEvents`](/docs/entity-events.md)\nand [`collectionEvents`](/docs/entity-events.md) respectively.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  modelEvents: {\n    'change:someattribute': 'onChangeSomeattribute'\n  },\n\n  collectionEvents: {\n    'update': 'onCollectionUpdate'\n  },\n\n  onChangeSomeattribute() {\n    console.log('someattribute was changed');\n  },\n\n  onCollectionUpdate() {\n    console.log('models were added or removed in the collection');\n  }\n});\n```\n\nFor more information, see the [Entity events documentation](/docs/entity-events.md).\n\n## Child View Events\n\nThe [`View`](/docs/view.md) and [`CollectionView`](/docs/collection-view.md)\ncan handle events from their direct managed children through `childViewEvents`,\nforward selected names through `childViewTriggers`, or opt into a prefix through\n`childViewEventPrefix`. Without one of those configurations, a parent does not\nautomatically forward every child event. For example:\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nconst ChildView = View.extend({\n  tagName: 'li',\n  template: () => '<a href=\"#details\">Select</a>',\n\n  triggers: {\n    'click a': 'select:model'\n  }\n});\n\nconst ListView = CollectionView.extend({\n  tagName: 'ul',\n  childView: ChildView,\n\n  childViewEvents: {\n    'select:model': 'modelSelected'\n  },\n\n  modelSelected(childView) {\n    console.log('model selected: ' + childView.model.id);\n  }\n});\n\nconst list = new ListView({ collection: [{ id: 'example' }] }).render();\nlist.el.querySelector('a').click(); // Logs 'model selected: example'\n```\n\n### Event Bubbling\n\nSet `childViewEventPrefix: 'childview'` on a parent to forward every child\nevent as `childview:<eventName>`. The default is `false`, so prefixed forwarding\nis opt-in. Explicit `childViewEvents` and `childViewTriggers` still work when\nthe prefix is disabled. Both `trigger` and `triggerMethod` events can be forwarded.\nThe parent's matching method runs before its event listeners.\n\nEach level must configure the forwarding it needs. Arguments pass through\nunchanged: Marionette does not prepend the child instance to arbitrary events.\nDOM `triggers` already supply `(view, event)`, while a custom event must explicitly\nsupply its View when handlers need it.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: false,\n  triggers: {\n    click: 'click:view'\n  },\n\n  doSomething() {\n    this.triggerMethod('did:something', this);\n  }\n});\n\nconst ParentView = View.extend({\n  template: () => '<div class=\"foo-hook\"></div>',\n  childViewEventPrefix: 'childview',\n  regions: {\n    foo: '.foo-hook'\n  },\n\n  onRender() {\n    this.showChildView('foo', new MyView());\n  },\n\n  onChildviewClickView(childView) {\n    console.log('View clicked ' + childView);\n  },\n\n  onChildviewDidSomething(childView) {\n    console.log('Something was done to ' + childView);\n  }\n});\n```\n\n**NOTE** `triggers` will automatically pass the child view as an argument to the parent view, however `triggerMethod` will not, and so notice that in the above example, the `triggerMethod` explicitly passes the child view.\n\n#### Using `CollectionView`\n\nThe same opt-in applies to a `CollectionView` and its `childView`:\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nconst MyChild = View.extend({\n  template: false,\n  triggers: {\n    click: 'click:child'\n  }\n});\n\nconst MyList = CollectionView.extend({\n  childView: MyChild,\n  childViewEventPrefix: 'childview',\n  onChildviewClickChild(childView) {\n    console.log('Childview ' + childView + ' was clicked');\n  }\n});\n```\n\n### A Child View's Event Prefix\n\nYou can customize the event prefix for events that are forwarded\nthrough the view. To do this, set the `childViewEventPrefix`\non the view or collectionview. For more information on the `childViewEventPrefix` see\n[Event bubbling](#event-bubbling).\n\nThe default value for `childViewEventPrefix` is `false`. It disables prefixed\nforwarding, while explicit child event maps remain active.\n\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst MyChildView = View.extend({ template: () => 'Child' });\nconst MyCollectionView = CollectionView.extend({\n  childViewEventPrefix: 'some:prefix',\n  childView: MyChildView\n});\nconst collectionView = new MyCollectionView({ collection: [{}] });\n\ncollectionView.on('some:prefix:render', childView => {\n  console.log('Child rendered', childView);\n});\ncollectionView.render();\n```\n\nThe `childViewEventPrefix` can be provided in the view definition or\nin the constructor function call, to get a view instance.\n\n### Explicit Event Listeners\n\nTo call specific functions on event triggers, use the `childViewEvents`\nattribute to map child events to methods on the parent view. This takes events\nfired on child views - _without the `childview:` prefix_ - and calls the\nmethod referenced or attached function.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: false,\n  triggers: {\n    click: 'view:clicked'\n  }\n});\n\nconst ParentView = View.extend({\n  template: () => '<div class=\"foo-hook\"></div>',\n  regions: {\n    foo: '.foo-hook'\n  },\n\n  childViewEvents: {\n    'view:clicked': 'displayMessage'\n  },\n\n  onRender() {\n    this.showChildView('foo', new MyView());\n  },\n\n  displayMessage(childView) {\n    console.log('Displaying message for ' + childView);\n  }\n});\n```\n\n#### Attaching Functions\n\nThe `childViewEvents` attribute can also attach functions directly to be event\nhandlers:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  template: false,\n  triggers: {\n    click: 'view:clicked'\n  }\n});\n\nconst ParentView = View.extend({\n  template: () => '<div class=\"foo-hook\"></div>',\n  regions: {\n    foo: '.foo-hook'\n  },\n\n  childViewEvents: {\n    'view:clicked'(childView) {\n      console.log('Function called for ' + childView);\n    }\n  },\n\n  onRender() {\n    this.showChildView('foo', new MyView());\n  }\n});\n```\n\n#### Using `CollectionView`'s `childViewEvents`\n\n```javascript\nimport { CollectionView } from 'marionette';\n\n// childViewEvents can be specified as a hash...\nconst MyCollectionView = CollectionView.extend({\n  childViewEvents: {\n    // This callback will be called whenever a child is rendered or emits a `render` event\n    render() {\n      console.log('A child view has been rendered.');\n    }\n  }\n});\n```\n\n### Triggering Events on Child Events\n\nA `childViewTriggers` hash or method permits proxying of child view events without manually\nsetting bindings. Each own map key selects a child event, and its value names the event\nto trigger on the parent. Inherited entries are ignored. `childViewEvents` also\nnormalizes only own enumerable string keys.\n\n`childViewTriggers` is sugar on top of [`childViewEvents`](#explicit-event-listeners) much\nin the same way that [view `triggers`](/docs/dom-interactions.md#view-triggers) are sugar for [view `events`](/docs/dom-interactions.md#view-events).\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\n// The child view fires a custom event, `show:message`\nconst ChildView = View.extend({\n  template: () => '<button class=\"button\">Message</button><form><button>Submit</button></form>',\n\n  // Events hash defines local event handlers that in turn may call `triggerMethod`.\n  events: {\n    'click .button': 'onClickButton'\n  },\n\n  triggers: {\n    'submit form': 'submit:form'\n  },\n\n  onClickButton () {\n    // Both `trigger` and `triggerMethod` events will be caught by parent.\n    this.trigger('show:message', 'foo');\n    this.triggerMethod('show:message', 'bar');\n  }\n});\n\n// The parent forwards the child's event through childViewTriggers.\nconst ParentView = CollectionView.extend({\n  childView: ChildView,\n\n  childViewTriggers: {\n    'show:message': 'child:show:message',\n    'submit:form': 'child:submit:form'\n  },\n\n  onChildShowMessage (message) {\n    console.log('A child view fired show:message with ' + message);\n  },\n\n  onChildSubmitForm (childView) {\n    console.log('A child view fired submit:form');\n  }\n});\n\nconst GrandParentView = View.extend({\n  template: () => '<div class=\"list\"></div>',\n  regions: {\n    list: '.list'\n  },\n\n  onRender() {\n    this.showChildView('list', new ParentView({\n      collection: this.collection\n    }));\n  },\n\n  childViewEvents: {\n    'child:show:message': 'showMessage'\n  },\n\n  showMessage(message) {\n    console.log('A child sent: ' + message);\n  }\n});\n```\n\n#### Using `CollectionView`'s `childViewTriggers`\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\n// The child view fires a custom event, `show:message`\nconst ChildView = View.extend({\n  template: () => '<button class=\"button\">Message</button><form><button>Submit</button></form>',\n\n  // Events hash defines local event handlers that in turn may call `triggerMethod`.\n  events: {\n    'click .button': 'onClickButton'\n  },\n\n  // Triggers hash converts DOM events directly to view events catchable on the parent.\n  // Note that `triggers` automatically pass the first argument as the child view.\n  triggers: {\n    'submit form': 'submit:form'\n  },\n\n  onClickButton () {\n    // Both `trigger` and `triggerMethod` events will be caught by parent.\n    this.trigger('show:message', 'foo');\n    this.triggerMethod('show:message', 'bar');\n  }\n});\n\n// The parent forwards the child's event through childViewTriggers.\nconst ParentView = CollectionView.extend({\n\n  childView: ChildView,\n\n  childViewTriggers: {\n    'show:message': 'child:show:message',\n    'submit:form': 'child:submit:form'\n  },\n\n  onChildShowMessage (message) {\n    console.log('A child view fired show:message with ' + message);\n  },\n\n  onChildSubmitForm (childView) {\n    console.log('A child view fired submit:form');\n  }\n});\n```\n\n## Lifecycle Events\n\nMarionette Views fire events during their creation and destruction lifecycle.\nFor more information see the documentation covering the\n[`View` Lifecycle](/docs/lifecycle.md).\n\n\n[Canonical source](/docs/markdown/docs/events.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/events.class.md",
      "title": "Class events",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/class-events/",
      "markdownUrl": "https://marionettejs.com/docs/class-events.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/events.class.md",
      "sourceSha256": "1985e744dbd49b2c2cd47afd9ae2364e60ad457961cc408c52b19ff6d1d8a6e7",
      "sha256": "cb7f4384ed8b3aa6446122cbd6924689564d3639ffbab50c753c138c765b26fc",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 1985e744dbd49b2c2cd47afd9ae2364e60ad457961cc408c52b19ff6d1d8a6e7. -->\n\n# Class Events\n\nClass events let you respond as a view renders, a Region shows a view, or an\nApplication starts and stops. Marionette uses\n[`triggerMethod`](/docs/events.md#triggermethod) to dispatch these events, so you can\nlisten to an event or define its matching\n[`onEvent` method](/docs/events.md#onevent-binding).\n\nArguments depend on the event. Use the signatures below rather than assuming\nthe first argument is the instance that triggered it; for example, a Behavior's\nproxied view events receive the host view.\n\n## Documentation Index\n\n* [Application Events](#application-events)\n  * [`before:start` event](#beforestart-event)\n  * [`start` event](#start-event)\n  * [`before:stop` event](#beforestop-event)\n  * [`stop` event](#stop-event)\n* [Behavior Events](#behavior-events)\n  * [`initialize` event](#initialize-event)\n  * [Proxied Events](#proxied-events)\n* [Region Events](#region-events)\n  * [`show` and `before:show` events](#show-and-beforeshow-events)\n  * [`empty` and `before:empty` events](#empty-and-beforeempty-events)\n* [MnObject Events](#mnobject-events)\n* [View Events](#view-events)\n  * [`add:region` and `before:add:region` events](#addregion-and-beforeaddregion-events)\n  * [`remove:region` and `before:remove:region` events](#removeregion-and-beforeremoveregion-events)\n* [CollectionView Events](#collectionview-events)\n  * [`add:child` and `before:add:child` events](#addchild-and-beforeaddchild-events)\n  * [`remove:child` and `before:remove:child` events](#removechild-and-beforeremovechild-events)\n  * [`sort` and `before:sort` events](#sort-and-beforesort-events)\n  * [`filter` and `before:filter` events](#filter-and-beforefilter-events)\n  * [`render:children` and `before:render:children` events](#renderchildren-and-beforerenderchildren-events)\n  * [`destroy:children` and `before:destroy:children` events](#destroychildren-and-beforedestroychildren-events)\n  * [CollectionView EmptyView Region Events](#collectionview-emptyview-region-events)\n* [DOM Change Events](#dom-change-events)\n  * [`render` and `before:render` events](#render-and-beforerender-events)\n  * [`attach` and `before:attach` events](#attach-and-beforeattach-events)\n  * [`detach` and `before:detach` events](#detach-and-beforedetach-events)\n  * [`dom:refresh` event](#domrefresh-event)\n  * [`dom:remove` event](#domremove-event)\n  * [Advanced Event Settings](#advanced-event-settings)\n* [Destroy Events](#destroy-events)\n  * [`destroy` and `before:destroy` events](#destroy-and-beforedestroy-events)\n* [Wrapping legacy views](#wrapping-legacy-views)\n\n## Application Events\n\nApplication events describe its asynchronous lifecycle. Use a readiness method\nwhen completion must wait for work; event-listener return values are not awaited.\n\n### `before:start` event\n\nReceives `(application, options, context)` before startup completes. The matching\n`onBeforeStart(application, options, { signal })` method may return a Promise to\ndelay readiness. Pass the signal to cancellable work and prevent stale results\nfrom committing application side effects.\n\n### `start` event\n\nReceives `(application, options)` after readiness and owned child startup complete.\nThe matching `onStart(application, options)` method can show the feature's View.\nBoth are completion notifications; their return values are not awaited.\n\nUse the [Application lifecycle example](/docs/application.md#starting-an-application)\nfor startup and the [routing guide](/docs/routing.md) to connect an application's\nrouter. Starting a history service is application setup, not a Marionette lifecycle\nrequirement.\n\nThe `options` passed to a lifecycle operation reach its hooks and events.\nReadiness hooks and `before:*` events also receive a context whose signal is\naborted when a later operation invalidates that readiness. A transferred stop\nphase retains its original options, context, and un-aborted signal. Only a Promise\nreturned by `onBeforeStart`, `onBeforeStop`, or `onBeforeDestroy` delays its phase.\nSee [Application lifecycle](/docs/application.md#application-lifecycle)\nfor operation results, ordering, and cancellation.\n\n### `before:stop` event\n\nFired just before the application is stopped. A Promise returned by\n`onBeforeStop` delays completion of the stop lifecycle.\n\n### `stop` event\n\nFired after the application has stopped. This event is a completion\nnotification and its return value is not awaited.\n\n#### Application `destroy` events\n\nThe `Application` class also triggers `before:destroy` and `destroy` as part of\nits [asynchronous lifecycle](/docs/application.md#application-lifecycle).\n`onBeforeDestroy` is awaited and receives `(application, options, context)`;\n`onDestroy` is a completion notification and receives `(application, options)`.\n\n## Behavior Events\n\n### `initialize` event\n\nAfter the view and behavior are [constructed and initialized](/docs/behavior.md#initialize-order),\nthe last event to occur is an `initialize` event on the behavior which is passed\nthe view instance and any options passed to the view at instantiation.\n\n```javascript\nimport { Behavior, View } from 'marionette';\n\nconst MyBehavior = Behavior.extend({\n  onInitialize(view, options) {\n    console.log(options.msg);\n  }\n});\n\nconst MyView = View.extend({\n  behaviors: [MyBehavior]\n});\n\nconst myView = new MyView({ msg: 'view initialized' });\n```\n\n**Note** This event is unique in that the triggering class instance (the view) is not the same instance\nas the handler (the behavior). In most cases internally triggered events are triggered and handled by\nthe same instance, but this is an exception.\n\n### Proxied Events\n\nA `Behavior`'s view events [are proxied directly on the behavior](/docs/behavior.md#proxy-handlers).\n\n**Note** In order to prevent conflict `Behavior` does not trigger [destroy events](#destroy-and-beforedestroy-events)\nwith its own destruction. A `destroy` event occurring on the `Behavior` will have originated from the related view.\n\n## Region Events\n\nWhen you show a view inside a region - either using [`region.show(view)`](/docs/region.md#showing-a-view) or\n[`showChildView('region', view)`](/docs/view.md#showing-a-child-view) - the `Region` will emit events around the view\nevents that you can hook into.\n\nThe `Region` class also triggers [Destroy Events](#destroy-and-beforedestroy-events).\n\n### `show` and `before:show` events\n\nThese events fire before (`before:show`) and after (`show`) showing anything in a region.\nA view may or may not be rendered during `before:show`, but a view will be rendered by `show`.\n\nThe `show` events will receive the region instance, the view being shown, and any options passed to `region.show`.\n\n```javascript\nimport { Region, View } from 'marionette';\n\nconst MyRegion = Region.extend({\n  onBeforeShow(myRegion, view, options) {\n    console.log(myRegion.hasView()); //false\n    console.log(view.isRendered()); // false\n    console.log(options.foo === 'bar'); // true\n  },\n  onShow(myRegion, view, options) {\n    console.log(myRegion.hasView()); //true\n    console.log(view.isRendered()); // true\n    console.log(options.foo === 'bar'); // true\n  }\n});\n\nconst MyView = View.extend({\n  template: () => 'hello'\n});\n\nconst regionElement = document.createElement('div');\nconst myRegion = new MyRegion({ el: regionElement });\n\nmyRegion.show(new MyView(), { foo: 'bar' });\n```\n\n### `empty` and `before:empty` events\n\nThese events fire before (`before:empty`) and after (`empty`) emptying a region's view.\nThese events will not fire if there is no view in the region, even if the region detaches\nDOM from within the region's `el`.\nThe view will not be detached or destroyed during `before:empty`,\nbut will be detached or destroyed during the `empty`.\n\nThe empty events will receive the region instance, the view leaving the region.\n\n```javascript\nimport { Region, View } from 'marionette';\n\nconst MyRegion = Region.extend({\n  onBeforeEmpty(myRegion, view) {\n    console.log(myRegion.hasView()); //true\n    console.log(view.isDestroyed()); // false\n  },\n  onEmpty(myRegion, view) {\n    console.log(myRegion.hasView()); //false\n    console.log(view.isDestroyed()); // true\n  }\n});\n\nconst MyView = View.extend({\n  template: () => 'hello'\n});\n\nconst regionElement = document.createElement('div');\nconst myRegion = new MyRegion({ el: regionElement });\n\nmyRegion.empty(); // no events, no view emptied\n\nmyRegion.show(new MyView());\n\nmyRegion.empty();\n```\n## MnObject Events\n\nThe `MnObject` class triggers [Destroy Events](#destroy-and-beforedestroy-events).\n\n## View Events\n\n### `add:region` and `before:add:region` events\n\nThese events fire before (`before:add:region`) and after (`add:region`) a region is added to a view.\nThis event handler will receive the view instance, the region name string, and the region instance as\nevent arguments. The Region is fully instantiated for both events.\n\n### `remove:region` and `before:remove:region` events\n\nThese events fire before (`before:remove:region`) and after (`remove:region`) a region is removed from a view.\nThis event handler will receive the view instance, the region name string, and the region instance as\nevent arguments. The Region is not yet destroyed in the before event, but is destroyed by `remove:region`.\n\n`removeRegion()` and the View's Region cleanup path emit these events. Destroying\na Region directly does not itself emit the owning View's remove-region events.\n\n## CollectionView Events\n\nThe `CollectionView` triggers unique events specifically related to child management.\n\n### `add:child` and `before:add:child` events\n\nThese events fire before (`before:add:child`) and after (`add:child`) each child\nView is added to [`children`](/docs/collection-view.md#accessing-a-child-view).\nBoth receive `(collectionView, childView)`; the child is already constructed at\n`before:add:child`.\nThese will fire once for each model in the attached collection or for any view added using\n[`addChildView`](/docs/collection-view.md#adding-a-child-view).\n\n### `remove:child` and `before:remove:child` events\n\nThese events fire before (`before:remove:child`) and after (`remove:child`) each child view\nis removed from the [`children`](/docs/collection-view.md#accessing-a-child-view).\nA view may be removed from the `children` if it is destroyed, if it is removed\nfrom the `collection` or if it is removed with [`removeChildView`](/docs/collection-view.md#removing-a-child-view).\n\n**NOTE** A childview may or may not be destroyed by this point.\n\n**NOTE** When a `CollectionView` is destroyed it will not individually remove its `children`.\nEach childview will be destroyed, but any needed clean up during the `CollectionView`'s destruction\nshould happen in [`before:destroy:children`](#destroychildren-and-beforedestroychildren-events).\n\n### `sort` and `before:sort` events\n\nThese events fire before (`before:sort`) and after (`sort`) sorting the children in the `CollectionView`.\nThese events fire when there are managed children and `getComparator()` returns\nan active comparator, including the default comparator for collection order.\nSee [`viewComparator`](/docs/collection-view.md#defining-the-viewcomparator).\n\n### `filter` and `before:filter` events\n\nThese events fire before (`before:filter`) and after (`filter`) filtering the children in the `CollectionView`.\nThis event will only fire if there are [`children`](/docs/collection-view.md#accessing-a-child-view)\nand a [`viewFilter`](/docs/collection-view.md#defining-the-viewfilter).\n\nWhen the `filter` event is fired the children filtered out will have already been\ndetached from the view's `el`, but new children will not yet have been rendered.\nThe `filter` event receives `(collectionView, passingViews, filteredViews)`.\nPassing Views are the selected result; some may already be attached, while new\nones are rendered and attached by the following child-render pass.\n\n```javascript\nimport { CollectionView } from 'marionette';\n\nconst MyCollectionView = CollectionView.extend({\n  onBeforeFilter(myCollectionView) {\n   console.log('Nothing has changed yet!');\n  },\n  onFilter(myCollectionView, passingViews, filteredViews) {\n    console.log('Views passing the filter', passingViews);\n    console.log('Views excluded by the filter', filteredViews);\n  }\n});\n```\n\n### `render:children` and `before:render:children` events\n\nSimilar to [`Region` `show` and `before:show` events](#show-and-beforeshow-events) these events fire\nbefore (`before:render:children`) and after (`render:children`) the `children` of the `CollectionView`\nare attached to the `CollectionView`'s `el` or `childViewContainer`.\n\nThese events will be passed the `CollectionView` instance and the array of views being attached.\nThe views in the array may or may not be rendered or attached for `before:render:children`,\nbut will be rendered and attached by `render:children`.\n\nBoth events receive the complete current presented `children` array, including\nalready-rendered survivors. An empty result still emits both events with an empty\narray while the empty-View Region is updated. “Attached” here means inserted into\nthe CollectionView container; the container itself may be detached from the document.\n\n### `destroy:children` and `before:destroy:children` events\n\nThese events fire before (`before:destroy:children`) and after (`destroy:children`) destroying the children\nin the `CollectionView`. These events will only fire if there are [`children`](/docs/collection-view.md#accessing-a-child-view).\n\n### CollectionView EmptyView Region Events\n\nThe `CollectionView` uses a Region internally to show or destroy its empty View.\nSee [Region Events](#region-events).\n\n```javascript\nimport { CollectionView, View } from 'marionette';\n\nconst MyEmptyView = View.extend({ template: () => 'No items' });\nconst MyView = CollectionView.extend({\n  emptyView: MyEmptyView\n});\n\nconst myView = new MyView();\n\nmyView.getEmptyRegion().on({\n  'show'() {\n    console.log('CollectionView is empty!');\n  },\n  'before:empty'() {\n    if (this.hasView()) {\n      console.log('CollectionView is removing the emptyView');\n    }\n  }\n});\n\nmyView.render();\n```\n\n## DOM Change Events\n\n### `render` and `before:render` events\n\nFor `View`, these events bracket template rendering. For `CollectionView`,\nthey bracket the complete child rebuild/render pass, even without a template.\nBoth receive the instance as their argument.\n\n`before:render` will occur prior to removing any current child views.\n`render` is an ideal event for attaching child views to the view's template as the first\nrender _generally_ occurs prior to the view attaching to the DOM.\n\n```javascript\nimport { View, CollectionView } from 'marionette';\n\nconst MyChildView = View.extend({ template: () => 'Child' });\n\nconst MyView = View.extend({\n  template: () => '<div class=\"foo-region\"></div>',\n  regions: {\n    'foo': '.foo-region'\n  },\n  onRender() {\n    this.showChildView('foo', new MyChildView());\n  }\n});\n\nconst MyCollectionView = CollectionView.extend({\n  childView: MyChildView,\n  onRender() {\n    // Add a child not from the `collection`\n    this.addChildView(new MyChildView());\n  }\n})\n```\n\nAdopting [prerendered contents](/docs/prerendered-dom.md) does not itself emit these\nevents. Use `initialize` for initial child setup on that path. `View#render()`\nreturns without events when `template` is `false`; `CollectionView#render()`\nstill emits its render events when its template is `false` or absent.\n\n### `attach` and `before:attach` events\n\nReflects when the `el` of a view is attached to the DOM. These events will not trigger when\na view is re-rendered as the `el` itself does not change.\n\n`attach` is the ideal event to setup any external DOM listeners such as `jQuery` plugins\nthat use the view's `el`, but _not_ its contents.\n\n### `detach` and `before:detach` events\n\nReflects when the `el` of a view is detached from the DOM. These events will not trigger when\na view is re-rendered as the `el` itself does not change.\n\n`before:detach` is the ideal event to clean up any external DOM listeners such as `jQuery` plugins\nthat use the view's `el`, but _not_ its contents.\n\n### `dom:refresh` event\n\nReflects when the _contents_ of a view's `el` change in the DOM.\nThis event will fire when the view is first [`attach`ed](#attach-and-beforeattach-events).\nIt will also fire if an attached view is re-rendered.\n\nThis is the ideal event to setup any external DOM listeners such as `jQuery` plugins\nthat use DOM _within_ the `el` of the view and not the view's `el` itself.\n\nThe monitor requires both `isAttached()` and `isRendered()` to be true.\nPrerendered contents can establish rendered state, and a CollectionView render\nestablishes it even without a template.\n\n### `dom:remove` event\n\nReflects when the _contents_ of a view's `el` are about to change in the DOM.\nThis event will fire when the view is about to be [`detach`ed](#detach-and-beforedetach-events).\nIt will also fire before an attached view is re-rendered.\n\nThis is the ideal event to clean up any external DOM listeners such as `jQuery` plugins\nthat use DOM _within_ the `el` of the view and not the view's `el` itself.\n\nThe monitor requires both `isAttached()` and `isRendered()` to be true.\nPrerendered contents can establish rendered state, and a CollectionView render\nestablishes it even without a template.\n\n### Advanced Event Settings\n\nMarionette is able to trigger `attach`/`detach` events down the view tree along with\ntriggering the `dom:refresh`/`dom:remove` events because of the view event monitor.\nThis monitor starts when a Marionette View is constructed.\n\nIn some cases it may be a useful performance improvement to disable this functionality.\nDoing so is as easy as setting `monitorViewEvents: false` on the view class.\n\n```javascript\nimport { View } from 'marionette';\n\nconst NonMonitoredView = View.extend({\n  monitorViewEvents: false\n});\n```\n\n**Note**: Disabling the view monitor will break the monitor generated events for this view\n_and all child views_ of this view. Disabling should be done carefully.\n\n## Destroy Events\n\n### `destroy` and `before:destroy` events\n\nEvery class has a `destroy` method which can be used to clean up the instance.\nWith the exception of `Behavior`, each class triggers a `before:destroy` and a\n`destroy` event. Application uses the separate asynchronous lifecycle described\nunder [Application Events](#application-events); this section describes the\nsynchronous owner classes.\n\nAs a general rule, `onBeforeDestroy` is the best handler for cleanup as the instance\nand any internally created children are already destroyed by the time `onDestroy` is called.\n\nFor classes with these lifecycle events, once destruction begins, reentrant\n`destroy()` calls from `before:destroy` or `destroy`, and later repeated calls,\nreturn the same instance without restarting teardown. `isDestroyed()` remains\n`false` during `before:destroy` and is `true` by the time `destroy` is triggered.\nIf a synchronous lifecycle handler throws, its error propagates and teardown\nstops. Later `destroy()` calls do not retry the lifecycle or resume partial\ncleanup. Application's asynchronous operation failures follow its separate\nlifecycle contract.\n\nUse [`dom:remove`](#domremove-event) or [`before:detach`](#detach-and-beforedetach-events)\nfor work tied to those transitions. Resources created while detached, or while\nattachment monitoring is disabled, also need owner cleanup in `onBeforeDestroy`;\ndo not rely on a DOM notification that may never occur.\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  onBeforeDestroy(view, options) {\n    console.log(options.foo);\n  }\n});\n\nconst myView = new MyView();\n\nmyView.destroy({ foo: 'destroy view' });\n```\n\n#### `CollectionView` `destroy:children` and `before:destroy:children` events\n\nSimilar to `destroy`, `CollectionView` has events for when all of its children\nare destroyed. See [the CollectionView's events](#destroychildren-and-beforedestroychildren-events)\nfor more information.\n\n## Wrapping legacy views\n\nManaged children provide Marionette's render and destroy lifecycle themselves.\n`supportsRenderLifecycle` and `supportsDestroyLifecycle` are removed; Regions and\nCollectionViews do not supply missing lifecycle events or call `remove()` as a\nsubstitute for `destroy()`.\n\nKeep non-Marionette views inside a [Marionette wrapper](/docs/region.md#wrapping-a-non-marionette-view)\nthat owns their rendering and cleanup. Mixing `Marionette.Events` into a Backbone\nView does not make it a supported managed child.\n\n\n[Canonical source](/docs/markdown/docs/events.class.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/events.entity.md",
      "title": "Model and collection events",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/entity-events/",
      "markdownUrl": "https://marionettejs.com/docs/entity-events.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/events.entity.md",
      "sourceSha256": "68b17daed92fab3108029e728c6f0263188e55ae860cf25df9a4307754457c00",
      "sha256": "63ba9a71b1af96e01d52a5d8728348872f600b80553144afca5258d5af5e77e4",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 68b17daed92fab3108029e728c6f0263188e55ae860cf25df9a4307754457c00. -->\n\n# Entity events\n\n[`View`, `CollectionView`, and `Behavior`](/docs/classes.md) can declaratively\nlisten to events from an attached `model` or `collection`. The configured\n[`DataApi.subscribe()`](/docs/data-api.md#adapter-contract) owns the entity's\nsubscription and teardown mechanics; Backbone is optional.\n\n## Handler ownership and arguments\n\n`modelEvents` and `collectionEvents` map entity event names to method names or\nfunction callbacks. Entity arguments pass through unchanged.\n\n- A View or CollectionView handler runs with that View or CollectionView as\n  `this`.\n- A Behavior listens to its owning View's `model` and `collection`, but its\n  handler runs with the Behavior as `this`. Use `this.view` to reach the owner.\n\n<!-- executable-example: entity-events-ownership -->\n```javascript\nimport { Behavior, Events, View } from 'marionette';\n\nclass Model {}\nObject.assign(Model.prototype, Events);\n\nconst StatusBehavior = Behavior.extend({\n  modelEvents() {\n    this.modelEventsResolutionCount = (this.modelEventsResolutionCount || 0) + 1;\n    return {\n      'change:status': 'onStatus'\n    };\n  },\n\n  onStatus(model, status) {\n    this.view.behaviorCall = {\n      arguments: [model, status],\n      owner: this\n    };\n  }\n});\n\nconst StatusView = View.extend({\n  behaviors: [StatusBehavior],\n\n  modelEvents() {\n    this.modelEventsResolutionCount = (this.modelEventsResolutionCount || 0) + 1;\n    return {\n      'change:status': 'onStatus'\n    };\n  },\n\n  onStatus(model, status) {\n    this.viewCall = {\n      arguments: [model, status],\n      owner: this\n    };\n  }\n});\n\nconst model = new Model();\nconst view = new StatusView({ model });\n\nmodel.trigger('change:status', model, 'ready');\n\nexport { Model, model, view };\n```\n\nFunction callbacks are also supported directly. This configuration fragment\nuses the `update(collection, options)` payload from Backbone or `@mnjs/data`;\nconfigure the matching DataApi before supplying that collection:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  collectionEvents: {\n    update(collection, options) {\n      console.log('Added models:', options.changes.added);\n    }\n  }\n});\n```\n\nIf a View has both entities, Marionette delegates both maps:\n\n```javascript\nimport { View } from 'marionette';\n\nconst MyView = View.extend({\n  modelEvents: {\n    'change:status': 'render'\n  },\n\n  collectionEvents: {\n    update: 'render'\n  }\n});\n```\n\n## Resolver and delegation lifecycle\n\nEach map may be a function returning an object. Marionette calls the resolver\nwith its owner as `this` and no arguments whenever `delegateEntityEvents()`\nperforms a delegation. The resolved map is cached for the matching\n`undelegateEntityEvents()` call.\n\nInitial entity-event delegation happens after the View or CollectionView's\n`initialize` method returns. Assigning a different `model` or `collection`\nlater does not automatically move existing subscriptions. Undelegate while the\nold entity is still assigned, replace it, and then delegate the new entity:\n\n```javascript\nview.undelegateEntityEvents();\nview.model = replacementModel;\nview.delegateEntityEvents();\n```\n\nDo not use repeated `delegateEntityEvents()` calls as an idempotent refresh;\ndelegate only after the matching undelegation.\n\nAfter a View or CollectionView's destruction completes successfully, its tracked\nentity subscriptions have been removed. Once destruction starts, its base\n`delegateEntityEvents()` returns the same instance without resolving its maps or\ndelegating the attached Behaviors' maps. A direct\n`Behavior#delegateEntityEvents()` call also returns the Behavior without\nresolving maps or binding once its owning View's destruction starts. These\nguards derive from the host lifecycle only; reusing a Behavior after calling\n`Behavior#destroy()` while its host remains live is outside this contract. A\ncustom override owns its behavior unless it delegates to the guarded base\nmethod. `undelegateEntityEvents()` remains available during teardown so cleanup\ncan complete.\n\n## Event-map names\n\nEntity-event maps cannot contain an own enumerable `__proto__` event name.\nMarionette throws `MarionetteError` code `MN0026` before binding or selectively\nunbinding such a map because third-party entity event implementations may not\nsafely store that name.\n\nMarionette does not reject other names inherited from `Object.prototype`, such\nas `constructor` and `toString`. Marionette's Events API supports those names\nand continues to support `__proto__`, but third-party emitters may not safely\nsupport every prototype-collision name.\n\n## Backbone entities\n\nA plain `Backbone.Model` or `Backbone.Collection` satisfies the default\nsubscription protocol for event-only use. The canonical Backbone setup\nconfigures the integration before constructing Marionette consumers;\nit also selects Backbone identity, reads, serialization, ordered model\nsnapshots, and structural observations:\n\n```javascript\nimport BackboneApi from '@mnjs/adapters/backbone';\nimport Backbone from 'backbone';\nimport { setDataApi, View } from 'marionette';\n\nsetDataApi(BackboneApi);\n\nconst model = new Backbone.Model();\nconst view = new View({ model });\n```\n\nSee [Optional Backbone](/docs/backbone.md) for the integration's exact boundary.\n\n\n[Canonical source](/docs/markdown/docs/events.entity.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/radio.md",
      "title": "Radio",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/radio/",
      "markdownUrl": "https://marionettejs.com/docs/radio.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/radio.md",
      "sourceSha256": "a5180c67bddc1c84125b0c7ca7fe9db0efc633b669bab2dfd566db47527a2635",
      "sha256": "0c53fa2091a01f0d52c2ea9c1712dc543ef77dd2a83da10087265f34d38e750b",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 a5180c67bddc1c84125b0c7ca7fe9db0efc633b669bab2dfd566db47527a2635. -->\n\n# Radio\n\nUse `Radio` to send events or request values between parts of an application\nthat do not need a direct reference to each other. Channels keep those messages\norganized by name. Import Radio directly from Marionette:\n\n```javascript\nimport { Radio } from 'marionette';\n```\n\nRadio is included in `marionette`; it does not require a separate\n`backbone.radio` installation.\n\nThe built-in singleton does not share channels with `backbone.radio`. Migrate\nall application imports atomically, including code that publishes or requests\noutside Marionette classes; mixing both packages creates disconnected buses.\nSee [Atomic Radio migration](/docs/upgrade-guide.md#atomic-radio-migration).\n\n## Documentation Index\n\n* [Channels](#channels)\n* [Events](#events)\n* [Requests and Replies](#requests-and-replies)\n* [Debugging](#debugging)\n* [Channel Lifecycle](#channel-lifecycle)\n* [Marionette Integration](#marionette-integration)\n\n## Channels\n\nA channel provides a namespace for events and requests. Retrieve one with\n`Radio.channel(name)`:\n\n```javascript\nimport { Radio } from 'marionette';\n\nconst notifications = Radio.channel('notifications');\n```\n\nCalling `Radio.channel(name)` again with the same name returns the same channel\ninstance. A channel name is required. Channel names that match inherited object\nproperties, such as `toString`, are treated as ordinary channel names.\n\nUse `new Channel(name)` from `@mnjs/radio` for an independent message bus.\nIt combines Events and Requests but does not join the registry. Its owner must\ncall `channel.reset()` when finished. `Radio.reset()` covers registered channels.\nThe named `Channel` export is `Radio.Channel`; an isolated runtime provides its\nown constructor at `runtime.Radio.Channel`.\n\nFor request/reply alone, import `Requests` from `@mnjs/radio` and compose it\nwith `Object.assign({}, Requests)`. It adds no event methods or registry.\n\n## Events\n\nChannels provide event-style messaging with methods including `on`, `once`,\n`off`, `trigger`, `listenTo`, and `stopListening`.\n\n```javascript\nimport { Radio } from 'marionette';\n\nconst session = Radio.channel('session');\n\nsession.on('expired', function(reason) {\n  console.log(`Session expired: ${ reason }`);\n});\n\nsession.trigger('expired', 'signed out remotely');\nsession.off('expired');\n```\n\nUse events when zero or more listeners may react to a notification and the\nsender does not need a return value.\n\n## Requests and Replies\n\nChannels also provide request/reply messaging. Register one reply with\n`reply`, then call it with `request`:\n\n```javascript\nimport { Radio } from 'marionette';\n\nconst account = Radio.channel('account');\nconst accountService = { currentUser: { id: 'example' } };\n\naccount.reply('current:user', function() {\n  return this.currentUser;\n}, accountService);\n\nconst currentUser = account.request('current:user');\n```\n\nArguments passed after the request name are passed to the reply handler, and\nthe handler's return value is returned from `request`. Invocation is synchronous:\na thrown error reaches the caller immediately; a returned Promise is passed\nthrough unchanged and must be awaited or handled by the caller. Radio does not\nadd cancellation, retries, or error handling.\n\nA named handler takes precedence over a handler registered as `default`.\nThe default handler receives `(requestName, ...args)`. With neither handler,\n`request` returns `undefined` and may emit a debug warning. A non-function value\nregistered with `reply(name, value)` is returned as-is for each request.\nRegistering a second reply for the same name replaces the first; it does not\nmulticast the request.\n\n`reply`, `replyOnce`, and `stopReplying` return the channel or Requests receiver.\nA `replyOnce` handler is removed before invocation, including when it throws or\nmakes a reentrant request. Removing it by its original callback before invocation\nalso cancels it. Choose ordinary events when several independent listeners need\nto react to the same notification.\n\nOnly explicitly registered own handlers are eligible for a named request or\nthe `default` fallback. Names matching inherited object properties, including\n`constructor`, `toString`, and `__proto__`, are ordinary request names. Result\nmaps from object-form or space-separated requests likewise define safe own\nstring properties. When an object-form key contains multiple space-separated\nnames, the nested result contributes its own enumerable string and symbol\nproperties; inherited and non-enumerable properties are ignored.\n\nUse `replyOnce` for a handler that should be removed after its first request.\nUse `stopReplying` to remove one or more handlers:\n\n```javascript\naccount.replyOnce('status:ready', () => true);\naccount.stopReplying('current:user');\n```\n\nThe request registration methods retain Backbone.Radio's customization\nseams: `replyOnce` installs its wrapper through overridable `reply`, and map or\nspace-separated `reply`, `replyOnce`, and `stopReplying` calls dispatch each\nentry through the corresponding public method. For object-form `request`, the\nmapped value is the first handler argument and any arguments after the map are\nforwarded after it.\n\nUse requests when one handler owns an operation or when the sender needs a\nreturn value.\n\n## Debugging\n\nEnable Radio debug warnings with `setDebug`:\n\n```javascript\nimport { Radio } from 'marionette';\n\nRadio.setDebug();\n```\n\nDebug mode warns when a request handler is overwritten or an unhandled request\nis made. Disable it explicitly when it is no longer needed:\n\n```javascript\nRadio.setDebug(false);\n```\n\n`Radio.log(channelName, eventName, ...args)` receives activity from `tuneIn()`.\n`Radio.debugLog(warning, eventName, channelName)` receives warnings while debug\nmode is enabled. Assign either hook to route output to an application logger or\ntest collector. Both default to console output.\n\n```javascript\nimport { createMarionette } from 'marionette';\n\nconst runtime = createMarionette();\nruntime.Radio.debugLog = (warning, eventName, channelName) => {\n  console.warn({ warning, eventName, channelName });\n};\nruntime.Radio.setDebug();\n```\n\nHooks belong to each Radio instance and run with that Radio as `this`. Replacing\na hook affects existing channels, including tuned channels. Disabling debug mode\nalso disables delivery to custom warning hooks. Exceptions from hooks propagate.\nStandalone `Channel` and `Requests` imports use the default Radio's warning\nconfiguration; `new runtime.Radio.Channel(name)` uses that runtime's configuration.\n\n## Channel Lifecycle\n\nChannels are shared by name within their Radio runtime and remain available for that\nruntime's lifetime. Root imports use one default Radio. Each\n[`createMarionette()`](/docs/runtime-isolation.md) call returns an isolated Radio and\nchannel registry. Clean up handlers when their owning object or feature is destroyed:\n\n```javascript\nimport { MnObject, Radio } from 'marionette';\n\nconst owner = new MnObject();\nconst channel = Radio.channel('feature');\n\nowner.stopListening(channel);\nchannel.off(null, null, owner);\nchannel.stopReplying(null, null, owner);\n```\n\nThe matching cleanup depends on whether the owner used `listenTo`, `on`, or\n`reply` to register the handler.\n\nCall `channel.reset()` to remove all event listeners, listening relationships,\nand reply handlers from that channel. `Radio.reset(name)` resets one existing\nchannel, while `Radio.reset()` resets all existing channels.\n\nResetting a channel clears its handlers but does not replace the shared channel\ninstance. Prefer targeted cleanup for long-lived application channels so one\nfeature does not remove another feature's handlers.\n\n| Operation | Unknown channel | Existing channel |\n| --- | --- | --- |\n| `Radio.channel(name)` | Creates and registers the channel. | Returns the same channel. |\n| Top-level event, request, and tuning methods | Create the channel through `Radio.channel(name)`. | Operate on the same channel. |\n| `Radio.reset(name)` | Throws `MarionetteError` with code [MN0021](/docs/diagnostics.md#look-up-a-code) without creating a channel. | Clears handlers and preserves the channel identity. |\n| `Radio.reset()` | Does not create channels. | Resets every registered channel without replacing it. |\n\nOnly a zero-argument `Radio.reset()` call means reset all. Supplying an empty or\notherwise falsy channel name throws the existing required-name diagnostic\n[MN0017](/docs/diagnostics.md#look-up-a-code) without resetting any channel.\n\n## Marionette Integration\n\n`Application` and `MnObject` can bind events and requests to a channel with\n`channelName`, `radioEvents`, and `radioRequests`. `getChannel()` returns the\nconfigured channel.\n\n`radioEvents` follows the [entity-event map contract](/docs/common.md#bindevents),\nincluding the `MN0026` rejection of an own enumerable `__proto__` map entry.\nThe direct Radio Events API continues to support `__proto__` as an event name.\n\n<!-- executable-example: radio-owner-lifecycle -->\n```javascript\nimport { MnObject, Radio } from 'marionette';\n\nexport const Notifications = MnObject.extend({\n  channelName: 'notifications',\n\n  initialize() {\n    this.messages = [];\n  },\n\n  radioEvents: {\n    'message:received': 'showMessage'\n  },\n\n  radioRequests: {\n    'message:count': 'getMessageCount'\n  },\n\n  showMessage(message) {\n    this.messages.push(message);\n  },\n\n  getMessageCount() {\n    return this.messages.length;\n  }\n});\n\nexport const notifications = new Notifications();\nexport const channel = Radio.channel('notifications');\nconst message = { text: 'Hello' };\n\nchannel.trigger('message:received', message);\nconst count = channel.request('message:count');\n```\n\nDestroying the Marionette object removes request handlers bound with that\nobject as their context. The object's event listeners are cleaned up through\nthe normal Marionette event lifecycle.\n\n## Backbone.Radio comparison\n\nThe v5 Radio implementation retains Backbone.Radio's channel messaging model,\nbut it is not a drop-in replacement for every exported property.\n`@mnjs/radio` can be used independently; core re-exports the same default\n`Radio` within each module format.\n\n| Area | v5 behavior |\n| --- | --- |\n| Requests and replies | Named/default handlers, callback context, map and space-separated forms, one-time replies, and selective removal retain the messaging contract. |\n| Events and cleanup | Channels use shared Marionette Events. Reset clears handlers and owned listeners while retaining channel identity. Events also provides `triggerMethod`. |\n| Debugging | Use `setDebug()` instead of assigning `DEBUG`. `log` and `debugLog` are replaceable per-instance hooks, and the debug toggle gates custom warning hooks too. Removing an absent reply does not warn. |\n| Construction and globals | Use `channel(name)` for registered channels, `new Channel(name)` for standalone channels, or the named `Requests` mixin for request/reply alone. `VERSION`, Backbone global installation, and `noConflict()` are not Radio exports. |\n| Names and maps | Request maps use own enumerable string keys. Inherited entries are ignored; names such as `__proto__` are supported without changing object prototypes. |\n| Reset arguments | Only `reset()` resets all channels. An explicitly supplied empty name is an error; an unknown named channel gets a Marionette diagnostic. |\n\n`test/unit/radio-parity.spec.js` runs shared behavioral scenarios against the\npublished Backbone.Radio 2.0.0 runtime and Marionette: fallback arguments, flat\nvalues, nested request maps, reentrant and throwing one-time handlers, callback\nand context removal, top-level forwarding, and channel/listener cleanup.\n\nThe extraction was also checked against the upstream request, channel, forwarding,\ntuning, and debug tests at\n[Backbone.Radio commit 7a58ade](https://github.com/marionettejs/backbone.radio/tree/7a58ade84bedb5551c2e12bdd3434d0fd6b1bdbd/test/unit).\nThat comparison adapts private registry names and the old debug toggle; tests\nrequiring removed public APIs are differences, not claims of full compatibility.\n\nOne intentional correction relative to the published 2.0.0 bundle is cancellation\nof `replyOnce` by its original callback: `stopReplying(name, callback)` removes\nthe pending reply in v5. The published bundle and inspected upstream source\nleave it registered. This follows the callback-identity behavior of\nBackbone.Events `once`/`off`. The comparison test records the difference\nexplicitly instead of claiming exact parity.\n\n\n[Canonical source](/docs/markdown/docs/radio.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/utils.md",
      "title": "Utilities",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/utils/",
      "markdownUrl": "https://marionettejs.com/docs/utils.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/utils.md",
      "sourceSha256": "5c2d0854895bb19f613926788cf81c5849cf18af1e43ac540e860b226fa80d2a",
      "sha256": "d7ea4080dad95c0bb3283a8461d569584b86e3f9cd7daa0faaa469798e3e777a",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 5c2d0854895bb19f613926788cf81c5849cf18af1e43ac540e860b226fa80d2a. -->\n\n# Marionette Utility Exports\n\nMarionette exports the standalone utilities and package facts that do not require a\nframework instance. Common framework conventions such as `bindEvents`, `getOption`,\n`mergeOptions`, `normalizeMethods`, and `triggerMethod` are documented as\n[instance methods](/docs/common.md).\n\nThe v4 target-first exports also adapted these conventions to arbitrary plain\nobjects. That adapter is not part of v5. Import reusable helpers from\n[`@mnjs/utils`](/docs/common.md#shared-helpers) when a plain component needs them;\nextend `MnObject` when it needs Marionette's initialization and cleanup lifecycle.\nDo not borrow a framework prototype solely to obtain a helper.\n\n## Documentation Index\n\n* [extend](#extend)\n* [VERSION](#version)\n\n## extend\n\n`extend` is Marionette's owned, standalone implementation of its classic\npseudo-class extension convention. Assign it to a constructor, then call it as\na method so that constructor is the parent. Marionette's extendable classes\nalready expose this method.\n\n<!-- executable-example: utils-owned-extend -->\n```javascript\nimport { extend } from 'marionette';\n\nfunction Service(name) {\n  this.name = name;\n}\n\nService.extend = extend;\n\nconst SpecialService = Service.extend({\n  label() {\n    return `special:${this.name}`;\n  }\n}, {\n  kind: 'special'\n});\n\nconst service = new SpecialService('api');\n\nexport { Service, SpecialService, extend, service };\n```\n\nThe child inherits the parent's prototype and static properties. Prototype\nproperties are supplied by the first argument and optional static properties\nby the second. See the [v4 compatibility ledger](/docs/migration-from-v4.md#compatibility-ledger)\nfor the v5 input-copying boundary.\n\n## VERSION\n\n`VERSION` is the installed Marionette package version. Marionette also uses it\nwhen constructing versioned diagnostic documentation URLs; exporting it does\nnot imply that a corresponding website deployment is available.\n\n<!-- executable-example: utils-version -->\n```javascript\nimport { VERSION } from 'marionette';\n\nexport { VERSION };\n```\n\n\n[Canonical source](/docs/markdown/docs/utils.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/marionette.mnobject.md",
      "title": "MnObject",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/mn-object/",
      "markdownUrl": "https://marionettejs.com/docs/mn-object.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/marionette.mnobject.md",
      "sourceSha256": "056bb3041902d66831a0031e2e9c97770f485f613450861ae55aba46ca592243",
      "sha256": "c92fd00483055350c4696082070a77361ec33fdc1b3d503e2a57175a1141e8d9",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 056bb3041902d66831a0031e2e9c97770f485f613450861ae55aba46ca592243. -->\n\n# Marionette.MnObject\n\nUse `MnObject` for objects that need Marionette events and cleanup without a\nDOM element. It provides `initialize`, options, the Events API, a unique `cid`,\nand `extend`, with no Backbone dependency.\n\n`MnObject` includes:\n- [Common Marionette Functionality](/docs/common.md)\n- [Class Events](/docs/class-events.md#mnobject-events)\n- [Radio API](/docs/radio.md#marionette-integration)\n- [State ownership](/docs/state.md#borrowed-and-owned-sources)\n\n## Documentation Index\n\n* [Instantiating a MnObject](#instantiating-a-mnobject)\n* [Unique Client ID](#unique-client-id)\n* [Destroying a MnObject](#destroying-a-mnobject)\n* [Basic Use](#basic-use)\n* [v4 Migration](#v4-migration)\n\n## Instantiating a MnObject\n\nConstructor options are shallow-copied into `this.options`. Own enumerable\n`channelName`, `radioEvents`, `radioRequests`, and `stateEvents` options with values other than\n`undefined` are also attached directly to the instance. Other options remain\navailable through `this.options` and `getOption` unless explicitly merged.\nThe channel options use Marionette's built-in [`Radio`](/docs/radio.md); see that guide\nfor the separate `backbone.radio` migration boundary.\n\nA supplied `state` source is borrowed. A source returned by `createState(options)`\nis owned and created lazily; `getState()` returns the exact source. Configured\n`stateEvents` subscribe after `initialize`. Destruction removes those\nsubscriptions and disposes owned State through the selected StateApi. See\n[State](/docs/state.md) before enabling observable State events.\n\n```javascript\nimport { MnObject } from 'marionette';\n\nconst myObject = new MnObject({ channelName: 'tasks' });\n\nmyObject.channelName; // 'tasks'\n```\n\n## Unique Client ID\nThe `cid` or client id is a unique identifier automatically assigned to MnObjects\nwhen they're first created and by default is prefixed with `mno`.\nYou can modify the prefix for `MnObject`s you `extend` by setting the `cidPrefix`,\nwhich should be a non-empty string when customized. IDs generated with the same\nprefix by one loaded copy of Marionette are unique, including when different\nMarionette types use that prefix. Treat the complete `cid` as opaque: its numeric\nsuffix and allocation order are not API, and its sequence is not coordinated with\nIDs generated by Underscore or Backbone.\nThe [v4-to-v5 migration ledger](/docs/migration-from-v4.md#compatibility-ledger)\nrecords the sequence-ownership rationale.\n\n```javascript\nimport { MnObject } from 'marionette';\n\nconst MyFoo = MnObject.extend({\n  cidPrefix: 'foo'\n});\n\nconst foo = new MyFoo();\n\nfoo.cid.startsWith('foo'); // true\n```\n\n## Destroying a MnObject\n\n### `destroy`\nOn successful completion of its lifecycle, `destroy` removes subscriptions the\ninstance made with `listenTo`, releases its owned Radio event subscriptions and\nreplies, cleans up State, and returns the MnObject synchronously. Returned Promises\nfrom destruction hooks are not awaited. It does not reset the shared Radio channel or\nremove unrelated channel handlers. Listeners registered directly on the\ninstance with `on` are not removed automatically. If a lifecycle callback\nthrows, cleanup that has not yet run may be skipped; the failure boundaries are\ndescribed below.\n\nInvoking `destroy` triggers `before:destroy` and `destroy` events and their\n[corresponding `onBeforeDestroy` and `onDestroy` methods](/docs/events.md#onevent-binding).\nEach receives the MnObject followed by the `options` passed to `destroy`.\n\nWhile a `destroy()` call is in progress, nested calls from either lifecycle\nevent return the same MnObject without restarting teardown. Calls after\ndestruction also return the same MnObject without repeating the lifecycle.\n`Application` has an asynchronous destruction lifecycle; see its\n[reference](/docs/application.md#application-lifecycle).\n`isDestroyed()` is `false` during `before:destroy` and `true` during `destroy`.\nIf a lifecycle handler throws, the error propagates and stops destruction.\nThe destruction guard remains set; later `destroy()` calls do not restart\nhooks or resume cleanup.\n\nA custom override that mutates owned state before calling the base `destroy`\nmethod is outside this guard. See the\n[v4-to-v5 compatibility ledger](/docs/migration-from-v4.md#compatibility-ledger) for\nthe override boundary.\n\n```javascript\nimport { MnObject } from 'marionette';\n\n// define a mnobject with an onBeforeDestroy method\nconst MyObject = MnObject.extend({\n\n  onBeforeDestroy(currentObject, options) {\n    // put other custom clean-up code here\n  }\n});\n\n// create new MnObject instances\nconst obj = new MyObject();\nconst source = new MnObject();\n\n// add some event handlers\nobj.on('before:destroy', function(currentObject, options) {\n  console.log(options.foo);\n});\nobj.listenTo(source, 'bar', function() {});\n\n// trigger the lifecycle and stop listening to source\nobj.destroy({ foo: 'bar' });\n```\n\n### `isDestroyed`\n\nThis method will return a boolean indicating if the mnobject has been destroyed.\n\n```javascript\nimport { MnObject } from 'marionette';\n\nconst obj = new MnObject();\nobj.isDestroyed(); // false\nobj.destroy();\nobj.isDestroyed(); // true\n```\n\n## Basic Use\n\nSelections is a simple MnObject that manages a selection of things.\nBecause Selections extends from MnObject, it inherits `initialize` and the\n[Events API](/docs/events.md).\n\n```javascript\nimport { MnObject } from 'marionette';\n\nconst Selections = MnObject.extend({\n\n  initialize() {\n    this.selections = {};\n  },\n\n  select(key, selection) {\n    this.selections[key] = selection;\n    this.triggerMethod('select', key, selection);\n  },\n\n  deselect(key, selection) {\n    delete this.selections[key];\n    this.triggerMethod('deselect', key, selection);\n  }\n\n});\n\nconst selections = new Selections();\nconst truck = { name: 'Dump truck' };\n\n// use the inherited Events API\nselections.on('select', function(key, selection) {\n  console.log(selection);\n});\n\nselections.select('toy', truck);\n```\n\n## v4 Migration\n\nv5 exports `MnObject` by name from `marionette`. The historical `Object` alias\nand v4 default namespace export are removed. See the\n[v4-to-v5 migration ledger](/docs/migration-from-v4.md) for the replacement paths.\n\n\n[Canonical source](/docs/markdown/docs/marionette.mnobject.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/diagnostic-catalog.md",
      "title": "Diagnostics",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/diagnostics/",
      "markdownUrl": "https://marionettejs.com/docs/diagnostics.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/diagnostic-catalog.md",
      "sourceSha256": "1df844c7e8edbea59a8c07776d656d45f77266108babb770d7690183fe85d180",
      "sha256": "060b1d0808d63c1934369d6ee65814b670306d2370a7516702b58c37c58fbd6e",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 1df844c7e8edbea59a8c07776d656d45f77266108babb770d7690183fe85d180. -->\n\n# Diagnostic catalog\n\nMarionette uses one machine-readable catalog to identify framework invariants across\nruntime diagnostics, static analysis, development and test tooling, documentation,\nand the public agent benchmark. The catalog is stored in\n`config/diagnostics/catalog.json`, and its executable contract is\n`config/diagnostics/catalog.schema.json`.\n\nThe catalog is static project metadata. Production entrypoints must not import the\ncatalog, and the catalog is not part of the production package surface. Runtime\ndiagnostics may embed a compact catalog code, but they must not load the full catalog.\nSchema version 2 adds explicit retired identities without restoring their emissions.\n\n## Look up a code\n\nRead the [machine-readable catalog](/docs/source/config/diagnostics/catalog.json), find the\nentry by `code`, and read its `remediation`. This file is included in packaged\ndocs for offline lookup. The website also provides a\n[diagnostic reference](/errors/index.md).\n\n## Runtime error contract\n\nFramework invariant failures use the public `MarionetteError` class:\n\n```javascript\nimport { MarionetteError, View } from 'marionette';\n\ntry {\n  new View({ template: false }).showChildView('missing', new View());\n} catch (error) {\n  if (error instanceof MarionetteError && error.code === 'MN0020') {\n    // Handle the missing named Region.\n  }\n}\n```\n\n`MarionetteError` extends the native `Error` class and exposes `name`, `code`,\n`message`, `stack`, and the existing `url` property. The code is the stable lookup\nkey for the repository-generated diagnostic reference. Error names preserve useful\nframework categories such as `ViewError`, `RegionError`, and `CollectionViewError`.\nMessages and legacy URLs are explanatory prose and are not machine contracts.\n\nProduction errors copy only supported Error fields and the compact code. They do not\nimport the catalog or perform runtime catalog lookup. Engines with\n`Error.captureStackTrace` use it; other engines retain the native fallback stack.\n\n## Entry contract\n\nEvery entry has these fields:\n\n- `code`: an opaque identifier in the form `MN0001`. The number does not encode the\n  diagnostic category, object, severity, or implementation order.\n- `slug`: a unique lowercase kebab-case name used by tools and people.\n- `status`: `defined` before the code is emitted, `active` once a supported surface\n  emits it, `deprecated` after it has a replacement, or `retired` after the\n  diagnostic is removed without a replacement. Retired entries remain cataloged\n  permanently but cannot be emitted.\n- `category`: the kind of contract involved: `configuration`, `communication`,\n  `dom`, `lifecycle`, or `ownership`.\n- `severity`: `error`, `warning`, or `info`, following the model below.\n- `objects`: the public Marionette objects involved in the invariant.\n- `remediation`: concise guidance for correcting the violation. This is human prose\n  and may improve without changing the diagnostic identity.\n- `docsAnchor`: the permanent version-neutral documentation route. It is always\n  `/errors/<code>/`.\n- `surfaces`: the places that report the diagnostic, or historically reported it\n  for a retired entry: `runtime`, `lint`, `development`, `test`, or `benchmark`.\n- `benchmarkCategory`: the public benchmark category used to classify the violation.\n\nA deprecated entry also has `replacementCode`, which must identify another catalog\nentry. Defined, active, and retired entries cannot declare a replacement.\n\n### Severity model\n\n- `error` means the invariant is violated and the requested operation cannot safely\n  continue. Runtime surfaces throw; lint and validation surfaces fail their check;\n  benchmark runs count the violation as incorrect.\n- `warning` means execution can continue but the usage is unsafe, deprecated, or\n  likely unintended. Tools report it without changing runtime control flow; release\n  evidence must explicitly approve or eliminate it.\n- `info` records deterministic context or guidance without indicating incorrect\n  behavior. It does not fail an operation, check, or benchmark result by itself.\n\nFor a retired entry, the stored severity and surfaces retain the diagnostic's\nhistorical classification. The generated reference labels those values as historical\nfor display only. The `retired` status is authoritative: the entry is not a current\nerror, warning, informational report, or supported-surface mapping.\n\n## Stability policy\n\nCodes and slugs are unique and are never reassigned. The numeric portion of a code is\nallocated monotonically, gaps are allowed, and entries are never renumbered to close\na gap. Deprecation retains both the catalog entry and its `/errors/<code>/` route and\nnames the replacement. Retirement retains the identity and route without implying a\nreplacement. Deletion and reuse are not supported.\n\nBefore stable v5, defined catalog fields may be revised through reviewed changes.\nAfter stable v5, active, deprecated, and retired entries follow these rules:\n\n- adding a diagnostic or deprecating one is a minor change;\n- retiring an active diagnostic changes supported behavior and requires\n  major-version review;\n- clarifying remediation without changing its meaning is a patch change;\n- changing the meaning of a machine-readable field or the schema is a breaking\n  change and requires a new schema version and major-version review;\n- deleting or reusing a published code, slug, or diagnostic route is prohibited.\n\nMessages are deliberately not catalog identifiers. Human-readable runtime messages\nmay improve while the code and slug remain stable.\n\n## Surface mappings\n\nRuntime diagnostics declare their catalog identifier as a literal `code` property.\nCustom ESLint rules under `eslint-rules/` default-export an object literal whose\n`meta` object declares exactly one literal `diagnosticCode`. Benchmark and test\nresults record the same code rather than copying the diagnostic meaning into a\nsecond identifier.\n\nRuntime diagnostic options and lint-rule metadata cannot use computed keys, spreads,\nor duplicate mapping properties. This keeps the emitted code statically decidable.\nA `defined` entry must move to `active` in the same change that first emits it.\nA retired entry cannot be emitted or mapped by a supported surface.\n\n`npm run check:diagnostics` derives the shipped source graph from the production\nRollup inputs, rejects runtime codes or lint-rule mappings that are not in the\ncatalog, and rejects a lint rule without a mapping. Documentation routes are\ngenerated from the catalog and then checked by `npm run docs:check`; they are not\nmaintained as a second hand-written list.\n\n## Initial scope\n\nThe initial active entries describe only deliberate errors already thrown by the\nframework. Retired entries reserve identities that were formerly active; they do not\nreserve codes for planned validation. Defined entries likewise are not placeholders\nfor incidental JavaScript exceptions or benchmark hypotheses. New invariants receive codes when their\nbehavior and remediation are implemented and reviewed.\n\nThe generated [diagnostic reference](/errors/index.md) lists the current catalog directly\nfrom the machine-readable source. A shared invariant has one code even when more\nthan one framework object reports it.\n\n## Argument types and runtime diagnostics\n\nMarionette trusts the declared shapes of callbacks, arrays, View instances,\nconfiguration objects, and adapter methods. TypeScript consumers receive errors\nfor unsupported shapes during type checking. JavaScript consumers follow the same\ndocumented contracts; unsupported arguments have no guaranteed runtime diagnostic.\n\nRuntime diagnostics remain for ownership conflicts, invalid collection identity,\nmissing DOM targets, unresolved handler names, and incompatible data sources.\nRetired shape-diagnostic codes remain listed for historical reference and are not\nreused. See [contributing](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/CONTRIBUTING.md#runtime-checks-and-types) for the rule\nused when adding or removing checks.\n\n\n[Canonical source](/docs/markdown/docs/diagnostic-catalog.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/public-api.md",
      "title": "Public exports",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/public-api/",
      "markdownUrl": "https://marionettejs.com/docs/public-api.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/public-api.md",
      "sourceSha256": "e25fca5580c61df0c4971f4dfc9b1947667917eb650a76dab6be8c42be217e26",
      "sha256": "7fc7fc3446f2c9951c47055c524f4520e5d205ba87e4764b52c022d8eebd64ee",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 e25fca5580c61df0c4971f4dfc9b1947667917eb650a76dab6be8c42be217e26. -->\n\n# Public API index\n\nUse this index to identify the supported import and follow its behavior contract.\nThe `marionette` package has named exports; it has no default export. Import\noptional integrations from their documented package subpaths, never from `src/`\nor generated internal files.\n\n## Core runtime exports\n\n| Export | Purpose and reference |\n| --- | --- |\n| `View` | [Render and own one part of the interface](/docs/view.md). |\n| `CollectionView` | [Own ordered child Views](/docs/collection-view.md). |\n| `Region` | [Show, replace, detach, or destroy a current View](/docs/region.md). |\n| `Application` | [Coordinate asynchronous feature lifecycle and child Applications](/docs/application.md). |\n| `Behavior` | [Share host View interactions and lifecycle](/docs/behavior.md). |\n| `MnObject` | [Own nonvisual events, State, and synchronous cleanup](/docs/mn-object.md). |\n| `Events` | [Compose the event/listening contract](/docs/events.md#events-api). |\n| `Radio` | [Use the default runtime's named message channels](/docs/radio.md). |\n| `DataApi`, `setDataApi` | [Read and observe the selected data source](/docs/data-api.md). |\n| `StateApi`, `setStateApi` | [Observe State and dispose owned sources](/docs/state.md). |\n| `DomApi`, `setDomApi` | [Create, query, attach, and update DOM](/docs/dom-api.md). |\n| `setRenderer` | [Configure synchronous template evaluation](/docs/rendering.md#using-a-custom-renderer). |\n| `setEventDelegator` | [Configure DOM event registration and cleanup](/docs/dom-interactions.md#eventdelegator-adapter). |\n| `createMarionette` | [Create independent classes, configuration, and Radio](/docs/runtime-isolation.md). |\n| `monitorViewEvents` | [Bridge lifecycle notifications for supported custom Views](#monitorvieweventsview). |\n| `extend` | [Extend a function constructor](/docs/utils.md#extend). |\n| `MarionetteError` | [Inspect a framework invariant failure](/docs/diagnostics.md). |\n| `VERSION` | [Read the package version](/docs/utils.md#version). |\n\n[Configuration method contracts](/docs/runtime-isolation.md#configuration-method-contract)\nidentify which classes each setter affects, its return value, and its scope.\nChoosing one provider does not configure the other providers.\n\n## `monitorViewEvents(view)`\n\nThis synchronous helper installs lifecycle listeners on a supported custom View\nand returns `undefined`. It propagates attachment and detachment notifications\nto managed children and derives `dom:refresh`/`dom:remove` from render and\nattachment state. Repeating the call does not install duplicate monitoring;\n`monitorViewEvents: false` skips installation.\n\nMarionette Views are monitored automatically. This helper is for integrations\nthat implement the [supported View lifecycle](/docs/region.md#wrapping-a-non-marionette-view),\nincluding event methods and managed-child access. It is not a MutationObserver:\nappending arbitrary DOM does not notify it. Prefer a Marionette wrapper View\nfor third-party widgets so ownership and cleanup remain explicit.\n\n## Companion packages\n\n| Import | Public surface | Reference |\n| --- | --- | --- |\n| `@mnjs/data` | `Model`, `Collection`, `DataApi`, `StateApi`, `triggerMethod` | [Native observable data](/docs/data-package.md) |\n| `@mnjs/radio` | `Radio`, `createRadio`, `Channel`, `Requests` | [Standalone Radio](/docs/radio-package.md) |\n| `@mnjs/utils` | Shared events, bindings, option, inheritance, and event-building helpers | [Utility exports](/docs/utils-package.md) |\n| `@mnjs/adapters/backbone` | Default Backbone data/State adapter | [Backbone integration](/docs/backbone.md) |\n| `@mnjs/adapters/xstate` | Default `createXStateActorApi` factory | [XState integration](/docs/data-api.md#xstate-actors) |\n| `@mnjs/adapters/dom/jquery` | Default jQuery DomApi | [jQuery DOM](/docs/dom-api.md#optional-jquery-adapter) |\n| `@mnjs/adapters/dom/morphdom` | Default Morphdom DomApi | [DOM update adapters](/docs/rendering.md#rendering-to-dom) |\n| `@mnjs/adapters/dom/lit-html` | Default Lit DomApi | [DOM update adapters](/docs/rendering.md#rendering-to-dom) |\n\nAdd a companion package as a direct dependency when application code imports it.\nMatch Marionette package versions during prereleases. Optional integrations need only\ntheir selected peers; see [Choosing integrations](/docs/choosing-integrations.md).\n\n## TypeScript exports\n\nCore also exports types for class instances and constructors, class configuration,\nRegion definitions and show options, Application readiness context, DOM events\nand triggers, UI bindings, Behavior definitions, event and request contracts, and\nprovider contracts (`DataApiContract`, `DomApiContract`, `StateApiContract`,\n`EventDelegator`, and `Renderer`). Use `import type` for these names. They do not\ncreate runtime values or install a provider.\n\nThe package's declarations are the exact signature reference. Keep inferred\nsubclass types when possible rather than annotating an extended View as the broad\nbase instance type and losing its application-specific methods.\n\n\n[Canonical source](/docs/markdown/docs/public-api.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "packages/radio/readme.md",
      "title": "Radio package",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/radio-package/",
      "markdownUrl": "https://marionettejs.com/docs/radio-package.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/packages/radio/readme.md",
      "sourceSha256": "60f7fc8cb3f782480cc9f91c565d9b8106c167d6089fa58da55381de972d207e",
      "sha256": "a0461bec43fb673ce109ae5d1902a78aeb8eb011ef53f00a1eb4a7121a261bb7",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 60f7fc8cb3f782480cc9f91c565d9b8106c167d6089fa58da55381de972d207e. -->\n\n# @mnjs/radio\n\nNamed channels for events and request/reply, usable without Marionette core or a DOM.\n\n```sh\nnpm install @mnjs/radio@5.0.0-beta.1\n```\n\n```js\nimport { Radio, createRadio } from '@mnjs/radio';\n\nconst channel = Radio.channel('app');\nchannel.reply('title', () => 'Hello');\nchannel.on('refresh', () => console.log('Refreshing'));\nchannel.request('title');\nchannel.trigger('refresh');\n\nconst isolatedRadio = createRadio();\n```\n\n`Radio` is the default instance also exported by `marionette`. Within the same\nmodule format and package installation, either import reaches the same channels.\n`createRadio()` creates an independent channel registry. Each `createMarionette()`\nruntime also owns its own Radio instance; use that runtime's `Radio` when binding\nits objects and applications.\n\nThe package depends on `@mnjs/utils`, which supplies Events and shared\nhelpers. It does not depend on core. ESM and CommonJS exports include `Radio`,\n`createRadio`, `Channel`, `Requests`, and their public types. ESM and CommonJS each have\ntheir own default instance; do not mix the two formats to share a channel registry.\n\nRadio, utils, data, adapters, and core are versioned and released together.\n\n## Standalone messaging\n\n```js\nimport { Channel, Requests } from '@mnjs/radio';\n\nconst local = new Channel('editor');\nlocal.on('save', () => console.log('Saved'));\nlocal.reply('title', 'Untitled');\n\nconst service = Object.assign({}, Requests);\nservice.reply('ready', true);\n```\n\n`new Channel(name)` creates an independent Events-and-Requests object. It is not\nregistered with Radio; call its `reset()` to remove its handlers and owned\nlisteners. Two standalone channels with the same name are still separate objects.\n`Radio.reset()` only covers channels obtained through `Radio.channel(name)`.\n\nThe named `Channel` export is `Radio.Channel`. Use `new isolatedRadio.Channel(name)`\nwhen a standalone channel should share a particular Radio instance's logging\nconfiguration. `Requests` adds only request/reply methods to its receiver; it uses\nthe default Radio's warning configuration.\n\n## Logging\n\nAssign `radio.log(channelName, eventName, ...args)` to receive activity from\n`tuneIn()`, and `radio.debugLog(warning, eventName, channelName)` to receive\ndiagnostics. The defaults write to the console.\n\n```js\nconst radio = createRadio();\nradio.log = (channel, event, ...args) => console.log({ channel, event, args });\nradio.debugLog = (warning, event, channel) => console.warn({ warning, event, channel });\nradio.setDebug();\nradio.tuneIn('app');\n```\n\nEach Radio instance owns its hooks. They run with that Radio as `this`, and\nexisting channels use the current hook, even when it is replaced after `tuneIn()`.\n`setDebug(false)` suppresses warning delivery to custom hooks too. Standalone\nchannels use their constructor's Radio configuration; the shared default\nRequests mixin uses the default Radio. Hook exceptions propagate to the caller.\n\n\n[Canonical source](/docs/markdown/packages/radio/readme.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "packages/utils/readme.md",
      "title": "Utils package",
      "section": "API reference",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/utils-package/",
      "markdownUrl": "https://marionettejs.com/docs/utils-package.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/packages/utils/readme.md",
      "sourceSha256": "c3529b92e78f3c25e894316d4776a6a355644f662dc412be769d2da597650b10",
      "sha256": "1c4030cc3fe442d93b97e44c5aab30341dc08ac3d02308185b5aba2ce7b56901",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 c3529b92e78f3c25e894316d4776a6a355644f662dc412be769d2da597650b10. -->\n\n# @mnjs/utils\n\nThe small helpers behind Marionette, available for your own components.\nMarionette and `@mnjs/data` import these same implementations.\n\n```bash\nnpm install @mnjs/utils@5.0.0-beta.1\n```\n\nUse the same version for all Marionette packages. Core and data\ninstall utils automatically as a regular dependency. Add it directly when your\napplication imports it.\n\n## Building a component\n\nMethods such as `getOption`, `normalizeMethods`, and `triggerMethod` use their\nreceiver as the component. Mix them into a prototype or call them with `.call()`.\n\n```js\nimport { Events, getOption, normalizeMethods, triggerMethod } from '@mnjs/utils';\n\nconst component = {\n  ...Events,\n  getOption,\n  normalizeMethods,\n  triggerMethod,\n  options: { label: 'Inbox' },\n  onOpen() {\n    return this.getOption('label');\n  }\n};\n\ncomponent.triggerMethod('open'); // 'Inbox'\ncomponent.normalizeMethods({ open: 'onOpen' });\n```\n\n## Events\n\n`Events` is the shared event implementation used by Marionette, Radio, and native\ndata. Mix it into an object with `Object.assign({}, Events)` to use `on`, `off`,\n`trigger`, `listenTo`, and `stopListening` without core.\n\n## Helpers\n\nUse object spread or `Object.assign` for ordinary copying and composition.\nInherited enumerable parent statics are copied only inside `extend`.\n\n- `getValue(object, key, fallback)` reads a value and calls it on the object if it\n  is a function. `getOption` reads from `this.options`, then the receiver.\n- `mergeOptions(options, keys)` copies selected options onto the receiver.\n- `normalizeMethods(map)` resolves method names on the receiver.\n  `resolveMethod(context, method, name)` resolves one handler.\n- `bindEvents` and `unbindEvents` use the receiver's listening methods.\n  `bindRequests` and `unbindRequests` register or remove channel replies with\n  the receiver as their context. `normalizeBindings(context, map)` resolves an\n  event map without subscribing.\n- `triggerMethod(eventName, ...args)` invokes the matching `onEventName` method\n  and triggers the event.\n- `extend` is the function-constructor inheritance helper used by Marionette.\n- `MarionetteError` is the same error constructor exported by Marionette.\n- `isString` recognizes primitive and boxed strings. `setProperty` assigns a\n  property, treating `__proto__` as an own data property.\n\nES modules, CommonJS, and TypeScript declarations are included. The package has\nno runtime dependencies and declares no side effects. Bundlers can retain only\nthe imported helpers. Marionette's standalone UMD bundles include these helpers;\nmodule consumers share the installed package.\n\nEvent-building helpers `buildEventArgs`, `eventSplitter`, `callHandler`, and\n`onceWrap`, plus `uniqueId`, are shared by core and Radio.\n\n\n[Canonical source](/docs/markdown/packages/utils/readme.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "docs/migration-from-v4.md",
      "title": "v4 compatibility ledger",
      "section": "Migration",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/migration-from-v4/",
      "markdownUrl": "https://marionettejs.com/docs/migration-from-v4.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/docs/migration-from-v4.md",
      "sourceSha256": "a835cd45ae3fe1bf0a35d6684d74bb9ac2806a91907e57a7cb4e344734e8aba1",
      "sha256": "7d62a1d35855c2e2889c479c6cafcd4c0909cc1d8a95d41547da1239e69aaede",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 a835cd45ae3fe1bf0a35d6684d74bb9ac2806a91907e57a7cb4e344734e8aba1. -->\n\n# Marionette v4 to v5 Compatibility Ledger\n\nThis ledger records the public compatibility boundary between Marionette v4\nand v5. It is a reference, not the full procedural upgrade guide. Detailed\nupgrade steps that are not already documented are tracked in\n[the stable-release documentation issue](https://github.com/marionettejs/marionette/issues/147).\n\nStatus values describe the v5 outcome:\n\n- **Preserved**: the supported public behavior remains available.\n- **Changed**: the public behavior remains relevant but has a different contract.\n- **Removed**: the v4 behavior is not supported in v5.\n- **Added**: v5 provides a new public capability with no core v4 equivalent.\n- **Optional**: the behavior is available only through an explicit opt-in.\n- **Renamed**: the capability remains under a different name.\n- **Documented**: the public extension point is retained and called out here.\n\nIf your application imports directly from @mnjs/radio, declare version 5.0.0-beta.1 as a direct dependency in your application package.json. Do not rely on Marionette’s transitive dependency.\n\n## Compatibility ledger\n\n| Area | v4 behavior | v5 behavior | Status | Migration note |\n| --- | --- | --- | --- | --- |\n| Package name | Installed as `backbone.marionette`. | Published as `marionette`. | Changed | Replace the package name. See [Installing Marionette](/docs/installation.md#install). |\n| Install command | `npm install backbone.marionette` installed Marionette under the v4 name. | Install core with `npm install marionette@5.0.0-beta.1`; add optional peers only when used. | Changed | See [peer dependencies](/docs/installation.md#peer-dependencies). |\n| Default export namespace | Namespace-style default import usage was supported. | A default namespace export is not supported. | Removed | Use named imports. See [Quick start](/docs/installation.md#quick-start); final migration guidance is tracked in [#147](https://github.com/marionettejs/marionette/issues/147). |\n| Named exports | Classes and utilities were available as named exports. | Named exports are the supported module API. | Preserved | Import only what is needed, for example `import { View, Region } from 'marionette';`. |\n| Feature flags | `setEnabled` and `isEnabled` configured one module-global registry, including `childViewEventPrefix`, `triggersPreventDefault`, `triggersStopPropagation`, `DEV_MODE`, and application-owned names. | The registry and both named exports are removed. Child event prefixes remain configurable per View. Trigger default prevention and propagation remain configurable per trigger. | Removed | Remove flag calls and imports. The disabled `triggersPreventDefault` and `triggersStopPropagation` flags globally inverted trigger defaults and have no global replacement; set `preventDefault: false` or `stopPropagation: false` on each affected trigger. Set `childViewEventPrefix` on the owning View, and move application-owned values to Application State or explicit application configuration. Future deprecations use cataloged diagnostics instead of `DEV_MODE`. |\n| Backbone dependency | Backbone was a required runtime dependency and supplied core model, collection, event, and view behavior. | Marionette core does not import Backbone. Plain objects and arrays use the neutral DataApi; Backbone is an explicit integration. | Optional | Install `@mnjs/adapters` and configure its `BackboneApi` with `setDataApi()` for model/collection use and `setStateApi()` separately for Backbone state observation. See [Optional Backbone](/docs/backbone.md). |\n| Model and collection data | Core read Backbone-specific `cid`, `attributes`, `get`, `models`, `indexOf`, and structural event payloads directly. | Core reads identity, values, serialization, ordered model snapshots, subscriptions, and structural changes through DataApi. | Changed | Use plain objects and arrays with the default adapter, configure `BackboneApi` for Backbone, or configure a custom adapter with `setDataApi`. See [Data API](/docs/data-api.md). |\n| Serialized collection template property | A View with a collection and no model supplied the result of `serializeCollection()` to the template as `items`. | The template receives that result as `models`, matching the DataApi vocabulary while remaining distinct from the raw ordered snapshot returned by `DataApi.models(collection)`. Default serialization returns an array of serialized values; an override may return another shape. The pre-stable `items` property is removed. | Changed | Replace collection-template reads and destructuring of `items` with `models`; do not retain a fallback for both names. |\n| Region display input | `Region#show` and `View#showChildView` accepted a View instance, template function, string, or View-options object. Non-View values implicitly constructed a base Marionette View. | Both methods require a Marionette View instance. The public types require an instance; Regions do not allocate hidden Views or provide a custom diagnostic for unsupported input shapes. | Changed | Construct the intended View explicitly and pass the instance. Replace strings or template functions with `new View({ template: () => content })`, and wrap former View-options objects with `new View(options)`. |\n| Local state | Core did not provide a first-class state-source composition contract; applications commonly used a Backbone model or separate mixin. Toolkit mixed Backbone-backed `getState(attr)`, `setState`, `toggleState`, `hasState`, and reset helpers into several owners. | `Application`, `MnObject`, `View`, `CollectionView`, and `Behavior` compose an exact source through borrowed `state` or owned `createState(options)`. `getState()` returns that source, and StateApi observes `stateEvents`. The v5 alpha concrete `State` export is removed. | Changed | For simple local values, return a plain object from [`createState()`](/docs/state.md) and use property access. For reactive state, supply the provider's source and configure its StateApi. Move mutation to the source's native API; core adds no universal mutation wrappers. |\n| Explicit Backbone integration | Backbone integration was applied as part of the v4 dependency relationship. | `@mnjs/adapters/backbone` provides one combined DataApi and StateApi adapter without modifying Backbone objects, prototypes, or native event behavior. | Optional | Pass `BackboneApi` to the selected runtime's `setDataApi()` and `setStateApi()` methods before constructing Marionette owners that consume those sources. See [Optional Backbone](/docs/backbone.md). |\n| jQuery dependency | jQuery commonly backed Backbone view and Marionette DOM behavior. | Marionette core does not import jQuery. | Optional | Install jQuery only when using `@mnjs/adapters/dom/jquery`. See [jQuery DOM adapter is optional](/docs/installation.md#jquery-dom-adapter-is-optional). |\n| Optional jQuery DomApi | jQuery-backed DOM operations were part of the common v4 stack. | The `@mnjs/adapters/dom/jquery` subpath provides explicitly selected jQuery-backed DOM methods without adding `$el` to core. | Optional | Configure it at app boot with `setDomApi`. See [jQuery DOM compatibility](/docs/upgrade-guide.md#jquery-dom-compatibility). |\n| `$el` | Views and Behaviors exposed a jQuery wrapper. | Core and adapters do not create `$el`; Views keep a fixed root. | Changed | Assign `this.$el = $(this.el)` in the View, CollectionView, or Behavior `initialize()` when needed. See [jQuery DOM compatibility](/docs/upgrade-guide.md#jquery-dom-compatibility). |\n| `view.$(selector)` | Returned a jQuery collection in the common Backbone/jQuery configuration. | Delegates to `DomApi.findEl`, which returns a native `NodeList` by default or a jQuery collection with the optional adapter. | Changed | Prefer native collection APIs, or opt into `@mnjs/adapters/dom/jquery`. See [jQuery DOM compatibility](/docs/upgrade-guide.md#jquery-dom-compatibility). |\n| CollectionView `attachHtml` container | The second override argument was a jQuery-wrapped `$container`. | The second argument is the native child container element, equal to the CollectionView's `el` unless `childViewContainer` selects another element. | Changed | Update overrides to accept `attachHtml(els, container)` and pass the native `container` to DomApi operations. Do not depend on jQuery collection methods or restore a dual-shape argument. |\n| Region element resolution | Construction resolved selector strings through public `Region#getEl` before `initialize`; `getEl` returned a jQuery collection, and custom DomApi adapters could implement `getEl(selector)`. | Construction preserves the configured selector for `initialize` and defers public `Region#getEl` dispatch until the first DOM operation. `Region#getEl` returns the first matching native DOM element. `DomApi#getEl` is removed; selector lookup delegates to `findEl(context, selector)`. | Changed | Do not rely on constructor-time DOM lookup or `getEl` side effects. Make Region `getEl` overrides return one native DOM element. Replace DomApi `getEl` overrides with `findEl`, returning an array-like collection whose first entry is the matched element. |\n| Region `el` input | Accepted a selector string, DOM element, or jQuery-wrapped element. | Selector-string and DOM-element support are preserved. A jQuery collection is rejected even when the optional DomApi adapter is selected. | Changed | Pass the native element, such as `wrappedElement[0]`. Region remains the Marionette mount-point abstraction. See [View `el` is element-only](/docs/upgrade-guide.md#view-el-is-element-only). |\n| View `el` | Selector strings and jQuery-wrapped elements commonly worked through Backbone and jQuery. | `View` accepts a DOM element only and throws a migration hint for strings or wrappers. | Changed | Resolve a selector with `document.querySelector(...)` or unwrap a jQuery collection with `[0]`. See [View `el` is element-only](/docs/upgrade-guide.md#view-el-is-element-only). |\n| View root replacement | `setElement()` transferred a View to another element. | View and CollectionView roots are fixed at construction; `setElement()` is removed and the public instance `el` is readonly. | Removed | Supply `el` at construction. For a different root, destroy the old View and construct a new owner. See [View roots are fixed at construction](/docs/upgrade-guide.md#view-roots-are-fixed-at-construction). |\n| View DOM attributes | View attribute cloning could copy inherited enumerable properties. Attributes were applied through jQuery. | Attribute maps contribute own enumerable string keys and use DOM attribute names. `renderAttributes()` refreshes root attributes without rendering content. Only explicit `null` removes an attribute; undefined and omitted entries leave it untouched. Other values use native string conversion. | Changed | Use own attribute declarations and `null` for removal. For boolean HTML attributes use `disabled: isDisabled ? '' : null`; `false` becomes the string `\"false\"`. Set live form properties explicitly. Keep using the View-level `className` option; inside `attributes`, use `class` and `for`. |\n| CollectionView `emptyView` | Direct falsy values and resolvers returning `undefined`, `null`, or `false` disabled the empty view; other invalid definitions were skipped silently or failed with incidental errors. | Omitted values, direct `undefined`, `null`, or `false`, and resolvers returning those values disable the empty view. The public types describe these alternatives; no custom shape diagnostic is emitted. | Preserved | Existing conditional resolvers require no migration; return a View class or a supported disabled value. |\n| Detach semantics | jQuery detach operations preserved jQuery listener and data bookkeeping for detached nodes. | The native DomApi removes nodes without cleaning their listeners or jQuery data; the optional adapter delegates to jQuery detach operations. Referenced nodes retain their handlers and data in either case. | Changed | Choose the optional jQuery adapter for its documented query and content-operation semantics, not merely to retain referenced nodes during detach. See [`detachContents` policy](/docs/upgrade-guide.md#detachcontents-policy). |\n| Radio singleton | Applications commonly consumed the separate `backbone.radio` package, which also backed Marionette's `channelName`, `radioEvents`, and `radioRequests` integration. | Marionette exports its own built-in `Radio` singleton. It does not share channels with `backbone.radio`. | Changed | Replace every `backbone.radio` import together with the Marionette upgrade, including publishers and requesters outside Marionette classes. A mixed migration silently creates two disconnected buses. Do not bridge or mirror them. See [Atomic Radio migration](/docs/upgrade-guide.md#atomic-radio-migration). |\n| Multiple Marionette configurations | Root imports and mutable class configuration were effectively process-scoped. | Root imports still form one default runtime. Optional `createMarionette()` calls create isolated runtimes with their own runtime classes, adapters, renderer configuration, and Radio registries. | Added | Keep ordinary root imports unless isolation is required. When using `createMarionette()`, construct Regions and child Applications from the selected runtime. See [Runtime isolation](/docs/runtime-isolation.md). |\n| Radio debug configuration | `Radio.DEBUG = true` enabled Backbone.Radio diagnostics. | Use `Radio.setDebug()` and `Radio.setDebug(false)`. The `DEBUG` property is not supported. | Changed | Replace assignments with the explicit method during the atomic Radio migration. |\n| Radio request mixin | Backbone.Radio exposed `Radio.Requests` for direct mixin use. | `Requests` is a named export from `@mnjs/radio`; request/reply methods remain on channels and the top-level Radio API. | Changed | Import `Requests` from the Radio package and compose it with `Object.assign({}, Requests)`. |\n| Radio diagnostic override hooks | Backbone.Radio exposed `Radio.log` and `Radio.debugLog`. | Both hooks are replaceable on each Radio instance; `setDebug` gates custom warning hooks. | Changed | Assign hooks on the Radio instance your channels use. Hooks receive that Radio as `this` and replacements apply to existing channels. |\n| Radio Channel construction and registry | Backbone.Radio exposed its Channel constructor and registry. | `Channel` and `Requests` are named exports from `@mnjs/radio`; each Radio also exposes its Channel constructor. The registry remains private. | Changed | Use `Radio.channel(name)` for shared channels or `new Channel(name)` for independent channels. Standalone owners call `reset()` themselves. |\n| Radio method receiver | Backbone.Radio top-level methods read their channel factory and registry from `this`, so borrowed methods could target an alternate receiver. | Top-level methods dispatch through the Radio instance that created them. | Changed | Use `createRadio()` for another registry. Borrowing a method does not create or select another Radio instance. |\n| Radio named reset | Resetting an unknown channel could fail with an incidental `TypeError`, and names matching inherited object properties could resolve incorrectly. | `Radio.reset(name)` throws `MN0021` for an unknown channel, while explicitly created channel names are registry-owned. | Changed | Create the channel before resetting it, or call `Radio.reset()` with no arguments to reset all existing channels. |\n| Request-name ownership | Inherited request-registry properties could be mistaken for named handlers or the `default` fallback. A `__proto__` request name could change the registry or result-map prototype instead of becoming an own entry. Flattening a nested multi-request result could copy inherited enumerable properties. | Only explicitly registered own handlers are invoked or reported as overwritten. Request result maps use safe own string properties, including for `__proto__`, and nested results contribute own enumerable string properties only. | Changed | Register every named and default handler explicitly; do not depend on request-registry prototype inheritance, and move intended nested result values onto the result object itself. |\n| UMD global | Script builds exposed the `Marionette` global. | Unminified and minified UMD compatibility builds remain supported throughout v5 for no-bundler, AMD, and `Marionette`-global consumers. | Preserved | Existing direct-script integrations can retain the global while updating changed APIs. New applications should use the canonical ESM entry. |\n| CJS entry | CommonJS consumers could require Marionette. | `require('marionette')` resolves to the CJS compatibility build and returns named API properties throughout v5. | Preserved | Legacy Node and build-tool consumers can destructure the required API instead of expecting a restored default namespace contract. New applications should use ESM. |\n| ESM entry | ES module named imports were supported. | `import` resolves to the ESM build and named imports remain supported. ESM is the canonical distribution for new applications. | Preserved | Use named imports from `marionette`. |\n| Underscore dependency | Marionette required Underscore through its package dependency relationship. | Marionette core does not import or declare Underscore as a peer dependency. | Removed | Remove Underscore if it was installed only for Marionette; keep it when application code uses it directly. Backbone manages its own dependency. See [Underscore is no longer a peer dependency](/docs/upgrade-guide.md#underscore-is-no-longer-a-peer-dependency). |\n| Client ID sequence ownership | Marionette constructors and event-listener bookkeeping drew IDs from Underscore's counter, so external Underscore calls could affect later Marionette numeric suffixes. | One loaded copy of Marionette owns one sequence shared by its constructors and event-listener bookkeeping. Complete Marionette-generated IDs remain unique when types reuse a custom prefix, but the sequence is not coordinated with Underscore or Backbone. | Changed | Treat `cid` values as opaque stable instance identifiers. Do not parse or compare numeric suffixes, depend on allocation order, or coordinate IDs through `_.uniqueId`. |\n| Class extension input inheritance | Inherited enumerable properties on the `staticProps` hash passed to `extend` could become child-constructor properties. | The public `protoProps` and `staticProps` hashes contribute own enumerable string and symbol keys. Inherited enumerable statics from the parent constructor remain available on the child. | Changed | Move intended prototype and static definitions onto the corresponding input hash itself; do not inherit configuration into either hash. |\n| Instance option and render-data inheritance | Underscore-backed shallow merges could copy inherited enumerable properties when combining constructor options and resolved defaults, Region definitions and defaults, `childViewOptions`, or serialized data and `templateContext`. `mergeOptions` could also read inherited or non-enumerable named properties. | Constructor/default options, Region options, and child View options use own enumerable string and symbol properties and safely preserve a literal own `__proto__` property. `mergeOptions` copies only requested own enumerable string properties. Serialized data and `templateContext` use own enumerable string and symbol properties when both are combined; a one-sided fast path still returns the original object unchanged. | Changed | Move intended merged values onto the supplied object itself; do not use prototype inheritance or non-enumerable properties for these inputs. |\n| Target-first root utilities | The package root exported `bindEvents`, `unbindEvents`, `bindRequests`, `unbindRequests`, `mergeOptions`, `getOption`, `normalizeMethods`, and `triggerMethod` wrappers that accepted any compatible target object as their first argument. | These conventions have one canonical form as methods on Marionette instances. The root exports, their internal proxy helper, and the public adapter for applying them to arbitrary plain objects are removed. | Removed | Call the corresponding instance method, such as `owner.normalizeMethods(bindings)` or `owner.bindEvents(entity, bindings)`. When a plain object needs similar behavior, extend `MnObject` or own that local adapter explicitly rather than borrowing a Marionette prototype method. |\n| `mergeOptions` key collection | Underscore's iterator accepted strings, `arguments`, generic array-like objects, and ordinary object values as requested option names. Invalid or missing key collections were silently ignored. | `mergeOptions(options, keys)` requires `keys` to be an Array when options are present; the declared contract replaces custom shape validation. | Changed | Pass the requested option names as an Array. |\n| Private immediate-child traversal | The private `_getImmediateChildren()` result was passed to Underscore's generic iterator, which also traversed arbitrary keyed objects. | Marionette-owned implementations return Arrays. The private type requires an Array; traversal trusts that contract. | Changed | Do not override private `_getImmediateChildren()`. Use documented View, Region, and CollectionView APIs to own child Views. |\n| View constructor option precedence | `View` and `CollectionView` passed options to `preinitialize`, then Backbone assigned the public `model`, `collection`, `el`, `id`, `attributes`, `className`, `tagName`, and `events` options before creating the element. Supplied options therefore won conflicts with assignments made by the hook. | The hook can observe the supplied options before the same public constructor options are reapplied. Conflicting supplied options remain authoritative, while v5's private initialization order is unchanged. | Preserved | Use `preinitialize` to derive early state from constructor options. Use `initialize` when an intentional replacement must occur after final public option assignment and element setup. |\n| View `preinitialize` and internal setup order | Before Backbone invoked the host's `preinitialize` hook, `View` installed lifecycle monitoring and constructed Behaviors and Regions; `CollectionView` installed monitoring and constructed its child storage and Behaviors. | The standalone host constructor invokes `preinitialize` before that internal setup. Behavior `initialize` can therefore read host state established by the hook, while the hook cannot depend on constructed Behaviors, Regions, child storage, or lifecycle monitoring. | Changed | Keep early host state derivation in `preinitialize`. Move code that needs Marionette-owned collaborators or lifecycle dispatch to the host's `initialize` method. |\n| CollectionView empty Region initialization | The constructor invoked the host's `initialize` before calling overridable `getEmptyRegion()` to establish the default empty-view Region. | The same order is preserved. An override can depend on state established by `initialize`; calling `getEmptyRegion()` from `initialize` remains safe because the later constructor call reuses that Region. | Preserved | Keep empty-Region override setup in `initialize` or `getEmptyRegion`; no migration is required. |\n| Destruction during View initialization | A `View` or `CollectionView` destroyed from its own `initialize` continued the constructor tail, rebinding entity events and firing Behavior `initialize` after Behavior destruction. `CollectionView` also replaced its destroyed empty Region with a live one. | Destruction is terminal. After `initialize` returns, a destroying or destroyed host skips remaining constructor setup; a destroyed CollectionView retains its destroyed empty Region. | Changed | Initialization code may destroy a host without adding guards for later constructor setup. Do not expect entity events, Behavior initialization hooks, or a live empty Region after that destruction. |\n| Child View collection helpers | `CollectionView#children` proxied Underscore collection methods, including iteratee shorthand, a private-array callback argument, Underscore return values, deep/function-form `invoke`, array-form deep paths in `pluck`, and count coercion. | The 19 documented helpers are owned by Marionette. Callback methods require functions and expose only View and index; `each` returns the child container; `reduce` follows native initial-value rules; `invoke` accepts a direct string method; `pluck` reads one direct View property; positional counts are nonnegative integers. Callback and method shapes are checked by the public types. Invalid counts and an empty reduction without an initial value still throw `MN0024`. | Changed | Replace `map('id')` with `map(view => view.id)` or `pluck('id')`. Replace `pluck(['model', 'cid'])` with `map(view => view.model?.cid)`. Do not use the callback's former third argument or depend on `each` returning an array. Replace deep/function-form `invoke` with an explicit callback, and pass valid integer counts. |\n| Child View collection aliases and iteration | Undocumented Underscore aliases such as `forEach`, `detect`, `select`, `all`, `any`, and `include` were available through the proxy. The child container was not natively iterable. | The aliases are removed. The canonical methods remain, and the child container supports `for...of`, spread, destructuring, and `Array.from`. | Changed | Replace the aliases with `each`, `find`, `filter`, `every`, `some`, and `contains`, respectively. Prefer native iteration when no collection-helper return value is needed. |\n| Child View identity and ownership | Plain-object cid indexes could mistake inherited property names for children, and `removeChildView` or `detachChildView` could mutate a supplied View that was not actually owned by the CollectionView. | View cids remain Marionette-owned keys. Model identity comes from `DataApi.key()` and is stored in a `Map`; `findByModelCid` is removed while `findByModel` uses the configured adapter. Membership requires the exact View instance. | Changed | Replace `findByModelCid(cid)` with `findByModel(model)`. Configure stable source identity through DataApi rather than adding `cid` to otherwise neutral application data. |\n| CollectionView filter iteration | Underscore supplied CollectionView child iteration and predicate-object matching, including accepting arrays as predicate objects. | Function filters run with the CollectionView as their receiver and receive `(childView, index, liveChildArray)` while traversing the initial length densely. Predicate maps snapshot own enumerable string keys and values per pass, require present strictly equal model attributes, and exclude inherited, symbol, and non-enumerable keys. Arrays are not predicate maps. | Changed | Use a function filter for custom matching or mutation-sensitive logic. Supply predicate shorthand as an ordinary object and use the same object reference for nested attribute values that should match. |\n| CollectionView removal-only updates | Every collection update flowed through sort, filter, and child rendering, so removing one model could move every surviving child through a document fragment even when default collection ordering or disabled ordering already preserved their relative order. | A removal-only update on an already-rendered, unfiltered CollectionView with default collection ordering or ordering disabled destroys the removed child without moving or rerendering synchronized visible survivors when the default sort, filter, and comparator-query methods are used. Empty-view, deferred-child, custom filter or comparator, overridden query methods, add, and merge cases retain the full update path. | Changed | Observe `remove:child` for removals. Do not rely on sort or `render:children` firing when no surviving child needs sorting, rendering, or placement. Private `_viewComparator` and `_onCollectionUpdate` overrides are not supported extension points; use the documented public options and methods. |\n| Event bookkeeping rename | Backbone-compatible private event fields such as `_events`, `_listeningTo`, and `_listenId` could be observed. | Marionette's built-in Events implementation uses private `_rdEvents`, `_rdListeningTo`, `_rdListeners`, and `_rdListenId` fields. | Renamed | Do not read or write event bookkeeping fields; use `on`, `off`, `listenTo`, and `stopListening`. Procedural guidance is tracked in [#147](https://github.com/marionettejs/marionette/issues/147). |\n| Event aliases | Backbone.Events exposed `bind` as an alias of `on` and `unbind` as an alias of `off`, including on Radio channels. | Marionette Events and built-in Radio expose only the canonical `on` and `off` methods. The optional Backbone integration does not modify Backbone objects, so native Backbone instances retain `bind` and `unbind`. | Changed | Replace the aliases on Marionette objects and Radio channels. Existing Backbone-owned code may continue using Backbone's native aliases, though `on` and `off` remain preferred. |\n| Event and request override dispatch | `once` registered through overridable `on`; `listenToOnce` registered through overridable `listenTo`; and Backbone.Radio registered `replyOnce` through overridable `reply`. Map and space-separated reply operations dispatched each entry through their public method. | The same public override dispatch is preserved. Emitter interoperability calls the documented three-argument `on` and `off` methods once per binding, including when an override delegates with only those documented arguments. | Preserved | Lifecycle and instrumentation mixins may continue overriding the canonical registration methods. Overrides should delegate synchronously when they want the base registration behavior. |\n| Object-form event triggering | Backbone.Events treated map keys as event names, ignored the mapped values, and passed arguments after the map to each handler. | Object-form `trigger` is a Marionette extension: each map value is the sole argument for its event, and arguments after the map are not forwarded. | Changed | Move the intended per-event handler argument into each map value. Use separate string-form `trigger` calls when an event needs multiple arguments. |\n| Object-form requests | Backbone.Radio passed each mapped value as the first argument to its handler and forwarded arguments after the map. | Marionette preserves that argument order and returns the same per-name result map shape. | Preserved | No request-call change is required. |\n| Event-name ownership | Event names matching inherited object properties could fail during registration or consult inherited private-store entries. A literal `__proto__` name could affect the event store's prototype. | Only explicitly registered own event names are dispatched or removed. `constructor`, `toString`, `__proto__`, and other inherited names are ordinary event names, and `__proto__` does not change the store prototype. | Changed | Register and remove event names through `on`, `off`, `listenTo`, and `stopListening`; do not modify or inherit from private event stores. |\n| Entity-event map `__proto__` name | Declarative entity-event maps silently discarded an own enumerable `__proto__` name during normalization, so it was never bound or selectively unbound. | `bindEvents` and selective `unbindEvents`, including `modelEvents`, `collectionEvents`, and `radioEvents`, throw `MN0026` before delegation when the map has an own enumerable `__proto__` entry. Marionette does not reject other prototype-collision names: its Events API supports them, but third-party emitters such as Backbone may not safely support every name. | Changed | Rename the `__proto__` entity event or bind it through an entity API that explicitly supports the name; verify other prototype-collision names against the entity's emitter, and omit the map to unbind every event from an entity. |\n| `Mn.Object` | The default namespace exposed an `Object` alias for the Marionette object class. | The alias is not restored. | Removed | Use `import { MnObject } from 'marionette';`; final migration guidance is tracked in [#147](https://github.com/marionettejs/marionette/issues/147). |\n| `MnObject` | The Marionette object class was available as the named `MnObject` export. | `MnObject` remains a named export. | Preserved | Import it directly: `import { MnObject } from 'marionette';`. |\n| Reentrant destruction | Calling `destroy()` from `before:destroy` could recurse or repeat teardown for MnObject, Application, and Region. View guarded reentry, but a throwing `before:destroy` left it unable to retry. | MnObject, View, Behavior, and Region guard repeated synchronous teardown as documented by their class contracts. Application destruction is part of its asynchronous lifecycle: compatible repeated calls share an in-flight Promise, and later calls after destruction resolve `true` without restarting teardown. | Changed | Synchronous lifecycle errors stop teardown; later `destroy()` calls do not retry it. For Application, await `destroy()` and treat a rejected current hook as failure; ordinary supersession resolves rather than rejects. |\n| Application lifecycle | `Application#start(options)` synchronously fired `before:start` and `start` on every call and returned the Application. Application had no core stop, restart, readiness, running-state, or overlap contract. | `start`, `stop`, `restart`, and `destroy` return `Promise<boolean>`. `true` means the requested target state settled, including idempotent no-op; `false` means a later incompatible operation superseded it. Current hook failures reject. `isRunning()` is true only after startup readiness. Readiness hooks receive an operation context whose `signal` is aborted when their phase is invalidated. | Changed | Await startup before route dispatch or other work that requires readiness. Move asynchronous preparation into a Promise returned by `onBeforeStart` and pass its context signal to cancellable work. Do not treat `false` as failure or add a catch for ordinary cancellation. Remove Toolkit-style `triggerStart` / `finallyStart` overrides; core awaits `onBeforeStart` directly. |\n| Application ownership and hierarchy | Core Application had no parent, named-child, root, or child lifecycle contract. Toolkit supplied a separate App class with class/config overloads and per-child lifecycle flags. | Application owns existing child Application instances through one explicit registration path. Name, individual-child, presence, and fresh-snapshot reads expose the public ownership contract without private-field access. Owned children start and stop sequentially with their owner. A conflicting direct child operation cancels owner completion, while descendant startup cannot interrupt owner destruction. Parent destruction stops children before its readiness hook, then destroys them in registration order. A child destroyed directly removes itself from its owner. Conflicts throw `MN0031`, while registration after either lifecycle becomes terminal is a no-op. | Added | Keep Toolkit's established `addChildApp`, `getChildApp(s)`, `removeChildApp`, and `getName` vocabulary, but construct the child explicitly and use `hasChildApp` when allocation must be avoided. Remove `AppClass` configs, `preventDestroy`, `*WithParent` flags, and public parent/root traversal; longer-lived capabilities need a longer-lived owner, and children should receive required collaborators explicitly. Await owner and child lifecycle operations. |\n| Application root View and Region ownership | Core Application could construct or receive a Region and proxy `showView`, but it read any `currentView` from that Region and did not coordinate Region or root View teardown with Application lifecycle. | The Application's View is its Region's `currentView`, including Views shown directly through the Region. Stop empties the Region's current View. Destroy also destroys a constructed Region, releases a borrowed Region without destroying it, and clears the Region reference. | Changed | Use a Region instance when an external owner controls the host lifetime; use a selector, Region class, or definition object when the Application should own it. Show a new root View from `onStart` after restart. Views shown directly in a borrowed Region are also emptied when the Application stops. |\n| Custom `destroy` overrides | An override could mutate owned state before calling the v4 base `destroy()` method. Reentrant calls and throwing `before:destroy` handlers did not have one consistent retry boundary. | The synchronous base method for MnObject, View, CollectionView, Behavior, and Region establishes its destruction guard before `before:destroy`. Application owns a separate asynchronous lifecycle and returns its destroy Promise. Cleanup performed before delegating remains outside either guarantee. | Changed | Audit every custom `destroy` override. Synchronous owner overrides must preserve the base reentry boundary. Application overrides must return or await the Promise from the base operation and must not recreate a synchronous teardown path. |\n| Behavior element retargeting | The undocumented `Behavior#proxyViewProperties()` helper copied the host View's element properties onto the Behavior. | Behaviors share their host's fixed root. `Behavior#setElement()` and `proxyViewProperties()` are removed. | Removed | Choose the host root at construction; do not retarget Behaviors independently. |\n| Rendering a destroyed View | A destroyed `View#render` could still resolve `getTemplate` before returning, while destroyed `CollectionView#render` behavior was undocumented. | Destroyed View and CollectionView render calls return the same instance without resolving templates, running render lifecycles, changing DOM, or recreating children. No diagnostic is thrown. | Changed | Render only live View and CollectionView instances. |\n| Adding a child to a CollectionView during or after destruction | Base `CollectionView#addChildView` could inspect or manage a supplied View and restart rendering once destruction began. | The base method returns the supplied View before inspecting the View, index, or options or changing events, ownership, DOM, or lifecycle state. | Changed | Add the child to a live CollectionView instead. Custom overrides own their behavior unless they delegate to the guarded base method. |\n| Delegating entity events during or after View destruction | Base `View#delegateEntityEvents`, `CollectionView#delegateEntityEvents`, and direct delegation through an attached Behavior could resolve maps and bind new model and collection subscriptions once host destruction began. | The base host methods return the host, and direct `Behavior#delegateEntityEvents` returns the Behavior, without resolving maps or binding handlers once the owning View's destruction starts. Behavior reuse after `Behavior#destroy` while its host remains live is outside this contract. `undelegateEntityEvents` is unchanged. | Changed | No guard is needed for a late base host or attached Behavior delegation call. Use a live View or CollectionView when subscriptions must be established, and undelegate before replacing its model or collection. Custom host and Behavior overrides own their behavior unless they delegate to the guarded base method. |\n| Binding UI during or after View destruction | Base `View#bindUIElements`, `CollectionView#bindUIElements`, and direct calls through a retained Behavior could query the retained root element and recreate bound UI once host destruction began. | The base host methods return the host, and direct `Behavior#bindUIElements` returns the Behavior, without resolving callable host UI, querying DOM, or binding View or Behavior UI once the owning View's destruction starts. Behavior reuse after `Behavior#destroy` while its host remains live is outside this contract. `unbindUIElements` and the `MN0023` unbound `getUI` diagnostic are unchanged. | Changed | No guard is needed for a late base host or Behavior binding call. Bind only while the owning View or CollectionView is live; continue to unbind explicitly when cleanup is required. Custom host and Behavior overrides own their behavior unless they delegate to the guarded base method. |\n| Framework errors | Framework invariant failures exposed names and prose messages without stable machine identifiers. | `MarionetteError` is a named export and framework invariant failures expose stable `MNxxxx` codes. | Changed | Catch `MarionetteError` and branch on `error.code`; do not parse message prose or legacy documentation URLs. |\n| Behavior declarations | Underscore could treat non-array values with numeric `length` as array-like behavior lists. | Arrays are the only list form. Object maps use own enumerable string keys in standard order; inherited, symbol, and non-enumerable keys are excluded, and numeric `length` is an ordinary map entry. | Changed | Use an array for list declarations or an ordinary object for named declarations; do not use generic array-like values. |\n| UI map ownership | Underscore could treat a UI map with numeric `length` as array-like and skip its other named keys. A literal own `__proto__` key could change the prototype of normalized or bound UI output instead of remaining a UI entry. | UI binding and map-normalization iteration use own enumerable string keys in standard JavaScript own-key order. Numeric `length` is an ordinary key, and literal own `__proto__` remains an own entry without changing output prototypes. Direct `@ui` lookup still accepts any own declared selector key, including a non-enumerable one. Arrays, sparse arrays, and other array-like values are not supported UI maps. | Changed | Supply iterated UI configuration as an ordinary object. Move intended iterated keys onto that object itself; do not use inherited, symbol, or non-enumerable properties or array-shaped maps. |\n| `@ui` reference validation | Missing `@ui` keys could normalize to an `undefined` selector or fail incidentally later. | Every `@ui.<name>` reference must name an own, declared `ui` key; otherwise Marionette throws `MN0018` during normalization. | Changed | Define the `ui` key or replace the reference with a literal selector. |\n| `getUI` binding lifecycle | Calling `getUI()` without declared or bound UI elements failed with an incidental `TypeError`. | View, CollectionView, and Behavior throw `MN0023` when `getUI()` is called without a declared `ui` map, before binding, or after unbinding. | Changed | Declare a `ui` map, then render a templated View or call `bindUIElements()` explicitly before `getUI()`; bind again before calling it after unbinding. |\n| Handler validation | Missing string handlers and invalid non-function values could be silently omitted during delegation or binding. | Every supplied handler must be a function or a string that resolves to a callable method; otherwise Marionette throws `MN0019` before delegation, binding, or selective unbinding. | Changed | Define or remove the named method, supply the handler as a function, or omit the map when unbinding everything. |\n| Region declaration maps | Underscore could treat a Region map with numeric `length` as array-like and skip its other named keys. | Region declarations and `addRegions` use own enumerable string keys in standard order. Inherited, symbol, and non-enumerable keys are excluded, and numeric `length` is an ordinary Region name. Arrays and other array-like values are not supported as Region declaration maps. | Changed | Supply Region declarations as an ordinary object and move intended definitions onto that object itself. |\n| Region names | Named Region methods inherited JavaScript property-key coercion, so arrays, objects, and Symbols could become or address Region names incidentally. | View Region names are non-empty strings. The public types require strings. Named registration, lookup, removal, and child operations reject empty names with `MN0032`; unsupported shapes have no guaranteed diagnostic. Explicitly registered string collisions such as `constructor`, `toString`, and `__proto__` remain valid. | Changed | Pass the intended non-empty string name directly; do not rely on property-key coercion. |\n| Named Region operations | Required View operations could fail with an incidental `TypeError` when the named Region did not exist. | `showChildView`, `detachChildView`, `getChildView`, and `removeRegion` throw `MN0020` for an unknown Region name; `getRegion` and `hasRegion` remain optional lookups. | Changed | Define the Region before using a required operation, or check it with `hasRegion` or `getRegion`. |\n| Region presence queries | `View#hasRegion` delegated to overridable `getRegion`, so querying an unrendered View rendered it before checking the name. | `hasRegion` checks only the View's own registered Region names without rendering, dispatching through `getRegion`, or changing View state, DOM, UI bindings, or lifecycle events. Missing and inherited-only names return `false`; prototype-collision names such as `constructor` return `true` when explicitly registered as own Regions. Destroyed Views return `false` after their Regions are removed. | Changed | Use `hasRegion` for a side-effect-free stored-ownership check. Use a child operation when rendering, override dispatch, and resolving the Region element are intended. |\n| Region lookup queries | `View#getRegion` rendered an unrendered View before looking up the Region, so `getRegion(name).show(view)` also rendered the parent implicitly. A non-delegating `getRegion` override could bypass that render. | `getRegion` returns an own registered Region without rendering or changing View state, DOM, UI bindings, or lifecycle events. Child operations now render a live, unrendered View before dispatching through overridable `getRegion`, including non-delegating overrides. Destroyed Views return `undefined` after their Regions are removed. | Changed | Use `getRegion` for a side-effect-free optional lookup. Use `showChildView`, `detachChildView`, or `getChildView` to retain deterministic render-before-lookup behavior; render the parent explicitly before calling a selector Region's `show` directly. |\n| Region snapshot queries | `View#getRegions` rendered an unrendered View before returning its Region map. | `getRegions` returns a fresh snapshot of own registered Region names without rendering or changing View state, DOM, UI bindings, or lifecycle events. Inherited keys are excluded, own prototype-collision names remain safe own entries, and destroyed Views return an empty snapshot. | Changed | Use `getRegions` for a side-effect-free ownership snapshot. `emptyRegions` remains a mutator: it renders a live, unrendered View before calling overridable `getRegions` and emptying the returned Regions. |\n| Region owner and name queries | Region ownership was maintained privately as `_parentView` and `_name`; reusing a Region instance or occupied name could leave conflicting private ownership records. | `Region#getOwner()` and `Region#getName()` expose the one current registered relationship without rendering, resolving elements, allocating a second registry, or mutating ownership. Standalone and successfully destroyed Regions return `undefined`. Re-adding the same Region under its current owner and name is a no-op. Registration rejects different-owner, different-name, lifecycle-state, and occupied-name conflicts with `MN0030` before committing them. If a lifecycle hook creates a conflict during ordered `addRegions` processing, earlier entries remain registered while the conflicting and later entries do not. | Added | Use these methods instead of reading private fields. Remove an existing named Region before replacing it, and use a fresh Region instance for another owner. For render-time setup, declare a stable Region in `regions` and only show its child from `onRender`. Keep `currentView` and `hasView()` for the Region's owned child rather than adding a second child lookup API. |\n| Operating through a destroyed Region | `Region#show` could render and retain a new View after destruction, while `empty`, `reset`, and `detachView` could continue mutating View ownership, DOM, or element caches. | After destruction, `show`, `empty`, and `reset` return the Region without changing it; `detachView` returns `undefined`. `show`, `detachView`, and recursive `destroy` calls are also no-ops while destruction is in progress. `empty` and `reset` remain available during cleanup. | Changed | Use a live Region when the operation must occur. Custom overrides own their behavior unless they delegate to the base method. |\n| Region destruction timing | `isDestroyed()` became `true` before `reset()` emptied the Region. | `isDestroyed()` becomes `true` after `reset()` completes, before the `destroy` event. It remains `false` in `before:empty` and `empty` handlers invoked during destruction. | Changed | Use the `destroy` event for completed teardown. Keep cleanup overrides synchronous and avoid recursive `empty` or `reset` calls from their own lifecycle handlers. Discard the Region if cleanup throws; later `destroy()` calls do not retry it. |\n| `onShow` | `Region` invoked `onShow(region, view, options)` for its `show` lifecycle event. | The Region `show` event and `onShow` method convention remain supported. | Preserved | No lifecycle rename is required. |\n| Native DomApi customization | Applications could replace or partially override Marionette's DomApi globally or per class. | The native DomApi is the default and remains customizable with `setDomApi` or class-level setters. | Documented | Customization applies to `View`, `CollectionView`, and `Region`. |\n| EventDelegator customization | DOM event delegation was supplied through Backbone view and jQuery behavior. | Native delegation is the default and can be replaced globally with `setEventDelegator` or per class. A complete adapter implements `delegate({ eventName, selector, handler, rootEl })` and returns an idempotent cleanup function for that exact registration; Marionette invokes it at most once. | Changed | Use the [EventDelegator runtime adapter contract](/docs/upgrade-guide.md#eventdelegator-runtime-adapter). Existing registrations retain their original cleanup when configuration changes; the current adapter is selected on the next delegation pass. |\n| Failed View construction cleanup | If `initialize()` or later constructor setup threw after DOM events, Behaviors, or State were initialized, those owned resources could remain attached to a caller-owned element or instance graph. | Constructor errors propagate without rolling back partially completed initialization. | Preserved | Do not depend on inspecting or retaining a partially constructed instance after an exception. See the [synchronous failure boundary](/docs/lifecycle.md#synchronous-failures). |\n| Host and Behavior DOM declaration collisions | Marionette flattened every Behavior and host `events` and `triggers` map before asking Backbone to delegate it. Identical event-and-selector keys overwrote earlier declarations according to merge order. | The host and each Behavior own independent delegated listeners. Every matching declaration runs once, without an ordering guarantee among Behavior handlers. | Changed | Remove code that depends on one declaration suppressing another. Give handlers distinct selectors or event types when only one should run, or coordinate the shared action explicitly. |\n| View DOM event redelegation | `View#delegateEvents(events?)` and `View#undelegateEvents()` refreshed or removed View and Behavior DOM handlers and returned the View. An explicit map replaced the View's configured `events` while retaining triggers and Behavior handlers. `setElement()` dispatched through the public pair. | The public pair remains available on View and CollectionView with the same explicit-map boundary, Behavior and trigger participation, and chainability. Callable maps and current UI selectors are resolved on each delegation pass, existing handlers are removed first, and calls after destruction starts are no-ops. | Preserved | Continue using the pair when declarative DOM configuration changes at runtime. Do not add destroyed-state guards around these calls. A method override owns cleanup or redelegation unless it calls the base method. |\n| `View#remove` | View inherited Backbone's `remove()` method, which removed its element and stopped listeners without running Marionette's complete destroy lifecycle. | The inherited method is intentionally removed. | Removed | Use `destroy()` for terminal cleanup. Use an owning Region's `detachView()` when the live View must be retained for reuse. |\n| Imperative `View#delegate` and `View#undelegate` | View inherited Backbone's singular low-level helpers for adding and removing individual delegated handlers. | The inherited helpers are intentionally removed; Marionette owns delegation through declarative maps and the EventDelegator adapter. | Removed | Prefer `events` and `triggers`, then call `delegateEvents()` to refresh them. Use native listeners or a custom EventDelegator only for interactions that cannot be expressed declaratively. |\n| Delegated DOM event semantics | Backbone delegated View events through jQuery, including jQuery special-event handling, namespaces, `return false` shorthand, and extra arguments supplied through jQuery triggering. | Delegated handlers receive a native event: `currentTarget` remains the View root and Marionette sets `delegateTarget` to the closest matching descendant, invoking once even when multiple ancestors match. Non-bubbling `mouseenter` is not emulated. Namespaces, `return false`, and extra trigger arguments are not native contracts. | Changed | Use bubbling native events or direct listeners, explicit event methods, and `CustomEvent.detail` as appropriate. See [Native delegation versus jQuery events](/docs/upgrade-guide.md#native-delegation-versus-jquery-events). The optional jQuery DomApi does not change event delegation. |\n| Adapter overlay input inheritance | DomApi and EventDelegator overlays could contribute inherited enumerable properties. | DomApi overlays copy own enumerable string and symbol properties and preserve a literal own `__proto__` property without changing the adapter prototype. EventDelegator configuration replaces the complete adapter object instead of overlaying it. | Changed | Move intended DomApi overrides onto the supplied object itself. Provide a complete EventDelegator with a callable `delegate` method. |\n\n## Reading changed and removed rows\n\nThe highest-impact migration boundaries are:\n\n- update the package name and imports before addressing runtime behavior;\n- keep default-namespace and `Mn.Object` compatibility out of new v5 code;\n- explicitly opt into Backbone or jQuery compatibility only where an\n  application still needs it;\n- resolve `View` and `CollectionView` selector strings before construction,\n  while leaving Region selector strings unchanged; and\n- audit code that depends on `$el`, jQuery-shaped `view.$()` results, or\n  the selected adapter's content replacement and cleanup semantics.\n\nThe full ordered migration procedure and remaining before-and-after examples are\ntracked in issue #147.\n\n### Await Application readiness\n\nV4 startup completed synchronously, so code commonly dispatched work on the\nnext line:\n\n```javascript\napp.start();\ndispatchInitialRoute();\n```\n\nV5 awaits a Promise returned by `onBeforeStart`. Await `start()` and dispatch\nonly when that exact startup reaches running state:\n\n```javascript\nconst App = Application.extend({\n  onBeforeStart(app, options, { signal }) {\n    return loadInitialData({ signal });\n  }\n});\n\nconst app = new App();\nif (await app.start()) {\n  dispatchInitialRoute();\n}\n```\n\nA `false` result means a later stop, restart, or destroy superseded this startup.\nIt is not a failure and does not need a `catch`. A current readiness failure\nrejects and should use the application's ordinary error path. Marionette aborts\nthe readiness signal before replacement readiness starts, so pass it to\ncancellable work rather than inventing a parallel cancellation hook.\n\n\n[Canonical source](/docs/markdown/docs/migration-from-v4.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "upgradeGuide.md",
      "title": "Upgrade guide",
      "section": "Migration",
      "kind": "guide",
      "url": "https://marionettejs.com/docs/upgrade-guide/",
      "markdownUrl": "https://marionettejs.com/docs/upgrade-guide.md",
      "sourceUrl": "https://marionettejs.com/docs/markdown/upgradeGuide.md",
      "sourceSha256": "d107bb7018e6b8b352bce0d5d9699add3562bf18399d7b529d97c612a17956a3",
      "sha256": "00cbeb1cfe92c5af4442ca7b2d45a9747175c760a9f68b64569d987a200141de",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 d107bb7018e6b8b352bce0d5d9699add3562bf18399d7b529d97c612a17956a3. -->\n\n# Upgrade guide\n\n## From backbone.marionette.js\n\nSee the [v4-to-v5 compatibility ledger](/docs/migration-from-v4.md) for the\ncurrent public behavior boundary. Final migration documentation is tracked in\n[issue #147](https://github.com/marionettejs/marionette/issues/147).\n\n## Use the included TypeScript declarations\n\nThe `marionette` package includes declarations for its public exports in ESM and\nCommonJS. Core declarations support TypeScript 6 and 7 with NodeNext or bundler\nresolution. Import instance and configuration types from `marionette`; a separate\ncore type package is not needed. Optional packages keep their own declarations\nand compiler support.\n\nBoth `.extend()` and direct native subclasses remain available. A native class's\ninherited `.extend()` needs an explicit constructor: default forwarding uses\n`parent.apply`, which cannot call a native class. Some native overrides after\n`.extend()` configuration, especially prototype `options` factories, encounter\nTypeScript's distinction between methods and properties. Define those overrides\nwith `.extend()`, or start the native subclass from the public base.\n\nCustom constructors can replace the instance. Their declared object return is\nthe constructed type; an unknown return stays unknown. See the\n[constructor typing guidance](https://github.com/marionettejs/marionette/blob/b06750c507494441f0b2298766b70087e45346a2/docs/maintainers/types.md) for preserving\nthe receiver through further extensions and the limits of return annotations.\n\n## Managed children use Marionette's lifecycle\n\nRegions, CollectionView children, and empty Views use Marionette View or\nCollectionView instances. Automatic Backbone View lifecycle adaptation is removed,\nincluding `supportsRenderLifecycle`, `supportsDestroyLifecycle`, and the fallback\nfrom `destroy()` to `remove()`.\n\nWrap an existing non-Marionette view in a Marionette View and own its rendering\nand cleanup explicitly. See the [wrapper example](/docs/region.md#wrapping-a-non-marionette-view).\nBehaviors also keep their initial host element; their internal `_syncElement()`\nretargeting method is removed. Event redelegation still refreshes their handlers.\n\n## Construct Views before showing them\n\n`Region#show` and `View#showChildView` require a Marionette View instance in v5. They no\nlonger construct a hidden base View from a template function, string, or View-options\nobject. Make the allocation and ownership explicit:\n\n```js\nimport { View } from 'marionette';\n\n// v4\nparent.showChildView('heading', 'Edit program');\nparent.showChildView('content', {\n  template,\n  templateContext: { section: 'main' }\n});\n\n// v5\nparent.showChildView('heading', new View({\n  template: () => 'Edit program'\n}));\nparent.showChildView('content', new View({\n  template,\n  templateContext: { section: 'main' }\n}));\n```\n\n## Configure model and collection data\n\n- Marionette core no longer reads Backbone-specific `cid`, `attributes`, `get`,\n  `models`, `indexOf`, or structural event payloads.\n- Plain object models and array collections work through the default DataApi.\n- `DataApi.models(collection)` replaces the pre-stable\n  `DataApi.items(collection)` name without a compatibility alias.\n\n  ```js\n  // before\n  const models = DataApi.items(collection);\n\n  // v5\n  const models = DataApi.models(collection);\n  ```\n- View templates with a collection and no model now receive the result of\n  `serializeCollection()` on the `models` property. By default, that result is an\n  array of serialized values. Replace the pre-stable `items` property without\n  retaining both names.\n\n  ```js\n  // before\n  template: ({ items }) => items.map(renderModel)\n\n  // v5\n  template: ({ models }) => models.map(renderModel)\n  ```\n- Applications whose Views use Backbone models or collections must select its\n  DataApi before constructing those Views:\n\n  ```sh\n  npm install @mnjs/adapters backbone\n  ```\n\n  ```js\n  import BackboneApi from '@mnjs/adapters/backbone';\n  import { setDataApi } from 'marionette';\n\n  setDataApi(BackboneApi);\n  ```\n\n  Configure `setStateApi(BackboneApi)` separately only when declarative\n  `stateEvents` observe a Backbone state source. Using Backbone.Router alone\n  requires neither adapter. See [Choosing integrations](/docs/choosing-integrations.md).\n\n- Other data sources can configure `setDataApi` with methods for identity,\n  reads, serialization, ordered model snapshots, subscriptions, and collection\n  observation. XState actors can use `@mnjs/adapters/xstate`.\n  See [Data API](/docs/data-api.md).\n- State owners return the exact supplied source from `getState()`. Use\n  `createState(options)` for an owned source, and configure `setStateApi` when\n  declarative `stateEvents` need observation. The v5 alpha concrete `State`\n  export is removed. See [State sources and StateApi](/docs/state.md).\n- `Application#getParentApp()` and `Application#getRootApp()` are removed. Pass\n  required collaborators to child Applications explicitly when constructing\n  them instead of traversing upward.\n- Replace `children.findByModelCid(cid)` with `children.findByModel(model)`.\n\n## Native data package\n\n- Use `Model.toObject()` and `Collection.toArray()` for plain attribute data.\n  `toJSON()` is removed from the native package; serialize those plain values\n  explicitly with `JSON.stringify`. Template data comes from attributes and is\n  independent of conversion overrides.\n- `Collection.touch()`, `swap()`, and `replace()` are removed. Update an existing\n  model with `model.set()` and bind child rendering with `modelEvents`. Use\n  `remove`/`add` or `reset` when replacing membership intentionally.\n- `Collection.move(modelOrId, index)` retains existing models and child Views for\n  explicit list ordering. Listen to `sort`, which both `move` and `sort` emit;\n  the native `reorder` event is removed.\n- Native DataApi keys are model `cid` values, so application ids can change\n  without changing child identity. Keep application ids unique for unambiguous\n  collection lookup.\n- Collection notifications now follow ordinary synchronous events. They do not\n  combine nested mutations or recover missed notifications after a listener\n  throws. Schedule structural mutations requested by collection or child\n  lifecycle listeners after the current notification has returned.\n\n## CollectionView child rendering\n\nCollection changes, `sort()`, and `filter()` share the child-rendering path.\nExisting visible children stay mounted, including with a custom comparator or\nfilter. `attachHtml` receives only elements that need attaching; it is no longer\ncalled just to reorder mounted children. Reordering uses `Dom.moveEl`.\n`Dom.swapEl` is removed; `swapChildViews()` exchanges the children using at most\ntwo `Dom.moveEl` calls. Custom DomApi implementations only need `moveEl` for\nthese placement operations. The child-render pass restores focus and text\nselection if a DOM move loses them; a direct swap only preserves them when the\nbrowser supports state-preserving moves.\n\nOnly a numeric `addChildView` index bypasses sorting and filtering. Passing\n`null` or options without an index now follows the same comparator/filter path\nas omitting the index.\n\n`before:render:children` and `render:children` receive all visible children,\nregardless of which templates needed rendering. Do not treat that argument as\nan added-children or updated-children list.\n\nOverrides of `sort()` and `filter()` own their behavior. Call the parent method\nwhen you want its sorting, filtering, and rendering steps. The early v5 fallback\nthat forced a render after an override has been removed.\n\n## CollectionView source order and presentation sorting\n\n- A normalized DataApi `reorder` or `update` keeps keyed children aligned with\n  the collection source order while `sortWithCollection` is enabled.\n- `viewComparator: false` disables the separate presentation comparator; it no\n  longer freezes the current child order against structural source changes.\n- Set `sortWithCollection: false` when a CollectionView must preserve manually\n  managed child order instead of following the source.\n- An immutable update that replaces a model with a different object at the same\n  stable key recreates that child View. Do not retain references to the old\n  child across such an update.\n\n## Underscore is no longer a peer dependency\n\n- Marionette v5 core does not import or declare Underscore as a peer dependency.\n- Remove an explicit Underscore installation if it existed only for Marionette.\n  Keep it as an application dependency when your own code uses it, such as an\n  `_.template` supplied to a View.\n- Applications using Backbone still receive Underscore through Backbone's own\n  declared dependency; the Marionette integration does not import it.\n\n## View roots are fixed at construction\n\n`View#setElement()` and `CollectionView#setElement()` are removed. Choose the\nroot through `new View({ el })` or `new CollectionView({ el })`; both also accept\nan `el` factory. Without an `el`, Marionette creates one from `tagName`.\nThe public instance `el` is readonly. Direct reassignment is unsupported.\n\nRender into the existing root and use Regions to move or detach the View.\nWhen another system replaces the root, destroy the old View and create a new\nowner for the replacement element. Keep persistent state in the model or an\nexternally owned state source. Custom `setElement()` overrides are no longer\ncalled during construction; move initialization to `initialize()` or an `el`\nfactory, as appropriate.\n\n## View `el` is element-only\n\n- `View` (and `CollectionView`) accept a DOM element for `el` in v5. Selector\n  strings are no longer resolved, and jQuery collections must be unwrapped.\n- v4 inherited string-`el` resolution from `Backbone.View._ensureElement`, which\n  used jQuery to look up the selector. v5 drops `Backbone.View` inheritance and\n  the default jQuery dependency, so the string-resolution path goes with them.\n- v5 now throws a `ViewError` with a migration hint on construction when a string is passed, instead of silently storing the raw\n  string as `view.el` and failing later in DOM code.\n- Migration: resolve at the call site.\n\n  ```js\n  // v4\n  new View({ el: '#root' });\n\n  // v5\n  new View({ el: document.querySelector('#root') });\n  ```\n\n- `Region` continues to accept selector strings. That API is Marionette-native\n  (the Region abstraction has always been \"where to mount\"), not inherited from\n  Backbone, so it is preserved. When the mount point is already resolved, pass\n  its native element rather than a jQuery collection.\n\n## Refresh View root attributes explicitly\n\nUse `renderAttributes()` when `attributes`, `id`, or `className` changed but the\nView's template content and owned children should remain in place:\n\n```js\nconst RowView = View.extend({\n  attributes() {\n    return {\n      'aria-selected': this.selected ? 'true' : 'false'\n    };\n  },\n\n  className() {\n    return this.selected ? 'selected' : null;\n  }\n});\n\nrow.selected = true;\nrow.renderAttributes();\n```\n\nThis explicit refresh is separate from `render()` and emits no render lifecycle\nevents. With the default DomApi, only explicit `null` removes a named attribute;\n`undefined` and omitted keys leave existing attributes untouched. Custom DomApi\nadapters must implement the same `setAttributes` behavior.\n\nAttribute maps use DOM attribute names (`class`, `for`), not property names\n(`className`, `htmlFor`). The View-level `className` option still works. Earlier\nv5 alphas also assigned matching element properties; v5 now applies attributes\nonly. Update live form values and custom element properties explicitly on `el`.\nFor boolean HTML attributes, use `disabled: isDisabled ? '' : null` instead of\n`disabled: isDisabled`. Other values, including `false`, are converted to strings;\nARIA attributes such as `aria-selected: false` therefore retain `\"false\"`.\n\n## jQuery DOM compatibility\n\nv5 core does not depend on jQuery and does not create `$el`. Configure the optional\nDOM adapter when the application needs jQuery queries and content operations:\n\n```js\nimport $ from 'jquery';\nimport { View } from 'marionette';\nimport JQueryDomApi from '@mnjs/adapters/dom/jquery';\n\nconst JQueryView = View.extend({\n  initialize() { this.$el = $(this.el); }\n});\nJQueryView.setDomApi(JQueryDomApi);\n```\n\nInstall `@mnjs/adapters` and `jquery` for this integration. The fixed root\nmakes the application-owned wrapper valid for the View's lifetime. CollectionViews\nand Behaviors can initialize `$el` in the same way. A subclass overriding\n`initialize()` must also perform any setup it needs from its application base.\n\nCore View, CollectionView, and Behavior types no longer take a `Wrapped` generic.\n`ViewInstance<Options, State, Query, Wrapped>` becomes\n`ViewInstance<Options, State, Query>`, and `DomApi<Query, Wrapped, Content>` becomes\n`DomApi<Query, Content>`. Declare `$el: JQuery<Element>` on application subclasses\nthat provide it. Use a TypeScript `declare` field so it does not overwrite the\nwrapper initialized by the base constructor.\n\nThis integration does not restore Backbone.View inheritance. Resolve selector\nstrings or unwrap jQuery collections before supplying a View `el`.\n\n## Native delegation versus jQuery events\n\nThe default EventDelegator uses `addEventListener` on the View's root element.\nDuring a delegated handler, the native `event.currentTarget` is therefore the\nView's root `el`. Marionette sets `event.delegateTarget` to the closest matching\ndescendant between the original target and that root. If nested ancestors match\nthe same selector, only that closest match invokes the handler; Marionette does\nnot invoke it again for every matching ancestor.\n\nThis is a native DOM contract, not an emulation of jQuery's event system:\n\n- `mouseenter` does not bubble, and Marionette does not provide jQuery's special\n  delegated `mouseenter` handling. Use a bubbling event such as `mouseover`\n  with an appropriate `relatedTarget` check, or bind `mouseenter` directly to\n  the intended element.\n- A name such as `click.menu` is a literal native event type, not a `click`\n  event in a jQuery namespace. Marionette already tracks and removes a View's\n  delegated listeners; application-owned native listeners should retain their\n  own callbacks or abort signals for cleanup.\n- Returning `false` from a handler does not prevent the default action or stop\n  propagation. Call `event.preventDefault()` and/or `event.stopPropagation()`\n  explicitly.\n- Browser `dispatchEvent()` supplies only the event object to a handler; jQuery\n  trigger arguments are not forwarded. Put application data in a\n  `CustomEvent`'s `detail`, or use Marionette events when positional arguments\n  are part of the application contract.\n- Delegated `focus` and `blur` handlers run during capture, before listeners on\n  the target element. A Marionette trigger stops propagation by default, so set\n  `stopPropagation: false` on a focus or blur trigger when the target must also\n  receive the event. Marionette does not translate these names to `focusin` or\n  `focusout`.\n\nThe optional jQuery DomApi changes query and DOM-manipulation operations only;\nit does not replace the native EventDelegator. Applications with a verified\nneed for different delegation semantics can provide an explicit adapter through\n`setEventDelegator`.\n\n### EventDelegator runtime adapter\n\nAn EventDelegator is a complete adapter with one method:\n`delegate({ eventName, selector, handler, rootEl })`. It registers that handler\nand returns an idempotent cleanup function for the exact registration, including\nits original root and listener options. Marionette stores the cleanup and calls\nit during redelegation or destruction. Registration and cleanup errors stop the\noperation; failed construction is not rolled back. The adapter must not mutate\nView internals. See the\nEventDelegator Adapter section of the DOM interactions API documentation for\nthe complete timing, error, and cleanup contract.\n\n## Atomic Radio migration\n\nMarionette v5 owns the `Radio` singleton used by `channelName`, `radioEvents`,\nand `radioRequests`. It is not the singleton exported by `backbone.radio`.\nReplace every application import in one migration:\n\n```js\n// v4\nimport Radio from 'backbone.radio';\n\n// v5\nimport { Radio } from 'marionette';\n```\n\nThis includes publishers and requesters that do not instantiate a Marionette\nclass. Leaving either import in the application creates two channels with the\nsame name on disconnected buses, so messages and requests can disappear\nwithout an exception. Do not bridge, mirror, or run both singletons as a\ncompatibility strategy.\n\nReplace `Radio.DEBUG = true` with `Radio.setDebug()` and disable it with\n`Radio.setDebug(false)`. Import the Requests mixin with\n`import { Requests } from '@mnjs/radio'` and compose it into an object with\n`Object.assign`. Import `Channel` from the same package for standalone channels,\nor use `new runtime.Radio.Channel(name)` for runtime-specific logging. Standalone\nchannels are not registered; their owner calls `reset()` when finished.\n\n`Radio.log` and `Radio.debugLog` remain replaceable hooks, scoped to each Radio\ninstance. `setDebug(false)` also suppresses custom warning hooks. Existing channels\nuse replacement hooks immediately, and hooks receive their Radio as `this`.\n\nRequest/reply methods are not mixed into `Application`, `Behavior`,\n`CollectionView`, `MnObject`, `Region`, or `View` instances. Replace an\nalpha-only instance call with an explicit channel:\n\n```js\n// before\nview.reply('status:current', getStatus);\n\n// v5\nRadio.channel('status').reply('status:current', getStatus);\n```\n\nUse `radioRequests` on `Application` or `MnObject` for declarative replies on\ntheir configured channel. Any owner can use `bindRequests(channel, bindings)`\nwhen it receives the channel explicitly. Pair that registration with\n`unbindRequests(channel)` in the owner's cleanup hook; imperative bindings to an\narbitrary channel are not automatically tracked for destruction. Unbinding this\nway removes only that owner's replies.\n\n## `detachContents` policy\n\n- The default native DomApi `detachContents(el)` clears the element via\n  `el.textContent = ''`. Children are removed from `el`; callers retaining a\n  child reference still retain its listeners and data.\n- v4 used jQuery's `$(el).contents().detach()`, which is jQuery's documented\n  detach-for-reinsertion path. It removes children from `el` while preserving\n  jQuery's internal handler/data bookkeeping on those elements.\n- Native node removal does not call jQuery's cleanup machinery either.\n  Referenced detached nodes retain native listeners, jQuery `.on()` handlers,\n  and `.data()` values with both implementations. Detachment alone is not a\n  reason to add jQuery. This differs from content replacement with jQuery's\n  `.html()`, which cleans jQuery handlers and data from removed descendants.\n- Applications needing jQuery query and content-operation semantics can select\n  the optional jQuery DomApi adapter at app boot:\n\n  ```js\n  import { setDomApi } from 'marionette';\n  import JQueryDomApi from '@mnjs/adapters/dom/jquery';\n\n  setDomApi(JQueryDomApi);\n  ```\n\n  The adapter's `detachContents(el)` calls `$(el).contents().detach()`,\n  matching the v4 behavior.\n\n- The optional jQuery adapter is described in the\n  [installation guide](/docs/installation.md#jquery-dom-adapter-is-optional).\n\n### DOM adapter setup\n\nMorphdom and Lit now live under `@mnjs/adapters/dom/` and export DOM\noperation objects rather than class installers. Update imports from the former\n`render` directory; those package subpaths are removed.\n\n```js\nimport MorphdomDomApi from '@mnjs/adapters/dom/morphdom';\nimport LitDomApi from '@mnjs/adapters/dom/lit-html';\n\nMorphView.setDomApi(MorphdomDomApi);\nLitView.setDomApi(LitDomApi);\n```\n\nCustom renderers must return their template result. `undefined` is passed to\n`Dom.setContents` and clears contents with the supplied native, jQuery, Morphdom,\nand Lit adapters; it no longer signals a renderer that performed its own DOM\nupdate. Put direct DOM updates in `setContents` instead.\n\nLit uses element-only `notifyAttach` and `notifyDetach` hooks and no longer patches View\nlifecycle methods. Detachment and destruction disconnect directives without\nemptying their DOM. With attachment monitoring disabled, deliver these\nnotifications from application code. Lit event handlers use the element as their\nreceiver rather than the View; use a closure for View access.\n\n## Shared utilities\n\nReusable helpers live in `@mnjs/utils`. Core and native data use the same\nimplementations; install the matching version directly when importing helpers\ninto your own components. Existing public Marionette helper exports still refer\nto those functions. Source-file imports are not package entry points.\n\nCore ESM and CommonJS builds import `@mnjs/utils` and `@mnjs/radio`.\nBrowser projects loading raw ES modules must map both packages in their import map, or use a\nbundler. Standalone UMD builds remain self-contained.\n\n### Native object copying\n\nUse object spread or `Object.assign` instead of the removed `@mnjs/utils`\n`assignOwn` and `assignIn` helpers. Configuration copies follow native own-property\nsemantics, including enumerable symbol keys; string sources expose character keys\ninstead of being silently ignored. There is no getter-ordering contract beyond\nthe chosen native operation. `extend` retains inherited enumerable parent statics\nand defines subclass properties so they can shadow inherited getters. Dynamic\nmodel and event keys such as `__proto__` remain ordinary data properties.\n\n### Standalone Events, Radio, and data\n\n`@mnjs/utils` owns the shared `Events` implementation. `@mnjs/radio`\nexports the default `Radio` and the `createRadio()` factory. Core continues to\nexport the same Events, Error, and default Radio within each module format.\n`createMarionette()` continues to create an isolated Radio for each runtime.\n\n`@mnjs/data` now depends only on utils; core is no longer a peer dependency.\nStandalone data and messaging consumers do not need to install Marionette core.\nThese packages keep the same version and release together with core and adapters.\n\n\n[Canonical source](/docs/markdown/upgradeGuide.md) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0001",
      "title": "MN0001: view el must be dom element",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0001/",
      "markdownUrl": "https://marionettejs.com/errors/MN0001.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "8b884a332790d23a2ca9947db27e4e4ca800690db2d589a44ca31438605d7848",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0001: view el must be dom element\n\nStatus: retired\nObjects: CollectionView, View\nCategory: dom\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0002",
      "title": "MN0002: region el type invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0002/",
      "markdownUrl": "https://marionettejs.com/errors/MN0002.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "7414f35dfbf770a2809704c5d788ea9c27f72a35f90b290844b94c5e4214a0e7",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0002: region el type invalid\n\nStatus: retired\nObjects: Region\nCategory: dom\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0003",
      "title": "MN0003: view already owned",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0003/",
      "markdownUrl": "https://marionettejs.com/errors/MN0003.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "cff081eb2f064d8890ba1dbf2add28adfbde27ad6cbd8e2b07f547bc40efcf13",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0003: view already owned\n\nStatus: active\nObjects: CollectionView, Region, View\nCategory: ownership\nSeverity: error\n\n## Remediation\n\nDetach or remove the view from its current Region or CollectionView before showing it elsewhere, or create a new view instance.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0004",
      "title": "MN0004: region el required",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0004/",
      "markdownUrl": "https://marionettejs.com/errors/MN0004.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "7a5f0a0389cbad2c7cea1572dd06149a84f58fdb415712f24b00adea1e84df1a",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0004: region el required\n\nStatus: active\nObjects: Region\nCategory: dom\nSeverity: error\n\n## Remediation\n\nConfigure the Region with an el selector or DOM element before using it.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0005",
      "title": "MN0005: region el not found",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0005/",
      "markdownUrl": "https://marionettejs.com/errors/MN0005.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "3808131e41585745d9aa9b22376f30c02b6d10cb4e01106becbd6f64a1a58584",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0005: region el not found\n\nStatus: active\nObjects: Region\nCategory: dom\nSeverity: error\n\n## Remediation\n\nRender the parent View before direct selector-backed Region operations, ensure the selector resolves within its parent element, or explicitly allow a missing element where supported.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0006",
      "title": "MN0006: region view required",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0006/",
      "markdownUrl": "https://marionettejs.com/errors/MN0006.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "b18d4b965ed0f2d17ed604f3c0bf6b43125691c1a314c618de0b66b417e21d2f",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0006: region view required\n\nStatus: retired\nObjects: Region\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0007",
      "title": "MN0007: region view destroyed",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0007/",
      "markdownUrl": "https://marionettejs.com/errors/MN0007.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "04972e5527754b44a3aa71001a6ee8d7188eca5635e17ba747571004588fdbcd",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0007: region view destroyed\n\nStatus: active\nObjects: Region, View\nCategory: lifecycle\nSeverity: error\n\n## Remediation\n\nCreate a new View instance instead of attempting to show a destroyed view.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0008",
      "title": "MN0008: region definition invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0008/",
      "markdownUrl": "https://marionettejs.com/errors/MN0008.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "8fbfb8f6471f15a5da7f16c055656b784ef440e994483b86aad9a27ec42f3a60",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0008: region definition invalid\n\nStatus: retired\nObjects: Application, Region, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0009",
      "title": "MN0009: event bindings invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0009/",
      "markdownUrl": "https://marionettejs.com/errors/MN0009.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "d584d785cd1beef5b2c4697906506ab0000f1a8c40a67d61dacdff59b086d1c1",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0009: event bindings invalid\n\nStatus: retired\nObjects: Application, Behavior, CollectionView, MnObject, Region, View\nCategory: communication\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0010",
      "title": "MN0010: request bindings invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0010/",
      "markdownUrl": "https://marionettejs.com/errors/MN0010.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "30136b709d90ea4a6e762f9090469017b8bcd6799062312bc271bb713dddb107",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0010: request bindings invalid\n\nStatus: retired\nObjects: Application, Behavior, CollectionView, MnObject, Region, View\nCategory: communication\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0011",
      "title": "MN0011: collection view child view required",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0011/",
      "markdownUrl": "https://marionettejs.com/errors/MN0011.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "777ded415378998f276f7a7eac30fb679907188e08f57a1ba7a83600133c6126",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0011: collection view child view required\n\nStatus: active\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nConfigure childView with a View class or a function that returns a View class.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0012",
      "title": "MN0012: collection view child view invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0012/",
      "markdownUrl": "https://marionettejs.com/errors/MN0012.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "f9997c022e1d503a9df5debd955becbc82876f68a0ae9fda4d6bb188ca6e4811",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0012: collection view child view invalid\n\nStatus: retired\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0013",
      "title": "MN0013: collection view container not found",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0013/",
      "markdownUrl": "https://marionettejs.com/errors/MN0013.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "3c32e8ea72b25150390f9ec20be0052b0b94cf4c7df1efbfbd98968bd5f2d125",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0013: collection view container not found\n\nStatus: active\nObjects: CollectionView\nCategory: dom\nSeverity: error\n\n## Remediation\n\nEnsure childViewContainer resolves to an element within the rendered CollectionView.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0014",
      "title": "MN0014: collection view filter invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0014/",
      "markdownUrl": "https://marionettejs.com/errors/MN0014.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "f3ef961d575cb45e25888b11b456cf9aa1a3776a8e49cb899e73b0d28b92a2c1",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0014: collection view filter invalid\n\nStatus: retired\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0015",
      "title": "MN0015: collection view swap non children",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0015/",
      "markdownUrl": "https://marionettejs.com/errors/MN0015.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "972be450f3de0a0a30aec3e33cdd914c47b9d0d9777948706a2453ca05920820",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0015: collection view swap non children\n\nStatus: active\nObjects: CollectionView\nCategory: ownership\nSeverity: error\n\n## Remediation\n\nPass two views currently owned by the CollectionView to swapChildViews.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0016",
      "title": "MN0016: behavior definition invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0016/",
      "markdownUrl": "https://marionettejs.com/errors/MN0016.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "e2a5811f4e6c418cb4874a6e576d040d7e4b5aa167ba997c5dcc6c23f8343f21",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0016: behavior definition invalid\n\nStatus: retired\nObjects: Behavior, CollectionView, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0017",
      "title": "MN0017: radio channel name required",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0017/",
      "markdownUrl": "https://marionettejs.com/errors/MN0017.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "9a6d76979e2852833daee4dee719ee3f8c180dbe83495c805f7aa891d1a77d17",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0017: radio channel name required\n\nStatus: active\nObjects: Radio\nCategory: communication\nSeverity: error\n\n## Remediation\n\nPass a non-empty channel name when creating or accessing a Radio channel.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0018",
      "title": "MN0018: ui reference invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0018/",
      "markdownUrl": "https://marionettejs.com/errors/MN0018.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "a2a752ad787afc3b9cac901a9348097634c0a18882b6cb7f1968a055ec75e946",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0018: ui reference invalid\n\nStatus: active\nObjects: Behavior, CollectionView, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse @ui.<name> with a non-empty own key whose value is a string selector, or replace the reference with a literal selector.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0019",
      "title": "MN0019: handler not callable",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0019/",
      "markdownUrl": "https://marionettejs.com/errors/MN0019.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "d5142f998935339dfd8f09f5115ad43e10d6adbf0dafa44742f534d04dc740a8",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0019: handler not callable\n\nStatus: active\nObjects: Application, Behavior, CollectionView, MnObject, Region, View\nCategory: communication\nSeverity: error\n\n## Remediation\n\nProvide a function or the string name of a callable method on the binding context.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0020",
      "title": "MN0020: named region not found",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0020/",
      "markdownUrl": "https://marionettejs.com/errors/MN0020.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "57a621e9c15427179f461a5e0b7c168355e5944cbe2f23e633a30dfc21f8cfaf",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0020: named region not found\n\nStatus: active\nObjects: View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nDefine the named Region before using child-View or Region-removal operations, or use getRegion or hasRegion for optional lookup.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0021",
      "title": "MN0021: radio channel not found",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0021/",
      "markdownUrl": "https://marionettejs.com/errors/MN0021.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "bd7727d567d1f0af9efc179582c73765fdc0d5d16f4a1e5ed1aa00a973c0cd0d",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0021: radio channel not found\n\nStatus: active\nObjects: Radio\nCategory: communication\nSeverity: error\n\n## Remediation\n\nCreate the named channel with Radio.channel(name) before resetting it, or call Radio.reset() with no arguments to reset all existing channels.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0022",
      "title": "MN0022: collection view empty view invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0022/",
      "markdownUrl": "https://marionettejs.com/errors/MN0022.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "e3d7711cb115fbe3de335e0c81f8e71d59e1e261ecdc5f1bd6e80de9e80159b5",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0022: collection view empty view invalid\n\nStatus: retired\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0023",
      "title": "MN0023: ui elements unavailable",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0023/",
      "markdownUrl": "https://marionettejs.com/errors/MN0023.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "f2abdd262d39f2c538bd0f80e1b713057221eeeb5a5e47ccb56aa1a002baec04",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0023: ui elements unavailable\n\nStatus: active\nObjects: Behavior, CollectionView, View\nCategory: lifecycle\nSeverity: error\n\n## Remediation\n\nDeclare a ui map, then render the View or explicitly bind its UI elements before calling getUI; bind them again before calling getUI after unbinding.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0024",
      "title": "MN0024: child container argument invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0024/",
      "markdownUrl": "https://marionettejs.com/errors/MN0024.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "cd1a41e24402d7f82eab71ccb297220a296f562afa48db3eb7e0873dca65050a",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0024: child container argument invalid\n\nStatus: active\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nPass nonnegative integer counts. Reducing an empty child container requires an initial value.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0025",
      "title": "MN0025: child container method not callable",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0025/",
      "markdownUrl": "https://marionettejs.com/errors/MN0025.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "d3d10535d2134bee64f3ef1d11a78ccb9752d622edc08ff67eacaacb1fb67f37",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0025: child container method not callable\n\nStatus: retired\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0026",
      "title": "MN0026: entity event name unsafe",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0026/",
      "markdownUrl": "https://marionettejs.com/errors/MN0026.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "efd8ec7e7f97ef0e88be75ef41d5f07e965b7c5d2002e9573b598d57777e696b",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0026: entity event name unsafe\n\nStatus: active\nObjects: Application, Behavior, CollectionView, MnObject, Region, View\nCategory: communication\nSeverity: error\n\n## Remediation\n\nRename an own __proto__ entry in an entity-event map before binding or selectively unbinding it.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0027",
      "title": "MN0027: feature name invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0027/",
      "markdownUrl": "https://marionettejs.com/errors/MN0027.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "7ee72950da25fc65cb3fc2f2e14571c2efc485461e77e2ee6104ea224c2ea5e1",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0027: feature name invalid\n\nStatus: retired\nObjects: Behavior, CollectionView, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nThe v5 feature registry is removed. Configure child event prefixes per View, trigger behavior per trigger, and application values through State or explicit configuration.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0028",
      "title": "MN0028: region destroyed operation",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0028/",
      "markdownUrl": "https://marionettejs.com/errors/MN0028.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "d1f1c5354fe123e9f31c0cd086c60a3364d80ec7385b916a09b8b4068a8ad760",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0028: region destroyed operation\n\nStatus: retired\nObjects: Region\nCategory: lifecycle\nSeverity: error\n\n## Remediation\n\nCalls to show, empty, or reset after Region destruction are lifecycle-safe no-ops. Use a live Region when the operation must take effect.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0029",
      "title": "MN0029: view destroyed set element",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0029/",
      "markdownUrl": "https://marionettejs.com/errors/MN0029.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "619151985ce25aee4a135a8b7fcc50c8558de8dd928c8644f6e55d6aa2efe99b",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0029: view destroyed set element\n\nStatus: retired\nObjects: CollectionView, View\nCategory: lifecycle\nSeverity: error\n\n## Remediation\n\nCalls to setElement after View or CollectionView destruction begins are lifecycle-safe no-ops. Use a live instance when element replacement must take effect.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0030",
      "title": "MN0030: region registration conflict",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0030/",
      "markdownUrl": "https://marionettejs.com/errors/MN0030.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "dd3339073a8895dfcfc482366670d27d3f0b4d6785c58c0714b82ea45a3c7bcd",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0030: region registration conflict\n\nStatus: active\nObjects: Region, View\nCategory: ownership\nSeverity: error\n\n## Remediation\n\nRegister a live, unowned Region under an unused name; remove an existing named Region before replacing it and use a fresh Region instance for a different owner.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0031",
      "title": "MN0031: application registration conflict",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0031/",
      "markdownUrl": "https://marionettejs.com/errors/MN0031.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "dcbfdc1c34fbdb9594182c85bf8b80d890da863158406bb559f7a9b89fbec8bf",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0031: application registration conflict\n\nStatus: active\nObjects: Application\nCategory: ownership\nSeverity: error\n\n## Remediation\n\nRegister a live, unowned Application instance under an unused non-empty string name; use hasChildApp before constructing a dynamic child when allocation must be avoided.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0032",
      "title": "MN0032: region name invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0032/",
      "markdownUrl": "https://marionettejs.com/errors/MN0032.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "677781cf631fd60c192965e10a41f08e419ca6df1e5f82730c080fb39b271931",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0032: region name invalid\n\nStatus: active\nObjects: View\nCategory: ownership\nSeverity: error\n\n## Remediation\n\nPass a non-empty string name to a named Region operation.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0033",
      "title": "MN0033: merge options keys invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0033/",
      "markdownUrl": "https://marionettejs.com/errors/MN0033.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "dd23595f7ace41f75ed90f02312f29a8fcb1fc942e77672c5ee6f20c5155f94c",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0033: merge options keys invalid\n\nStatus: retired\nObjects: Application, Behavior, CollectionView, MnObject, Region, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0034",
      "title": "MN0034: state key invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0034/",
      "markdownUrl": "https://marionettejs.com/errors/MN0034.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "a7cad34a588c69fd2e1e082310a7b8571891b31abec06009e034f2fa9de90f40",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0034: state key invalid\n\nStatus: retired\nObjects: StateApi\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nThe concrete v5 alpha State key validation is removed. Use the selected source's native key contract.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0035",
      "title": "MN0035: state ownership conflict",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0035/",
      "markdownUrl": "https://marionettejs.com/errors/MN0035.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "97f7c4a427ef5572b99cc65ed904e7a39261389dbf2bb503361ff1648388d63c",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0035: state ownership conflict\n\nStatus: retired\nObjects: Behavior, CollectionView, MnObject, View\nCategory: ownership\nSeverity: error\n\n## Remediation\n\nThe concrete v5 alpha State ownership rule is removed. Supplied sources are borrowed and may be shared by multiple owners; createState results are owned and disposed by their owner.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0036",
      "title": "MN0036: event delegator contract invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0036/",
      "markdownUrl": "https://marionettejs.com/errors/MN0036.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "53b7deb4f31876430d9c8ff04fcc744d1496897ce0be96e8d00cbe0588955e3e",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0036: event delegator contract invalid\n\nStatus: retired\nObjects: Behavior, CollectionView, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nUse the documented argument types. Marionette no longer emits a dedicated runtime diagnostic for this unsupported input shape.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0037",
      "title": "MN0037: adapter observation unsupported",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0037/",
      "markdownUrl": "https://marionettejs.com/errors/MN0037.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "10c30f6d32962e0606cbc62331c7f70c346e44bd1177c1517c5603eddb744752",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0037: adapter observation unsupported\n\nStatus: active\nObjects: Application, Behavior, CollectionView, MnObject, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nConfigure a StateApi or DataApi that can observe the selected source, or remove the declarative event map.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0038",
      "title": "MN0038: adapter cleanup invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0038/",
      "markdownUrl": "https://marionettejs.com/errors/MN0038.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "3042b84a37efe4dba22f70d2831b7b3e630c4aceb16a48a147741bdc6be83786",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0038: adapter cleanup invalid\n\nStatus: retired\nObjects: Application, Behavior, CollectionView, MnObject, View\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nDataApi and StateApi adapters must return cleanup functions. Core no longer wraps or validates cleanup on each registration.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/MN0039",
      "title": "MN0039: collection data contract invalid",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/MN0039/",
      "markdownUrl": "https://marionettejs.com/errors/MN0039.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "9d5d87c884052f20a0213ea7b27d3a3f2c891826337f82ab4941ae4e1bbc45d6",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# MN0039: collection data contract invalid\n\nStatus: active\nObjects: CollectionView\nCategory: configuration\nSeverity: error\n\n## Remediation\n\nReturn an ordered array with unique stable keys and emit a valid reorder, reset, or update structural record.\n\n[Diagnostic catalog](/errors/index.md) · [Source identity](/docs/manifest.json)\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    },
    {
      "id": "errors/index",
      "title": "Diagnostic codes",
      "section": "Diagnostics",
      "kind": "diagnostic",
      "url": "https://marionettejs.com/errors/",
      "markdownUrl": "https://marionettejs.com/errors/index.md",
      "sourceUrl": "https://marionettejs.com/docs/source/config/diagnostics/catalog.json",
      "sourceSha256": "8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c",
      "sha256": "6ed6699baacdaa830950596305c8e41b4b15d62a6aac7a180e50abb15a5abd4a",
      "markdown": "<!-- Documentation snapshot: package 5.0.0-beta.1; channel next; base revision b06750c507494441f0b2298766b70087e45346a2; local changes false; original source SHA-256 8aaf72a68997636ef31de752f45110222104a5dc0e7e884a104e462cee7cda9c. -->\n\n# Diagnostic codes\n\n- [MN0001: view el must be dom element](/errors/MN0001.md): retired\n- [MN0002: region el type invalid](/errors/MN0002.md): retired\n- [MN0003: view already owned](/errors/MN0003.md): active\n- [MN0004: region el required](/errors/MN0004.md): active\n- [MN0005: region el not found](/errors/MN0005.md): active\n- [MN0006: region view required](/errors/MN0006.md): retired\n- [MN0007: region view destroyed](/errors/MN0007.md): active\n- [MN0008: region definition invalid](/errors/MN0008.md): retired\n- [MN0009: event bindings invalid](/errors/MN0009.md): retired\n- [MN0010: request bindings invalid](/errors/MN0010.md): retired\n- [MN0011: collection view child view required](/errors/MN0011.md): active\n- [MN0012: collection view child view invalid](/errors/MN0012.md): retired\n- [MN0013: collection view container not found](/errors/MN0013.md): active\n- [MN0014: collection view filter invalid](/errors/MN0014.md): retired\n- [MN0015: collection view swap non children](/errors/MN0015.md): active\n- [MN0016: behavior definition invalid](/errors/MN0016.md): retired\n- [MN0017: radio channel name required](/errors/MN0017.md): active\n- [MN0018: ui reference invalid](/errors/MN0018.md): active\n- [MN0019: handler not callable](/errors/MN0019.md): active\n- [MN0020: named region not found](/errors/MN0020.md): active\n- [MN0021: radio channel not found](/errors/MN0021.md): active\n- [MN0022: collection view empty view invalid](/errors/MN0022.md): retired\n- [MN0023: ui elements unavailable](/errors/MN0023.md): active\n- [MN0024: child container argument invalid](/errors/MN0024.md): active\n- [MN0025: child container method not callable](/errors/MN0025.md): retired\n- [MN0026: entity event name unsafe](/errors/MN0026.md): active\n- [MN0027: feature name invalid](/errors/MN0027.md): retired\n- [MN0028: region destroyed operation](/errors/MN0028.md): retired\n- [MN0029: view destroyed set element](/errors/MN0029.md): retired\n- [MN0030: region registration conflict](/errors/MN0030.md): active\n- [MN0031: application registration conflict](/errors/MN0031.md): active\n- [MN0032: region name invalid](/errors/MN0032.md): active\n- [MN0033: merge options keys invalid](/errors/MN0033.md): retired\n- [MN0034: state key invalid](/errors/MN0034.md): retired\n- [MN0035: state ownership conflict](/errors/MN0035.md): retired\n- [MN0036: event delegator contract invalid](/errors/MN0036.md): retired\n- [MN0037: adapter observation unsupported](/errors/MN0037.md): active\n- [MN0038: adapter cleanup invalid](/errors/MN0038.md): retired\n- [MN0039: collection data contract invalid](/errors/MN0039.md): active\n\n\n[Canonical source](/docs/markdown/config/diagnostics/catalog.json) · [Source identity](/docs/manifest.json)\n"
    }
  ]
}
