{"_id":"@ape-egg/vite-plugin-vibe","_rev":"5-1871c8e77fecbeaabfc9d3ddfca5f7f7","name":"@ape-egg/vite-plugin-vibe","dist-tags":{"latest":"0.4.1"},"versions":{"0.0.2":{"name":"@ape-egg/vite-plugin-vibe","version":"0.0.2","keywords":["vite","vite-plugin","vibe","hmr","components"],"author":{"name":"kkortes"},"license":"ISC","_id":"@ape-egg/vite-plugin-vibe@0.0.2","maintainers":[{"name":"kortes","email":"me@korte.kim"}],"homepage":"https://vibe.korte.kim","dist":{"shasum":"ba7e2b52df1c9075955b3019d1a803f76a1783d9","tarball":"https://registry.npmjs.org/@ape-egg/vite-plugin-vibe/-/vite-plugin-vibe-0.0.2.tgz","fileCount":4,"integrity":"sha512-aD0UGZeKKpUF+gxTSLjmq9jMsFrykHK/Eg1MbEg3w/MqrK1CJ2VHVrXcleuKBGVL6aUYy90PuK83wf/imn6x/A==","signatures":[{"sig":"MEQCIBatYSxu42WPhv6qaosSkVPdyDar9bMu+TfDkA8OJKtqAiAPL6x1Q9GHNJRjKs7e/tq9olecE2uHjJy7cKfkREoMdw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28613},"main":"index.js","type":"module","exports":{".":"./index.js"},"gitHead":"3956a587c965aa078f4dd36dfeb1db91c054257f","_npmUser":{"name":"kortes","email":"me@korte.kim"},"_npmVersion":"11.6.2","description":"Vite plugin for Vibe — component HMR and raw HTML serving","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vite":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vite-plugin-vibe_0.0.2_1777620247707_0.8114185766313149","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ape-egg/vite-plugin-vibe","version":"0.1.1","keywords":["vite","vite-plugin","vibe","hmr","components","preview","gallery"],"author":{"name":"kkortes"},"license":"ISC","_id":"@ape-egg/vite-plugin-vibe@0.1.1","maintainers":[{"name":"kortes","email":"me@korte.kim"}],"homepage":"https://vibe.korte.kim","dist":{"shasum":"dfb45e7453773cb8b551960400d3d235531cf820","tarball":"https://registry.npmjs.org/@ape-egg/vite-plugin-vibe/-/vite-plugin-vibe-0.1.1.tgz","fileCount":21,"integrity":"sha512-mMnCzUstDyne7R/h1tjHyJD0gY0ZhL3E3QoOKuhjOMERSX3qzIDx6s4Z8i/nqZP2G263gH52cON5D9jw+MHU6g==","signatures":[{"sig":"MEUCIQDT5tDPyAdZ2qv99qUSeH8BgklZCb0WqtxMV3AvbdLhNAIgRzBrSsp7mGqYLCdGVIcSmj+0MBlqUnT/PSlS9Dimwfc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83579},"main":"index.js","type":"module","exports":{".":"./index.js","./preview":"./preview/index.js"},"gitHead":"a66fcf736a04cadee55ff51ecdd6ec072a0893bd","_npmUser":{"name":"kortes","email":"me@korte.kim"},"_npmVersion":"11.6.2","description":"Vite plugin for Vibe — component HMR, raw HTML serving, and an opt-in component preview","directories":{},"_nodeVersion":"24.12.0","dependencies":{"acorn":"^8.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vite":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vite-plugin-vibe_0.1.1_1784499107181_0.04925218338779036","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@ape-egg/vite-plugin-vibe","version":"0.2.0","keywords":["vite","vite-plugin","vibe","hmr","components","preview","gallery"],"author":{"name":"kkortes"},"license":"ISC","_id":"@ape-egg/vite-plugin-vibe@0.2.0","maintainers":[{"name":"kortes","email":"me@korte.kim"}],"homepage":"https://vibe.korte.kim","dist":{"shasum":"632006f00b949ace34a8b958a9181dc31109a849","tarball":"https://registry.npmjs.org/@ape-egg/vite-plugin-vibe/-/vite-plugin-vibe-0.2.0.tgz","fileCount":21,"integrity":"sha512-eE2VHOSEeZXAlZGkueNwUJlgbR7rBvpYb6sQAw3uO6d1LVBeQ3G4G+payAMetqOVA6H/ZfU0QkCXMqKYdKDV3A==","signatures":[{"sig":"MEMCIARowRIlP3RSTMnVzGmU93KI7MoYoKZAqN09zDjQNVuvAh88eJ0whLeILzC+rYFSnrL131N34+ALGfIMaGtd6Tqv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86608},"main":"index.js","type":"module","exports":{".":"./index.js","./preview":"./preview/index.js"},"gitHead":"02d73f3c10eb2a94979412440299e7b9b65fcccd","_npmUser":{"name":"kortes","email":"me@korte.kim"},"_npmVersion":"11.6.2","description":"Vite plugin for Vibe — component HMR, raw HTML serving, and an opt-in component preview","directories":{},"_nodeVersion":"24.12.0","dependencies":{"acorn":"^8.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vite":">=5.0.0","@ape-egg/vibe":">=4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vite-plugin-vibe_0.2.0_1787335507883_0.39419551341946835","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@ape-egg/vite-plugin-vibe","version":"0.3.0","keywords":["vite","vite-plugin","vibe","hmr","components","preview","gallery"],"author":{"name":"kkortes"},"license":"ISC","_id":"@ape-egg/vite-plugin-vibe@0.3.0","maintainers":[{"name":"kortes","email":"me@korte.kim"}],"homepage":"https://vibe.korte.kim","dist":{"shasum":"6b646e714497f730eee18c5fa9fdc18b0c4e0e1e","tarball":"https://registry.npmjs.org/@ape-egg/vite-plugin-vibe/-/vite-plugin-vibe-0.3.0.tgz","fileCount":21,"integrity":"sha512-zZF/Kb/AtuTiETwg/ZW38fOtLo2tQQ3E0Ota/BBoVy5S0sMh8z1aN9ZiM38fWtHDtlFgGCf+4yvqNgHOWg5E8Q==","signatures":[{"sig":"MEYCIQCHDk46eRkB0j3Y7bMU8SrWxSdVo1J243BxOK9FTjyphgIhALgqOJmc+Nm/uNMJq+lzrdMwH+l0RLk3xWl8TatORZ4S","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":65822},"main":"index.js","type":"module","exports":{".":"./index.js","./preview":"./preview/index.js"},"gitHead":"4f172be4e24c5698b77af248f31bcc2d5601587e","_npmUser":{"name":"kortes","email":"me@korte.kim"},"_npmVersion":"11.6.2","description":"Vite plugin for Vibe — component HMR, raw HTML serving, and an opt-in component preview","directories":{},"_nodeVersion":"24.12.0","dependencies":{"acorn":"^8.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"vite":">=5.0.0","@ape-egg/vibe":">=4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vite-plugin-vibe_0.3.0_1787814870191_0.07216326938484685","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@ape-egg/vite-plugin-vibe","version":"0.4.1","type":"module","description":"Vite plugin for Vibe — component HMR, raw HTML serving, and an opt-in component preview","main":"index.js","homepage":"https://vibe.korte.kim","exports":{".":"./index.js","./preview":"./preview/index.js"},"keywords":["vite","vite-plugin","vibe","hmr","components","preview","gallery"],"author":{"name":"kkortes"},"license":"ISC","publishConfig":{"access":"public"},"dependencies":{"acorn":"^8.0.0"},"peerDependencies":{"@ape-egg/vibe":">=4.3.0","vite":">=5.0.0"},"gitHead":"c61fe767beaf55e37455a11e10e5ef826d8c82c6","_id":"@ape-egg/vite-plugin-vibe@0.4.1","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-V1ihYgsTs7lcwgwp/848R3O1KI2wVKQt2gMIcayrETO1JAKwqvJ9m7oUlB0cQn+pc64Aog9u0UONtaaCUSqHhg==","shasum":"0950b4c946e473068c165e857140c4b314d0f459","tarball":"https://registry.npmjs.org/@ape-egg/vite-plugin-vibe/-/vite-plugin-vibe-0.4.1.tgz","fileCount":22,"unpackedSize":76516,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEifBXDRmJcWW9oSVgJpQmK53IGGWvN0eDHsTzv75B8dAiBJ+9prhFd25HUvZOJf3+Mpn14Xk8hWjXYgBrlsbXmAGw=="}]},"_npmUser":{"name":"kortes","email":"me@korte.kim"},"directories":{},"maintainers":[{"name":"kortes","email":"me@korte.kim"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vite-plugin-vibe_0.4.1_1788432708634_0.33937728893466"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-01T07:24:07.603Z","modified":"2026-09-03T10:51:48.978Z","0.0.2":"2026-05-01T07:24:07.905Z","0.1.1":"2026-07-19T22:11:47.314Z","0.2.0":"2026-08-21T18:05:08.016Z","0.3.0":"2026-08-27T07:14:30.326Z","0.4.1":"2026-09-03T10:51:48.772Z"},"author":{"name":"kkortes"},"license":"ISC","homepage":"https://vibe.korte.kim","keywords":["vite","vite-plugin","vibe","hmr","components","preview","gallery"],"description":"Vite plugin for Vibe — component HMR, raw HTML serving, and an opt-in component preview","maintainers":[{"name":"kortes","email":"me@korte.kim"}],"readme":"# @ape-egg/vite-plugin-vibe\n\n> ⚠️ **Early alpha — subject to change.** This plugin is a development-only HMR layer for [Vibe](https://github.com/kkortes/vibe). Vibe itself is still evolving, so achieving full 1-to-1 feature parity is a moving target — and not the priority right now.\n>\n> Because the plugin only runs in development (it powers `vite dev` HMR and is never shipped to production), it is acceptable for it to have rough edges while Vibe stabilises. It updates alongside Vibe, will keep catching up to new runtime features, and will reach a stable release once the underlying framework settles.\n\nVite plugin for [Vibe](https://github.com/kkortes/vibe) projects. Gives you hot refresh of components and pages without losing state — `window.$` is untouched across edits.\n\n## Install\n\n```bash\nbun add -d @ape-egg/vite-plugin-vibe\n# or\nnpm install -D @ape-egg/vite-plugin-vibe\n```\n\n## Usage\n\n```js\n// vite.config.js\nimport { defineConfig } from 'vite';\nimport vibe from '@ape-egg/vite-plugin-vibe';\n\nexport default defineConfig({\n  plugins: [vibe()],\n});\n```\n\nThat's it. `bun dev` / `vite` now serves your Vibe project with:\n\n- **Component HMR** — saving a file in `components/` patches exactly what changed in every mounted instance: a text node, an attribute, a binding expression, an iteration or conditional template, a `<style>` rule. Scroll position, DOM identity, focus and component state survive; a changed `<script type=\"module\">` re-mounts the component\n- **Page HMR** — saving an HTML page patches the page body the same way; a changed page `<script>` reloads, since a boot script defines initial state and cannot be re-run in place\n- **JS module HMR** — saving a plain `.js` module re-seeds the state it fed: every key of `window.$` (and of component states) that holds a value the module exported is assigned the fresh module's value, and Vibe re-renders what reads it. `vibe({ ...demo })` follows `demo.js` with no `import.meta.hot.accept` in your code. Pages that never imported the module are left alone; a module that seeds no state on a page reloads that page only\n- **Normal reload fallback** — pages without Vibe on them reload normally\n- **Component preview** — an opt-in gallery at `/__vibe` (see below)\n\n## Component preview\n\nOpt-in: enable it with a boolean flag, then open **`/__vibe`** while the dev\nserver is running. Every component in your project shows up automatically — no\nregistration, no maintained manifest. Adding a file under `components/` makes it\nappear.\n\n```js\nvibe({ preview: true })            // enable with defaults\n```\n\n- **Router page** (`/__vibe`) lists all components grouped by folder, with a name filter and a count.\n- **Per-component page** (`/__vibe/<path>`) renders the component standalone in an isolated stage (its own `window.$`, so nothing leaks between components), with:\n  - a **DataInspector** showing the component's declared state + the inputs it reads (`@[name]`, `<!-- each name as x -->`). Each key has a type toggle (`string` / `number` / `array` / `object`); editing a value updates the live preview.\n  - an **editable source view** (powered by [`@ape-egg/codie`](https://www.npmjs.com/package/@ape-egg/codie)) — edits re-mount the preview instantly and are never written to disk.\n\nState for each component lives in a single committed **`__vibe.component-previewer.json`**\nat your project root, keyed by component path. The plugin keeps it in sync with\nyour components automatically (adds new keys, prunes removed ones, preserves\nany types you set). **When the preview is disabled this file is never written\nor updated.**\n\nThe preview is plain static-deployable output: `bakePreview()` (from\n`@ape-egg/vite-plugin-vibe/preview`) emits the whole gallery — pages, component\nlist, analysis, fixtures, and sources — as static files with no backend, so it\ncan be hosted or shared. In a baked deploy, type-toggles and source edits still\nwork but persist only in the browser session.\n\n## Options\n\n```js\nvibe({\n  components: 'components', // directory to serve raw + watch for HMR (default: 'components')\n\n  // Preview is OFF by default. Enable with `preview: true`, or pass an object\n  // with `enabled: true` plus configuration. Anything else (omitted, false, or\n  // an object without `enabled`) leaves it disabled — and never writes the\n  // __vibe.component-previewer.json fixture file.\n  preview: {\n    enabled: true,                    // the enable flag (or use `preview: true`)\n    route: '/__vibe',                 // route prefix for the gallery\n    css: ['/index.css'],              // stylesheets the isolated stage includes (default: none)\n    stageAttrs: ['stylecheat'],       // boolean attrs set on the stage <body> for attribute-gated CSS\n    vibeUrl: '/nodemodules/@ape-egg/vibe/index.js',   // where kit pages load the runtime\n    codieUrl: '/nodemodules/@ape-egg/codie/codie.js', // where kit pages load the editor\n  },\n})\n```\n\nBy default the stage renders a component on the Vibe base only. Use\n`preview.css` (and `preview.stageAttrs` for frameworks like Stylecheat that key\noff `<body>` attributes) to give a component the styling it needs.\n\n## Requirements\n\n- Vite `>= 5.0` (`hotUpdate` on Vite 6+, `handleHotUpdate` on Vite 5)\n- `@ape-egg/vibe` `>= 4.3.0` — the HMR brain lives in `@ape-egg/vibe/hot-module-refresh` and drives the runtime through `$.reconcile`, `$._refreshComponent` and `$._remountComponent`; the plugin itself is only the Vite transport\n- `@ape-egg/codie` — _optional_; powers the preview's editable source cell. The kit pages load it from `preview.codieUrl` (default `/nodemodules/@ape-egg/codie/codie.js`). If it isn't installed/served, the per-component page still renders (inspector + live stage) and just shows the source cell as disabled.\n- `acorn` — bundled dependency; the preview uses it to statically read each component's declared-state literal and binding surface (no bespoke parser).\n\n## How it works\n\nVibe fetches components at runtime via `<component src=\"\">`. Vite's default HTML pipeline would inject its HMR client and rewrite `<script type=\"module\">` inside every HTML file it serves — which breaks Vibe's component processing.\n\nThis plugin:\n\n1. **Serves component HTML raw** through a middleware, bypassing Vite's HTML transform for files under your components directory.\n2. **Answers every `.html` change through Vite's HMR API.** The injected `/@vibe-hmr` module is a self-accepting boundary; the `hotUpdate` hook sends a custom event first (`vibe:component-update` for files under `components/`, `vibe:page-update` for everything else, with `scriptsChanged` when a page `<script>` differs from the last served copy) and returns that module, so Vite emits an ordinary `js-update` and never a full reload.\n3. **The brain does the work in the runtime.** `@ape-egg/vibe/hot-module-refresh` fetches the new source and hands it to the runtime: a component whose scripts are unchanged goes through `$._refreshComponent` (render with the live wrapper's own props, slot and component ids, then a template-aware `$.reconcile` that updates bindings and iteration/conditional templates alongside the DOM); a component whose script changed is re-mounted through the runtime's staged remount; a page edit reconciles the page body against the freshly fetched document.\n4. **Owns `.js` changes too.** For a script module in Vite's client module graph the hook sends `vibe:module-update` (module url, the entry scripts at the roots of its importer chain, Vite's timestamp) and returns an empty module list, so Vite never reaches its no-boundary full reload. The client (`client.js`) ignores modules its page never loaded, otherwise imports the held instance and a timestamp-busted fresh one and re-seeds state: keys of `window.$` and of component states whose raw value is a value the old module exported (matched by key through named exports, the default export and nested plain objects; identity for objects and functions, equality for primitives) take the fresh module's value at the same path. Nothing re-seeded means the module is boot-only code on that page, which reloads.\n\nNo server state beyond a per-page script hash, no WebSocket patching, no user configuration of which files are pages vs components — the plugin serves `components/` raw and lets Vite watch everything.\n\n## Limitations\n\n- A changed page-level `<script>` reloads the page — initial state comes from that script and there is no way to re-run it in place. Component scripts re-mount the component instead\n- A JS module edit follows the module's *exported values* into state. State the boot script derives from them (`vibe({ rows: build(demo) })`) is not re-derived; if nothing on the page followed, the page reloads\n- **Preview:** components that read global `$` inside their `<script>` (e.g. `$.characters[...]`) render best-effort — the inspector surfaces declared state + the inputs referenced in the template, not arbitrary `$` reads, so such a component may render its empty/else branch. Failures are isolated to that component's stage cell.\n\n## License\n\nISC\n","readmeFilename":"README.md"}