{"_id":"@aegisjsproject/disposable","_rev":"4-3a885eedc9315c3b0baaa15ae73ec480","name":"@aegisjsproject/disposable","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@aegisjsproject/disposable","version":"1.0.0","keywords":[],"author":{"name":"Chris Zuber","email":"admin@kernvalley.us"},"license":"MIT","_id":"@aegisjsproject/disposable@1.0.0","maintainers":[{"name":"shgysk8zer0","email":"shgysk8zer0@gmail.com"}],"homepage":"https://github.com/AegisJSProject/disposable#readme","bugs":{"url":"https://github.com/AegisJSProject/disposable/issues"},"dist":{"shasum":"f69335b04619311eb12c67dd995b905eb823898d","tarball":"https://registry.npmjs.org/@aegisjsproject/disposable/-/disposable-1.0.0.tgz","fileCount":9,"integrity":"sha512-e1pOYeyN7hr2QTOsx43OOOMGVp4avy60vV7/EtlQ/T9Tza07JlbDYjTLPynj+8bTmHtGjOAGVt5EzYfFH4HTFQ==","signatures":[{"sig":"MEUCIHcVGIIBZcgw6k08Rkb3Yf3FoYH4FP1AokrH/3D4AZMYAiEAhDO0zUYUV0iYD5wwIeIxX0fGa1myPnCdSWA+EZw11jw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45822},"main":"./disposable.cjs","type":"module","unpkg":"./disposable.min.js","module":"./disposable.js","engines":{"node":">=24.10.0"},"exports":{".":{"import":"./disposable.js","require":"./index.cjs"},"./*":{"import":"./*.js","require":"./*.cjs"},"./*.js":{"import":"./*.js","require":"./*.cjs"},"./*.cjs":{"import":"./*.js","require":"./*.cjs"},"./*.mjs":{"import":"./*.js","require":"./*.cjs"}},"funding":[{"url":"https://liberapay.com/shgysk8zer0","type":"librepay"},{"url":"https://github.com/sponsors/shgysk8zer0","type":"github"}],"gitHead":"287731a305e6307e666f2327518ef5e6bf7d5485","private":false,"scripts":{"test":"npm run lint:js && npm run run:tests","build":"npm run build:js","clean":"rm -f ./*.cjs","start":"http-server -c ./http.config.js","fix:js":"eslint . --fix","lint:js":"eslint .","prepare":"npm test && npm run build --if-present","build:js":"npm run clean && rollup -c rollup.config.js","run:tests":"node --test","preversion":"npm test && npm run build --if-present","create:lock":"npm i --package-lock-only --ignore-scripts --no-audit --no-fund","version:bump":"npm run version:bump:patch","version:bump:major":"npm version --no-git-tag-version major && npm run create:lock","version:bump:minor":"npm version --no-git-tag-version minor && npm run create:lock","version:bump:patch":"npm version --no-git-tag-version patch && npm run create:lock"},"_npmUser":{"name":"shgysk8zer0","email":"shgysk8zer0@gmail.com"},"repository":{"url":"git+https://github.com/AegisJSProject/disposable.git","type":"git"},"_npmVersion":"11.6.1","description":"A library of utility functions for working with disposable objects","directories":{},"_nodeVersion":"24.10.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.2","rollup":"^4.57.1","@rollup/plugin-terser":"^0.4.4","@shgysk8zer0/importmap":"^1.7.7","@shgysk8zer0/http-server":"^1.1.1","@aegisjsproject/dev-server":"^1.0.5","@aegisjsproject/http-utils":"^1.0.4","@shgysk8zer0/eslint-config":"^1.0.4"},"_npmOperationalInternal":{"tmp":"tmp/disposable_1.0.0_1770424461850_0.5249696711250011","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aegisjsproject/disposable","version":"1.0.1","keywords":["disposable","resource-management","explicit-resource-management","cleanup","lifecycle","memory-leaks","abort-controller","abort-signal","using"],"author":{"name":"Chris Zuber","email":"admin@kernvalley.us"},"license":"MIT","_id":"@aegisjsproject/disposable@1.0.1","maintainers":[{"name":"shgysk8zer0","email":"shgysk8zer0@gmail.com"}],"homepage":"https://github.com/AegisJSProject/disposable#readme","bugs":{"url":"https://github.com/AegisJSProject/disposable/issues"},"dist":{"shasum":"d9bc19f98e69e7088c18961de9ecc0c69effa144","tarball":"https://registry.npmjs.org/@aegisjsproject/disposable/-/disposable-1.0.1.tgz","fileCount":9,"integrity":"sha512-SYc9PMhg3cChesTtO34WNjdUU7Q8tOIEm9fb9mYzfm7L9VZPe9Jl+oNuR3RU45JsSnH/NtppxfpumfdEPX8amw==","signatures":[{"sig":"MEUCIQD0Hv18EtQwv5FGewzU4yExolpQQL0Zt3vmNiNre++cRgIgdiS/ToQRjNW3A9CFdyvl2vLYgeQ8QoqlEGHagD++pXE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aegisjsproject%2fdisposable@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":46086},"main":"./disposable.cjs","type":"module","unpkg":"./disposable.min.js","module":"./disposable.js","engines":{"node":">=24.10.0"},"exports":{".":{"import":"./disposable.js","require":"./index.cjs"},"./*":{"import":"./*.js","require":"./*.cjs"},"./*.js":{"import":"./*.js","require":"./*.cjs"},"./*.cjs":{"import":"./*.js","require":"./*.cjs"},"./*.mjs":{"import":"./*.js","require":"./*.cjs"}},"funding":[{"url":"https://liberapay.com/shgysk8zer0","type":"librepay"},{"url":"https://github.com/sponsors/shgysk8zer0","type":"github"}],"gitHead":"dba83a40d542cd371db686c9720fed8567aea661","private":false,"scripts":{"test":"npm run lint:js && npm run run:tests","build":"npm run build:js","clean":"rm -f ./*.cjs","start":"http-server -c ./http.config.js","fix:js":"eslint . --fix","lint:js":"eslint .","prepare":"npm test && npm run build --if-present","build:js":"npm run clean && rollup -c rollup.config.js","run:tests":"node --test","preversion":"npm test && npm run build --if-present","create:lock":"npm i --package-lock-only --ignore-scripts --no-audit --no-fund","version:bump":"npm run version:bump:patch","version:bump:major":"npm version --no-git-tag-version major && npm run create:lock","version:bump:minor":"npm version --no-git-tag-version minor && npm run create:lock","version:bump:patch":"npm version --no-git-tag-version patch && npm run create:lock"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f44c5377-1d13-4fba-b832-6cde97c5d72a"}},"repository":{"url":"git+https://github.com/AegisJSProject/disposable.git","type":"git"},"_npmVersion":"11.6.1","description":"A library of utility functions for working with disposable objects","directories":{},"_nodeVersion":"24.10.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.2","rollup":"^4.57.1","@rollup/plugin-terser":"^0.4.4","@shgysk8zer0/importmap":"^1.7.7","@shgysk8zer0/http-server":"^1.1.1","@aegisjsproject/dev-server":"^1.0.5","@aegisjsproject/http-utils":"^1.0.4","@shgysk8zer0/eslint-config":"^1.0.4"},"_npmOperationalInternal":{"tmp":"tmp/disposable_1.0.1_1770424971942_0.7416962872941224","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@aegisjsproject/disposable","version":"1.0.2","keywords":["disposable","resource-management","explicit-resource-management","cleanup","lifecycle","memory-leaks","abort-controller","abort-signal","using"],"author":{"name":"Chris Zuber","email":"admin@kernvalley.us"},"license":"MIT","_id":"@aegisjsproject/disposable@1.0.2","maintainers":[{"name":"shgysk8zer0","email":"shgysk8zer0@gmail.com"}],"homepage":"https://github.com/AegisJSProject/disposable#readme","bugs":{"url":"https://github.com/AegisJSProject/disposable/issues"},"dist":{"shasum":"551f778b672f95af55a39f60158e0c5dca166566","tarball":"https://registry.npmjs.org/@aegisjsproject/disposable/-/disposable-1.0.2.tgz","fileCount":17,"integrity":"sha512-lzdWZ3uWSUkB1XXKTjiA9Cg1vXdciS+1S25la+Qm3k75TkADpBWgfp5HsOuq4tFkwV2xAb5O5dK4AcJ0cQOzFA==","signatures":[{"sig":"MEUCIQD3vMPAsEeDSzmm9wVWyFWoEC1bjrIA8/ANgeoCnU/1/gIgOXjRwEtdCCzKKw3hvAkEtZzO7HI//IjB8BGFpEy2IjM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aegisjsproject%2fdisposable@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":77130},"main":"./disposable.cjs","type":"module","unpkg":"./disposable.min.js","module":"./disposable.js","engines":{"node":">=24.10.0"},"exports":{".":{"import":"./disposable.js","require":"./index.cjs"},"./*":{"import":"./*.js","require":"./*.cjs"},"./*.js":{"import":"./*.js","require":"./*.cjs"},"./*.cjs":{"import":"./*.js","require":"./*.cjs"},"./*.mjs":{"import":"./*.js","require":"./*.cjs"}},"funding":[{"url":"https://liberapay.com/shgysk8zer0","type":"librepay"},{"url":"https://github.com/sponsors/shgysk8zer0","type":"github"}],"gitHead":"13b4278fbaac6ff9bf3729440744c939f0c4db2d","private":false,"scripts":{"test":"npm run lint:js && npm run run:tests","build":"npm run build:js","clean":"rm -f ./*.cjs","start":"http-server -c ./http.config.js","fix:js":"eslint . --fix","lint:js":"eslint .","prepare":"npm test && npm run build --if-present","build:js":"npm run clean && rollup -c rollup.config.js","run:tests":"node --test","preversion":"npm test && npm run build --if-present","create:lock":"npm i --package-lock-only --ignore-scripts --no-audit --no-fund","version:bump":"npm run version:bump:patch","version:bump:major":"npm version --no-git-tag-version major && npm run create:lock","version:bump:minor":"npm version --no-git-tag-version minor && npm run create:lock","version:bump:patch":"npm version --no-git-tag-version patch && npm run create:lock"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f44c5377-1d13-4fba-b832-6cde97c5d72a"}},"repository":{"url":"git+https://github.com/AegisJSProject/disposable.git","type":"git"},"_npmVersion":"11.6.1","description":"A library of utility functions for working with disposable objects","directories":{},"_nodeVersion":"24.10.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.2","rollup":"^4.57.1","@rollup/plugin-terser":"^0.4.4","@shgysk8zer0/importmap":"^1.7.7","@shgysk8zer0/http-server":"^1.1.1","@aegisjsproject/dev-server":"^1.0.5","@aegisjsproject/http-utils":"^1.0.4","@shgysk8zer0/eslint-config":"^1.0.4"},"_npmOperationalInternal":{"tmp":"tmp/disposable_1.0.2_1770522914732_0.9187995872770578","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@aegisjsproject/disposable","version":"1.0.3","description":"A library of utility functions for working with disposable objects","keywords":["disposable","resource-management","explicit-resource-management","cleanup","lifecycle","memory-leaks","abort-controller","abort-signal","using"],"type":"module","main":"./disposable.cjs","module":"./disposable.js","unpkg":"./disposable.min.js","exports":{".":{"import":"./disposable.js","require":"./index.cjs"},"./*.js":{"import":"./*.js","require":"./*.cjs"},"./*.mjs":{"import":"./*.js","require":"./*.cjs"},"./*.cjs":{"import":"./*.js","require":"./*.cjs"},"./*":{"import":"./*.js","require":"./*.cjs"}},"engines":{"node":">=24.10.0"},"private":false,"scripts":{"test":"npm run lint:js && npm run run:tests","start":"http-server -c ./http.config.js","preversion":"npm test && npm run build --if-present","prepare":"npm test && npm run build --if-present","lint:js":"eslint .","fix:js":"eslint . --fix","build":"npm run build:js","run:tests":"node --test","clean":"rm -f ./*.cjs","build:js":"npm run clean && rollup -c rollup.config.js","create:lock":"npm i --package-lock-only --ignore-scripts --no-audit --no-fund","version:bump":"npm run version:bump:patch","version:bump:patch":"npm version --no-git-tag-version patch && npm run create:lock","version:bump:minor":"npm version --no-git-tag-version minor && npm run create:lock","version:bump:major":"npm version --no-git-tag-version major && npm run create:lock"},"repository":{"type":"git","url":"git+https://github.com/AegisJSProject/disposable.git"},"author":{"name":"Chris Zuber","email":"admin@kernvalley.us"},"license":"MIT","funding":[{"type":"librepay","url":"https://liberapay.com/shgysk8zer0"},{"type":"github","url":"https://github.com/sponsors/shgysk8zer0"}],"bugs":{"url":"https://github.com/AegisJSProject/disposable/issues"},"homepage":"https://github.com/AegisJSProject/disposable#readme","devDependencies":{"@aegisjsproject/dev-server":"^1.0.5","@aegisjsproject/http-utils":"^1.0.4","@rollup/plugin-terser":"^0.4.4","@shgysk8zer0/eslint-config":"^1.0.4","@shgysk8zer0/http-server":"^1.1.1","@shgysk8zer0/importmap":"^1.7.7","eslint":"^9.39.2","rollup":"^4.57.1"},"gitHead":"839304e499b78b899fed2b98d538d77efb05e80f","_id":"@aegisjsproject/disposable@1.0.3","_nodeVersion":"24.10.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-igRmavSeMaz8xxT1UcEO21RIFA4YBsTOMQTHHQiVxKSFQsByJ/whXtAF7BR6gedXIrlVgeam+BHjhdRSBzRAwA==","shasum":"7c9dc66483804f14a315332bc48a07090e3a8135","tarball":"https://registry.npmjs.org/@aegisjsproject/disposable/-/disposable-1.0.3.tgz","fileCount":17,"unpackedSize":77210,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aegisjsproject%2fdisposable@1.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBWtp5RNXVhUxK6FA2Aa9BNVMwtVkhch3/6BQLYVf39nAiEAhHHjbA+Q4IWRXbY4W73+v3s855/QS+QGhFnX2oaYmAw="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f44c5377-1d13-4fba-b832-6cde97c5d72a"}},"directories":{},"maintainers":[{"name":"shgysk8zer0","email":"shgysk8zer0@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/disposable_1.0.3_1770523638149_0.10026868022934599"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-07T00:34:21.789Z","modified":"2026-02-08T04:07:18.582Z","1.0.0":"2026-02-07T00:34:22.017Z","1.0.1":"2026-02-07T00:42:52.084Z","1.0.2":"2026-02-08T03:55:14.879Z","1.0.3":"2026-02-08T04:07:18.300Z"},"bugs":{"url":"https://github.com/AegisJSProject/disposable/issues"},"author":{"name":"Chris Zuber","email":"admin@kernvalley.us"},"license":"MIT","homepage":"https://github.com/AegisJSProject/disposable#readme","keywords":["disposable","resource-management","explicit-resource-management","cleanup","lifecycle","memory-leaks","abort-controller","abort-signal","using"],"repository":{"type":"git","url":"git+https://github.com/AegisJSProject/disposable.git"},"description":"A library of utility functions for working with disposable objects","maintainers":[{"name":"shgysk8zer0","email":"shgysk8zer0@gmail.com"}],"readme":"# `@aegisjsproject/disposable`\n\nA library of utility functions for working with disposable objects \n\n[![CodeQL](https://github.com/AegisJSProject/disposable/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AegisJSProject/disposable/actions/workflows/codeql-analysis.yml)\n![Node CI](https://github.com/AegisJSProject/disposable/workflows/Node%20CI/badge.svg)\n![Lint Code Base](https://github.com/AegisJSProject/disposable/workflows/Lint%20Code%20Base/badge.svg)\n\n[![GitHub license](https://img.shields.io/github/license/AegisJSProject/disposable.svg)](https://github.com/AegisJSProject/disposable/blob/master/LICENSE)\n[![GitHub last commit](https://img.shields.io/github/last-commit/AegisJSProject/disposable.svg)](https://github.com/AegisJSProject/disposable/commits/master)\n[![GitHub release](https://img.shields.io/github/release/AegisJSProject/disposable?logo=github)](https://github.com/AegisJSProject/disposable/releases)\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/shgysk8zer0?logo=github)](https://github.com/sponsors/shgysk8zer0)\n\n[![npm](https://img.shields.io/npm/v/@aegisjsproject/disposable)](https://www.npmjs.com/package/@aegisjsproject/disposable)\n![node-current](https://img.shields.io/node/v/@aegisjsproject/disposable)\n![npm bundle size gzipped](https://img.shields.io/bundlephobia/minzip/@aegisjsproject/disposable)\n[![npm](https://img.shields.io/npm/dw/@aegisjsproject/disposable?logo=npm)](https://www.npmjs.com/package/@aegisjsproject/disposable)\n\n[![GitHub followers](https://img.shields.io/github/followers/AegisJSProject.svg?style=social)](https://github.com/AegisJSProject)\n![GitHub forks](https://img.shields.io/github/forks/AegisJSProject/disposable.svg?style=social)\n![GitHub stars](https://img.shields.io/github/stars/AegisJSProject/disposable.svg?style=social)\n[![Twitter Follow](https://img.shields.io/twitter/follow/shgysk8zer0.svg?style=social)](https://twitter.com/shgysk8zer0)\n\n[![Donate using Liberapay](https://img.shields.io/liberapay/receives/shgysk8zer0.svg?logo=liberapay)](https://liberapay.com/shgysk8zer0/donate \"Donate using Liberapay\")\n- - -\n\n- [Code of Conduct](./.github/CODE_OF_CONDUCT.md)\n- [Contributing](./.github/CONTRIBUTING.md)\n<!-- - [Security Policy](./.github/SECURITY.md) -->\n\nA lightweight utility library for managing resource lifecycles in the browser and Node.js. It leverages the new `DisposableStack` and `using` syntax to handle cleanup for DOM elements, Event Listeners, Blob URLs, and AbortControllers automatically.\n\n## Installation\n\n```bash\nnpm install @aegisjsproject/disposable\n```\n\n> **Note:** This library relies on modern JavaScript features including `DisposableStack`, `Promise.withResolvers`, and `Promise.try`. Ensure your environment supports them or provide polyfills.\n\n## Features\n\n* **DOM Integration:** Auto-remove elements and revoke Blob URLs when a scope closes.\n* **AbortSignal Synergy:** Link `AbortController` lifecycles directly to the disposal stack.\n* **Async Scopes:** Handle complex async flows with auto-cleanup on resolution or error.\n* **Safety Guards:** Create revocable proxies that strictly enforce object access only within a specific scope.\n\n## Usage\n\n### The \"All-In-One\" Example\n\nManage complex async workflows where every resource (network requests, DOM elements, Blob URLs) is cleaned up automatically when the task finishes or is aborted.\n\n```javascript\nimport { useAsyncDisposableStack, DisposableObjectURL, createDisposableElement } from '@aegisjsproject/disposable';\n\nawait useAsyncDisposableStack(async (stack, { signal }) => {\n    // 1. Fetch a resource (aborts if the stack closes early)\n    const resp = await fetch('/data.json', { signal });\n    const data = await resp.blob();\n\n    // 2. Create a Blob URL that revokes itself on dispose\n    // Note: DisposableObjectURL extends String, so it works directly in template literals\n    const url = stack.use(new DisposableObjectURL(data));\n\n    // 3. Create a temporary DOM element that removes itself on dispose\n    const dialog = createDisposableElement(stack, { tag: 'dialog' });\n    \n    dialog.innerHTML = `<img src=\"${url}\" />`;\n    document.body.append(dialog);\n    dialog.showModal();\n\n    // Keep the scope open for 5 seconds, then auto-cleanup everything\n    await new Promise(resolve => setTimeout(resolve, 5000));\n});\n// At this point: Dialog is removed, URL is revoked, fetch signal is aborted.\n```\n\n## API Reference\n\n### Scopes\n\n#### `useDisposableStack(callback)`\nCreates a synchronous scope. The stack is disposed immediately after the callback returns.\n\n```javascript\nuseDisposableStack((stack) => {\n    stack.defer(() => console.log('Cleanup'));\n    // Do work...\n});\n```\n\n#### `useAsyncDisposableStack(callback, { signal })`\nCreates an asynchronous scope. The stack is disposed when the promise resolves, rejects, or if the optional `signal` is aborted.\n\n* **`signal`**: An `AbortSignal` that, if triggered, will immediately abort the scope and dispose of the stack.\n* **`callback` args**: `{ controller, signal, timeStamp, id }`.\n\n```javascript\nconst controller = new AbortController();\n\nawait useAsyncDisposableStack(async (stack, { signal }) => {\n    // This signal combines the input signal and the stack's lifecycle\n    await fetch('/api', { signal });\n}, { signal: controller.signal });\n```\n\n### Primitives\n\n#### `DisposableAbortController`\nExtends `AbortController`. When disposed, it automatically aborts its signal (if not already aborted).\n\n```javascript\n{\n    using controller = new DisposableAbortController();\n    // controller will abort automatically at the end of this block\n}\n```\n\n#### `DisposableObjectURL`\nExtends `String`. Wraps a `Blob` or `File` to create a URL that revokes itself upon disposal.\n\n* **Behaves like a string:** Can be used in `img.src` or template literals.\n* **Revocable:** Calls `URL.revokeObjectURL` on dispose.\n\n```javascript\n{\n  using url = new DisposableObjectURL(blob);\n  img.src = url; // Works directly\n  // Revokes the object URL automatically\n}\n```\n\n#### `DisposableTask`\nA wrapper around `scheduler.postTask` that is integrated with disposal.\n\n* Auto-aborts the task if the object is disposed before completion.\n* Provides standard Promise methods (`then`, `catch`, `finally`).\n\n```javascript\nusing task = new DisposableTask(() => heavyComputation(), { priority: 'background' });\n// Task is aborted if not executed when leaving scope\n```\n\n#### `createDisposableElement(stack, config)`\nCreates a DOM element that is automatically `remove()`'d from the DOM when the stack is disposed.\n\n* `config.tag`: The HTML tag name (default: `'div'`).\n* `config.attrs`: All other properties are set as attributes on the element.\n\n```javascript\nusing stack = new DisposableStack();\n\nconst spinner = createDisposableElement(stack, { \n    tag: 'div', \n    class: 'loader',\n    'aria-busy': 'true' \n});\ndocument.body.append(spinner);\n// Spinner is removed from DOM automatically when stack disposes\n```\n\n#### `guard(stack, target, handler)`\nCreates a `Proxy` that becomes unusable (throws `TypeError`) once the stack is disposed. Useful for preventing memory leaks or access to stale objects.\n\n```javascript\nconst state = { sensitive: true };\nconst safeState = guard(stack, state);\n// safeState is usable here\n// ... stack disposes ...\nconsole.log(safeState.sensitive); // Throws TypeError\n```\n\n#### `whenDisposed(stack, { signal })`\nReturns a `Promise<void>` that resolves when the provided stack is disposed.\n\n```javascript\nconst stack = new DisposableStack();\n\nwhenDisposed(stack).then(() => {\n  console.log('Stack is now clean');\n});\n\nstack.dispose();\n```\n","readmeFilename":"README.md"}