Adjust ts_compile to also call ts_deploy to make compilation easier

This commit is contained in:
Tom Elliott 2025-01-29 08:32:44 +13:00
parent d70a70cbe1
commit 2e4e00c5d6
3 changed files with 22 additions and 40 deletions

View File

@ -1,12 +1,15 @@
#' Compile R functions to TypeScript schemas
#' Compile R functions
#'
#' Generates TypeScript schema for the given R function or file path. If a path, the R app is also generated.
#'
#' @param f A function or file path
#' @param name The name of the function
#' @param ... Additional arguments
#' @param file The file path to write the TypeScript schema (optional). If `""`, the output is printed to the standard output console (see `cat`).
#' @param ... Additional arguments (passed to ts_deploy)
#' @param filename The base file path to write the TypeScript schema and R app to (optional, uses `[path of f].rserve` by default). `.R` and `.ts` file extensions are appended automatically. If `""`, the output is printed to the standard output console (see `cat`).
#' @return Character vector of TypeScript schema, or NULL if writing to file
#' @md
#' @export
ts_compile <- function(f, ..., name, file) {
ts_compile <- function(f, ..., name, filename) {
o <- UseMethod("ts_compile")
}
@ -27,7 +30,8 @@ ts_compile.ts_function <- function(f, ..., name = deparse(substitute(f))) {
#' @export
ts_compile.character <- function(
f,
file = sprintf("%s.rserve.ts", tools::file_path_sans_ext(f))) {
...,
filename = sprintf("%s.rserve", tools::file_path_sans_ext(f))) {
if (length(f) > 1) {
return(sapply(f, ts_compile))
}
@ -39,7 +43,7 @@ ts_compile.character <- function(
e <- new.env()
source(f, local = e)
x <- sapply(ls(e), \(x) ts_compile(e[[x]], file = file, name = x))
x <- sapply(ls(e), \(x) ts_compile(e[[x]], filename = "", name = x))
src <- c(
"import { Robj } from 'rserve-ts';",
@ -50,7 +54,10 @@ ts_compile.character <- function(
sprintf("export default {\n %s\n};", paste(ls(e), collapse = ",\n "))
)
cat(src, file = file, sep = "\n")
cat(src, file = sprintf("%s.ts", filename), sep = "\n")
# R file
ts_deploy(f, file = sprintf("%s.R", filename), silent = TRUE, ...)
invisible()
}

View File

@ -7,6 +7,7 @@
#' @param port The port to deploy the app on
#' @param run Whether to run the deployment script,
#' takes values "no", "here", "background"
#' @param silent Whether to print the deployment script
#' @return NULL, called to open an Rserve instance
#' @export
#' @md
@ -14,7 +15,8 @@ ts_deploy <- function(f,
file = sprintf("%s.rserve.R", tools::file_path_sans_ext(f)),
init = NULL,
port = 6311,
run = c("no", "here", "background")) {
run = c("no", "here", "background"),
silent = FALSE) {
if (length(f) != 1) stop("Expected a single path")
if (!file.exists(f)) stop("File not found")
@ -57,8 +59,10 @@ ts_deploy <- function(f,
run <- match.arg(run)
switch(run,
"no" = {
cat("Run the following command to deploy the app:\n")
cat(sprintf("Rscript %s", file), "\n")
if (!silent) {
cat("Run the following command to deploy the app:\n")
cat(sprintf("Rscript %s", file), "\n")
}
},
"here" = source(file),
"background" = system(sprintf("Rscript %s", file))

View File

@ -8,39 +8,10 @@ test_that("anonomous functions", {
expect_equal(add_c, "const add = Robj.ocap([z.number(), z.number()], Robj.numeric(1));")
})
# test_that("Complex functions", {
# get_sample <- ts_function(
# function(n = ts_numeric(1)) {
# sample(values, n)
# },
# result = ts_numeric()
# )
# sampler <- ts_function(
# function(values = ts_numeric()) {
# list(
# get = get_sample$copy(),
# set = ts_function(
# function(value = ts_numeric()) {
# values <<- value
# }
# )
# )
# },
# result = ts_list(
# get = get_sample,
# set = ts_function(NULL, value = ts_numeric())
# )
# )
# sampler_c <- ts_compile(sampler)
# s <- sampler_c(1:10)
# expect_equal()
# })
test_that("Compile files", {
f <- tempfile(fileext = ".rserve.ts")
on.exit(unlink(f))
res <- ts_compile("sampler/app.R", file = f)
res <- ts_compile("sampler/app.R", filename = tools::file_path_sans_ext(f))
expect_true(file.exists(f))
})