-
Notifications
You must be signed in to change notification settings - Fork 0
/
r.js
98 lines (78 loc) · 2.64 KB
/
r.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
* R Stuff
*
* @module rstuff
*/
import { WebR } from 'https://rud.is/webr/webr.mjs'
import { json as readJSON } from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
globalThis.webR = new WebR({
WEBR_URL: "/webr/",
SW_URL: "/webr/",
baseUrl: "/webr/",
serviceWorkerUrl: "/webr/"
});
// so we can use it from the console
await globalThis.webR.init();
// handy shortcut for ^^
export const webR = globalThis.webR;
// R major/minor version as string
export const rVersion = await globalThis.webR.evalRString(`paste0(unclass(getRversion())[[1]][1:2], collapse=".")`)
/**
* Install one or more R packages from R universe
*
* Inspired by timelyportfolio
*
* @note IT IS ON YOU FOR NOW TO ENSURE NO PACKAGES IN THE
* DEPENDENCY TREE REQUIRE COMPILATION
* @param {string[] | string} pkgs string or string array of R pkg names
* @example
* await R.installRUniversePackages("basetheme")
* R.library("basetheme")
*/
export async function installRUniversePackages(pkgs) {
if (typeof pkgs === 'string') {
pkgs = [ pkgs ]
}
for (const pkg of pkgs) {
const pkgMeta = await rUniversePkgInfo(pkg, rVersion)
if (pkgMeta.compiled) {
console.warn(`'${pkg}' cannot be installed because it reqires compilation`)
} else {
installRUniversePackageFromURL(pkg, pkgMeta.rUniverseDownloadURL)
}
}
}
/**
* Install a built package from an R Universe URL
*
* Inspired by timelyportfolio
*
* @param {string} pkg package name
* @param {string} rUniverseURL full r-univ URL
*/
function installRUniversePackageFromURL(pkg, rUniverseURL) {
globalThis.webR.evalR(`
tmp <- tempfile()
message(paste("Installing webR package: ${pkg} from ${rUniverseURL}"));
utils::download.file("${rUniverseURL}", tmp, quiet = FALSE);
utils::untar(tmp, exdir = .libPaths()[[1]], tar = "internal", extras = "--no-same-permissions");
`)
}
/**
* Get R pkg author, compilation req, and version from r-universe
* @param {string} rPackage
* @returns {object} with `compiled`, `rUniverseDownloadURL`
*/
export async function rUniversePkgInfo(rPackage, rVersion = "4.1") {
const rPkgs = await readJSON(`https://r-universe.dev/stats/powersearch?limit=1&all=true&q=${rPackage}`)
const rPkgAuthor = rPkgs.results[ 0 ].maintainer.login;
const rPkgDetails = await readJSON(`https://${rPkgAuthor}.r-universe.dev/${rPackage}/json`)
const rPkgVersion = rPkgDetails.binaries
.filter((d) => (d.os == "mac") & d.r.startsWith(rVersion))
.pop(1).version;
const pkgDownloadInfo = {
compiled: rPkgDetails.NeedsCompilation !== "no",
rUniverseDownloadURL: `https://${rPkgAuthor}.r-universe.dev/bin/macosx/contrib/${rVersion}/${rPackage}_${rPkgVersion}.tgz`
}
return pkgDownloadInfo
}