Skip to content

Neel - 2.1.0

Latest

Choose a tag to compare

@Niminem Niminem released this 16 Oct 22:38

Neel 2.1.0

Neel 2.1 adds serve mode: the same app as a persistent server for one user, opened from any of your devices. Nothing is removed or renamed; existing 2.0 apps compile and behave as before, apart from the two small local-mode differences listed below. Verified on macOS, Windows, and Linux (Ubuntu) with Nim 2.2.12.

Serve mode

startApp(serve = true, port = 8080,
         allowedOrigins = @["https://myapp.example.com"])

No browser, no idle exit. No browser is discovered or launched, and the app stays up until quitApp() or a stop signal. You open it yourself, at http://127.0.0.1:<port> or through an SSH forward, a tunnel, or a reverse proxy. The server still binds 127.0.0.1 only, and the programming model is unchanged: {.expose.}, neel.foo(), js.foo(), js.wait.foo().

One window, many devices. The app has a single window. A new device or tab takes it over, and the displaced page is closed with code 4000 (CloseDisplaced), so it can show "opened on another device" instead of fighting back. onWindowOpen fires once, for the first connection; onWindowClose fires once, at exit. openWindow and closeWindow raise NeelServeModeError.

Works behind proxies and auth. allowedOrigins lists the public origins your tunnel or proxy serves the app at; entries are validated and normalized at startup (ValueError names the bad one). Cross-site top-level navigations are accepted, so an auth proxy's login redirect (Cloudflare Access, for example) works; frames, scripts, and fetches from other sites are still refused, and /ws requires an exact origin.

Survives idle proxies and sleeping phones. The server pings idle WebSockets every 30 s, below nginx's 60 s and Cloudflare's roughly 100 s. When the page runs out of reconnect attempts it goes dormant instead of giving up for good, and reconnects when it becomes visible again or the network comes back. A reload recipe handles server restarts, including an auth proxy's login redirect.

Clean stops. Ctrl-C and SIGTERM (Ctrl-Break, closing the console, logoff, and shutdown on Windows) shut down cleanly, and startApp returns erQuit. On macOS and Linux a second signal exits at once (130 / 143). A startup line, neel: serving http://127.0.0.1:8080 (allowed origins: ...), goes to stdout, so scripts and service managers can wait for it.

Verified setups. An SSH port forward, a cloudflared quick tunnel, and Cloudflare Tunnel with Access, with a step-by-step walkthrough in docs/CLOUDFLARE_ACCESS.md. Also tested from a phone (Android Chrome): lock, unlock, and the page reconnects by itself. Everything is in the guide's Serve mode section.

Changes in local mode

  • A displaced connection (a duplicated tab, or a stale page against a fixed port) now closes with code 4000 instead of 1000. The shim behaves the same (final, no reconnect); only the code neel.onclose reports changes.
  • On Windows, a second app on a fixed port that is already in use now fails at start with OSError, as it already did on macOS and Linux. Before, both bound the port. The default port = 0 is unaffected.

Minor updates

  • New exports: NeelServeModeError, CloseDisplaced. ExitReason is unchanged; a stop signal returns erQuit.
  • New example: examples/serve, a shared note that shows every connection state a serve-mode page handles (displaced, dormant, server restarted).
  • Docs: a Serve mode section and What's new in 2.1 in the guide, a serve-mode quick start in the README, and the Cloudflare walkthrough.
  • Known issue, not in Neel: on Windows, Ctrl-C crashes a debug build in Nim's own signal handler. Release builds, and serve mode, which installs its own handler, are fine. See the guide's Caveats.