@jaredwray/mockhttp 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,32 @@
5
5
  "home_page_url": "https://mockhttp.org/",
6
6
  "feed_url": "https://mockhttp.org/changelog.json",
7
7
  "items": [
8
+ {
9
+ "id": "v3-0-0",
10
+ "title": "v3.0.0",
11
+ "url": "https://mockhttp.org/changelog/v3-0-0/",
12
+ "date_published": "2026-10-20",
13
+ "date_modified": "2026-10-20",
14
+ "summary": "<p>Request bins now use Keyv via MockHttpBins, and the Worker can store them in MongoDB Atlas.</p>\n<ul>\n<li>Replace <code>BinManager</code>, <code>BinStore</code>, and <code>InMemoryBinStore</code> with async <code>MockHttpBins</code>. <code>mock.bins.start()</code> and <code>mock.bins.stop()</code> are removed. The default <code>maxBodySize</code> is 128 KiB (was 1 MiB). Node engines are now <code>>=22.19.0</code> (was <code>>=22.18.0</code>). (<code>b1ddcc0</code>, #246)\r\nMigration: assign <code>mock.bins = new MockHttpBins({ keyv })</code> before <code>start()</code> (default store is <code>new Keyv()</code>) and <code>await</code> the bin...</li>\n</ul>",
15
+ "content_html": "<h2 id=\"jaredwraymockhttp300--2026-10-19\">@jaredwray/mockhttp@3.0.0 — 2026-10-19</h2>\n<p>Request bins now use Keyv via MockHttpBins, and the Worker can store them in MongoDB Atlas.</p>\n<h3 id=\"-breaking-changes\">⚠ BREAKING CHANGES</h3>\n<ul>\n<li>\n<p>Replace <code>BinManager</code>, <code>BinStore</code>, and <code>InMemoryBinStore</code> with async <code>MockHttpBins</code>. <code>mock.bins.start()</code> and <code>mock.bins.stop()</code> are removed. The default <code>maxBodySize</code> is 128 KiB (was 1 MiB). Node engines are now <code>>=22.19.0</code> (was <code>>=22.18.0</code>). (<code>b1ddcc0</code>, #246)\r\nMigration: assign <code>mock.bins = new MockHttpBins({ keyv })</code> before <code>start()</code> (default store is <code>new Keyv()</code>) and <code>await</code> the bin methods.</p>\n<pre><code class=\"hljs language-ts\"><span class=\"hljs-keyword\">import</span> <span class=\"hljs-title class_\">Keyv</span> <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"keyv\"</span>;\r\n<span class=\"hljs-keyword\">import</span> { <span class=\"hljs-title class_\">MockHttp</span>, <span class=\"hljs-title class_\">MockHttpBins</span> } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">\"@jaredwray/mockhttp\"</span>;\r\n\r\n<span class=\"hljs-keyword\">const</span> mock = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">MockHttp</span>();\r\nmock.<span class=\"hljs-property\">bins</span> = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">MockHttpBins</span>({ <span class=\"hljs-attr\">keyv</span>: <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Keyv</span>(), <span class=\"hljs-attr\">maxBodySize</span>: <span class=\"hljs-number\">128</span> * <span class=\"hljs-number\">1024</span> });\r\n<span class=\"hljs-keyword\">await</span> mock.<span class=\"hljs-title function_\">start</span>();\r\n<span class=\"hljs-keyword\">const</span> bin = <span class=\"hljs-keyword\">await</span> mock.<span class=\"hljs-property\">bins</span>.<span class=\"hljs-title function_\">createBin</span>();\n</code></pre>\n</li>\n</ul>\n<h3 id=\"features\">Features</h3>\n<ul>\n<li>\n<p>Store Worker request bins in MongoDB Atlas when <code>MONGODB_URI</code> is set (<code>266157b</code>, #247)</p>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># Cloudflare Worker secret. Bins go in the Atlas `bins` collection.</span>\r\n<span class=\"hljs-comment\"># Leave MONGODB_URI unset to keep the in-memory Keyv.</span>\r\nwrangler secret put MONGODB_URI\n</code></pre>\n</li>\n</ul>\n<h3 id=\"bug-fixes\">Bug Fixes</h3>\n<ul>\n<li>security - upgrade fastify proxy-addr, fast-uri, find-my-way, undici (<code>9c52869</code>, #233)</li>\n<li>security - upgrade handlebars, source-map-js (<code>28aa662</code>, #236)</li>\n</ul>\n<h3 id=\"internal\">Internal</h3>\n<ul>\n<li>sync defense-in-depth files from agentic (<code>7fb3ce4</code>, #234)</li>\n<li>upgrade code quality dependencies (<code>a57b990</code>, #235)</li>\n<li>upgrade TypeScript and build tooling (<code>b11fa0f</code>, #237)</li>\n<li>upgrade monorepo tooling (<code>58e8596</code>, #238)</li>\n<li>upgrade GitHub Actions (<code>58bc448</code>, #239)</li>\n<li>upgrade Dev Container images (<code>2047c3c</code>, #240)</li>\n<li>upgrade Fastify dependencies (<code>3e93bea</code>, #241)</li>\n<li>upgrade hookified (<code>d938e6e</code>, #242)</li>\n<li>upgrade pino and pino-pretty (<code>c2a94ad</code>, #243)</li>\n<li>upgrade Docker Node.js runtime image (<code>cd5decf</code>, #244)</li>\n<li>pin the Compose image (<code>74ad4ea</code>, #245)</li>\n</ul>\n<h3 id=\"contributors\">Contributors</h3>\n<ul>\n<li>@jaredwray (11)</li>\n<li>@cursoragent (5)</li>\n</ul>\n<h3 id=\"full-list-of-changes\">Full List of Changes</h3>\n<ul>\n<li>fix: security - upgrade fastify proxy-addr, fast-uri, find-my-way, undici by @jaredwray in #233</li>\n<li>mono - chore: sync defense-in-depth files from agentic by @jaredwray in #234</li>\n<li>mono - chore: upgrade code quality dependencies by @jaredwray in #235</li>\n<li>fix: security - upgrade handlebars, source-map-js by @jaredwray in #236</li>\n<li>mono - chore: upgrade TypeScript and build tooling by @jaredwray in #237</li>\n<li>mono - chore: upgrade monorepo tooling by @jaredwray in #238</li>\n<li>mono - chore: upgrade GitHub Actions by @jaredwray in #239</li>\n<li>mono - chore: upgrade Dev Container images by @jaredwray in #240</li>\n<li>mono - chore: upgrade Fastify dependencies by @jaredwray in #241</li>\n<li>mono - chore: upgrade hookified by @jaredwray in #242</li>\n<li>mono - chore: upgrade pino and pino-pretty by @jaredwray in #243</li>\n<li>mono - chore: upgrade Docker Node.js runtime image by @jaredwray in #244</li>\n<li>mono - chore: pin the Compose image by @jaredwray in #245</li>\n<li>Store request bins in Keyv by @jaredwray in #246</li>\n<li>Store Worker request bins in MongoDB Atlas by @jaredwray in #247</li>\n</ul>\n<p><strong>Full diff:</strong> <a href=\"https://github.com/jaredwray/mockhttp/compare/v2.1.0...v3.0.0\">https://github.com/jaredwray/mockhttp/compare/v2.1.0...v3.0.0</a></p>",
16
+ "content_text": "## @jaredwray/mockhttp@3.0.0 — 2026-10-19\r\n\r\nRequest bins now use Keyv via MockHttpBins, and the Worker can store them in MongoDB Atlas.\r\n\r\n### ⚠ BREAKING CHANGES\r\n- Replace `BinManager`, `BinStore`, and `InMemoryBinStore` with async `MockHttpBins`. `mock.bins.start()` and `mock.bins.stop()` are removed. The default `maxBodySize` is 128 KiB (was 1 MiB). Node engines are now `>=22.19.0` (was `>=22.18.0`). (`b1ddcc0`, #246)\r\n Migration: assign `mock.bins = new MockHttpBins({ keyv })` before `start()` (default store is `new Keyv()`) and `await` the bin methods.\r\n\r\n ```ts\r\n import Keyv from \"keyv\";\r\n import { MockHttp, MockHttpBins } from \"@jaredwray/mockhttp\";\r\n\r\n const mock = new MockHttp();\r\n mock.bins = new MockHttpBins({ keyv: new Keyv(), maxBodySize: 128 * 1024 });\r\n await mock.start();\r\n const bin = await mock.bins.createBin();\r\n ```\r\n\r\n### Features\r\n- Store Worker request bins in MongoDB Atlas when `MONGODB_URI` is set (`266157b`, #247)\r\n\r\n ```bash\r\n # Cloudflare Worker secret. Bins go in the Atlas `bins` collection.\r\n # Leave MONGODB_URI unset to keep the in-memory Keyv.\r\n wrangler secret put MONGODB_URI\r\n ```\r\n\r\n### Bug Fixes\r\n- security - upgrade fastify proxy-addr, fast-uri, find-my-way, undici (`9c52869`, #233)\r\n- security - upgrade handlebars, source-map-js (`28aa662`, #236)\r\n\r\n### Internal\r\n- sync defense-in-depth files from agentic (`7fb3ce4`, #234)\r\n- upgrade code quality dependencies (`a57b990`, #235)\r\n- upgrade TypeScript and build tooling (`b11fa0f`, #237)\r\n- upgrade monorepo tooling (`58e8596`, #238)\r\n- upgrade GitHub Actions (`58bc448`, #239)\r\n- upgrade Dev Container images (`2047c3c`, #240)\r\n- upgrade Fastify dependencies (`3e93bea`, #241)\r\n- upgrade hookified (`d938e6e`, #242)\r\n- upgrade pino and pino-pretty (`c2a94ad`, #243)\r\n- upgrade Docker Node.js runtime image (`cd5decf`, #244)\r\n- pin the Compose image (`74ad4ea`, #245)\r\n\r\n### Contributors\r\n- @jaredwray (11)\r\n- @cursoragent (5)\r\n\r\n### Full List of Changes\r\n- fix: security - upgrade fastify proxy-addr, fast-uri, find-my-way, undici by @jaredwray in #233\r\n- mono - chore: sync defense-in-depth files from agentic by @jaredwray in #234\r\n- mono - chore: upgrade code quality dependencies by @jaredwray in #235\r\n- fix: security - upgrade handlebars, source-map-js by @jaredwray in #236\r\n- mono - chore: upgrade TypeScript and build tooling by @jaredwray in #237\r\n- mono - chore: upgrade monorepo tooling by @jaredwray in #238\r\n- mono - chore: upgrade GitHub Actions by @jaredwray in #239\r\n- mono - chore: upgrade Dev Container images by @jaredwray in #240\r\n- mono - chore: upgrade Fastify dependencies by @jaredwray in #241\r\n- mono - chore: upgrade hookified by @jaredwray in #242\r\n- mono - chore: upgrade pino and pino-pretty by @jaredwray in #243\r\n- mono - chore: upgrade Docker Node.js runtime image by @jaredwray in #244\r\n- mono - chore: pin the Compose image by @jaredwray in #245\r\n- Store request bins in Keyv by @jaredwray in #246\r\n- Store Worker request bins in MongoDB Atlas by @jaredwray in #247\r\n\r\n**Full diff:** [https://github.com/jaredwray/mockhttp/compare/v2.1.0...v3.0.0](https://github.com/jaredwray/mockhttp/compare/v2.1.0...v3.0.0)",
17
+ "tags": [
18
+ "Release"
19
+ ]
20
+ },
21
+ {
22
+ "id": "v2-1-0",
23
+ "title": "v2.1.0",
24
+ "url": "https://mockhttp.org/changelog/v2-1-0/",
25
+ "date_published": "2026-10-03",
26
+ "date_modified": "2026-10-03",
27
+ "summary": "<p>Add AUTO_DETECT_PORT=false so the process keeps PORT, and include the docs site in the npm package.</p>\n<ul>\n<li>\n<p>Deploy the Node server to Wasmer Edge (#225)</p>\n<pre><code class=\"hljs language-bash\">PORT=3000 AUTO_DETECT_PORT=<span class=\"hljs-literal\">false</span> node dist/index.mjs\n</code></pre>\n</li>\n<li>\n<p>include Docula site in the npm tarball (#222)</p>\n</li>\n<li>\n<p>deploy Wasmer with a remote build (#226)</p>\n</li>\n<li>\n<p>deploy Wasmer through the Anybuild file (#228)</p>\n</li>\n<li>\n<p>add Drydock review badge to README (#224)</p>\n</li>\n<li>\n<p>rename Hosted Service page to MockHttp.org Live (#230)</p>\n</li>\n</ul>",
28
+ "content_html": "<h2 id=\"jaredwraymockhttp210--2026-10-03\">@jaredwray/mockhttp@2.1.0 — 2026-10-03</h2>\n<p>Add AUTO_DETECT_PORT=false so the process keeps PORT, and include the docs site in the npm package.</p>\n<h3 id=\"features\">Features</h3>\n<ul>\n<li>\n<p>Deploy the Node server to Wasmer Edge (#225)</p>\n<pre><code class=\"hljs language-bash\">PORT=3000 AUTO_DETECT_PORT=<span class=\"hljs-literal\">false</span> node dist/index.mjs\n</code></pre>\n</li>\n</ul>\n<h3 id=\"bug-fixes\">Bug Fixes</h3>\n<ul>\n<li>include Docula site in the npm tarball (#222)</li>\n<li>deploy Wasmer with a remote build (#226)</li>\n<li>deploy Wasmer through the Anybuild file (#228)</li>\n</ul>\n<h3 id=\"documentation\">Documentation</h3>\n<ul>\n<li>add Drydock review badge to README (#224)</li>\n<li>rename Hosted Service page to MockHttp.org Live (#230)</li>\n<li>add How to Deploy guides for Cloudflare, Docker, and Wasmer (#229)</li>\n</ul>\n<h3 id=\"internal\">Internal</h3>\n<ul>\n<li>root - defense - close catalog gaps from current skill (#221)</li>\n<li>Publish the GitHub Actions build to Wasmer (#227)</li>\n</ul>\n<h3 id=\"contributors\">Contributors</h3>\n<ul>\n<li>@jaredwray (owner)</li>\n</ul>\n<h3 id=\"full-list-of-changes\">Full List of Changes</h3>\n<ul>\n<li>root - chore: defense - close catalog gaps from current skill by @jaredwray in #221</li>\n<li>fix: include Docula site in the npm tarball by @jaredwray in #222</li>\n<li>docs: add Drydock review badge to README by @jaredwray in #224</li>\n<li>Deploy the Node server to Wasmer Edge by @jaredwray in #225</li>\n<li>Fix the Wasmer deploy by using a remote build by @jaredwray in #226</li>\n<li>Publish the GitHub Actions build to Wasmer by @jaredwray in #227</li>\n<li>Deploy Wasmer with the Anybuild file by @jaredwray in #228</li>\n<li>docs: rename Hosted Service to MockHttp.org Live by @jaredwray in #230</li>\n<li>docs: add How to Deploy guides for Cloudflare, Docker, and Wasmer by @jaredwray in #229</li>\n</ul>\n<p><strong>Full diff:</strong> <a href=\"https://github.com/jaredwray/mockhttp/compare/v2.0.0...v2.1.0\">https://github.com/jaredwray/mockhttp/compare/v2.0.0...v2.1.0</a></p>",
29
+ "content_text": "## @jaredwray/mockhttp@2.1.0 — 2026-10-03\r\n\r\nAdd AUTO_DETECT_PORT=false so the process keeps PORT, and include the docs site in the npm package.\r\n\r\n### Features\r\n- Deploy the Node server to Wasmer Edge (#225)\r\n\r\n ```bash\r\n PORT=3000 AUTO_DETECT_PORT=false node dist/index.mjs\r\n ```\r\n\r\n### Bug Fixes\r\n- include Docula site in the npm tarball (#222)\r\n- deploy Wasmer with a remote build (#226)\r\n- deploy Wasmer through the Anybuild file (#228)\r\n\r\n### Documentation\r\n- add Drydock review badge to README (#224)\r\n- rename Hosted Service page to MockHttp.org Live (#230)\r\n- add How to Deploy guides for Cloudflare, Docker, and Wasmer (#229)\r\n\r\n### Internal\r\n- root - defense - close catalog gaps from current skill (#221)\r\n- Publish the GitHub Actions build to Wasmer (#227)\r\n\r\n### Contributors\r\n- @jaredwray (owner)\r\n\r\n### Full List of Changes\r\n- root - chore: defense - close catalog gaps from current skill by @jaredwray in #221\r\n- fix: include Docula site in the npm tarball by @jaredwray in #222\r\n- docs: add Drydock review badge to README by @jaredwray in #224\r\n- Deploy the Node server to Wasmer Edge by @jaredwray in #225\r\n- Fix the Wasmer deploy by using a remote build by @jaredwray in #226\r\n- Publish the GitHub Actions build to Wasmer by @jaredwray in #227\r\n- Deploy Wasmer with the Anybuild file by @jaredwray in #228\r\n- docs: rename Hosted Service to MockHttp.org Live by @jaredwray in #230\r\n- docs: add How to Deploy guides for Cloudflare, Docker, and Wasmer by @jaredwray in #229\r\n\r\n**Full diff:** [https://github.com/jaredwray/mockhttp/compare/v2.0.0...v2.1.0](https://github.com/jaredwray/mockhttp/compare/v2.0.0...v2.1.0)",
30
+ "tags": [
31
+ "Release"
32
+ ]
33
+ },
8
34
  {
9
35
  "id": "v2-0-0",
10
36
  "title": "v2.0.0",
@@ -368,32 +394,6 @@
368
394
  "tags": [
369
395
  "Release"
370
396
  ]
371
- },
372
- {
373
- "id": "v0-2-0",
374
- "title": "v0.2.0",
375
- "url": "https://mockhttp.org/changelog/v0-2-0/",
376
- "date_published": "2024-12-13",
377
- "date_modified": "2024-12-13",
378
- "summary": "<ul>\n<li>response inspection by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/14\">https://github.com/jaredwray/mockhttp/pull/14</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0\">https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0</a></p>",
379
- "content_html": "<h2 id=\"whats-changed\">What's Changed</h2>\n<ul>\n<li>response inspection by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/14\">https://github.com/jaredwray/mockhttp/pull/14</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0\">https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0</a></p>",
380
- "content_text": "## What's Changed\r\n* response inspection by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/14](https://github.com/jaredwray/mockhttp/pull/14)\r\n\r\n\r\n**Full Changelog**: [https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0](https://github.com/jaredwray/mockhttp/compare/v0.1.0...v0.2.0)",
381
- "tags": [
382
- "Release"
383
- ]
384
- },
385
- {
386
- "id": "v0-1-0",
387
- "title": "v0.1.0",
388
- "url": "https://mockhttp.org/changelog/v0-1-0/",
389
- "date_published": "2024-12-12",
390
- "date_modified": "2024-12-12",
391
- "summary": "<ul>\n<li>adding in contributing and code of conduct by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/1\">https://github.com/jaredwray/mockhttp/pull/1</a></li>\n<li>migrating to correct folder format by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/2\">https://github.com/jaredwray/mockhttp/pull/2</a></li>\n<li>adding in logo and favicon by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/3\">https://github.com/jaredwray/mockhttp/pull/3</a></li>\n<li>adding in headers and user-agent endpoints by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/4\">https://github.com/jaredwray/mockhttp/pull/4</a></li>\n<li>moving to scalar by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/5\">https://github.com/jaredwray/mockhttp/pull/5</a></li>\n</ul>",
392
- "content_html": "<h2 id=\"whats-changed\">What's Changed</h2>\n<ul>\n<li>adding in contributing and code of conduct by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/1\">https://github.com/jaredwray/mockhttp/pull/1</a></li>\n<li>migrating to correct folder format by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/2\">https://github.com/jaredwray/mockhttp/pull/2</a></li>\n<li>adding in logo and favicon by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/3\">https://github.com/jaredwray/mockhttp/pull/3</a></li>\n<li>adding in headers and user-agent endpoints by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/4\">https://github.com/jaredwray/mockhttp/pull/4</a></li>\n<li>moving to scalar by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/5\">https://github.com/jaredwray/mockhttp/pull/5</a></li>\n<li>adding in status codes by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/6\">https://github.com/jaredwray/mockhttp/pull/6</a></li>\n<li>adding in unit tests and workflows by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/7\">https://github.com/jaredwray/mockhttp/pull/7</a></li>\n<li>fixing the title that had an extra space by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/8\">https://github.com/jaredwray/mockhttp/pull/8</a></li>\n<li>moving to scalar locally instead of via CDN by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/9\">https://github.com/jaredwray/mockhttp/pull/9</a></li>\n<li>adding in dynamic version from package.json by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/10\">https://github.com/jaredwray/mockhttp/pull/10</a></li>\n<li>adding in fastify helmet by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/11\">https://github.com/jaredwray/mockhttp/pull/11</a></li>\n<li>upgrading xo to 0.60.0 by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/12\">https://github.com/jaredwray/mockhttp/pull/12</a></li>\n<li>updating build to tsup and upgrading vitest by @jaredwray in <a href=\"https://github.com/jaredwray/mockhttp/pull/13\">https://github.com/jaredwray/mockhttp/pull/13</a></li>\n</ul>\n<h2 id=\"new-contributors\">New Contributors</h2>\n<ul>\n<li>@jaredwray made their first contribution in <a href=\"https://github.com/jaredwray/mockhttp/pull/1\">https://github.com/jaredwray/mockhttp/pull/1</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/jaredwray/mockhttp/commits/v0.1.0\">https://github.com/jaredwray/mockhttp/commits/v0.1.0</a></p>",
393
- "content_text": "## What's Changed\r\n* adding in contributing and code of conduct by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/1](https://github.com/jaredwray/mockhttp/pull/1)\r\n* migrating to correct folder format by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/2](https://github.com/jaredwray/mockhttp/pull/2)\r\n* adding in logo and favicon by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/3](https://github.com/jaredwray/mockhttp/pull/3)\r\n* adding in headers and user-agent endpoints by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/4](https://github.com/jaredwray/mockhttp/pull/4)\r\n* moving to scalar by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/5](https://github.com/jaredwray/mockhttp/pull/5)\r\n* adding in status codes by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/6](https://github.com/jaredwray/mockhttp/pull/6)\r\n* adding in unit tests and workflows by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/7](https://github.com/jaredwray/mockhttp/pull/7)\r\n* fixing the title that had an extra space by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/8](https://github.com/jaredwray/mockhttp/pull/8)\r\n* moving to scalar locally instead of via CDN by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/9](https://github.com/jaredwray/mockhttp/pull/9)\r\n* adding in dynamic version from package.json by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/10](https://github.com/jaredwray/mockhttp/pull/10)\r\n* adding in fastify helmet by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/11](https://github.com/jaredwray/mockhttp/pull/11)\r\n* upgrading xo to 0.60.0 by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/12](https://github.com/jaredwray/mockhttp/pull/12)\r\n* updating build to tsup and upgrading vitest by @jaredwray in [https://github.com/jaredwray/mockhttp/pull/13](https://github.com/jaredwray/mockhttp/pull/13)\r\n\r\n## New Contributors\r\n* @jaredwray made their first contribution in [https://github.com/jaredwray/mockhttp/pull/1](https://github.com/jaredwray/mockhttp/pull/1)\r\n\r\n**Full Changelog**: [https://github.com/jaredwray/mockhttp/commits/v0.1.0](https://github.com/jaredwray/mockhttp/commits/v0.1.0)",
394
- "tags": [
395
- "Release"
396
- ]
397
397
  }
398
398
  ]
399
399
  }
@@ -35,7 +35,7 @@
35
35
  </script>
36
36
  <title>MockHTTP - Bins</title>
37
37
  <script type="application/ld+json">
38
- {"@context":"https://schema.org","@type":"TechArticle","headline":"Bins","description":"","url":"https://mockhttp.org/docs/bins/","publisher":{"@type":"Organization","name":"MockHTTP"},"dateModified":"2026-09-18","keywords":[]}
38
+ {"@context":"https://schema.org","@type":"TechArticle","headline":"Bins","description":"","url":"https://mockhttp.org/docs/bins/","publisher":{"@type":"Organization","name":"MockHTTP"},"dateModified":"2026-10-20","keywords":[]}
39
39
  </script>
40
40
  </head>
41
41
 
@@ -191,7 +191,26 @@
191
191
  <section class="nav-sidebar__section">
192
192
  <ul class="nav-sidebar__list">
193
193
  <li>
194
- <a href="/docs/hosted/" class="nav-sidebar__item">Hosted Service</a>
194
+ <a href="/docs/hosted/" class="nav-sidebar__item">MockHttp.org Live</a>
195
+ </li>
196
+ </ul>
197
+ </section>
198
+ <section class="nav-sidebar__section nav-sidebar__section--collapsible">
199
+ <h2 class="nav-sidebar__title">
200
+ <button type="button" class="nav-sidebar__toggle" aria-expanded="true">
201
+ <span class="nav-sidebar__toggle-label">How to Deploy</span>
202
+ <svg class="nav-sidebar__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
203
+ </button>
204
+ </h2>
205
+ <ul class="nav-sidebar__list">
206
+ <li>
207
+ <a href="/docs/how-to-deploy/cloudflare/" class="nav-sidebar__item">Cloudflare</a>
208
+ </li>
209
+ <li>
210
+ <a href="/docs/how-to-deploy/docker/" class="nav-sidebar__item">Docker</a>
211
+ </li>
212
+ <li>
213
+ <a href="/docs/how-to-deploy/wasmer/" class="nav-sidebar__item">Wasmer</a>
195
214
  </li>
196
215
  </ul>
197
216
  </section>
@@ -244,7 +263,26 @@
244
263
  <section class="nav-sidebar__section">
245
264
  <ul class="nav-sidebar__list">
246
265
  <li>
247
- <a href="/docs/hosted/" class="nav-sidebar__item">Hosted Service</a>
266
+ <a href="/docs/hosted/" class="nav-sidebar__item">MockHttp.org Live</a>
267
+ </li>
268
+ </ul>
269
+ </section>
270
+ <section class="nav-sidebar__section nav-sidebar__section--collapsible">
271
+ <h2 class="nav-sidebar__title">
272
+ <button type="button" class="nav-sidebar__toggle" aria-expanded="true">
273
+ <span class="nav-sidebar__toggle-label">How to Deploy</span>
274
+ <svg class="nav-sidebar__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
275
+ </button>
276
+ </h2>
277
+ <ul class="nav-sidebar__list">
278
+ <li>
279
+ <a href="/docs/how-to-deploy/cloudflare/" class="nav-sidebar__item">Cloudflare</a>
280
+ </li>
281
+ <li>
282
+ <a href="/docs/how-to-deploy/docker/" class="nav-sidebar__item">Docker</a>
283
+ </li>
284
+ <li>
285
+ <a href="/docs/how-to-deploy/wasmer/" class="nav-sidebar__item">Wasmer</a>
248
286
  </li>
249
287
  </ul>
250
288
  </section>
@@ -292,7 +330,7 @@ here is stored against bin <code>:id</code></li>
292
330
  <li><a href="#configuration">Configuration</a>
293
331
  <ul>
294
332
  <li><a href="#defaults">Defaults</a></li>
295
- <li><a href="#pluggable-storage">Pluggable Storage</a></li>
333
+ <li><a href="#storage">Storage</a></li>
296
334
  </ul>
297
335
  </li>
298
336
  </ul>
@@ -476,11 +514,11 @@ curl -s <span class="hljs-string">"http://localhost:3000/bins/<span class="hljs-
476
514
  | jq -r <span class="hljs-string">'.requests[0].body'</span> | <span class="hljs-built_in">base64</span> -d > recovered.png
477
515
  </code></pre>
478
516
  <h3 id="truncation">Truncation</h3>
479
- <p>Bodies larger than <code>maxBodySize</code> (1 MiB by default) are cut off and flagged:</p>
517
+ <p>Bodies larger than <code>maxBodySize</code> (128 KiB by default) are cut off and flagged:</p>
480
518
  <pre><code class="hljs language-javascript"><span class="hljs-comment">// In test setup</span>
481
- <span class="hljs-keyword">import</span> { <span class="hljs-title class_">MockHttp</span>, <span class="hljs-title class_">BinManager</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
519
+ <span class="hljs-keyword">import</span> { <span class="hljs-title class_">MockHttp</span>, <span class="hljs-title class_">MockHttpBins</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
482
520
  <span class="hljs-keyword">const</span> mock = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MockHttp</span>();
483
- mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">BinManager</span>({ <span class="hljs-attr">maxBodySize</span>: <span class="hljs-number">1024</span> }); <span class="hljs-comment">// 1 KiB cap</span>
521
+ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MockHttpBins</span>({ <span class="hljs-attr">maxBodySize</span>: <span class="hljs-number">1024</span> }); <span class="hljs-comment">// 1 KiB cap</span>
484
522
  <span class="hljs-keyword">await</span> mock.<span class="hljs-title function_">start</span>();
485
523
  </code></pre>
486
524
  <pre><code class="hljs language-bash"><span class="hljs-comment"># Send 5000 bytes to a bin with a 1 KiB cap</span>
@@ -512,21 +550,20 @@ curl -s <span class="hljs-string">"http://localhost:3000/bins/<span class="hljs-
512
550
  <span class="hljs-comment"># "/event/105"</span>
513
551
  </code></pre>
514
552
  <h2 id="programmatic-access">Programmatic Access</h2>
515
- <p>The bin manager is exposed on the <code>MockHttp</code> instance as <code>mock.bins</code>. This
516
- makes it easy to drive bins from a test suite without going through HTTP:</p>
553
+ <p>Use <code>mock.bins</code> to control request bins from a test. You do not need an HTTP call:</p>
517
554
  <pre><code class="hljs language-javascript"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">MockHttp</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
518
555
 
519
556
  <span class="hljs-keyword">const</span> mock = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MockHttp</span>({ <span class="hljs-attr">logging</span>: <span class="hljs-literal">false</span> });
520
557
  <span class="hljs-keyword">await</span> mock.<span class="hljs-title function_">start</span>();
521
558
 
522
559
  <span class="hljs-comment">// Create a bin</span>
523
- <span class="hljs-keyword">const</span> bin = mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">createBin</span>();
560
+ <span class="hljs-keyword">const</span> bin = <span class="hljs-keyword">await</span> mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">createBin</span>();
524
561
  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Webhook target: http://localhost:<span class="hljs-subst">${mock.port}</span>/b/<span class="hljs-subst">${bin.id}</span>`</span>);
525
562
 
526
563
  <span class="hljs-comment">// ... point your code-under-test at that URL ...</span>
527
564
 
528
565
  <span class="hljs-comment">// Read captured requests (newest first)</span>
529
- <span class="hljs-keyword">const</span> requests = mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">getRequests</span>(bin.<span class="hljs-property">id</span>);
566
+ <span class="hljs-keyword">const</span> requests = <span class="hljs-keyword">await</span> mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">getRequests</span>(bin.<span class="hljs-property">id</span>);
530
567
  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">`Captured <span class="hljs-subst">${requests.length}</span> requests`</span>);
531
568
 
532
569
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> req <span class="hljs-keyword">of</span> requests) {
@@ -534,8 +571,8 @@ makes it easy to drive bins from a test suite without going through HTTP:</p>
534
571
  }
535
572
 
536
573
  <span class="hljs-comment">// Clean up</span>
537
- mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">deleteBin</span>(bin.<span class="hljs-property">id</span>);
538
- <span class="hljs-keyword">await</span> mock.<span class="hljs-title function_">close</span>(); <span class="hljs-comment">// also stops the bin cleanup timer</span>
574
+ <span class="hljs-keyword">await</span> mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">deleteBin</span>(bin.<span class="hljs-property">id</span>);
575
+ <span class="hljs-keyword">await</span> mock.<span class="hljs-title function_">close</span>();
539
576
  </code></pre>
540
577
  <h3 id="using-bins-in-a-vitest-test">Using Bins in a Vitest Test</h3>
541
578
  <pre><code class="hljs language-typescript"><span class="hljs-keyword">import</span> { afterAll, beforeAll, expect, test } <span class="hljs-keyword">from</span> <span class="hljs-string">'vitest'</span>;
@@ -553,14 +590,14 @@ mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">
553
590
  });
554
591
 
555
592
  <span class="hljs-title function_">test</span>(<span class="hljs-string">'my SDK sends the right webhook payload'</span>, <span class="hljs-title function_">async</span> () => {
556
- <span class="hljs-keyword">const</span> bin = mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">createBin</span>();
593
+ <span class="hljs-keyword">const</span> bin = <span class="hljs-keyword">await</span> mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">createBin</span>();
557
594
  <span class="hljs-keyword">const</span> webhookUrl = <span class="hljs-string">`http://localhost:<span class="hljs-subst">${mock.port}</span>/b/<span class="hljs-subst">${bin.id}</span>`</span>;
558
595
 
559
596
  <span class="hljs-comment">// Drive your SDK at the bin</span>
560
597
  <span class="hljs-keyword">await</span> mySdk.<span class="hljs-title function_">notify</span>(webhookUrl, { <span class="hljs-attr">event</span>: <span class="hljs-string">'user.created'</span>, <span class="hljs-attr">id</span>: <span class="hljs-number">42</span> });
561
598
 
562
599
  <span class="hljs-comment">// Assert on what actually arrived</span>
563
- <span class="hljs-keyword">const</span> [captured] = mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">getRequests</span>(bin.<span class="hljs-property">id</span>);
600
+ <span class="hljs-keyword">const</span> [captured] = <span class="hljs-keyword">await</span> mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">getRequests</span>(bin.<span class="hljs-property">id</span>);
564
601
  <span class="hljs-title function_">expect</span>(captured.<span class="hljs-property">method</span>).<span class="hljs-title function_">toBe</span>(<span class="hljs-string">'POST'</span>);
565
602
  <span class="hljs-title function_">expect</span>(captured.<span class="hljs-property">contentType</span>).<span class="hljs-title function_">toBe</span>(<span class="hljs-string">'application/json'</span>);
566
603
  <span class="hljs-title function_">expect</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(captured.<span class="hljs-property">body</span>!)).<span class="hljs-title function_">toEqual</span>({
@@ -576,16 +613,15 @@ mock.<span class="hljs-property">bins</span>.<span class="hljs-title function_">
576
613
  <span class="hljs-attr">httpBin</span>: { <span class="hljs-attr">bins</span>: <span class="hljs-literal">false</span> },
577
614
  });
578
615
  </code></pre>
579
- <p>To tune limits, replace the default <code>BinManager</code> before starting:</p>
580
- <pre><code class="hljs language-javascript"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">MockHttp</span>, <span class="hljs-title class_">BinManager</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
616
+ <p>To change the limits, replace the default <code>MockHttpBins</code> before you start the server:</p>
617
+ <pre><code class="hljs language-javascript"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">MockHttp</span>, <span class="hljs-title class_">MockHttpBins</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
581
618
 
582
619
  <span class="hljs-keyword">const</span> mock = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MockHttp</span>();
583
- mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">BinManager</span>({
620
+ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MockHttpBins</span>({
584
621
  <span class="hljs-attr">defaultTtlMs</span>: <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// 1 hour (default: 24h)</span>
585
622
  <span class="hljs-attr">maxRequestsPerBin</span>: <span class="hljs-number">500</span>, <span class="hljs-comment">// (default: 100)</span>
586
- <span class="hljs-attr">maxBodySize</span>: <span class="hljs-number">5</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>, <span class="hljs-comment">// 5 MiB (default: 1 MiB)</span>
623
+ <span class="hljs-attr">maxBodySize</span>: <span class="hljs-number">512</span> * <span class="hljs-number">1024</span>, <span class="hljs-comment">// 512 KiB (default: 128 KiB)</span>
587
624
  <span class="hljs-attr">idLength</span>: <span class="hljs-number">16</span>, <span class="hljs-comment">// (default: 12)</span>
588
- <span class="hljs-attr">cleanupIntervalMs</span>: <span class="hljs-number">30</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// sweep every 30s (default: 60s)</span>
589
625
  });
590
626
 
591
627
  <span class="hljs-keyword">await</span> mock.<span class="hljs-title function_">start</span>();
@@ -603,7 +639,7 @@ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</s
603
639
  <tr>
604
640
  <td><code>defaultTtlMs</code></td>
605
641
  <td><code>86400000</code> (24h)</td>
606
- <td>Bin lifetime. Expired bins return 404 and are lazily removed.</td>
642
+ <td>Bin lifetime, set as the Keyv TTL. An expired bin returns 404.</td>
607
643
  </tr>
608
644
  <tr>
609
645
  <td><code>maxRequestsPerBin</code></td>
@@ -612,7 +648,7 @@ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</s
612
648
  </tr>
613
649
  <tr>
614
650
  <td><code>maxBodySize</code></td>
615
- <td><code>1048576</code> (1 MiB)</td>
651
+ <td><code>131072</code> (128 KiB)</td>
616
652
  <td>Larger bodies are truncated; <code>truncated: true</code> is set on the capture.</td>
617
653
  </tr>
618
654
  <tr>
@@ -621,40 +657,29 @@ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</s
621
657
  <td>Length of generated bin and request ids.</td>
622
658
  </tr>
623
659
  <tr>
624
- <td><code>cleanupIntervalMs</code></td>
625
- <td><code>60000</code> (1 min)</td>
626
- <td>How often expired bins are swept. The timer is <code>unref()</code>'d so it never keeps the process alive.</td>
660
+ <td><code>keyv</code></td>
661
+ <td><code>new Keyv()</code></td>
662
+ <td>Keyv store for bins. The default keeps bins in memory.</td>
627
663
  </tr>
628
664
  </tbody>
629
665
  </table>
630
- <h3 id="pluggable-storage">Pluggable Storage</h3>
631
- <p><code>BinManager</code> accepts a <code>store: BinStore</code> so you can plug in alternative
632
- backends (Redis, SQLite, etc.) without changing the rest of the codebase. The
633
- default <code>InMemoryBinStore</code> keeps state in process memory.</p>
634
- <pre><code class="hljs language-typescript"><span class="hljs-keyword">import</span> {
635
- <span class="hljs-title class_">BinManager</span>,
636
- <span class="hljs-title class_">InMemoryBinStore</span>,
637
- <span class="hljs-keyword">type</span> <span class="hljs-title class_">Bin</span>,
638
- <span class="hljs-keyword">type</span> <span class="hljs-title class_">BinStore</span>,
639
- <span class="hljs-keyword">type</span> <span class="hljs-title class_">CapturedRequest</span>,
640
- } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
641
-
642
- <span class="hljs-keyword">class</span> <span class="hljs-title class_">RedisBinStore</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">BinStore</span> {
643
- <span class="hljs-title function_">createBin</span>(<span class="hljs-attr">bin</span>: <span class="hljs-title class_">Bin</span>): <span class="hljs-built_in">void</span> { <span class="hljs-comment">/* SET bin:${bin.id} ... */</span> }
644
- <span class="hljs-title function_">getBin</span>(<span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span>): <span class="hljs-title class_">Bin</span> | <span class="hljs-literal">undefined</span> { <span class="hljs-comment">/* GET ... */</span> }
645
- <span class="hljs-title function_">listBins</span>(): <span class="hljs-title class_">Bin</span>[] { <span class="hljs-comment">/* SCAN ... */</span> }
646
- <span class="hljs-title function_">deleteBin</span>(<span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">boolean</span> { <span class="hljs-comment">/* DEL ... */</span> }
647
- <span class="hljs-title function_">addRequest</span>(<span class="hljs-attr">binId</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">req</span>: <span class="hljs-title class_">CapturedRequest</span>, <span class="hljs-attr">max</span>: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
648
- <span class="hljs-comment">/* LPUSH bin:${binId}:requests + LTRIM to max */</span>
649
- }
650
- <span class="hljs-title function_">getRequests</span>(<span class="hljs-attr">binId</span>: <span class="hljs-built_in">string</span>): <span class="hljs-title class_">CapturedRequest</span>[] { <span class="hljs-comment">/* LRANGE ... */</span> }
651
- <span class="hljs-title function_">getRequest</span>(<span class="hljs-attr">binId</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">reqId</span>: <span class="hljs-built_in">string</span>): <span class="hljs-title class_">CapturedRequest</span> | <span class="hljs-literal">undefined</span> { <span class="hljs-comment">/* ... */</span> }
652
- <span class="hljs-title function_">clearRequests</span>(<span class="hljs-attr">binId</span>: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">void</span> { <span class="hljs-comment">/* DEL bin:${binId}:requests */</span> }
653
- <span class="hljs-title function_">cleanupExpired</span>(<span class="hljs-attr">now</span>: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">string</span>[] { <span class="hljs-comment">/* scan + delete */</span> <span class="hljs-keyword">return</span> []; }
654
- }
655
-
656
- mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">BinManager</span>({ <span class="hljs-attr">store</span>: <span class="hljs-keyword">new</span> <span class="hljs-title class_">RedisBinStore</span>() });
666
+ <h3 id="storage">Storage</h3>
667
+ <p><code>MockHttpBins</code> stores each bin in <a href="https://github.com/jaredwray/keyv">Keyv</a> 6. The default is <code>new Keyv()</code>. That store keeps the data in memory for this process.</p>
668
+ <p>Pass a Keyv 6 instance when you want a different adapter. Install the adapter in your project. This package does not include an adapter. <code>@keyv/redis</code> 6 matches this Keyv version.</p>
669
+ <pre><code class="hljs language-typescript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Keyv</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'keyv'</span>;
670
+ <span class="hljs-keyword">import</span> <span class="hljs-title class_">KeyvRedis</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'@keyv/redis'</span>; <span class="hljs-comment">// pnpm add @keyv/redis</span>
671
+ <span class="hljs-keyword">import</span> { <span class="hljs-title class_">MockHttpBins</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@jaredwray/mockhttp'</span>;
672
+
673
+ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MockHttpBins</span>({
674
+ <span class="hljs-attr">keyv</span>: <span class="hljs-keyword">new</span> <span class="hljs-title class_">Keyv</span>({ <span class="hljs-attr">store</span>: <span class="hljs-keyword">new</span> <span class="hljs-title class_">KeyvRedis</span>(<span class="hljs-string">'redis://localhost:6379'</span>) }),
675
+ });
657
676
  </code></pre>
677
+ <p>Each capture writes the full bin again. A large body or a high request limit makes that write large. Set <code>maxBodySize</code> and <code>maxRequestsPerBin</code> to limit the size. With the defaults, a full bin of binary bodies is about 17 MB.</p>
678
+ <p>Two processes that share one Keyv can lose a capture. This occurs when both processes write the same bin at the same time.</p>
679
+ <p>If Keyv does not store a write, the bin route returns <code>500</code> with the standard Fastify error body: <code>statusCode</code>, <code>error</code>, and <code>message</code>.</p>
680
+ <p>A failed read depends on the Keyv <code>error</code> listener. Without a listener, Keyv throws the store error and the route returns <code>500</code>. With a listener, Keyv does not throw. A failed read then looks like a missing bin, and the route returns <code>404</code>. <code>listBins()</code> returns only the bins that it read before the error.</p>
681
+ <p><code>listBins()</code> throws an error when the adapter has no iterator.</p>
682
+ <p>An expired bin returns 404. The in-memory Keyv store deletes an expired bin only when a read or <code>listBins()</code> reaches it. Until then, the bin stays in memory.</p>
658
683
  </main>
659
684
  <aside class="content-aside">
660
685
  <h2 class="content-aside__title">TABLE OF CONTENTS</h2>
@@ -677,7 +702,7 @@ mock.<span class="hljs-property">bins</span> = <span class="hljs-keyword">new</s
677
702
  <a href="https://docula.org/" target="_blank" rel="noopener noreferrer" class="footer__link" aria-label="Docula">
678
703
  <svg class="footer__bat" xmlns="http://www.w3.org/2000/svg" viewBox="70 110 360 205" fill="currentColor"><path d="M420,173c-16.76-18-72.78-36.65-131.59-30.58A160.15,160.15,0,0,0,269,120.55c-3.78,4.52-11.15,9.45-19,9.45s-15.23-4.93-19-9.45a160.15,160.15,0,0,0-19.4,21.83C152.78,136.31,96.76,154.94,80,173c48.86,5.86,79.5,34.09,79.5,72.06,52.37,0,77,28,90.5,59.94C263.54,273,288.13,245,340.5,245,340.5,207,371.14,178.8,420,173Z"/><circle cx="239.19" cy="145.36" r="3.32" fill="#fff"/><circle cx="260.81" cy="145.36" r="3.32" fill="#fff"/></svg>
679
704
  </a>
680
- <span class="footer__updated">updated: 2026-09-18</span>
705
+ <span class="footer__updated">updated: 2026-10-20</span>
681
706
  </footer>
682
707
  <script src="/css/highlight/highlight.min.js"></script>
683
708
  <script>
@@ -35,7 +35,7 @@
35
35
  </script>
36
36
  <title>MockHTTP - Configuration</title>
37
37
  <script type="application/ld+json">
38
- {"@context":"https://schema.org","@type":"TechArticle","headline":"Configuration","description":"","url":"https://mockhttp.org/docs/configuration/","publisher":{"@type":"Organization","name":"MockHTTP"},"dateModified":"2026-09-18","keywords":[]}
38
+ {"@context":"https://schema.org","@type":"TechArticle","headline":"Configuration","description":"","url":"https://mockhttp.org/docs/configuration/","publisher":{"@type":"Organization","name":"MockHTTP"},"dateModified":"2026-10-20","keywords":[]}
39
39
  </script>
40
40
  </head>
41
41
 
@@ -191,7 +191,26 @@
191
191
  <section class="nav-sidebar__section">
192
192
  <ul class="nav-sidebar__list">
193
193
  <li>
194
- <a href="/docs/hosted/" class="nav-sidebar__item">Hosted Service</a>
194
+ <a href="/docs/hosted/" class="nav-sidebar__item">MockHttp.org Live</a>
195
+ </li>
196
+ </ul>
197
+ </section>
198
+ <section class="nav-sidebar__section nav-sidebar__section--collapsible">
199
+ <h2 class="nav-sidebar__title">
200
+ <button type="button" class="nav-sidebar__toggle" aria-expanded="true">
201
+ <span class="nav-sidebar__toggle-label">How to Deploy</span>
202
+ <svg class="nav-sidebar__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
203
+ </button>
204
+ </h2>
205
+ <ul class="nav-sidebar__list">
206
+ <li>
207
+ <a href="/docs/how-to-deploy/cloudflare/" class="nav-sidebar__item">Cloudflare</a>
208
+ </li>
209
+ <li>
210
+ <a href="/docs/how-to-deploy/docker/" class="nav-sidebar__item">Docker</a>
211
+ </li>
212
+ <li>
213
+ <a href="/docs/how-to-deploy/wasmer/" class="nav-sidebar__item">Wasmer</a>
195
214
  </li>
196
215
  </ul>
197
216
  </section>
@@ -244,7 +263,26 @@
244
263
  <section class="nav-sidebar__section">
245
264
  <ul class="nav-sidebar__list">
246
265
  <li>
247
- <a href="/docs/hosted/" class="nav-sidebar__item">Hosted Service</a>
266
+ <a href="/docs/hosted/" class="nav-sidebar__item">MockHttp.org Live</a>
267
+ </li>
268
+ </ul>
269
+ </section>
270
+ <section class="nav-sidebar__section nav-sidebar__section--collapsible">
271
+ <h2 class="nav-sidebar__title">
272
+ <button type="button" class="nav-sidebar__toggle" aria-expanded="true">
273
+ <span class="nav-sidebar__toggle-label">How to Deploy</span>
274
+ <svg class="nav-sidebar__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
275
+ </button>
276
+ </h2>
277
+ <ul class="nav-sidebar__list">
278
+ <li>
279
+ <a href="/docs/how-to-deploy/cloudflare/" class="nav-sidebar__item">Cloudflare</a>
280
+ </li>
281
+ <li>
282
+ <a href="/docs/how-to-deploy/docker/" class="nav-sidebar__item">Docker</a>
283
+ </li>
284
+ <li>
285
+ <a href="/docs/how-to-deploy/wasmer/" class="nav-sidebar__item">Wasmer</a>
248
286
  </li>
249
287
  </ul>
250
288
  </section>
@@ -506,7 +544,7 @@ GET /status/429/foo/bar
506
544
  <a href="https://docula.org/" target="_blank" rel="noopener noreferrer" class="footer__link" aria-label="Docula">
507
545
  <svg class="footer__bat" xmlns="http://www.w3.org/2000/svg" viewBox="70 110 360 205" fill="currentColor"><path d="M420,173c-16.76-18-72.78-36.65-131.59-30.58A160.15,160.15,0,0,0,269,120.55c-3.78,4.52-11.15,9.45-19,9.45s-15.23-4.93-19-9.45a160.15,160.15,0,0,0-19.4,21.83C152.78,136.31,96.76,154.94,80,173c48.86,5.86,79.5,34.09,79.5,72.06,52.37,0,77,28,90.5,59.94C263.54,273,288.13,245,340.5,245,340.5,207,371.14,178.8,420,173Z"/><circle cx="239.19" cy="145.36" r="3.32" fill="#fff"/><circle cx="260.81" cy="145.36" r="3.32" fill="#fff"/></svg>
508
546
  </a>
509
- <span class="footer__updated">updated: 2026-09-18</span>
547
+ <span class="footer__updated">updated: 2026-10-20</span>
510
548
  </footer>
511
549
  <script src="/css/highlight/highlight.min.js"></script>
512
550
  <script>
@@ -33,9 +33,9 @@
33
33
  }
34
34
  })();
35
35
  </script>
36
- <title>MockHTTP - Hosted Service</title>
36
+ <title>MockHTTP - MockHttp.org Live</title>
37
37
  <script type="application/ld+json">
38
- {"@context":"https://schema.org","@type":"TechArticle","headline":"Hosted Service","description":"","url":"https://mockhttp.org/docs/hosted/","publisher":{"@type":"Organization","name":"MockHTTP"},"dateModified":"2026-09-18","keywords":[]}
38
+ {"@context":"https://schema.org","@type":"TechArticle","headline":"MockHttp.org Live","description":"","url":"https://mockhttp.org/docs/hosted/","publisher":{"@type":"Organization","name":"MockHTTP"},"dateModified":"2026-10-20","keywords":[]}
39
39
  </script>
40
40
  </head>
41
41
 
@@ -142,7 +142,7 @@
142
142
  <script src="/js/search.js" defer></script>
143
143
  <div class="page-dropdown" id="page-dropdown">
144
144
  <button class="page-dropdown__toggle" id="page-dropdown-toggle">
145
- <span class="page-dropdown__title">Hosted Service</span>
145
+ <span class="page-dropdown__title">MockHttp.org Live</span>
146
146
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></svg>
147
147
  </button>
148
148
  <div class="page-dropdown__list" id="page-dropdown-list">
@@ -191,7 +191,26 @@
191
191
  <section class="nav-sidebar__section">
192
192
  <ul class="nav-sidebar__list">
193
193
  <li>
194
- <a href="/docs/hosted/" class="nav-sidebar__item">Hosted Service</a>
194
+ <a href="/docs/hosted/" class="nav-sidebar__item">MockHttp.org Live</a>
195
+ </li>
196
+ </ul>
197
+ </section>
198
+ <section class="nav-sidebar__section nav-sidebar__section--collapsible">
199
+ <h2 class="nav-sidebar__title">
200
+ <button type="button" class="nav-sidebar__toggle" aria-expanded="true">
201
+ <span class="nav-sidebar__toggle-label">How to Deploy</span>
202
+ <svg class="nav-sidebar__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
203
+ </button>
204
+ </h2>
205
+ <ul class="nav-sidebar__list">
206
+ <li>
207
+ <a href="/docs/how-to-deploy/cloudflare/" class="nav-sidebar__item">Cloudflare</a>
208
+ </li>
209
+ <li>
210
+ <a href="/docs/how-to-deploy/docker/" class="nav-sidebar__item">Docker</a>
211
+ </li>
212
+ <li>
213
+ <a href="/docs/how-to-deploy/wasmer/" class="nav-sidebar__item">Wasmer</a>
195
214
  </li>
196
215
  </ul>
197
216
  </section>
@@ -244,18 +263,38 @@
244
263
  <section class="nav-sidebar__section">
245
264
  <ul class="nav-sidebar__list">
246
265
  <li>
247
- <a href="/docs/hosted/" class="nav-sidebar__item">Hosted Service</a>
266
+ <a href="/docs/hosted/" class="nav-sidebar__item">MockHttp.org Live</a>
267
+ </li>
268
+ </ul>
269
+ </section>
270
+ <section class="nav-sidebar__section nav-sidebar__section--collapsible">
271
+ <h2 class="nav-sidebar__title">
272
+ <button type="button" class="nav-sidebar__toggle" aria-expanded="true">
273
+ <span class="nav-sidebar__toggle-label">How to Deploy</span>
274
+ <svg class="nav-sidebar__chevron" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>
275
+ </button>
276
+ </h2>
277
+ <ul class="nav-sidebar__list">
278
+ <li>
279
+ <a href="/docs/how-to-deploy/cloudflare/" class="nav-sidebar__item">Cloudflare</a>
280
+ </li>
281
+ <li>
282
+ <a href="/docs/how-to-deploy/docker/" class="nav-sidebar__item">Docker</a>
283
+ </li>
284
+ <li>
285
+ <a href="/docs/how-to-deploy/wasmer/" class="nav-sidebar__item">Wasmer</a>
248
286
  </li>
249
287
  </ul>
250
288
  </section>
251
289
  </aside>
252
290
  <article class="article">
253
291
  <header class="article__header">
254
- <h1 class="article__title">Hosted Service</h1>
292
+ <h1 class="article__title">MockHttp.org Live</h1>
255
293
  </header>
256
294
  <div class="article__body">
257
295
  <main class="article__main">
258
- <p><a href="https://mockhttp.org">mockhttp.org</a> is a free hosted instance of this codebase for testing. It runs on a <a href="https://developers.cloudflare.com/workers/">Cloudflare Worker</a> (no containers): documentation is served from Workers Assets, and mock APIs such as <code>/get</code> and <code>/post</code> run in the Worker. The service is globally available and rate-limited (1000 requests per minute per IP) to prevent abuse.</p>
296
+ <p><a href="https://mockhttp.org">mockhttp.org</a> is a free hosted instance of this codebase for testing. It runs on a <a href="/docs/how-to-deploy/cloudflare/">Cloudflare Worker</a> (no containers): documentation is served from Workers Assets, and mock APIs such as <code>/get</code> and <code>/post</code> run in the Worker. The service is globally available and rate-limited (1000 requests per minute per IP) to prevent abuse. Request bins on this service are stored in MongoDB Atlas, in the <code>bins</code> collection, so they are shared across isolates.</p>
297
+ <p>All <a href="https://mockhttp.org">mockhttp.org</a> traffic stays on Cloudflare. A separate test app runs the Node server on <a href="/docs/how-to-deploy/wasmer/">Wasmer Edge</a> at <a href="https://mockhttp.wasmer.app">mockhttp.wasmer.app</a>.</p>
259
298
  <p>Getting Started is served at <code>/</code> and <code>/docs</code>, other guides at <code>/docs/...</code>, and the interactive HTTP API reference at <code>/api</code>. Mock endpoints such as <code>/get</code> and <code>/post</code> are unchanged.</p>
260
299
  </main>
261
300
  <aside class="content-aside">
@@ -279,7 +318,7 @@
279
318
  <a href="https://docula.org/" target="_blank" rel="noopener noreferrer" class="footer__link" aria-label="Docula">
280
319
  <svg class="footer__bat" xmlns="http://www.w3.org/2000/svg" viewBox="70 110 360 205" fill="currentColor"><path d="M420,173c-16.76-18-72.78-36.65-131.59-30.58A160.15,160.15,0,0,0,269,120.55c-3.78,4.52-11.15,9.45-19,9.45s-15.23-4.93-19-9.45a160.15,160.15,0,0,0-19.4,21.83C152.78,136.31,96.76,154.94,80,173c48.86,5.86,79.5,34.09,79.5,72.06,52.37,0,77,28,90.5,59.94C263.54,273,288.13,245,340.5,245,340.5,207,371.14,178.8,420,173Z"/><circle cx="239.19" cy="145.36" r="3.32" fill="#fff"/><circle cx="260.81" cy="145.36" r="3.32" fill="#fff"/></svg>
281
320
  </a>
282
- <span class="footer__updated">updated: 2026-09-18</span>
321
+ <span class="footer__updated">updated: 2026-10-20</span>
283
322
  </footer>
284
323
  <script src="/css/highlight/highlight.min.js"></script>
285
324
  <script>