diff --git a/.Rbuildignore b/.Rbuildignore index 2508f20..b127c8e 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -11,3 +11,4 @@ ^shinylive_assets$ ^cran-comments\.md$ ^revdep$ +^CRAN-SUBMISSION$ diff --git a/DESCRIPTION b/DESCRIPTION index 8dc34de..ece5178 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: shinylive -Title: Run Shiny applications in the browser +Title: Run 'shiny' Applications in the Browser Version: 0.1.0 Authors@R: c( @@ -9,7 +9,7 @@ Authors@R: person("George", "Stagg", role = "ctb", email = "george.stagg@posit.co"), person("Posit Software, PBC", role = c("cph", "fnd")) ) -Description: Run Shiny applications in the browser using 'webR' package. +Description: Exporting 'shiny' applications with 'shinylive' allows you to run them entirely in a web browser, without the need for a separate R server. The traditional way of deploying 'shiny' applications involves in a separate server and client: the server runs R and 'shiny', and clients connect via the web browser. When an application is deployed with 'shinylive', R and 'shiny' run in the web browser (via 'webR'): the browser is effectively both the client and server for the application. This allows for your 'shiny' application exported by 'shinylive' to be hosted by a static web server. License: MIT + file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) @@ -26,6 +26,7 @@ Imports: rlang, tools Suggests: + plumber, httr, spelling, testthat (>= 3.0.0) diff --git a/R/assets.R b/R/assets.R index ad045aa..df47270 100644 --- a/R/assets.R +++ b/R/assets.R @@ -13,6 +13,10 @@ #' @param url The URL to download the assets from. Unless testing, the default #' behavior should be used. #' @export +#' @return +#' `assets_version()` returns the version of the currently supported Shinylive. +#' +#' All other methods return `invisible()`. assets_download <- function( version = assets_version(), ..., @@ -37,6 +41,8 @@ assets_download <- function( message("Unzipping to ", dir, "/") fs::dir_create(dir) archive::archive_extract(tmp_targz, dir) + + invisible() } @@ -122,6 +128,7 @@ install_local_helper <- function( #' @param version The version of the assets being installed. #' @inheritParams assets_download #' @seealso [`assets_download()`], [`assets_ensure()`], [`assets_cleanup()`] +#' @return All method return `invisible()`. #' @export assets_install_copy <- function( assets_repo_dir, @@ -138,6 +145,8 @@ assets_install_copy <- function( dir = dir, version = version ) + + invisible() } #' @describeIn install Creates a symlink of the local shinylive assets to the @@ -165,6 +174,8 @@ assets_install_link <- function( dir = dir, version = version ) + + invisible() } @@ -190,7 +201,7 @@ assets_ensure <- function( assets_download(url = url, version = version, dir = dir) } - assets_path + invisible(assets_path) } @@ -333,6 +344,8 @@ assets_info <- function() { )), sep = "" ) + + invisible() } diff --git a/R/export.R b/R/export.R index 3a16af5..1c82ce8 100644 --- a/R/export.R +++ b/R/export.R @@ -1,7 +1,7 @@ #' Export a Shiny app to a directory #' #' This function exports a Shiny app to a directory, which can then be served -#' using `httpuv::runStaticServer()`. +#' using `plumber`. #' #' @param appdir Directory containing the application. #' @param destdir Destination directory. @@ -10,28 +10,29 @@ #' interactively. #' @param ... Ignored #' @export +#' @return Nothing. The app is exported to `destdir`. Instructions for serving +#' the directory are printed to stdout. #' @importFrom rlang is_interactive -#' @examples -#' \dontrun{ +#' @examplesIf interactive() #' app_dir <- system.file("examples", "01_hello", package = "shiny") #' out_dir <- tempfile("shinylive-export") #' #' # Export the app to a directory #' export(app_dir, out_dir) -#' #> Run the following in an R session to serve the app: -#' #> httpuv::runStaticServer() #' #' # Serve the exported directory -#' httpuv::runStaticServer(out_dir) +#' if (require(plumber)) { +#' library(plumber) +#' pr() %>% +#' pr_static("/", out_dir) %>% +#' pr_run() #' } export <- function( appdir, destdir, ..., subdir = "", - verbose = is_interactive() - # full_shinylive = FALSE - ) { + verbose = is_interactive()) { verbose_print <- if (verbose) message else list stopifnot(fs::is_dir(appdir)) @@ -154,7 +155,8 @@ export <- function( verbose_print( "\nRun the following in an R session to serve the app:\n", - " httpuv::runStaticServer(\"", destdir, "\")\n" + " library(plumber)\n", + " pr() %>% pr_static(\"/\", \"", destdir, "\") %>% pr_run()\n" ) invisible() diff --git a/R/quarto_ext.R b/R/quarto_ext.R index fee7a6a..d81dbe2 100644 --- a/R/quarto_ext.R +++ b/R/quarto_ext.R @@ -1,6 +1,3 @@ -#' TODO-barret; update docs in py-shinylive - - #' Quarto extension for shinylive #' #' Integration with https://github.com/quarto-ext/shinylive @@ -8,7 +5,7 @@ #' @param args Command line arguments passed by the extension. See details for more information. #' @param ... Ignored. #' @param pretty Whether to pretty print the JSON output. -#' @returns Nothing. Values are printed to stdout. +#' @return Nothing. Values are printed to stdout. #' @section Command arguments: #' #' The first argument must be `"extension"`. This is done to match diff --git a/README.md b/README.md index a28d267..a1428e4 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Twin shinylive python package: https://github.com/posit-dev/py-shinylive ## Installation +You can install the released version of shinylive from CRAN via: + +``` r +install.packages("shinylive") +``` + You can install the development version of shinylive from GitHub via: ``` r @@ -40,13 +46,13 @@ Once you have a Shiny application in `myapp/` and would like turn it into a Shin shinylive::export("myapp", "site") ``` -Then you can preview the application by running a web server and visiting it in a browser (this example is using the development version of `{httpuv}`): +Then you can preview the application by running a web server and visiting it in a browser: ``` r -## Get development version of `{httpuv}` -# install.packages("pak") -# pak::pak("rstudio/httpuv") -httpuv::runStaticServer("site/") +library(plumber) +pr() %>% + pr_static("/", "site/") %>% + pr_run() ``` At this point, you can deploy the `site/` directory to any static web hosting service. @@ -185,13 +191,13 @@ shinylive_lua |> Export a local app to a directory and run it: ```r +library(plumber) pkgload::load_all() + # Delete prior -unlink("local/shiny-apps-out/") +unlink("local/shiny-apps-out/", recursive = TRUE) export("local/shiny-apps/simple-r", "local/shiny-apps-out") -#> Run the following in an R session to serve the app: -#> httpuv::runStaticServer("local/shiny-apps-out") # Host the local directory -httpuv::runStaticServer("local/shiny-apps-out") +pr() %>% pr_static("/", "local/shiny-apps-out") %>% pr_run() ``` diff --git a/cran-comments.md b/cran-comments.md index 4b6c2eb..f38202a 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,4 +1,61 @@ -## 2023-09-12 +## Comments + +#### 2023-10-10 + +Updates: +* Package description length and wording. +* Added single quotes around `'shiny'` +* Added return value for `assets.Rd` and `install.Rd` +* Updated `export.Rd` example to use `if(interactive())` +* The `export.Rd` example writes to a temp folder, the tests are only run on CI, and there are no vignettes. Only temp files are created. + +Thank you, +Barret + + +#### 2023-10-09 + +Thanks, + +Please do not start the description with "This package", package name, +title or similar. + +The Description field is intended to be a (one paragraph) description of +what the package does and why it may be useful. Please add more details +about the package functionality and implemented methods in your +Description text. + +Please always write package names, software names and API (application +programming interface) names in single quotes in title and description. +e.g: --> 'shiny' +Please note that package names are case sensitive. + +Please add \value to .Rd files regarding exported methods and explain +the functions results in the documentation. Please write about the +structure of the output (class) and also what the output means. (If a +function does not return a value, please document that too, e.g. +\value{No return value, called for side effects} or similar) +Missing Rd-tags: + install.Rd: \value + +Functions which are supposed to only run interactively (e.g. shiny) +should be wrapped in if(interactive()). Please replace /dontrun{} with +if(interactive()){} if possible, then users can see that the functions +are not intended for use in scripts / functions that are supposed to run +non interactively. + +Please ensure that your functions do not write by default or in your +examples/vignettes/tests in the user's home filespace (including the +package directory and getwd()). This is not allowed by CRAN policies. +Please omit any default path in writing functions. In your +examples/vignettes/tests you can write to tempdir(). + +Please fix and resubmit. + +Best, +Benjamin Altmann + +#### 2023-10-06 This is a new package. @@ -12,4 +69,7 @@ Barret 0 errors | 0 warnings | 1 note -* This is a new release. +* checking CRAN incoming feasibility ... NOTE +Maintainer: 'Barret Schloerke ' + +New submission diff --git a/man/assets.Rd b/man/assets.Rd index c9ef973..e48dd7d 100644 --- a/man/assets.Rd +++ b/man/assets.Rd @@ -44,6 +44,11 @@ behavior should be used.} \item{versions}{The assets versions to remove.} } +\value{ +\code{assets_version()} returns the version of the currently supported Shinylive. + +All other methods return \code{invisible()}. +} \description{ Helper methods for managing shinylive assets. } diff --git a/man/export.Rd b/man/export.Rd index 08f7b52..1703297 100644 --- a/man/export.Rd +++ b/man/export.Rd @@ -18,21 +18,28 @@ export(appdir, destdir, ..., subdir = "", verbose = is_interactive()) \item{verbose}{Print verbose output. Defaults to \code{TRUE} if running interactively.} } +\value{ +Nothing. The app is exported to \code{destdir}. Instructions for serving +the directory are printed to stdout. +} \description{ This function exports a Shiny app to a directory, which can then be served -using \code{httpuv::runStaticServer()}. +using \code{plumber}. } \examples{ -\dontrun{ +\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} app_dir <- system.file("examples", "01_hello", package = "shiny") out_dir <- tempfile("shinylive-export") # Export the app to a directory export(app_dir, out_dir) -#> Run the following in an R session to serve the app: -#> httpuv::runStaticServer() # Serve the exported directory -httpuv::runStaticServer(out_dir) +if (require(plumber)) { + library(plumber) + pr() \%>\% + pr_static("/", out_dir) \%>\% + pr_run() } +\dontshow{\}) # examplesIf} } diff --git a/man/install.Rd b/man/install.Rd index f3c4e9a..8c2be8e 100644 --- a/man/install.Rd +++ b/man/install.Rd @@ -30,6 +30,9 @@ should be used.} \item{version}{The version of the assets being installed.} } +\value{ +All method return \code{invisible()}. +} \description{ Helper methods for testing updates to shinylive assets. } diff --git a/man/quarto_ext.Rd b/man/quarto_ext.Rd index ff3437b..2a90ebb 100644 --- a/man/quarto_ext.Rd +++ b/man/quarto_ext.Rd @@ -2,8 +2,7 @@ % Please edit documentation in R/quarto_ext.R \name{quarto_ext} \alias{quarto_ext} -\title{TODO-barret; update docs in py-shinylive -Quarto extension for shinylive} +\title{Quarto extension for shinylive} \usage{ quarto_ext( args = commandArgs(trailingOnly = TRUE),