Skip to content

Commit 76b01ca

Browse files
committed
refactor: enhance README with clearer structure and additional usage examples
1 parent e673f6d commit 76b01ca

File tree

2 files changed

+194
-44
lines changed

2 files changed

+194
-44
lines changed

README.Rmd

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,60 +23,81 @@ knitr::opts_chunk$set(
2323
[![CRAN status](https://www.r-pkg.org/badges/version/lzstring)](https://CRAN.R-project.org/package=lzstring)
2424
[![Monthly metacran downloads](https://cranlogs.r-pkg.org/badges/lzstring)](https://cran.r-project.org/package=lzstring)
2525
[![Total metacran downloads](https://cranlogs.r-pkg.org/badges/grand-total/lzstring)](https://cran.r-project.org/package=lzstring)
26-
2726
<!-- badges: end -->
2827

28+
The goal of **lzstring-r** is to provide an R wrapper for the [lzstring C++ library](https://github.com/andykras/lz-string-cpp). [lzstring](https://github.com/pieroxy/lz-string) is originally a JavaScript library that provides fast and efficient string compression and decompression using a [LZ-based algorithm](https://en.wikipedia.org/wiki/Lempel–Ziv–Welch).
29+
30+
Credit goes to [Winston Chang](https://github.com/wch) for spotting this missing R package and guiding me over at the R Shinylive repo—check out his awesome contributions which this repo is based on [here](https://github.com/posit-dev/r-shinylive/issues/70) and [here](https://github.com/posit-dev/r-shinylive/pull/71). Also, shoutout to Andy Kras for his implementation in C++ of lzstring, which you can find right [here](https://github.com/andykras/lz-string-cpp), and [pieroxy](https://github.com/pieroxy), the original brain behind lzstring in JavaScript—peek at his work over [here](https://github.com/pieroxy/lz-string).
2931

30-
The goal of lzstring-r is to provide an R wrapper for the [lzstring C++ library](https://github.com/andykras/lz-string-cpp). [lzstring](https://github.com/pieroxy/lz-string) is originally a JavaScript library that provides fast and efficient string compression and decompression using a [LZ-based algorithm](https://en.wikipedia.org/wiki/Lempel–Ziv–Welch). Credit goes to [Winston Chang](https://github.com/wch) for spotting this missing R package and guiding me over at the R Shinylive repo—check out his awesome contributions which this repo is based on [here](https://github.com/posit-dev/r-shinylive/issues/70) and [here](https://github.com/posit-dev/r-shinylive/pull/71). Also, shoutout to Andy Kras for his implementation in C++ of lzstring, which you can find right [here](https://github.com/andykras/lz-string-cpp), and [pieroxy](https://github.com/pieroxy), the original brain behind lzstring in JavaScript—peek at his work over [here](https://github.com/pieroxy/lz-string).
32+
---
3133

3234
## Installation
3335

34-
You can install the released version of lzstringr from [CRAN](https://CRAN.R-project.org/package=lzstring) with:
36+
You can install the released version of lzstring from [CRAN](https://CRAN.R-project.org/package=lzstring) with:
3537

36-
``` r
38+
```r
3739
install.packages("lzstring")
3840
```
3941

40-
You can install the development version of lzstringr from [GitHub](https://github.com/) with:
42+
Or the development version from [GitHub](https://github.com/parmsam/lzstring-r):
4143

42-
``` r
44+
```r
4345
# install.packages("devtools")
4446
devtools::install_github("parmsam/lzstring-r")
4547
```
4648

47-
## Example
49+
---
50+
51+
## Usage
4852

49-
This is a basic example which shows you how to solve a common problem:
53+
### Basic Example
5054

5155
```{r example}
5256
library(lzstring)
5357
54-
# text data
55-
message = "The quick brown fox jumps over the lazy dog!";
56-
57-
compressed = lzstring::compressToBase64(message)
58+
# Text data
59+
message <- "The quick brown fox jumps over the lazy dog!"
60+
compressed <- lzstring::compressToBase64(message)
5861
compressed
5962
60-
decompressed = lzstring::decompressFromBase64(compressed)
63+
decompressed <- lzstring::decompressFromBase64(compressed)
6164
cat(decompressed)
6265
```
6366

64-
### JSON data
67+
---
68+
69+
### Compressing and Decompressing JSON
6570

6671
```{r}
67-
# JSON data
6872
json_data <- list(name = "John Doe", age = 30, email = "[email protected]")
6973
json_string <- jsonlite::toJSON(json_data)
7074
71-
compressed = lzstring::compressToBase64(json_string)
75+
compressed <- lzstring::compressToBase64(json_string)
7276
compressed
7377
74-
decompressed = lzstring::decompressFromBase64(compressed)
78+
decompressed <- lzstring::decompressFromBase64(compressed)
7579
identical(json_string, decompressed)
7680
cat(decompressed)
7781
```
7882

79-
### R code
83+
---
84+
85+
### Round-Trip for Complex R Objects
86+
87+
> **Note:** Always serialize complex R objects (lists, data frames, etc.) to JSON before compressing. After decompression, deserialize back to R.
88+
89+
```{r}
90+
obj <- list(a = 1, b = "text", c = list(x = 1:3))
91+
json <- jsonlite::serializeJSON(obj)
92+
lz <- lzstring::compressToBase64(json)
93+
json2 <- lzstring::decompressFromBase64(lz)
94+
obj2 <- jsonlite::unserializeJSON(json2)
95+
identical(obj, obj2) # TRUE
96+
```
97+
98+
---
99+
100+
### R Code Example
80101

81102
```{r}
82103
r_code <- '
@@ -94,12 +115,14 @@ filtered_data <- filter(data, age > 25)
94115
# Add a new column with updated salary
95116
data <- mutate(data, updated_salary = salary * 1.05)
96117
'
97-
compressed = lzstring::compressToBase64(r_code)
118+
compressed <- lzstring::compressToBase64(r_code)
98119
compressed
99-
decompose = lzstring::decompressFromBase64(compressed)
120+
decompose <- lzstring::decompressFromBase64(compressed)
100121
cat(decompose)
101122
```
102123

124+
---
125+
103126
### Compress Shinylive Hashes
104127

105128
```{r example1-shinylive}
@@ -120,9 +143,53 @@ cat(paste0("https://shinylive.io/r/app/#code=", files_lz))
120143
```
121144

122145
### Decompress Shinylive Hashes
146+
123147
```{r example2-shinylive}
124148
x <- lzstring::decompressFromEncodedURIComponent("NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbDOAD1R04LFkw4xUxOmTERUAVzJ4mQiABM4dZfI4AdCPp0YuCsgH0WAGw4a6ACl2RHyxwDlnTAAzKAjJ+9MAEyeAJT64RAAAqq2GBR8ZPoaNExkCXYhiPpMOSpwZPJ0EEw0jhAAVIFioiAmihgQGUzlQQC+jvpgrQC6QA")
125149
y <- jsonlite::fromJSON(x)
126150
cat(y$name)
127151
cat(y$content)
128152
```
153+
154+
---
155+
156+
## Encoding and Limitations
157+
158+
> **Important:**
159+
> - lzstring operates on strings. For non-string or binary data, encode as JSON or base64 first.
160+
> - Always ensure your input is UTF-8 encoded.
161+
> - If you compress an R object directly (without serialization), the result may not decompress as expected.
162+
163+
---
164+
165+
## Troubleshooting
166+
167+
- **Why do I get an empty string after decompressing?**
168+
This may happen if the input was not properly encoded, or if the compressed string is corrupted.
169+
170+
- **Why does my decompressed JSON fail to parse?**
171+
Ensure you serialize your R object to JSON (or use `serializeJSON`) before compressing.
172+
173+
- **Can I compress binary data?**
174+
Encode it as base64 or hex first, then compress the resulting string.
175+
176+
---
177+
178+
## Use Cases
179+
180+
- Sharing Shiny app code via URL (see [Shinylive](https://shinylive.io/r/app/))
181+
- Compact storage of large JSON blobs
182+
- Embedding compressed data in web apps
183+
- **Automatic Shinylive links in documentation:**
184+
The [roxy.shinylive](https://github.com/insightsengineering/roxy.shinylive) package uses lzstring to provide a [roxygen2](https://roxygen2.r-lib.org/) extension that automatically takes the code from the `@examples` tag and creates a URL to the [shinylive.io](https://shinylive.io/r/app/) service. During documentation build, a new section is added to the function manual containing the link and an iframe to the application itself.
185+
186+
---
187+
188+
## References
189+
190+
- [lz-string JavaScript library (pieroxy)](https://github.com/pieroxy/lz-string)
191+
- [lz-string C++ port (Andy Kras)](https://github.com/andykras/lz-string-cpp)
192+
- [Shinylive for R](https://github.com/posit-dev/r-shinylive)
193+
- [roxy.shinylive](https://github.com/insightsengineering/roxy.shinylive)
194+
195+
---

README.md

Lines changed: 107 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ status](https://www.r-pkg.org/badges/version/lzstring)](https://CRAN.R-project.o
1414
downloads](https://cranlogs.r-pkg.org/badges/lzstring)](https://cran.r-project.org/package=lzstring)
1515
[![Total metacran
1616
downloads](https://cranlogs.r-pkg.org/badges/grand-total/lzstring)](https://cran.r-project.org/package=lzstring)
17-
1817
<!-- badges: end -->
1918

20-
The goal of lzstring-r is to provide an R wrapper for the [lzstring C++
21-
library](https://github.com/andykras/lz-string-cpp).
19+
The goal of **lzstring-r** is to provide an R wrapper for the [lzstring
20+
C++ library](https://github.com/andykras/lz-string-cpp).
2221
[lzstring](https://github.com/pieroxy/lz-string) is originally a
2322
JavaScript library that provides fast and efficient string compression
2423
and decompression using a [LZ-based
25-
algorithm](https://en.wikipedia.org/wiki/Lempel–Ziv–Welch). Credit goes
26-
to [Winston Chang](https://github.com/wch) for spotting this missing R
27-
package and guiding me over at the R Shinylive repo—check out his
28-
awesome contributions which this repo is based on
24+
algorithm](https://en.wikipedia.org/wiki/Lempel–Ziv–Welch).
25+
26+
Credit goes to [Winston Chang](https://github.com/wch) for spotting this
27+
missing R package and guiding me over at the R Shinylive repo—check out
28+
his awesome contributions which this repo is based on
2929
[here](https://github.com/posit-dev/r-shinylive/issues/70) and
3030
[here](https://github.com/posit-dev/r-shinylive/pull/71). Also, shoutout
3131
to Andy Kras for his implementation in C++ of lzstring, which you can
@@ -34,61 +34,85 @@ find right [here](https://github.com/andykras/lz-string-cpp), and
3434
lzstring in JavaScript—peek at his work over
3535
[here](https://github.com/pieroxy/lz-string).
3636

37+
------------------------------------------------------------------------
38+
3739
## Installation
3840

39-
You can install the released version of lzstringr from
41+
You can install the released version of lzstring from
4042
[CRAN](https://CRAN.R-project.org/package=lzstring) with:
4143

4244
``` r
4345
install.packages("lzstring")
4446
```
4547

46-
You can install the development version of lzstringr from
47-
[GitHub](https://github.com/) with:
48+
Or the development version from
49+
[GitHub](https://github.com/parmsam/lzstring-r):
4850

4951
``` r
5052
# install.packages("devtools")
5153
devtools::install_github("parmsam/lzstring-r")
5254
```
5355

54-
## Example
56+
------------------------------------------------------------------------
57+
58+
## Usage
5559

56-
This is a basic example which shows you how to solve a common problem:
60+
### Basic Example
5761

5862
``` r
5963
library(lzstring)
6064

61-
# text data
62-
message = "The quick brown fox jumps over the lazy dog!";
63-
64-
compressed = lzstring::compressToBase64(message)
65+
# Text data
66+
message <- "The quick brown fox jumps over the lazy dog!"
67+
compressed <- lzstring::compressToBase64(message)
6568
compressed
6669
#> [1] "CoCwpgBAjgrglgYwNYQEYCcD2B3AdhAM0wA8IArGAWwAcBnCTANzHQgBdwIAbAQwC8AnhAAmmAOYBCIA"
6770

68-
decompressed = lzstring::decompressFromBase64(compressed)
71+
decompressed <- lzstring::decompressFromBase64(compressed)
6972
cat(decompressed)
7073
#> The quick brown fox jumps over the lazy dog!
7174
```
7275

73-
### JSON data
76+
------------------------------------------------------------------------
77+
78+
### Compressing and Decompressing JSON
7479

7580
``` r
76-
# JSON data
7781
json_data <- list(name = "John Doe", age = 30, email = "[email protected]")
7882
json_string <- jsonlite::toJSON(json_data)
7983

80-
compressed = lzstring::compressToBase64(json_string)
84+
compressed <- lzstring::compressToBase64(json_string)
8185
compressed
8286
#> [1] "N4IgdghgtgpiBcBtEApA9gCzAAgCJrgF0AaECAcziQGYAGEkGKCASwBsFkArTMAOgAmBAAIwAHtAAObGHwDGaKCEIBfIA==="
8387

84-
decompressed = lzstring::decompressFromBase64(compressed)
88+
decompressed <- lzstring::decompressFromBase64(compressed)
8589
identical(json_string, decompressed)
8690
#> [1] FALSE
8791
cat(decompressed)
8892
#> {"name":["John Doe"],"age":[30],"email":["[email protected]"]}
8993
```
9094

91-
### R code
95+
------------------------------------------------------------------------
96+
97+
### Round-Trip for Complex R Objects
98+
99+
> **Note:** Always serialize complex R objects (lists, data frames,
100+
> etc.) to JSON before compressing. After decompression, deserialize
101+
> back to R.
102+
103+
``` r
104+
obj <- list(a = 1, b = "text", c = list(x = 1:3))
105+
json <- jsonlite::serializeJSON(obj)
106+
lz <- lzstring::compressToBase64(json)
107+
json2 <- lzstring::decompressFromBase64(lz)
108+
obj2 <- jsonlite::unserializeJSON(json2)
109+
identical(obj, obj2) # TRUE
110+
#> [1] TRUE
111+
```
112+
113+
------------------------------------------------------------------------
114+
115+
### R Code Example
92116

93117
``` r
94118
r_code <- '
@@ -106,10 +130,10 @@ filtered_data <- filter(data, age > 25)
106130
# Add a new column with updated salary
107131
data <- mutate(data, updated_salary = salary * 1.05)
108132
'
109-
compressed = lzstring::compressToBase64(r_code)
133+
compressed <- lzstring::compressToBase64(r_code)
110134
compressed
111135
#> [1] "FAGwlgRgTghlCeAKAJgBxPKBKYxkwBcYACAHgFpj8iA6AM1gFsBTRYY4gOxheIF5iAY0QAiAFIB7ABacRAGmLiYnZvMViYAa1VY57YjADmzfkMQAmABwLz5hQGZzu/QGcYIOPFPCArAAYAvwUANkCg4h9/AJwcYABiYgAxMBACZigqQhI6CQyjE0MoZkJ04gIpZWJzH2A6FLSi5AB9ahIKYjrU9JQshXziAD4qn1iEgEFkZAMuZgB3IQkQAFdGTmJZsHLiJdRqZim3DwQ8LLJKRiWiNJ6iBR295sPPUyeEYgAqYgBGGj8R4CAA=="
112-
decompose = lzstring::decompressFromBase64(compressed)
136+
decompose <- lzstring::decompressFromBase64(compressed)
113137
cat(decompose)
114138
#>
115139
#> library(dplyr)
@@ -127,6 +151,8 @@ cat(decompose)
127151
#> data <- mutate(data, updated_salary = salary * 1.05)
128152
```
129153

154+
------------------------------------------------------------------------
155+
130156
### Compress Shinylive Hashes
131157

132158
``` r
@@ -164,3 +190,60 @@ cat(y$content)
164190
#> def txt():
165191
#> return f"n*2 is {input.n() * 2}"
166192
```
193+
194+
------------------------------------------------------------------------
195+
196+
## Encoding and Limitations
197+
198+
> **Important:**
199+
> - lzstring operates on strings. For non-string or binary data, encode
200+
> as JSON or base64 first.
201+
> - Always ensure your input is UTF-8 encoded.
202+
> - If you compress an R object directly (without serialization), the
203+
> result may not decompress as expected.
204+
205+
------------------------------------------------------------------------
206+
207+
## Troubleshooting
208+
209+
- **Why do I get an empty string after decompressing?**
210+
This may happen if the input was not properly encoded, or if the
211+
compressed string is corrupted.
212+
213+
- **Why does my decompressed JSON fail to parse?**
214+
Ensure you serialize your R object to JSON (or use `serializeJSON`)
215+
before compressing.
216+
217+
- **Can I compress binary data?**
218+
Encode it as base64 or hex first, then compress the resulting string.
219+
220+
------------------------------------------------------------------------
221+
222+
## Use Cases
223+
224+
- Sharing Shiny app code via URL (see
225+
[Shinylive](https://shinylive.io/r/app/))
226+
- Compact storage of large JSON blobs
227+
- Embedding compressed data in web apps
228+
- **Automatic Shinylive links in documentation:**
229+
The
230+
[roxy.shinylive](https://github.com/insightsengineering/roxy.shinylive)
231+
package uses lzstring to provide a
232+
[roxygen2](https://roxygen2.r-lib.org/) extension that automatically
233+
takes the code from the `@examples` tag and creates a URL to the
234+
[shinylive.io](https://shinylive.io/r/app/) service. During
235+
documentation build, a new section is added to the function manual
236+
containing the link and an iframe to the application itself.
237+
238+
------------------------------------------------------------------------
239+
240+
## References
241+
242+
- [lz-string JavaScript library
243+
(pieroxy)](https://github.com/pieroxy/lz-string)
244+
- [lz-string C++ port (Andy
245+
Kras)](https://github.com/andykras/lz-string-cpp)
246+
- [Shinylive for R](https://github.com/posit-dev/r-shinylive)
247+
- [roxy.shinylive](https://github.com/insightsengineering/roxy.shinylive)
248+
249+
------------------------------------------------------------------------

0 commit comments

Comments
 (0)