{"_id":"@mdrv/wbh","_rev":"28-86113685aed69548e413c5f855c30d9a","name":"@mdrv/wbh","dist-tags":{"latest":"269.0.0"},"versions":{"257.0.3":{"name":"@mdrv/wbh","version":"257.0.3","keywords":["browsers","caniuse","support","target"],"author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"license":"GPL-3.0","_id":"@mdrv/wbh@257.0.3","maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"homepage":"https://github.com/mdrv/wbh","bugs":{"url":"https://github.com/mdrv/wbh/issues"},"dist":{"shasum":"77e1da17afd408319010957f320b5a2061c0c77c","tarball":"https://registry.npmjs.org/@mdrv/wbh/-/wbh-257.0.3.tgz","fileCount":15,"integrity":"sha512-eEam8wSBPWjTgNnE3KJrlG/gnvfNJxSXVU1Sf7iTS5Of9o5xESjD1JZVGdYKCBtygFZmIxwhxt83t6xwrN3kxg==","signatures":[{"sig":"MEQCIGn79LRq5QLye5LW5/Izv6qnO4sSDJrF6bDu6goo9ma4AiA/6sGb4IXIHShRRVbVsrVMoaLkVYQ01jcEWQFDtp1YsA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mdrv%2fwbh@257.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":132048},"main":"dist/v257/index.js","type":"module","types":"./dist/v257/index.d.ts","exports":{".":{"default":"./dist/v257/index.js","development":"./src/v257/index.ts"},"./data":{"default":"./dist/v257/data.js","development":"./src/v257/data.ts"},"./mount":{"default":"./dist/v257/mount.js","development":"./src/v257/mount.ts"}},"gitHead":"8c38fd4ec4296b22ec1f343efc22ed1aa226da8e","scripts":{"b":"tsc && swc --strip-leading-paths ./src/v*/ -d ./dist/","g":"V=257 bun ./src/gen.ts"},"_npmUser":{"name":"mdrv","actor":{"name":"mdrv","type":"user","email":"medrivia@gmail.com"},"email":"medrivia@gmail.com"},"deprecated":"This version is not supported. Please update to @latest","repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"_npmVersion":"11.3.0","description":"Restrict access to your website from web browsers with(out) specific features.","directories":{},"_nodeVersion":"24.2.0","_hasShrinkwrap":false,"devDependencies":{"redom":"^4.3.0","@swc/cli":"^0.7.7","is-mobile":"^5.0.0","snarkdown":"^2.0.0","caniuse-db":"^1.0.30001724","es-toolkit":"^1.39.3","@mdn/browser-compat-data":"^6.0.25","@swc/plugin-transform-imports":"^8.0.3"},"_npmOperationalInternal":{"tmp":"tmp/wbh_257.0.3_1750464549363_0.966151665043784","host":"s3://npm-registry-packages-npm-production"}},"257.1.6":{"name":"@mdrv/wbh","version":"257.1.6","keywords":["browsers","caniuse","support","target"],"author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"license":"GPL-3.0","_id":"@mdrv/wbh@257.1.6","maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"homepage":"https://github.com/mdrv/wbh","bugs":{"url":"https://github.com/mdrv/wbh/issues"},"dist":{"shasum":"349da8f1a3bc2f6a879434274b84aec899bc44c8","tarball":"https://registry.npmjs.org/@mdrv/wbh/-/wbh-257.1.6.tgz","fileCount":15,"integrity":"sha512-daKDCRkmJzBa8AeRY6y/MjQlRcGEoyuHIldsPYy+/ogAiEoS/y2BHiFNFj7aYw0SgwKFACNgUyvGeeuP4e7oIw==","signatures":[{"sig":"MEUCIQCWbyJqwKMXF5oj4kgh94vHq0Hmm0CN6ZnG+soPW74eiQIgAMebxXaxVOXzlGtgbh5vP3Uyj9KWaifSnTLom8usMUI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mdrv%2fwbh@257.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":135738},"main":"./dist/v257/index.js","type":"module","types":"./dist/v257/index.d.ts","exports":{".":{"types":"./dist/v257/index.d.ts","default":"./dist/v257/index.js"},"./*":{"types":"./dist/*/index.d.ts","default":"./dist/*/index.js"},"./data":{"types":"./dist/v257/data.d.ts","default":"./dist/v257/data.js"},"./mount":{"types":"./dist/v257/mount.d.ts","default":"./dist/v257/mount.js"},"./*/data":{"types":"./dist/*/data.d.ts","default":"./dist/*/data.js"},"./*/mount":{"types":"./dist/*/mount.d.ts","default":"./dist/*/mount.js"}},"gitHead":"9c4181511a6e2a3c5ff48e72df755fbc7d0261e0","scripts":{"b":"tsc && swc --strip-leading-paths ./src/v*/ -d ./dist/","g":"V=257 bun ./src/gen.ts"},"_npmUser":{"name":"mdrv","actor":{"name":"mdrv","type":"user","email":"medrivia@gmail.com"},"email":"medrivia@gmail.com"},"repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"_npmVersion":"11.3.0","description":"Restrict access to your website from web browsers with(out) specific features.","directories":{},"_nodeVersion":"24.2.0","_hasShrinkwrap":false,"devDependencies":{"redom":"^4.3.0","@swc/cli":"^0.7.7","is-mobile":"^5.0.0","snarkdown":"^2.0.0","caniuse-db":"^1.0.30001724","es-toolkit":"^1.39.4","@mdn/browser-compat-data":"^6.0.25","@swc/plugin-transform-imports":"^8.0.3"},"_npmOperationalInternal":{"tmp":"tmp/wbh_257.1.6_1750517073250_0.5501625179277978","host":"s3://npm-registry-packages-npm-production"}},"257.1.8":{"name":"@mdrv/wbh","version":"257.1.8","keywords":["browsers","caniuse","support","target","wbh","webdev"],"author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"license":"GPL-3.0","_id":"@mdrv/wbh@257.1.8","maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"homepage":"https://github.com/mdrv/wbh","bugs":{"url":"https://github.com/mdrv/wbh/issues"},"dist":{"shasum":"d424bed22b429c01504d6863cbce8cd5732ee807","tarball":"https://registry.npmjs.org/@mdrv/wbh/-/wbh-257.1.8.tgz","fileCount":15,"integrity":"sha512-D3P8wwUQLAbWGxjckZSlUp+X25gnREeUTNr/f8z1YP11cFlqMNAryi707OT8WomncIDK3ju8NMZEjg+ozUVZ2g==","signatures":[{"sig":"MEUCICQNNhIB70wzdDZB2xaouEgHQZPWSiPIqAoPHrLUiW8TAiEAi07l7hAdTwqUGK4NMS0Rkt1ce+Firguw3XYhahBaiSs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mdrv%2fwbh@257.1.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":126960},"main":"./dist/v257/index.js","type":"module","types":"./dist/v257/index.d.ts","exports":{".":{"types":"./dist/v257/index.d.ts","default":"./dist/v257/index.js"},"./*":{"types":"./dist/*/index.d.ts","default":"./dist/*/index.js"},"./data":{"types":"./dist/v257/data.d.ts","default":"./dist/v257/data.js"},"./mount":{"types":"./dist/v257/mount.d.ts","default":"./dist/v257/mount.js"},"./*/data":{"types":"./dist/*/data.d.ts","default":"./dist/*/data.js"},"./*/mount":{"types":"./dist/*/mount.d.ts","default":"./dist/*/mount.js"}},"gitHead":"58682a4ee9e0931c90908fcdb65526380a6a6af2","scripts":{"b":"tsdown","f":"dprint fmt","g":"V=257 bun ./src/gen.ts","fc":"dprint check"},"_npmUser":{"name":"mdrv","email":"medrivia@gmail.com"},"repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"_npmVersion":"11.4.2","description":"🔨 Restrict access to your website from web browsers without specific features.","directories":{},"_nodeVersion":"24.4.1","dependencies":{"redom":"^4.3.0","is-mobile":"^5.0.0","snarkdown":"^2.0.0","es-toolkit":"^1.39.7"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.12.9","caniuse-db":"^1.0.30001727","@mdn/browser-compat-data":"^6.0.33"},"_npmOperationalInternal":{"tmp":"tmp/wbh_257.1.8_1753110177999_0.9749617400951425","host":"s3://npm-registry-packages-npm-production"}},"257.1.9":{"name":"@mdrv/wbh","version":"257.1.9","keywords":["browsers","caniuse","support","target","wbh","webdev"],"author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"license":"GPL-3.0","_id":"@mdrv/wbh@257.1.9","maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"homepage":"https://github.com/mdrv/wbh","bugs":{"url":"https://github.com/mdrv/wbh/issues"},"dist":{"shasum":"37056556d092a7f3b07b02e5f1f8df5633574515","tarball":"https://registry.npmjs.org/@mdrv/wbh/-/wbh-257.1.9.tgz","fileCount":15,"integrity":"sha512-uY1MeSd7KBk/wdzY5Lw/s0d4Xi1P8hnL5UJ/kGerp/Yflr8KJknVzrhk5galOTOs5aGXBN5lIlxOTojql+dxAw==","signatures":[{"sig":"MEQCIEtZyLwQljiETZs7K1cfFqHCWZ9IB+NljkRUWuNSrFATAiBTlMFP06hryg3i08R3lmjbs+bO8UOAuD4G9g3sWVH2Xw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mdrv%2fwbh@257.1.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":126987},"main":"./dist/v257/index.js","type":"module","types":"./dist/v257/index.d.ts","exports":{".":{"types":"./dist/v257/index.d.ts","default":"./dist/v257/index.js"},"./data":{"types":"./dist/v257/data.d.ts","default":"./dist/v257/data.js"},"./v257":{"types":"./dist/v257/index.d.ts","default":"./dist/v257/index.js"},"./mount":{"types":"./dist/v257/mount.d.ts","default":"./dist/v257/mount.js"},"./v257/data":{"types":"./dist/v257/data.d.ts","default":"./dist/v257/data.js"},"./v257/mount":{"types":"./dist/v257/mount.d.ts","default":"./dist/v257/mount.js"}},"gitHead":"af1cd118f23e8e0a29e1797f62a8fb53509aee37","scripts":{"b":"tsdown","f":"dprint fmt","g":"V=257 bun ./src/gen.ts","fc":"dprint check"},"_npmUser":{"name":"mdrv","email":"medrivia@gmail.com"},"repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"_npmVersion":"11.4.2","description":"🔨 Restrict access to your website from web browsers without specific features.","directories":{},"_nodeVersion":"24.4.1","dependencies":{"redom":"^4.3.0","is-mobile":"^5.0.0","snarkdown":"^2.0.0","es-toolkit":"^1.39.7"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.12.9","caniuse-db":"^1.0.30001727","@mdn/browser-compat-data":"^6.0.33"},"_npmOperationalInternal":{"tmp":"tmp/wbh_257.1.9_1753118592646_0.18551670301634648","host":"s3://npm-registry-packages-npm-production"}},"265.0.0":{"name":"@mdrv/wbh","version":"265.0.0","keywords":["browsers","caniuse","support","target","wbh","webdev"],"author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"license":"GPL-3.0","_id":"@mdrv/wbh@265.0.0","maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"homepage":"https://github.com/mdrv/wbh","bugs":{"url":"https://github.com/mdrv/wbh/issues"},"dist":{"shasum":"b18db5203d60620346f10b667b77595881504248","tarball":"https://registry.npmjs.org/@mdrv/wbh/-/wbh-265.0.0.tgz","fileCount":14,"integrity":"sha512-XRkW9GPZ94yd0zTyPmuco9lmkzF2qa4f26EhG2U/p+QE+iZuV1GznCvkPtHdZpBJnJQsc/c3JD0W72ltVtv6wQ==","signatures":[{"sig":"MEYCIQDynkv0/DTv4BOwHpLyVXkJbOK8DCHKUDzjavY/tHUP4wIhAJNjbGv6QhQX5lBFwiz8gwt2OKdHCA6McfLtJhOg12HA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mdrv%2fwbh@265.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":149667},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./data":{"types":"./dist/data.d.ts","default":"./dist/data.js"}},"gitHead":"10c0e1023dc16cbf01c17e866cdd12ec9652684e","scripts":{"b":"tsdown","f":"dprint fmt","g":"bun ./scripts/gen.ts","fc":"dprint check"},"_npmUser":{"name":"mdrv","email":"medrivia@gmail.com"},"repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"_npmVersion":"11.13.0","description":"🔨 Restrict access to your website from web browsers without specific features.","directories":{},"_nodeVersion":"26.2.0","dependencies":{"es-toolkit":"^1.46.1"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.22.0","@types/bun":"^1.3.14","caniuse-db":"^1.0.30001793","@mdn/browser-compat-data":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/wbh_265.0.0_1779606638044_0.33910394009845013","host":"s3://npm-registry-packages-npm-production"}},"269.0.0":{"_id":"@mdrv/wbh@269.0.0","bugs":{"url":"https://github.com/mdrv/wbh/issues"},"dist":{"shasum":"39207edbafb82141268b184ff465f886668be669","tarball":"https://registry.npmjs.org/@mdrv/wbh/-/wbh-269.0.0.tgz","fileCount":14,"integrity":"sha512-XrjvM9eD9FI60wl4xmHXrTuTGIDLV1bG/eIsJ3b16ghADH2j2XRMPmgrSP0/pejkRVM0frcRib4lUjqgGYmnSQ==","signatures":[{"sig":"MEUCIDrauJCWw5d8Ou3A50AwV3aYctPBFdnO7Exwz9iUDKZTAiEA0/GvDgTzStTkPBqRGn7Elfn79G0AxXI1UZkheskJo8I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC63ccBc5a8qz66q+46IyYvBoE4305t/oJY3D9OE0DPDQIgToGEZyihkK3l4vH02S7cUrpLQ79/PxiPs9jtE13sAjE="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mdrv%2fwbh@269.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":154085},"main":"./dist/index.js","name":"@mdrv/wbh","type":"module","types":"./dist/index.d.ts","author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./data":{"types":"./dist/data.d.ts","default":"./dist/data.js"}},"gitHead":"3ca54abc68e5de3724829487e2afe1cf6e017b27","license":"GPL-3.0","scripts":{"b":"tsdown","f":"dprint fmt","g":"bun ./scripts/gen.ts","fc":"dprint check"},"version":"269.0.0","_npmUser":{"name":"mdrv","email":"medrivia@gmail.com"},"homepage":"https://github.com/mdrv/wbh","keywords":["browsers","caniuse","support","target","wbh","webdev"],"repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"_npmVersion":"11.19.1","description":"🔨 Restrict access to your website from web browsers without specific features.","directories":{},"maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"_nodeVersion":"26.10.0","dependencies":{"es-toolkit":"^1.46.1"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"^0.22.0","@types/bun":"^1.3.14","caniuse-db":"^1.0.30001793","@mdn/browser-compat-data":"^8.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wbh_269.0.0_1790147771861_0.6523360299516952"}}},"time":{"created":"2025-06-20T15:26:51.909Z","modified":"2026-09-23T07:16:12.406Z","257.0.0":"2025-06-20T15:26:52.222Z","257.0.1":"2025-06-20T16:10:21.302Z","257.0.2":"2025-06-20T16:31:35.658Z","257.0.3":"2025-06-21T00:09:09.562Z","257.1.0":"2025-06-21T11:06:37.403Z","257.1.1":"2025-06-21T12:40:57.192Z","257.1.2":"2025-06-21T13:01:26.573Z","257.1.3":"2025-06-21T13:40:03.652Z","257.1.4":"2025-06-21T14:01:32.406Z","257.1.5":"2025-06-21T14:23:08.787Z","257.1.6":"2025-06-21T14:44:33.453Z","257.1.7":"2025-07-21T14:58:16.610Z","257.1.8":"2025-07-21T15:02:58.188Z","257.1.9":"2025-07-21T17:23:12.861Z","265.0.0":"2026-05-24T07:10:38.189Z","269.0.0":"2026-09-23T07:16:11.960Z"},"bugs":{"url":"https://github.com/mdrv/wbh/issues"},"author":{"url":"https://alfarouk.id","name":"Umar Alfarouk","email":"medrivia@gmail.com"},"license":"GPL-3.0","homepage":"https://github.com/mdrv/wbh","keywords":["browsers","caniuse","support","target","wbh","webdev"],"repository":{"url":"git+https://github.com/mdrv/wbh.git","type":"git"},"description":"🔨 Restrict access to your website from web browsers without specific features.","maintainers":[{"name":"mdrv","email":"medrivia@gmail.com"}],"readme":"# 🔨 Web Browser Hard (WBH)\n\n<p align=\"center\">\n    <img src=\"res/logo.svg\" width=\"180\" height=\"180\" /><br/>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://github.com/mdrv/wbh/actions/workflows/release.yml\">\n        <img alt=\"GitHub Workflow Status\" src=\"https://img.shields.io/github/actions/workflow/status/mdrv/wbh/release.yml?event=release\"/>\n    </a>\n    <a href=\"https://www.npmjs.com/package/@mdrv/wbh\">\n        <img alt=\"Visit the NPM page\" src=\"https://img.shields.io/npm/v/@mdrv/wbh\"/>\n    </a>\n    <a href=\"https://github.com/mdrv/wbh/blob/master/LICENSE\">\n        <img alt=\"GitHub License\" src=\"https://img.shields.io/github/license/mdrv/wbh\">\n    </a>\n</p>\n\n<p align=\"center\">\n    <b><i>Restrict access to your website from web browsers without specific features.</i></b>\n</p>\n\n> The API of this module is **rapidly changing** and is not intended for production or commercial use.\n>\n> To suit your specific needs, it's necessary to fork this project (with attribution). You can expect `v265`+ to be **more stable**. 🌟\n\n## 🎁 Features\n\n- 🧬 **Modular**: Use it on any framework (Svelte, Vue, etc.)\n- 📊 **Versatile**: Pick from [70+ browser features](https://github.com/mdrv/wbh/wiki/feature-list) to check\n- 🎛️ **Customizable**: Set metadata per-feature with levels, scores, and wisdom text\n- 🌲 **Tree-shakeable**: Unused imports stay out of bundle\n- 🚀 **Easy to use**: Comes with TypeScript types out of the box\n- 📦 **Presets**: Ready-made profiles for common app types (modern web apps, SPAs, e-commerce, etc.)\n- 🔍 **Version inference**: Infer minimum browser versions required by your feature set\n\nAny question? Read [Q&A](https://github.com/mdrv/wbh/wiki/Q&A) on the wiki.\n\n## 🧭 Example Code\n\n### Basic usage\n\n```ts\nimport {\n\tWBH,\n\tWBHLevel as L,\n\tavif,\n\tfileSystemApi,\n\tcssAspectRatio,\n} from '@mdrv/wbh'\n\nconst wbh = new WBH([\n\t{\n\t\tfeat: avif,\n\t\tlevel: L.CRITICAL,\n\t\tscore: 50,\n\t\twisdom: 'Most images are optimized AVIF.',\n\t},\n\t{\n\t\tfeat: fileSystemApi,\n\t\tlevel: L.IMPORTANT,\n\t\tscore: 50,\n\t\twisdom: 'Needed for local binary storage.',\n\t},\n\t{\n\t\tfeat: cssAspectRatio,\n\t\tlevel: L.OPTIONAL,\n\t\tscore: 49,\n\t\twisdom: 'Some layouts depend on aspect ratio.',\n\t},\n])\n\nconst result = await wbh.getResultAsync()\nif (result.score >= 0) {\n\t// Render your app\n} else {\n\t// Browser missing features — show fallback UI\n}\n```\n\n### Using presets\n\n```ts\nimport { WBH, presets } from '@mdrv/wbh'\n\nconst wbh = new WBH(presets.modernWebApp())\nconst result = await wbh.getResultAsync()\n\nconsole.log(result.unsupported.map((f) => f.name))\n```\n\n### Browser version inference\n\n```ts\nconst wbh = new WBH(presets.modernWebApp())\nawait wbh.getResultAsync()\n\nconst versions = wbh.inferMinimumVersions()\n// { chrome: \"120\", firefox: \"121\", safari: \"17\", edge: \"120\" }\n\nconst comparison = wbh.compareBrowser('firefox', 115)\n// { browser: \"firefox\", version: 115, status: \"outdated\", gap: 6, ... }\n```\n\n### Options\n\n```ts\nnew WBH(features, {\n\tcache: false, // opt-in: cache detection results (default off)\n\tmockUnsupported: false, // simulate all features unsupported (for testing)\n})\n```\n\n## 🔔 Release Info\n\nThis package implements **Gregorian YYM-based** semver notation.\n\n| Version    | Date         |\n| ---------- | ------------ |\n| `v257.x.x` | July 2025    |\n| `v260.x.x` | Oct–Dec 2025 |\n| `v265.x.x` | May 2026     |\n\nSee [CHANGELOG](https://github.com/mdrv/wbh/wiki/changelog) for full history.\n\n---\n\n<details>\n<summary><strong>v265 Changelog</strong> (click to expand)</summary>\n\n### Breaking Changes\n\n- **Renamed** `forceFail` option → `mockUnsupported`\n- **Removed** built-in CSS (`css.ts`) — handle your own fallback UI\n- **Removed** `is-mobile` dependency\n- **Updated** `Result` type: now includes `timestamp` and `durationMs` fields\n- **Updated** feature data: each feature now includes `safari` and `edge` version fields\n\n### New Features\n\n- **Presets system** (`src/presets.ts`) — 7 ready-made profiles:\n  - `modernWebApp()` — CSS nesting, grid, container queries, dialog, view transitions\n  - `spa()` — Single-page app essentials (view transitions, navigation API, promises)\n  - `contentSite()` — Content-focused sites (text-wrap, viewport units, typography)\n  - `dataHeavy()` — Data-intensive apps (IndexedDB, WebSockets, structuredClone)\n  - `cuttingEdge()` — Latest APIs (anchor positioning, scroll timeline, declarative shadow DOM)\n  - `minimal()` — Bare minimum for basic compatibility\n  - `ecommerce()` — E-commerce features (dialog modals, payment API, popover)\n- **`inferMinimumVersions()`** — Returns min Chrome/Firefox/Safari/Edge versions needed\n- **`compareBrowser(browser, version)`** — Compare a browser version against requirements; returns `current`, `outdated`, or `unsupported` status\n- **Opt-in cache** via `{ cache: true }` option (default off to avoid stale results)\n- **Enriched Result** — `timestamp` (Date.now()) and `durationMs` (performance.now())\n\n### New Feature Detections (+20)\n\n| Feature                | Level     | Notes                             |\n| ---------------------- | --------- | --------------------------------- |\n| `htmlDialog`           | CRITICAL  | `<dialog>` + showModal            |\n| `viewTransitions`      | CRITICAL  | View Transitions API              |\n| `cssNesting`           | CRITICAL  | CSS nesting syntax                |\n| `cssHasSelector`       | CRITICAL  | `:has()` relational selector      |\n| `structuredClone`      | CRITICAL  | Deep cloning without hacks        |\n| `promiseWithResolvers` | CRITICAL  | Promise.withResolvers()           |\n| `arrayAt`              | IMPORTANT | Array.at() negative indexing      |\n| `arrayWith`            | IMPORTANT | Array.with() immutable mutation   |\n| `cssColorMix`          | IMPORTANT | color-mix() function              |\n| `viewportUnits`        | IMPORTANT | svh/lvh/dvh units                 |\n| `cssFocusVisible`      | IMPORTANT | :focus-visible pseudo-class       |\n| `navigationApi`        | IMPORTANT | Navigation API (Chrome/Edge only) |\n| `urlPattern`           | IMPORTANT | URLPattern API                    |\n| `cssAnchorPositioning` | OPTIONAL  | Anchor positioning (Chrome only)  |\n| `declarativeShadowDom` | OPTIONAL  | Declarative Shadow DOM            |\n| `promiseTry`           | OPTIONAL  | Promise.try()                     |\n| `regexpEscape`         | OPTIONAL  | RegExp.escape()                   |\n| `importAttributes`     | OPTIONAL  | Import attributes                 |\n\n### Internal Improvements\n\n- **gen.ts** now extracts Safari and Edge version data from MDN BCD + caniuse-db\n- **types.ts** cleaned up: `caniuse` is `readonly string[]`, added `reason?`, `BrowserVersionMap`, `BrowserComparison`\n- **dynamicImport** no longer references removed `is-mobile` dep\n- Test suite expanded from 4 → 10 tests covering all new functionality\n\n</details>\n\n---\n\n## 💖 Thank You\n\nThis project proudly uses:\n\n- 🧩 [**es-toolkit**](https://github.com/toss/es-toolkit) (modern JS utilities with TypeScript support)\n- 🥟 [**Bun.js**](https://github.com/oven-sh/bun) (blazing fast server-side JS runtime)\n- 📚 Additional data: [**MDN**](https://github.com/mdn/browser-compat-data) and [**Can I use...**](https://github.com/Fyrd/caniuse)\n\n<p align=\"center\"><sub><strong>© 2025 MEDRIVIA ／ Umar Alfarouk</strong></sub></p>\n","readmeFilename":"README.md"}