From 83e149ac36771200804ff3420916e07fb018e66c Mon Sep 17 00:00:00 2001 From: parmsam Date: Sun, 16 Jun 2024 11:38:39 -0400 Subject: [PATCH 1/2] switch over to lzstring r pkg from js pkg --- DESCRIPTION | 2 +- R/lzstring.R | 42 ----------------------------- R/url.R | 48 ++++++++++++++++++++++++++------- inst/lz-string/lz-string.min.js | 1 - package-lock.json | 20 -------------- package.json | 5 ---- 6 files changed, 40 insertions(+), 78 deletions(-) delete mode 100644 R/lzstring.R delete mode 100644 inst/lz-string/lz-string.min.js delete mode 100644 package-lock.json delete mode 100644 package.json diff --git a/DESCRIPTION b/DESCRIPTION index 854a5fa..ec3154e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -31,7 +31,7 @@ Suggests: httpuv (>= 1.6.12), spelling, testthat (>= 3.0.0), - V8 + lzstring Config/Needs/website: tidyverse/tidytemplate Config/testthat/edition: 3 Language: en-US diff --git a/R/lzstring.R b/R/lzstring.R deleted file mode 100644 index caa6574..0000000 --- a/R/lzstring.R +++ /dev/null @@ -1,42 +0,0 @@ -.v8 <- new.env(parent = emptyenv()) - -check_v8_installed <- function() { - rlang::check_installed("V8", "for shinylive url encoding and decoding.") -} - -get_v8 <- function() { - check_v8_installed() - - if (exists("context", envir = .v8)) { - return(.v8$context) - } - - context <- V8::v8() - - context$source( - system.file("lz-string", "lz-string.min.js", package = "shinylive") - ) - - assign("context", context, envir = .v8) - context -} - -lzstring_compress_uri <- function(x) { - x <- jsonlite::toJSON(x, auto_unbox = TRUE, null = "null", na = "null") - - v8 <- get_v8() - v8$call("LZString.compressToEncodedURIComponent", x) -} - -lzstring_decompress_uri <- function(x) { - v8 <- get_v8() - - x <- v8$call("LZString.decompressFromEncodedURIComponent", x) - - jsonlite::fromJSON( - x, - simplifyVector = TRUE, - simplifyDataFrame = FALSE, - simplifyMatrix = FALSE - ) -} diff --git a/R/url.R b/R/url.R index e4c2eec..d8a7521 100644 --- a/R/url.R +++ b/R/url.R @@ -1,11 +1,10 @@ url_encode_dir <- function( - dir, - language = c("auto", "r", "py"), - mode = c("editor", "app"), - hide_header = FALSE, - exclude = "rsconnect/" + dir, + language = c("auto", "r", "py"), + mode = c("editor", "app"), + hide_header = FALSE, + exclude = "rsconnect/" ) { - check_v8_installed() stopifnot(fs::dir_exists(dir)) @@ -46,19 +45,50 @@ url_encode_dir <- function( } names <- fs::path_rel(files, path_root) - bundle <- unname(Map(as_file_list, files, names)) - + bundle <- jsonlite::toJSON(bundle, auto_unbox = TRUE, null = "null", na = "null") + URI <- lzstring::compressToEncodedURIComponent(bundle) + URI <- gsub("/", "-", URI) sprintf( "https://%s/%s/%s/#%scode=%s", getOption("shinylive.host", "shinylive.io"), language, mode, if (hide_header) "h=0&" else "", - lzstring_compress_uri(bundle) + URI ) } +url_decode <- function(encoded_url, dir = NULL, json = FALSE) { + url_in <- strsplit(encoded_url, "code=")[[1]][2] + sl_app <- lzstring::decompressFromEncodedURIComponent(url_in) + sl_app <- jsonlite::fromJSON(sl_app, simplifyVector = FALSE, simplifyDataFrame = FALSE, simplifyMatrix = FALSE) + if (json) { + sl_app <- jsonlite::toJSON(sl_app) + return(sl_app) + } + if (!is.null(dir)) { + write_files(sl_app, dir) + } else { + print(sl_app) + } +} + +write_files <- function(sl_app, dest) { + if (!fs::dir_exists(dest)) { + fs::dir_create(dest) + } + for (file in sl_app) { + if ("type" %in% names(file) && file[["type"]] == "binary") { + file_content <- base64enc::base64decode(file[["content"]]) + writeBin(file_content, file.path(dest, file[["name"]])) + } else { + file_content <- iconv(file[["content"]], "UTF-8", "UTF-8", sub = "") + writeLines(file_content, file.path(dest, file[["name"]])) + } + } + return(dest) +} as_file_list <- function(path, name = fs::path_file(path), type = NULL) { if (is.null(type)) { diff --git a/inst/lz-string/lz-string.min.js b/inst/lz-string/lz-string.min.js deleted file mode 100644 index f7c26ae..0000000 --- a/inst/lz-string/lz-string.min.js +++ /dev/null @@ -1 +0,0 @@ -var LZString=function(){var r=String.fromCharCode,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",e={};function t(r,o){if(!e[r]){e[r]={};for(var n=0;n>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null==o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;e>=1}else{for(t=1,e=0;e>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e>=1;0==--l&&(l=Math.pow(2,h),h++),s[p]=f++,c=String(a)}if(""!==c){if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e>=1}else{for(t=1,e=0;e>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e>=1;0==--l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;e>=1;for(;;){if(m<<=1,v==o-1){d.push(n(m));break}v++}return d.join("")},decompress:function(r){return null==r?"":""==r?null:i._decompress(r.length,32768,function(o){return r.charCodeAt(o)})},_decompress:function(o,n,e){var t,i,s,u,a,p,c,l=[],f=4,h=4,d=3,m="",v=[],g={val:e(0),position:n,index:1};for(t=0;t<3;t+=1)l[t]=t;for(s=0,a=Math.pow(2,2),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 2:return""}for(l[3]=c,i=c,v.push(c);;){if(g.index>o)return"";for(s=0,a=Math.pow(2,d),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(c=s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 2:return v.join("")}if(0==f&&(f=Math.pow(2,d),d++),l[c])m=l[c];else{if(c!==h)return null;m=i+i.charAt(0)}v.push(m),l[h++]=i+m.charAt(0),i=m,0==--f&&(f=Math.pow(2,d),d++)}}};return i}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 1cf89ae..0000000 --- a/package-lock.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "r-shinylive", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "lz-string": "^1.5.0" - } - }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "bin": { - "lz-string": "bin/bin.js" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 17c6876..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "lz-string": "^1.5.0" - } -} From c5b9913045ec7aafe3d7551ff999ba149966f06e Mon Sep 17 00:00:00 2001 From: parmsam Date: Tue, 18 Jun 2024 10:01:45 -0400 Subject: [PATCH 2/2] dont add new line at end of file via writelines --- R/url.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/url.R b/R/url.R index d8a7521..addd57a 100644 --- a/R/url.R +++ b/R/url.R @@ -84,7 +84,7 @@ write_files <- function(sl_app, dest) { writeBin(file_content, file.path(dest, file[["name"]])) } else { file_content <- iconv(file[["content"]], "UTF-8", "UTF-8", sub = "") - writeLines(file_content, file.path(dest, file[["name"]])) + writeLines(file_content, file.path(dest, file[["name"]]), sep = "") } } return(dest)