

{"id":13849,"date":"2023-03-21T12:40:55","date_gmt":"2023-03-21T17:40:55","guid":{"rendered":"https:\/\/rud.is\/b\/?p=13849"},"modified":"2023-03-21T12:40:55","modified_gmt":"2023-03-21T17:40:55","slug":"youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/","title":{"rendered":"You&#8217;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites"},"content":{"rendered":"<p>After writing the initial version of a <a href=\"https:\/\/rud.is\/w\/bind\/\">tutorial on wrapping and binding R functions on the javascript side of WebR<\/a>, I had a number of other WebR projects on the TODO list. But, I stuck around noodling on the whole &#8220;wrapping &amp; binding&#8221; thing, and it dawned on me that there was a &#8220;pretty simple&#8221; way to make R functions available to javascript using javascript&#8217;s <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Function\/Function\">Function()<\/a> constructor. I&#8217;ll eventually get this whole thing into the <a href=\"https:\/\/github.com\/hrbrmstr\/webr-experiments\">GH webr-experiments repo<\/a>, but you can see below and just <a href=\"view-source:https:\/\/rud.is\/w\/bind\/main.js\">view-source<\/a> (it&#8217;s as of the time of this post, in the 130&#8217;s re: line #&#8217;s) to check it out before that.<\/p>\n<h3>Dynamic JavaScript Function Creation<\/h3>\n<p>The <code>Function()<\/code> constructor has many modes, one of which involves providing the whole function source and letting it build a function for you. R folks likely know you can do that in R (ref: <a href=\"https:\/\/github.com\/hrbrmstr\/curlconverter\/blob\/94164d67bf68dd936a27029f95f91b946469de3f\/R\/utils.r#L134-L142\">my {curlconverter} pkg<\/a>), and it&#8217;s as straightforward on the javascript side. Open up DevTools Console and enter this:<\/p>\n<pre><code class=\"language-js\">const sayHello = new Function('return function (name) { return `Hello, ${name}` }')();\n<\/code><\/pre>\n<p>then call the function with some string value.<\/p>\n<p>We only need one input to create a dynamic R function wrapper (for SUPER BASIC R functions ONLY). Yes, I truly mean that you can just do this:<\/p>\n<pre><code class=\"language-js\">let rbeta = await wrapRFunction(\"rbeta\");\nawait rbeta(10, 1, 1, 0)\n<\/code><\/pre>\n<p>and get back the result in the way WebR&#8217;s <code>toJs()<\/code> function returns R objects:<\/p>\n<pre><code class=\"language-js\">{\n  \"type\": \"double\",\n  \"names\": null,\n  \"values\": [\n    0.9398577840605595,\n    0.42045006265859153,\n    0.26946718094298633,\n    0.3913958406551122,\n    0.8123499099597378,\n    0.49116132695862963,\n    0.754970193716774,\n    0.2952198011408607,\n    0.11734111483990002,\n    0.6263863870230043\n  ]\n}\n<\/code><\/pre>\n<h3>Formal Attire<\/h3>\n<p>R&#8217;s <code>formals()<\/code> function will let us get the argument list to a function, including any default values. We won&#8217;t be using them in this MVP version of the auto-wrapper, but I see no reason we couldn&#8217;t do that in a later iteration. It&#8217;s &#8220;easy&#8221; to make that a javascript function &#8220;the hard way&#8221;:<\/p>\n<pre><code class=\"language-js\">async function formals(rFunctionName) {\n  let result = await globalThis.webR.evalR(`formals(${rFunctionName})`);\n  let output = await result.toJs();\n  return(Promise.resolve(output))\n}\n<\/code><\/pre>\n<p>Now, we just need to use those names to construct the function. This is an ugly little function, but it&#8217;s really just doing some basic things:<\/p>\n<pre><code class=\"language-js\">async function wrapRFunction(rFunctionName) {\n  let f = await formals(rFunctionName)\n  let argNames = f.names.filter(argName =&gt; argName != '...');\n  let params = argNames.join(', ')\n  let env = argNames.map(name =&gt; `${name}: ${name}`).join(', ');\n  let fbody =\n  `return async function ${rFunctionName}(${params}) {\n    let result = await globalThis.webR.evalR(\n      '${rFunctionName}(${params})',\n      { env: { ${env} }}\n   );\n    let output = await result.toJs();\n    globalThis.webR.destroy(result);\n    return Promise.resolve(output);\n  }`;\n  return new Function(fbody)()\n}\n<\/code><\/pre>\n<ul>\n<li>first, we get the formals for the function name provided to us<\/li>\n<li>then we remove ones we can&#8217;t handle (yet!)<\/li>\n<li>then we take the R function parameter names and make two objects:\n<ul>\n<li>one that will make a comma-separated parameter declaration list (e.g. <code>param1, param2, param3<\/code>)<\/li>\n<li>another that does the same, but as <code>key: value<\/code> pairs to pass as the environment (see previous WebR blog posts and experiments)<\/li>\n<\/ul>\n<\/li>\n<li>the function body is another template string that just makes the standard WebR set operations to evaluate an R object and get the value back.<\/li>\n<\/ul>\n<p>We pass the built function string to the <code>Function()<\/code> constructor, and we have an automagic javascript wrapper for it.<\/p>\n<h3>FIN<\/h3>\n<p>This is a <em>very<\/em> naive wrapper. It&#8217;s all on the caller to specify <em>all<\/em> the values. R has some fun features, like the ability to not specify a value for a given parameter, and then check on the R side to see if it&#8217;s missing. It can also intermix named and positional parameters, and then there&#8217;s the dreaded <code>...<\/code>.<\/p>\n<p>I&#8217;m going to noodle a bit more on how best to account and\/or implement ^^, but I&#8217;ll 100% be using this idiom to wrap R functions as I keep experimenting.<\/p>\n<p>One more thing: I had to abandon the use of the <code>microlight<\/code> syntax highlighter. It&#8217;s super tiny and fast, but it doesn&#8217;t handle the code I need, so I&#8217;ll be updating my nascent <a href=\"https:\/\/github.com\/hrbrmstr\/webr-template\">webr-template<\/a> to incorporate what I am using now: <a href=\"https:\/\/shiki.matsu.io\/\">Shiki<\/a>. The next release will also include these basic wrapper functions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After writing the initial version of a tutorial on wrapping and binding R functions on the javascript side of WebR, I had a number of other WebR projects on the TODO list. But, I stuck around noodling on the whole &#8220;wrapping &amp; binding&#8221; thing, and it dawned on me that there was a &#8220;pretty simple&#8221; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[91,867],"tags":[],"class_list":["post-13849","post","type-post","status-publish","format-standard","hentry","category-r","category-webr"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>You&#039;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"You&#039;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites - rud.is\" \/>\n<meta property=\"og:description\" content=\"After writing the initial version of a tutorial on wrapping and binding R functions on the javascript side of WebR, I had a number of other WebR projects on the TODO list. But, I stuck around noodling on the whole &#8220;wrapping &amp; binding&#8221; thing, and it dawned on me that there was a &#8220;pretty simple&#8221; [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2023-03-21T17:40:55+00:00\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"You&#8217;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\\\/Sites\",\"datePublished\":\"2023-03-21T17:40:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/\"},\"wordCount\":572,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"articleSection\":[\"R\",\"webr\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/\",\"name\":\"You're One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\\\/Sites - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"datePublished\":\"2023-03-21T17:40:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2023\\\/03\\\/21\\\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"You&#8217;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\\\/Sites\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rud.is\\\/b\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\\\/\\\/rud.is\"],\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/author\\\/hrbrmstr\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"You're One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/","og_locale":"en_US","og_type":"article","og_title":"You're One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites - rud.is","og_description":"After writing the initial version of a tutorial on wrapping and binding R functions on the javascript side of WebR, I had a number of other WebR projects on the TODO list. But, I stuck around noodling on the whole &#8220;wrapping &amp; binding&#8221; thing, and it dawned on me that there was a &#8220;pretty simple&#8221; [&hellip;]","og_url":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/","og_site_name":"rud.is","article_published_time":"2023-03-21T17:40:55+00:00","author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"You&#8217;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites","datePublished":"2023-03-21T17:40:55+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/"},"wordCount":572,"commentCount":1,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"articleSection":["R","webr"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/","url":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/","name":"You're One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"datePublished":"2023-03-21T17:40:55+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2023\/03\/21\/youre-one-javascript-function-call-away-from-using-most-webr-r-functions-in-your-webr-powered-apps-sites\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"You&#8217;re One JavaScript Function Call Away From Using (Most) WebR R Functions In Your WebR-Powered Apps\/Sites"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-3Bn","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":13789,"url":"https:\/\/rud.is\/b\/2023\/03\/12\/almost-bare-bones-webr-starter-app\/","url_meta":{"origin":13849,"position":0},"title":"Almost Bare Bones WebR Starter App","author":"hrbrmstr","date":"2023-03-12","format":false,"excerpt":"Let's walk through how to set up a ~minimal HTML\/JS\/CSS + WebR-powered \"app\" on a server you own. This will be vanilla JS (i.e. no React\/Vue\/npm\/bundler) you can hack on at-will. TL;DR: You can find the source to the app and track changes to it over on GitHub if you\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"screenshot of the example webr app showing a portion of mtcars","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-12-at-10.24.18.png?fit=1200%2C772&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-12-at-10.24.18.png?fit=1200%2C772&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-12-at-10.24.18.png?fit=1200%2C772&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-12-at-10.24.18.png?fit=1200%2C772&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-12-at-10.24.18.png?fit=1200%2C772&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":13860,"url":"https:\/\/rud.is\/b\/2023\/03\/25\/linking-lits-lightweight-web-components-and-webr-for-vanilla-js-reactivity\/","url_meta":{"origin":13849,"position":1},"title":"Linking Lit&#8217;s Lightweight Web Components And WebR For Vanilla JS Reactivity","author":"hrbrmstr","date":"2023-03-25","format":false,"excerpt":"See it live before reading! This is a Lit + WebR reproduction of the OG Shiny Demo App Lit is a javascript library that makes it a bit easier to work with Web Components, and is especially well-suited in reactive environments. My recent hack-y WebR experiments have been using Reef\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"some descriptive text you can read at the linked url in the post. there's also a popup menu and a barplot.","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/lit-webr-phones.png?fit=1200%2C972&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/lit-webr-phones.png?fit=1200%2C972&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/lit-webr-phones.png?fit=1200%2C972&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/lit-webr-phones.png?fit=1200%2C972&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/lit-webr-phones.png?fit=1200%2C972&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":13773,"url":"https:\/\/rud.is\/b\/2023\/03\/09\/webr-is-here\/","url_meta":{"origin":13849,"position":2},"title":"WebR IS HERE!","author":"hrbrmstr","date":"2023-03-09","format":false,"excerpt":"WebR 0.1.0 was released! I had been git-stalking George (the absolute genius who we all must thank for this) for a while and noticed the GH org and repos being updated earlier this week, So, I was already pretty excited. It dropped today, and you can hit that link for\u2026","rel":"","context":"In &quot;d3&quot;","block_context":{"text":"d3","link":"https:\/\/rud.is\/b\/category\/d3\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13845,"url":"https:\/\/rud.is\/b\/2023\/03\/20\/webr-filesystem-and-reefr\/","url_meta":{"origin":13849,"position":3},"title":"WebR Filesystem Machinations &#038; ReefR","author":"hrbrmstr","date":"2023-03-20","format":false,"excerpt":"It's difficult to believe it has only been a couple of weeks since WebR has been around. But that might just be my perception. The spike protein invasion has significantly increased sedentary time, and that has enabled me to focus on this new toy to keep my attention focused on\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":13834,"url":"https:\/\/rud.is\/b\/2023\/03\/18\/the-road-to-ggplot2-in-webr-part-1-the-road-is-paved-with-good-base-r-plots\/","url_meta":{"origin":13849,"position":4},"title":"The Road To ggplot2 In WebR, Part 1: The Road Is Paved With Good Base R Plots","author":"hrbrmstr","date":"2023-03-18","format":false,"excerpt":"I have graphics working in Vanilla JS WebR, now, and I'll cover the path to that in two parts. The intent was to jump straight into ggplot2-land, but, as you saw in my previous post, WASM'd ggplot2 is a bear. And, I really didn't grok what the WebR site docs\u2026","rel":"","context":"In &quot;ggplot&quot;","block_context":{"text":"ggplot","link":"https:\/\/rud.is\/b\/category\/ggplot\/"},"img":{"alt_text":"WebR plot example with a faceted scatterplot","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-18-at-10.10.23.png?fit=974%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-18-at-10.10.23.png?fit=974%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-18-at-10.10.23.png?fit=974%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/Screenshot-2023-03-18-at-10.10.23.png?fit=974%2C1200&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":13824,"url":"https:\/\/rud.is\/b\/2023\/03\/18\/webr-wasm-r-package-load-library-benchmarking-rabbit-hole\/","url_meta":{"origin":13849,"position":5},"title":"WebR WASM R Package Load\/Library Benchmarking Rabbit Hole","author":"hrbrmstr","date":"2023-03-18","format":false,"excerpt":"I have a post coming on using base and {ggplot2} plots in VanillaJS WebR, but after posting some bits on social media regarding how slow {ggplot2} is to deal with, I had some \"performance\"-related inquiries, which led me down a rabbit hole that I'm, now, dragging y'all down into as\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/rud.is\/b\/category\/javascript\/"},"img":{"alt_text":"Histogram of WASM R package load times. Most load in well under 1s","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/pkgload.png?fit=1200%2C869&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/pkgload.png?fit=1200%2C869&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/pkgload.png?fit=1200%2C869&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/pkgload.png?fit=1200%2C869&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/03\/pkgload.png?fit=1200%2C869&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/13849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=13849"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/13849\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=13849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=13849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=13849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}