UNPKG

@fxi/shiny-manager

Version:

A package for managing R Shiny application processes with a programmable proxy

142 lines (105 loc) 4.21 kB
# @fxi/shiny-manager A Node.js package for managing R Shiny application processes with a programmable reverse proxy. It provides a browser interface to interact with Shiny apps, featuring a pre-warmed session pool for near-instant load times, token-based session stickiness across browser refreshes, and basic process controls. ## Quick Start for Development 1. **Clone and install dependencies** ```bash git clone https://github.com/fxi/shiny-manager.git cd shiny-manager npm install ``` 2. **Build the project** ```bash npm run build ``` 3. **Run the demo app** ```bash npm run test:r ``` This launches the demo Shiny app on http://localhost:8080. ## Features - **Pre-warmed session pool** — R processes are started in the background at server startup so users connect to a ready session instead of waiting for a cold start. - **Session stickiness** — each browser profile receives a stable token (stored in `localStorage`) that maps it back to its R session across page refreshes and reconnects. - **30-minute idle TTL** — disconnected sessions stay alive for 30 minutes, then are cleaned up automatically. The pool replenishes itself so the next user always finds a warm session. - **Process controls** — Restart and Stop buttons are exposed in the UI for quick process management without touching the server. - **Dynamic proxy routing** with full WebSocket support (required by Shiny). - **Graceful fallback** — if the pool is empty (e.g. all seats taken), new users get a cold-start session with a progress indicator. ## Usage ### Command Line ```bash # Install globally npm install -g @fxi/shiny-manager # Start a Shiny app (default port 8080, pool of 2 idle sessions) shiny-manager ./path/to/app.R # Start on a specific port shiny-manager ./path/to/app.R 3000 # Set a custom title and pool size shiny-manager --title "My App" --pool 3 ./path/to/app.R # Show help shiny-manager --help ``` #### Options | Flag | Default | Description | |------|---------|-------------| | `-t, --title <title>` | `"Shiny App Manager"` | Browser tab title | | `-n, --pool <n>` | `2` | Number of pre-warmed idle sessions to keep ready | | `<port>` | `8080` | Port for the Node.js server | ### Programmatic Usage ```javascript import { ProgrammableProxy } from '@fxi/shiny-manager/proxy.js'; import { Session } from '@fxi/shiny-manager/session.js'; import { SessionPool } from '@fxi/shiny-manager/pool.js'; const proxy = new ProgrammableProxy(); // Pool approach (recommended) const pool = new SessionPool(proxy, '/path/to/app.R', 2); pool.warm(); // start background pre-warming // On user connect const session = pool.claim(userToken); pool.attach(userToken, socket, title); // On user disconnect (keep session alive) pool.release(userToken); // On explicit stop pool.evict(userToken); // Direct session usage (cold start) const session = new Session(socket, proxy, '/path/to/app.R'); await session.init(); session.destroy(); ``` ## Development Workflow The project has two main components: 1. **Client-side code** (`/client/`) — browser interface built with Vite + Socket.IO 2. **Server-side code** (`/src/`) — Node.js server that manages R processes After making changes, rebuild and test: ```bash npm run build npm run test:r # starts server at http://localhost:8080 npm test # runs unit tests (Vitest) ``` > **Important:** Always run `npm run build` after changing client code. The build copies the > Vite output to `dist/public/`, which is served by the Node.js server. ## Project Structure ``` src/ Server-side Node.js code bin/ CLI entry point (shiny-manager) pool.js SessionPool — pre-warming and token-based stickiness session.js Session — R process lifecycle and proxy registration proxy.js ProgrammableProxy — HTTP + WebSocket reverse proxy utils.js Port allocation, wait helper client/ Client-side code (Vite build) build/ Build scripts dist/ (Generated) Distribution files demo/ Demo Shiny app for testing test/ Unit tests (Vitest) ``` ## Requirements - Node.js >= 18.0.0 - R with the `shiny` package installed ## License MIT