Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ First [install Deno](https://docs.deno.com/runtime/getting_started/installation/
then run directly (dependencies are fetched automatically):

```bash
deno run https://raw.githubusercontent.com/grantmcdermott/jgd/refs/heads/main/server/main.ts
# macOS / Linux
deno run --allow-net --allow-read --allow-write --allow-env https://raw.githubusercontent.com/grantmcdermott/jgd/refs/heads/main/server/main.ts

# Windows
deno run -A https://raw.githubusercontent.com/grantmcdermott/jgd/refs/heads/main/server/main.ts
```

Or, clone the repo and run locally:
Expand All @@ -109,6 +113,19 @@ Or, clone the repo and run locally:
cd server && deno task start && cd ..
```

> [!NOTE]
> On **Windows**, R connections default to a named pipe, and Deno has no
> permission combination narrower than `-A` (`--allow-all`) that can satisfy
> binding one — that's why the Windows command above needs it (`deno task
> start` above already grants `-A` for the same reason).
>
> To keep permissions scoped on Windows instead, add `--tcp <port>` (e.g.
> `--tcp 8888`) to connect over localhost TCP rather than a named pipe:
>
> ```bash
> deno run --allow-net --allow-read --allow-write --allow-env https://raw.githubusercontent.com/grantmcdermott/jgd/refs/heads/main/server/main.ts --tcp 8888
> ```

Once the Deno server is running, open `http://127.0.0.1:<port>/`
in your browser (the URL is printed on startup). Then you start executing
plotting commands from any R session.
Expand Down
29 changes: 14 additions & 15 deletions server/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,23 @@
"@astral/astral": "jsr:@astral/astral@^0.5"
},
"tasks": {
// --allow-net is unrestricted (not scoped to 127.0.0.1): since Deno
// PR denoland/deno#34395, Deno.listen/connect({transport:"unix"}) also
// requires an --allow-net=unix:<path> grant, in addition to
// --allow-read/--allow-write, to bind/connect the R unix socket. The
// socket path is randomly generated at runtime when --socket isn't
// passed explicitly, so it can't be allow-listed up front; unscoped
// --allow-net is the documented escape hatch for that case.
"start": "deno run --allow-net --allow-read --allow-write --allow-env main.ts",
"dev": "deno run --allow-net --allow-read --allow-write --allow-env --watch main.ts",
// -A is required here (not just --allow-net/read/write/env): on Windows,
// node:net's PipeWrap.bind/listen/connect (used for named pipes) routes
// -A (--allow-all) is required on Windows: R connections default to a
// named pipe there, and node:net's PipeWrap.bind/listen/connect routes
// any non-drive-letter path like \\.\pipe\... through Deno's permission
// checker's check_special_file, which demands every permission category
// (read/write/net/env/sys/run/ffi/import) be fully granted -- i.e. -A
// itself, with no narrower combination accepted. These tasks exercise
// that code path directly (in-process pipe tests) or indirectly (via
// TestServer spawning main.ts), so they need -A on Windows; -A here for
// all platforms keeps the task portable without OS-specific branching.
// itself, with no narrower combination accepted. Separately, on
// Linux/macOS, Deno.listen({transport:"unix"}) requires an unscoped
// --allow-net (since denoland/deno#34395) because the R socket path is
// randomly generated at runtime and can't be allow-listed up front.
// -A satisfies both without OS-specific branching (deno.json tasks
// can't conditionally vary flags by platform). -A is hardcoded into
// these tasks, so passing --tcp <port> here does NOT narrow permissions
// (deno task start -- --tcp 8888 still runs with -A). To actually get
// scoped permissions with --tcp, invoke `deno run` directly instead of
// this task -- see the README's Deno-server quick-start section.
"start": "deno run -A main.ts",
"dev": "deno run -A --watch main.ts",
"test": "deno test -A --parallel --ignore=tests/e2e tests/",
"test:e2e": "deno test -A tests/e2e/",
"test:all": "deno task test && deno task test:e2e"
Expand Down