Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds README and fixes Description #7

Merged
merged 4 commits into from
Jan 31, 2024
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
3 changes: 3 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
^LICENSE\.md$
^\.github$
^_pkgdown\.yml$
^docs$
^pkgdown$
43 changes: 43 additions & 0 deletions .github/workflows/pkgdown.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main]

name: pkgdown

jobs:
pkgdown:
runs-on: ubuntu-latest
# Only restrict concurrency for non-PR jobs
concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
permissions:
contents: write
steps:
- uses: actions/checkout@v3

- uses: r-lib/actions/setup-pandoc@v2

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::pkgdown, local::.
needs: website

- name: Build site
run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
shell: Rscript {0}

- name: Deploy to GitHub pages 🚀
if: github.event_name != 'pull_request'
uses: JamesIves/[email protected]
with:
clean: false
branch: gh-pages
folder: docs
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ po/*~

# RStudio Connect folder
rsconnect/
docs
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tower
Title: Easy middle ware library for Shiny
Version: 0.0.0.9000
Title: Easy Middle Ware Library for Shiny
Version: 0.1.0
Authors@R:
c(person(given = "ixpantia, SRL",
role = "cph",
Expand All @@ -16,9 +16,9 @@ Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
Imports:
shiny,
compiler
Suggests:
testthat (>= 3.0.0),
shiny,
stringr
Config/testthat/edition: 3
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,76 @@
# tower

<!-- badges: start -->
[![R-CMD-check](https://github.com/ixpantia/tower/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/ixpantia/tower/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->

Dead simple middleware for R Shiny.

## Summary

`tower` is a simple library for adding middleware to Shiny applications.
It is inspired by the [tower](https://docs.rs/tower/latest/tower/) crate for Rust.
It is designed to enable package authors and Shiny developers to extend
Shiny a little bit more than what is usually possible.

You can use `tower` to add middlewares that forward, modify, or intercept
requests in Shiny applications. This can be useful for adding logging, authentication,
caching, or routing to your Shiny applications.

## Installation

You can install the development version of `tower` from GitHub with:

``` r
# install.packages("remotes")
remotes::install_github("ixpantia/tower")
```

## Example

We may want to add a new route to our Shiny application that adds a count
to a counter every time a user visits the route. We can do this with `tower`
by adding a middleware that intercepts the request and increments the counter.

``` r
library(shiny)
library(tower)

# Counter environment
COUNTER <- new.env()
COUNTER$counter <- 0

# Middleware to increment the counter
increment_counter <- function(req) {
if (req$PATH_INFO == "/increment") {
COUNTER$counter <- COUNTER$counter + 1
return(
httpResponse(
200,
"text/plain",
paste("Counter is now", COUNTER$counter)
)
)
}
}

# A very empty Shiny app (not necessary for the demo)
ui <- fluidPage()
server <- function(input, output, session) {}

shinyApp(ui, server) |>
create_tower() |>
add_http_layer(increment_counter) |>
build_tower()
```

If you run the code above and visit the route `/increment` in your browser,
you will see the counter increment every time you visit the route.

## How it works

Basically, `tower` adds layers to a Shiny application. A layer is a function
that takes a request and returns either a response or NULL. If a layer returns
a response, the response is sent to the client and the request is not forwarded
to the next layer. If a layer returns NULL, the request is forwarded to the next
layer.
4 changes: 4 additions & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
url: ~
template:
bootstrap: 5

29 changes: 29 additions & 0 deletions inst/examples/counter/app.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
library(shiny)
library(tower)

# Counter environment
COUNTER <- new.env()
COUNTER$counter <- 0

# Middleware to increment the counter
increment_counter <- function(req) {
if (req$PATH_INFO == "/increment") {
COUNTER$counter <- COUNTER$counter + 1
return(
httpResponse(
200,
"text/plain",
paste("Counter is now", COUNTER$counter)
)
)
}
}

# A very empty Shiny app (not necesarry for the demo)
ui <- fluidPage()
server <- function(input, output, session) {}

shinyApp(ui, server) |>
create_tower() |>
add_http_layer(increment_counter) |>
build_tower()
Loading