{"_id":"@aseity/mirage","_rev":"5-ef7622f4a92705905b2b84cd8b12f14b","name":"@aseity/mirage","dist-tags":{"latest":"0.4.0"},"versions":{"0.0.1":{"name":"@aseity/mirage","version":"0.0.1","license":"MIT","_id":"@aseity/mirage@0.0.1","maintainers":[{"name":"yt902","email":"ty29022@gmail.com"}],"dist":{"shasum":"8e85fc43bf2783c9abcf7cd7ac1d39aad4f252fe","tarball":"https://registry.npmjs.org/@aseity/mirage/-/mirage-0.0.1.tgz","fileCount":21,"integrity":"sha512-9KM7zGagV75s0Ib8g/6tTDTpO8Cooof4T9HWSkK1EFxoEE9cGwvn0X139jwYFQFHsDLf3Pp6K+ocFeGgtsLu3w==","signatures":[{"sig":"MEQCIHPf3fHVOFRowSR9n+hINPd457pQhx9exURblwbi8pMOAiAyZbuOd2otA2BVSjOE9qMhVRoqql8s8wlRFm4BaSbEFQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80823},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"1be8653203ad1b588bf5460ea723c595af662bcd","scripts":{"build":"tsc --project tsconfig.build.json","clean":"","build:watch":"tsc --watch --project tsconfig.build.json"},"_npmUser":{"name":"yt902","email":"ty29022@gmail.com"},"_npmVersion":"10.9.2","directories":{},"sideEffects":false,"_nodeVersion":"23.7.0","_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","typescript":"5.8.3","@types/node":"^24.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mirage_0.0.1_1773988706741_0.9077924282229259","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@aseity/mirage","version":"0.0.2","license":"MIT","_id":"@aseity/mirage@0.0.2","maintainers":[{"name":"yt902","email":"ty29022@gmail.com"}],"dist":{"shasum":"0a8cd1068d151a98f8eb32acefd41b99d23928d8","tarball":"https://registry.npmjs.org/@aseity/mirage/-/mirage-0.0.2.tgz","fileCount":21,"integrity":"sha512-kUKAKIIZep8Q3vsfAQhy52Ub5D2OtQh0Mw0E9OT0WEodNoZiMb4hIjUKswfmc3CMMiNwIci0cNwdS/aMONN2SQ==","signatures":[{"sig":"MEUCIQCEej1Z6hy04umU+ThMSRtWzP3xWoz+abaHGwh1uX+fxgIgfBwpp/ZgBxt4aHVC/VwQjLIn/EL9dzXeHf79fsHb7RY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83484},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"501f2c29e51f4c102d66bfc7610c4609c68dec02","scripts":{"build":"tsc --project tsconfig.build.json","clean":"","build:watch":"tsc --watch --project tsconfig.build.json"},"_npmUser":{"name":"yt902","email":"ty29022@gmail.com"},"_npmVersion":"10.9.2","directories":{},"sideEffects":false,"_nodeVersion":"23.7.0","_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","typescript":"5.8.3","@types/node":"^24.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mirage_0.0.2_1774590250031_0.44784917826853876","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aseity/mirage","version":"0.1.1","license":"MIT","_id":"@aseity/mirage@0.1.1","maintainers":[{"name":"yt902","email":"ty29022@gmail.com"}],"dist":{"shasum":"99e1380e385e0b194fba04b6da260529e453bb3e","tarball":"https://registry.npmjs.org/@aseity/mirage/-/mirage-0.1.1.tgz","fileCount":21,"integrity":"sha512-3lGTwo0ePxuiccebouv4HZ1LeSkWrLbkJNVyLQ5pinL8aGsKGh1n450+4sZMNCI4OCQ7Ut4at4Z0w/TaZbrQ6w==","signatures":[{"sig":"MEUCIQCfmcab70vgHsHDWFcJaPAINppgepOCVooj7mUd8JWuSwIgDqJl6aefWFjWZD404mG27QGiILd5rGnrbTXaDOH/fM0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83941},"main":"dist/index.js","type":"module","_from":"file:aseity-mirage-0.1.1.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"lint":"biome check .","build":"tsc --project tsconfig.build.json","clean":"","format":"biome format --write .","lint:fix":"biome check --write .","build:watch":"tsc --watch --project tsconfig.build.json"},"_npmUser":{"name":"yt902","email":"ty29022@gmail.com"},"_resolved":"/tmp/c793b57d29fdd2e5b2735340b835f418/aseity-mirage-0.1.1.tgz","_integrity":"sha512-3lGTwo0ePxuiccebouv4HZ1LeSkWrLbkJNVyLQ5pinL8aGsKGh1n450+4sZMNCI4OCQ7Ut4at4Z0w/TaZbrQ6w==","_npmVersion":"10.9.2","directories":{},"sideEffects":false,"_nodeVersion":"23.7.0","_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","typescript":"5.8.3","@types/node":"^24.5.2","@biomejs/biome":"2.5.0"},"_npmOperationalInternal":{"tmp":"tmp/mirage_0.1.1_1782816331316_0.5780321298637485","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aseity/mirage","version":"0.3.0","license":"MIT","_id":"@aseity/mirage@0.3.0","maintainers":[{"name":"yt902","email":"ty29022@gmail.com"}],"homepage":"https://github.com/Ty026/max#readme","bugs":{"url":"https://github.com/Ty026/max/issues"},"dist":{"shasum":"673ee88787fa768f8a6b67f78fcfadd63875b783","tarball":"https://registry.npmjs.org/@aseity/mirage/-/mirage-0.3.0.tgz","fileCount":13,"integrity":"sha512-bHlDkl7uvsyQmkaVVBU5/FBq6N1ixF5JH1oUuaW01jK8pDV0RPIGdtdZZkAwvPr3bj0BTcGmrJFtnDrMr/HgDA==","signatures":[{"sig":"MEUCIAI7DR8k9LWqk3csmWhgUymr/KCWOkbrTmqPFsZqMtEhAiEA6skDMlIP+ytif1VRcEPSjuao5c83ZXXzeAbQ9q++Jew=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55097},"main":"dist/index.js","type":"module","_from":"file:aseity-mirage-0.3.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"lint":"biome check .","build":"tsc --project tsconfig.build.json","clean":"","format":"biome format --write .","lint:fix":"biome check --write .","build:watch":"tsc --watch --project tsconfig.build.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:11ce89ff-5cc9-4279-b602-7566627d2eca"}},"_resolved":"/tmp/b7c2b3a2099bfb65eb55442c1cba6eae/aseity-mirage-0.3.0.tgz","_integrity":"sha512-bHlDkl7uvsyQmkaVVBU5/FBq6N1ixF5JH1oUuaW01jK8pDV0RPIGdtdZZkAwvPr3bj0BTcGmrJFtnDrMr/HgDA==","repository":{"url":"git+https://github.com/Ty026/max.git","type":"git","directory":"packages/mirage"},"_npmVersion":"11.19.0","description":"Browser-side virtual backend for generated web app previews.","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","typescript":"5.8.3","@types/node":"^24.5.2","@biomejs/biome":"2.5.0"},"_npmOperationalInternal":{"tmp":"tmp/mirage_0.3.0_1786004179257_0.3705313346760726","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@aseity/mirage@0.4.0","bugs":{"url":"https://github.com/Ty026/max/issues"},"dist":{"shasum":"d411c0095a311d92aaa98256c9f636e8b53f849c","tarball":"https://registry.npmjs.org/@aseity/mirage/-/mirage-0.4.0.tgz","fileCount":15,"integrity":"sha512-rhKTTWwDY8qK+NGFWFuxs7sPaw5pwInZXZfwRRFlKpKOjG5H2TX1exRyPk8swNsGPD5jy9G1htG00lZ3ea6KBA==","signatures":[{"sig":"MEUCIQDNdAO+wO6Pee3LipsRjmjZ4KHTfbV5c7CpHc8RaJpuFwIgM7VvOvfXyE3C7IM48P1S6FS3mXsukCp0YjX/pRsaBA0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEFmwX3+xa8j+QFosi7d5HFUKLANVADupRPfi0+CMk/6AiAR8QJa+G+7JI3CleJKLPctSePPufkWO2P5wNgqGQW50w=="}],"unpackedSize":21796},"main":"dist/index.js","name":"@aseity/mirage","type":"module","_from":"file:aseity-mirage-0.4.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"license":"MIT","scripts":{"lint":"biome check .","test":"pnpm build && node --test test/worker.test.mjs && playwright test","build":"tsc --project tsconfig.build.json","clean":"rimraf dist *.tsbuildinfo","format":"biome format --write .","lint:fix":"biome check --write .","typecheck":"tsc --project tsconfig.test.json","build:watch":"tsc --watch --project tsconfig.build.json"},"version":"0.4.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:11ce89ff-5cc9-4279-b602-7566627d2eca"}},"homepage":"https://github.com/Ty026/max#readme","_resolved":"/tmp/b3114130f664f9492a9249f06799fd61/aseity-mirage-0.4.0.tgz","_integrity":"sha512-rhKTTWwDY8qK+NGFWFuxs7sPaw5pwInZXZfwRRFlKpKOjG5H2TX1exRyPk8swNsGPD5jy9G1htG00lZ3ea6KBA==","repository":{"url":"git+https://github.com/Ty026/max.git","type":"git","directory":"packages/mirage"},"_npmVersion":"11.19.1","description":"Browser-side virtual backend for generated web app previews.","directories":{},"maintainers":[{"name":"yt902","email":"ty29022@gmail.com"}],"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.0.1","typescript":"5.8.3","@types/node":"^24.5.2","@biomejs/biome":"2.5.0","@playwright/test":"^1.62.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mirage_0.4.0_1789468302962_0.3813690475871645"}}},"time":{"created":"2026-03-20T06:38:26.631Z","modified":"2026-09-15T10:31:43.256Z","0.0.1":"2026-03-20T06:38:26.877Z","0.0.2":"2026-03-27T05:44:10.171Z","0.1.1":"2026-06-30T10:45:31.447Z","0.3.0":"2026-08-06T08:16:19.396Z","0.4.0":"2026-09-15T10:31:43.073Z"},"bugs":{"url":"https://github.com/Ty026/max/issues"},"license":"MIT","homepage":"https://github.com/Ty026/max#readme","repository":{"url":"git+https://github.com/Ty026/max.git","type":"git","directory":"packages/mirage"},"description":"Browser-side virtual backend for generated web app previews.","maintainers":[{"name":"yt902","email":"ty29022@gmail.com"}],"readme":"# @aseity/mirage\n\nMirage publishes a collection of files as an independent browser preview. A\nservice worker serves its URLs to an iframe, including relative scripts, styles,\nimages, and fetches.\n\n## Setup\n\n```sh\npnpm add @aseity/mirage\n```\n\nServe `MIRAGE_WORKER_SOURCE` as JavaScript at `/mirage-backend/worker.js`.\nFor example, a Next.js route at `app/mirage-backend/worker.js/route.ts`:\n\n```ts\nimport { MIRAGE_WORKER_SOURCE } from '@aseity/mirage';\n\nexport function GET() {\n  return new Response(MIRAGE_WORKER_SOURCE, {\n    headers: {\n      'Content-Type': 'application/javascript; charset=utf-8',\n      'Cache-Control': 'no-cache',\n    },\n  });\n}\n```\n\nMirage requires HTTPS or localhost and a browser with service worker support.\nThe worker's directory is its scope; use `serviceWorkerPath` to change it. The\nhost page can live outside that scope.\n\n## Publish a preview\n\n```ts\nimport { createMirage } from '@aseity/mirage';\n\nconst mirage = await createMirage();\nconst preview = await mirage.mount({\n  '/index.html': '<h1>Hello</h1><script src=\"./app.js\"></script>',\n  '/app.js': 'console.log(\"Ready\")',\n  '/api/data.json': {\n    type: 'file',\n    content: JSON.stringify({ ready: true }),\n    contentType: 'application/json',\n  },\n  '/images/logo.png': {\n    type: 'proxy',\n    target: 'https://example.com/logo.png',\n  },\n});\n\niframe.src = preview.url('/index.html');\n\n// When the preview closes, remove its persisted files and proxy configuration.\nawait preview.dispose();\n```\n\n## Interface\n\n- `createMirage({ serviceWorkerPath? })` registers the worker and returns a host.\n  It has no global configuration or active namespace. Multiple hosts can share\n  the same worker without clearing one another's previews.\n- `mirage.mount(files)` publishes a complete snapshot and returns a preview only\n  after every file and proxy configuration has been persisted. Each call creates\n  a new preview URL. File contents are copied when called; later input mutations\n  do not change the snapshot. A failed publication removes its partial data.\n- `preview.url(path)` returns an absolute URL, encoding each filename segment.\n  `preview.url('/')` gives its base URL. Treat the URL structure as opaque.\n- `preview.dispose()` removes that snapshot. Repeated calls are safe, including\n  concurrent calls; a failed disposal can be retried. New requests to removed\n  files return 404. Requests already in progress may finish.\n\nFile values are strings, `{ type: 'file', content, contentType? }`, or\n`{ type: 'proxy', target, headers? }`. Contents can be strings, ArrayBuffers, or\nUint8Arrays. Content types default from the filename. Directories are implicit;\nempty directories and directory listings are not supported. Paths escaping the\npreview root and duplicate normalized paths are rejected.\n\nEach preview supports GET and HEAD. Queries do not change which file is served.\nProxy entries fetch their configured HTTP(S) target on every request, preserving\nthe upstream status and content type. They support fixed request headers and\nfollow ordinary browser CORS restrictions; they are resource mappings, not a\nrequest-forwarding backend.\n\nUse relative asset URLs inside a preview (`./app.js`, `images/logo.png`). URLs\nstarting with `/` refer to the site's root. Fetching a preview URL from a host\npage outside the worker scope does not route through Mirage; fetch from the\npreview iframe instead.\n\nSnapshots, including proxy configurations, survive worker termination and host\nreloads through Cache Storage. Proxy response bodies are not persisted. Browser\nstorage eviction can remove snapshots. The host owns disposal; navigating away\nwithout disposing leaves the snapshot stored. Releasing one preview does not\nrelease any other preview.\n\nFor refreshes, mount a new snapshot, switch the iframe to its URL, and dispose the\nold preview when no longer needed. If an asynchronous mount finishes after its\nowner has closed, dispose the returned preview immediately.\n\n## Migrating from 0.3\n\nThis is a breaking interface change:\n\n- Replace `getMirage`, `configureMirage`, and `await mirage` with `createMirage`.\n- Remove `setNamespace` and `clearPrevious`; each mount is independently owned.\n- Replace `mount(files, { overwrite: true })` with `const preview = await mount(files)`.\n- Replace manually constructed URLs with `preview.url(entry)` and release the\n  preview on close or replacement with `preview.dispose()`.\n- Remove `writeFile`, `mkdir`, `rm`, `watch`, directory mount entries, and proxy\n  memory-cache options. Publish a new snapshot to change files.\n- Replace `MirageMountTree` with `MirageFiles`. Worker protocol and internal entry\n  types are no longer exported. `scope`, `namespace`, and `debug` initialization\n  options and `mirageContext` have been removed.\n\nDeploy the updated worker source together with the client. Legacy namespace URLs\nand the old `mirage-cache-v1` storage format are not read by this version. Remount\npreviews from their source files after upgrading; Mirage does not automatically\ndelete the old cache.\n\n## Development\n\n```sh\npnpm exec playwright install chromium\npnpm test\npnpm typecheck\npnpm lint\n```\n\nTests cover atomic publication and rollback, real iframe loading, concurrent\nmounts, multiple tabs, disposal, encoded paths, and worker termination/recovery.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}