# Package runtimes and automatic assets

## User experience

Installing an advanced package should be enough:

```bash
bun add @wrnexus/captcha
```

Then use its component:

```wrn
<Captcha type="number" action="signup" />
```

The user does not copy JavaScript, add a public asset, add a script tag, or duplicate the component.

## Declaring a package plugin

```json
{
  "name": "@example/maps",
  "wrnexus": {
    "plugin": {
      "plugin": "./src/plugin.ts",
      "export": "default",
      "factory": true
    }
  }
}
```

```ts
import { definePlugin } from "@wrnexus/plugin";

export default function mapsPlugin() {
  return definePlugin({
    name: "@example/maps",
    componentDirs: [new URL("../components", import.meta.url).pathname],
    clientRuntimes: [
      {
        id: "maps",
        entry: new URL("../client/maps.ts", import.meta.url).pathname,
        type: "module",
        load: "defer",
        singleton: true,
      },
    ],
    styleSources: [
      {
        id: "maps-components",
        source: new URL("../components", import.meta.url).pathname,
      },
    ],
  });
}
```

The rendered component declares:

```html
<div data-wrnexus-runtime="maps"></div>
```

## Development behavior

- Runtime URL defaults to `/__wrnexus/assets/maps.js`.
- JavaScript files can be served directly.
- TypeScript/TSX entries are bundled for the browser.
- MIME type is JavaScript and `X-Content-Type-Options: nosniff` is set.
- Assets use `no-cache` during development.
- Workspace package sources participate in HMR.

## Production behavior

- Runtime entries are browser-bundled and minified when required.
- The emitted filename includes a SHA-256 content hash.
- The asset is served with an immutable cache policy.
- The final HTML includes the runtime only when its marker appears.
- Multiple instances inject one script.
- Build reports list plugins, runtime chunks, assets, component directories, routes, and migrations.

## CSR navigation

Before replacing `#app`, WRNexusJS calls package `unmount` hooks for runtimes used by the current content. It imports script attributes from the fetched document, loads missing chunks once, then calls `mount` for the new page.

## Security requirements

- Runtime and asset IDs are validated.
- Duplicate IDs and public paths fail startup/build.
- Local package asset paths cannot contain traversal segments.
- Production builds do not rely on application public-directory copies.
- Secrets must remain server-side; browser runtimes receive only public configuration and one-use response tokens.
