diff --git a/README.Rmd b/README.Rmd index 6495465..ab8caf5 100644 --- a/README.Rmd +++ b/README.Rmd @@ -33,8 +33,8 @@ devtools::install_github("tmelliott/ts") Writing functions is easy, just use the `ts_*()` functions to define formals and return types. - ```r +# demo.R library(ts) addFn <- ts_function( function(a = ts_numeric(1), b = ts_numeric(1)) a + b, @@ -52,58 +52,44 @@ app <- ts_function( ) }, result = ts_list( - add = appFn, + add = addFn, sample = sampleFn ) ) -ts_compile(app) +# TODO: specify exactly which functions to export in the entry point +# ts_export(app) ``` -This will generate the following rserve-ts function definitions: +Then use `ts_compile()` to generate the TypeScript schemas: ```typescript -import { types as R } from "rserve-ts"; +import { Robj } from 'rserve-ts'; +import { z } from 'zod'; -export const app = { - add: z.function( - z.tuple([z.number(), z.number()]), - z.promise(R.numeric(1)) - ), - sample: z.function( - z.tuple([z.array(z.string()), z.integer()]), - z.promise(R.character()) - ) +const addFn = Robj.ocap([z.number(), z.number()], Robj.numeric(1)); +const app = Robj.ocap([], + Robj.list({ + add: Robj.ocap(), + sample: Robj.ocap() + }) +); +const sampleFn = Robj.ocap( + [z.union([z.string(), z.array(z.string())]), z.number()], + Robj.character() +); + +export default { + addFn, + app, + sampleFn }; ``` -which will generate the following types: -```typescript -type App = { - add: (x: number, y: number) => Promise>; - sample: (x: string[], n: number) => Promise; -}; -``` +You can then import this into your [rserve-ts](https://www.npmjs.com/package/rserve-ts) application. See `tests/testthat/sampler` for an example. -Besides generating the schema as shown above, the app object can also be 'deployed' using Rserve: +It is also possible to generate a sourceable file to deploy an Rserve instance with your app code using `ts_deploy()`: ```r -ts_deploy(app, port = 6311, daemon = FALSE) -# listening on port 6311 -``` - -## State of the project - -Here's what's currently working: - -```{r, error = TRUE} -library(ts) - -myfun <- ts_function(mean, x = ts_numeric(), result = ts_numeric(1)) -myfun$call(1:5) - -myfun$call("hello world") - -cat(readLines("tests/testthat/app.R"), sep = "\n") - -ts_compile("tests/testthat/app.R", file = "") +ts_deploy(app) +# run with: Rscript app.rserve.R ``` diff --git a/README.md b/README.md index b84c7c2..e5cf272 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Writing functions is easy, just use the `ts_*()` functions to define formals and return types. ``` r +# demo.R library(ts) addFn <- ts_function( function(a = ts_numeric(1), b = ts_numeric(1)) a + b, @@ -44,82 +45,48 @@ app <- ts_function( ) }, result = ts_list( - add = appFn, + add = addFn, sample = sampleFn ) ) -ts_compile(app) +# TODO: specify exactly which functions to export in the entry point +# ts_export(app) ``` -This will generate the following rserve-ts function definitions: +Then use `ts_compile()` to generate the TypeScript schemas: ``` typescript -import { types as R } from "rserve-ts"; +import { Robj } from 'rserve-ts'; +import { z } from 'zod'; -export const app = { - add: z.function( - z.tuple([z.number(), z.number()]), - z.promise(R.numeric(1)) - ), - sample: z.function( - z.tuple([z.array(z.string()), z.integer()]), - z.promise(R.character()) - ) +const addFn = Robj.ocap([z.number(), z.number()], Robj.numeric(1)); +const app = Robj.ocap([], + Robj.list({ + add: Robj.ocap(), + sample: Robj.ocap() + }) +); +const sampleFn = Robj.ocap( + [z.union([z.string(), z.array(z.string())]), z.number()], + Robj.character() +); + +export default { + addFn, + app, + sampleFn }; ``` -which will generate the following types: +You can then import this into your +[rserve-ts](https://www.npmjs.com/package/rserve-ts) application. See +`tests/testthat/sampler` for an example. -``` typescript -type App = { - add: (x: number, y: number) => Promise>; - sample: (x: string[], n: number) => Promise; -}; -``` - -Besides generating the schema as shown above, the app object can also be -‘deployed’ using Rserve: +It is also possible to generate a sourceable file to deploy an Rserve +instance with your app code using `ts_deploy()`: ``` r -ts_deploy(app, port = 6311, daemon = FALSE) -# listening on port 6311 -``` - -## State of the project - -Here’s what’s currently working: - -``` r -library(ts) - -myfun <- ts_function(mean, x = ts_numeric(), result = ts_numeric(1)) -myfun$call(1:5) -#> [1] 3 - -myfun$call("hello world") -#> Error: Invalid argument 'x': Expected a number - -cat(readLines("tests/testthat/app.R"), sep = "\n") -#> library(ts) -#> -#> fn_mean <- ts_function(mean, x = ts_numeric(), result = ts_numeric(1)) -#> fn_first <- ts_function(function(x = ts_character(-1)) x[1], -#> result = ts_character(1) -#> ) -#> -#> sample_num <- ts_function( -#> sample, -#> x = ts_numeric(0), -#> result = ts_numeric(1) -#> ) - -ts_compile("tests/testthat/app.R", file = "") -#> import { Robj } from 'rserve-ts'; -#> import { z } from 'zod'; -#> -#> -#> const fn_first = Robj.ocap([z.union([z.string(), Robj.character(0)])], Robj.character(1)); -#> const fn_mean = Robj.ocap([z.union([z.number(), z.instanceof(Float64Array)])], Robj.numeric(1)); -#> const sample_num = Robj.ocap([z.instanceof(Float64Array)], Robj.numeric(1)); +ts_deploy(app) +# run with: Rscript app.rserve.R ```