<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: quickjs</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/quickjs.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2024-04-08T19:44:20+00:00</updated><author><name>Simon Willison</name></author><entry><title>Introducing Enhance WASM</title><link href="https://simonwillison.net/2024/Apr/8/enhance-wasm/#atom-tag" rel="alternate"/><published>2024-04-08T19:44:20+00:00</published><updated>2024-04-08T19:44:20+00:00</updated><id>https://simonwillison.net/2024/Apr/8/enhance-wasm/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://begin.com/blog/posts/2024-04-08-introducing-enhance-wasm"&gt;Introducing Enhance WASM&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“Backend agnostic server-side rendering (SSR) for Web Components”—fascinating new project from Brian LeRoux and Begin.&lt;/p&gt;

&lt;p&gt;The idea here is to provide server-side rendering of Web Components using WebAssembly that can run on any platform that is supported within the Extism WASM ecosystem.&lt;/p&gt;

&lt;p&gt;The key is the enhance-ssr.wasm bundle, a 4.1MB WebAssembly version of the enhance-ssr JavaScript library, compiled using the Extism JavaScript PDK (Plugin Development Kit) which itself bundles a WebAssembly version of QuickJS.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://indieweb.social/@enhance_dev@fosstodon.org/112237109269781175"&gt;@enhance_dev@fosstodon.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/web-components"&gt;web-components&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webassembly"&gt;webassembly&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quickjs"&gt;quickjs&lt;/a&gt;&lt;/p&gt;



</summary><category term="javascript"/><category term="web-components"/><category term="webassembly"/><category term="quickjs"/></entry><entry><title>Weeknotes: a Datasette release, an LLM release and a bunch of new plugins</title><link href="https://simonwillison.net/2024/Feb/9/weeknotes/#atom-tag" rel="alternate"/><published>2024-02-09T23:59:06+00:00</published><updated>2024-02-09T23:59:06+00:00</updated><id>https://simonwillison.net/2024/Feb/9/weeknotes/#atom-tag</id><summary type="html">
    &lt;p&gt;I wrote extensive annotated release notes for &lt;a href="https://simonwillison.net/2024/Feb/7/datasette-1a8/"&gt;Datasette 1.0a8&lt;/a&gt; and &lt;a href="https://simonwillison.net/2024/Jan/26/llm/"&gt;LLM 0.13&lt;/a&gt; already. Here's what else I've been up to this past three weeks.&lt;/p&gt;
&lt;h4 id="new-plugins-datasette"&gt;New plugins for Datasette&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://datasette.io/plugins/datasette-proxy-url"&gt;datasette-proxy-url&lt;/a&gt;&lt;/strong&gt; is a very simple plugin that simple lets you configure a path within Datasette that serves content proxied from another URL.&lt;/p&gt;
&lt;p&gt;I built this one because I ran into a bug with Substack where Substack were denying requests to my newsletter's RSS feed from code running in GitHub Actions! Frustrating, since the whole &lt;em&gt;point&lt;/em&gt; of RSS is to be retrieved by bots.&lt;/p&gt;
&lt;p&gt;I solved it by deploying a quick proxy to a Datasette instance I already had up and running, effectively treating Datasette as a cheap deployment platform for random pieces of proxying infrastructure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://datasette.io/plugins/datasette-homepage-table"&gt;datasette-homepage-table&lt;/a&gt;&lt;/strong&gt; lets you configure Datasette to display a specific table as the homepage of the instance. I've wanted this for a while myself, someone requested it on &lt;a href="https://datasette.io/discord"&gt;Datasette Discord&lt;/a&gt; and it turned out to be pretty quick to build.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://datasette.io/plugins/datasette-events-db"&gt;datasette-events-db&lt;/a&gt;&lt;/strong&gt; hooks into the new &lt;a href="https://docs.datasette.io/en/1.0a8/plugin_hooks.html#event-tracking"&gt;events mechanism&lt;/a&gt; in Datasette 1.0a8 and logs any events (&lt;code&gt;create-table&lt;/code&gt;, &lt;code&gt;login&lt;/code&gt; etc) to a &lt;code&gt;datasette_events&lt;/code&gt; table. I released this partly as a debugging tool and partly because I like to ensure every Datasette plugin hook has at least one released plugin that uses it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://datasette.io/plugins/datasette-enrichments-quickjs"&gt;datasette-enrichments-quickjs&lt;/a&gt;&lt;/strong&gt; was this morning's project. It's a plugin for &lt;a href="https://simonwillison.net/2023/Dec/1/datasette-enrichments/"&gt;Datasette Enrichments&lt;/a&gt; that takes advantage of the &lt;a href="https://pypi.org/project/quickjs/"&gt;quickjs&lt;/a&gt; Python package - a wrapper around the excellent &lt;a href="https://bellard.org/quickjs/"&gt;QuickJS engine&lt;/a&gt; - to support running a custom JavaScript function against every row in a table to populate a new column.&lt;/p&gt;
&lt;p&gt;QuickJS appears to provide a robust sandbox, including both memory and time limits! I need to write more about this plugin, it opens up some very exciting new possibilities for Datasette.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also published some significant updates to existing plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://datasette.io/plugins/datasette-upload-csvs"&gt;datasette-upload-csvs&lt;/a&gt;&lt;/strong&gt; got a long-overdue improvement allowing it to upload CSVs to a specified database, rather than just using the first available one. As part of this I completely re-engineered how it works in terms of threading strategies, as described in &lt;a href="https://github.com/simonw/datasette-upload-csvs/issues/38"&gt;issue 38&lt;/a&gt;. Plus it's now tested against the Datasette 1.0 alpha series in addition to 0.x stable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="plugins-for-llm"&gt;Plugins for LLM&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://llm.datasette.io/"&gt;LLM&lt;/a&gt; is my command-line tool and Python library for interacting with Large Language Models. I released one new plugin for that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/llm-embed-onnx"&gt;llm-embed-onnx&lt;/a&gt;&lt;/strong&gt; is a thin wrapper on top of &lt;a href="https://github.com/taylorai/onnx_embedding_models"&gt;onnx_embedding_models&lt;/a&gt; by Benjamin Anderson which itself wraps the powerful &lt;a href="https://onnxruntime.ai/"&gt;ONNX Runtime&lt;/a&gt;. It makes several new embeddings models available for use with LLM, listed &lt;a href="https://github.com/simonw/llm-embed-onnx/blob/main/README.md#usage"&gt;in the README&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I released updates for two LLM plugins as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/simonw/llm-gpt4all"&gt;llm-gpt4all&lt;/a&gt;&lt;/strong&gt; got a release with improvements from three contributors. I'll quote &lt;a href="https://github.com/simonw/llm-gpt4all/releases/tag/0.3"&gt;the release notes&lt;/a&gt; in full:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Now provides access to model options such as &lt;code&gt;-o max_tokens 3&lt;/code&gt;. Thanks, &lt;a href="https://github.com/RangerMauve"&gt;Mauve Signweaver&lt;/a&gt;. &lt;a href="https://github.com/simonw/llm-gpt4all/issues/3"&gt;#3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Models now work without an internet connection. Thanks, &lt;a href="https://github.com/hydrosquall"&gt;Cameron Yick&lt;/a&gt;. &lt;a href="https://github.com/simonw/llm-gpt4all/issues/10"&gt;#10&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation now includes the location of the model files. Thanks, &lt;a href="https://github.com/slhck"&gt;Werner Robitza&lt;/a&gt;. &lt;a href="https://github.com/simonw/llm-gpt4all/pull/21"&gt;#21&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/simonw/llm-sentence-transformers"&gt;llm-sentence-transformers&lt;/a&gt;&lt;/strong&gt; now has a &lt;code&gt;llm sentence-transformers register --trust-remote-code&lt;/code&gt; option, which was necessary to support the newly released &lt;a href="https://huggingface.co/nomic-ai/nomic-embed-text-v1"&gt;nomic-embed-text-v1&lt;/a&gt; embedding model.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I finally started hacking on a &lt;code&gt;llm-rag&lt;/code&gt; plugin which will provide an implementation of Retrieval Augmented Generation for LLM, similar to the process I describe in &lt;a href="https://til.simonwillison.net/llms/embed-paragraphs"&gt;Embedding paragraphs from my blog with E5-large-v2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I'll write more about that once it's in an interesting state.&lt;/p&gt;
&lt;h4 id="shot-scraper-1.4"&gt;shot-scraper 1.4&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://shot-scraper.datasette.io/"&gt;shot-scraper&lt;/a&gt; is my CLI tool for taking screenshots of web pages and running scraping code against them using JavaScript, built on top of &lt;a href="https://playwright.dev/"&gt;Playwright&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I dropped into the repo to add HTTP Basic authentication support and found several excellent PRs waiting to be merged, so I bundled those together into a new release.&lt;/p&gt;
&lt;p&gt;Here are the full release notes for &lt;a href="https://github.com/simonw/shot-scraper/releases/tag/1.4"&gt;shot-scraper 1.4&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;New &lt;code&gt;--auth-username x --auth-password y&lt;/code&gt; options for each &lt;code&gt;shot-scraper&lt;/code&gt; command, allowing a username and password to be set for HTTP Basic authentication. &lt;a href="https://github.com/simonw/shot-scraper/issues/140"&gt;#140&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shot-scraper URL --interactive&lt;/code&gt; mode now respects the &lt;code&gt;-w&lt;/code&gt; and &lt;code&gt;-h&lt;/code&gt; arguments setting the size of the browser viewport. Thanks, &lt;a href="https://github.com/mhalle"&gt;mhalle&lt;/a&gt;. &lt;a href="https://github.com/simonw/shot-scraper/issues/128"&gt;#128&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;--scale-factor&lt;/code&gt; option for setting scale factors other than 2 (for retina). Thanks, &lt;a href="https://github.com/nielthiart"&gt;Niel Thiart&lt;/a&gt;. &lt;a href="https://github.com/simonw/shot-scraper/issues/136"&gt;#136&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;--browser-arg&lt;/code&gt; option for passing extra browser arguments (such as &lt;code&gt;--browser-args "--font-render-hinting=none"&lt;/code&gt;) through to the underlying browser. Thanks, &lt;a href="https://github.com/nielthiart"&gt;Niel Thiart&lt;/a&gt;. &lt;a href="https://github.com/simonw/shot-scraper/issues/137"&gt;#137&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 id="misc-other-projects"&gt;Miscellaneous other projects&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;We had some pretty severe storms in the San Francisco Bay Area last week, inspired me to revisit &lt;a href="https://github.com/simonw/shot-scraper/releases/tag/1.4"&gt;my old PG&amp;amp;E outage scraper&lt;/a&gt;. PG&amp;amp;E's outage map changed and broke that a couple of years ago, but I got &lt;a href="https://github.com/simonw/pge-outages"&gt;a new scraper up&lt;/a&gt; and running just in time to start capturing outages.&lt;/li&gt;
&lt;li&gt;I've been wanting a way to quickly create additional labels for my GitHub repositories for a while. I finally put together a simple system for that based on GitHub Actions, described in this TIL: &lt;a href="https://til.simonwillison.net/github-actions/creating-github-labels"&gt;Creating GitHub repository labels with an Actions workflow&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="weeknotes-feb-9-releases"&gt;Releases&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/datasette/datasette-enrichments-quickjs/releases/tag/0.1a0"&gt;datasette-enrichments-quickjs 0.1a0&lt;/a&gt;&lt;/strong&gt; - 2024-02-09&lt;br /&gt;Enrich data with a custom JavaScript function&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/datasette/datasette-events-db/releases/tag/0.1a0"&gt;datasette-events-db 0.1a0&lt;/a&gt;&lt;/strong&gt; - 2024-02-08&lt;br /&gt;Log Datasette events to a database table&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/datasette/releases/tag/1.0a8"&gt;datasette 1.0a8&lt;/a&gt;&lt;/strong&gt; - 2024-02-07&lt;br /&gt;An open source multi-tool for exploring and publishing data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/shot-scraper/releases/tag/1.4"&gt;shot-scraper 1.4&lt;/a&gt;&lt;/strong&gt; - 2024-02-05&lt;br /&gt;A command-line utility for taking automated screenshots of websites&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/llm-sentence-transformers/releases/tag/0.2"&gt;llm-sentence-transformers 0.2&lt;/a&gt;&lt;/strong&gt; - 2024-02-04&lt;br /&gt;LLM plugin for embeddings using sentence-transformers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/datasette/datasette-homepage-table/releases/tag/0.2"&gt;datasette-homepage-table 0.2&lt;/a&gt;&lt;/strong&gt; - 2024-01-31&lt;br /&gt;Show a specific Datasette table on the homepage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/datasette-upload-csvs/releases/tag/0.9"&gt;datasette-upload-csvs 0.9&lt;/a&gt;&lt;/strong&gt; - 2024-01-30&lt;br /&gt;Datasette plugin for uploading CSV files and converting them to database tables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/llm-embed-onnx/releases/tag/0.1"&gt;llm-embed-onnx 0.1&lt;/a&gt;&lt;/strong&gt; - 2024-01-28&lt;br /&gt;Run embedding models using ONNX&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/llm/releases/tag/0.13.1"&gt;llm 0.13.1&lt;/a&gt;&lt;/strong&gt; - 2024-01-27&lt;br /&gt;Access large language models from the command-line&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/llm-gpt4all/releases/tag/0.3"&gt;llm-gpt4all 0.3&lt;/a&gt;&lt;/strong&gt; - 2024-01-24&lt;br /&gt;Plugin for LLM adding support for the GPT4All collection of models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/simonw/datasette-granian/releases/tag/0.1"&gt;datasette-granian 0.1&lt;/a&gt;&lt;/strong&gt; - 2024-01-23&lt;br /&gt;Run Datasette using the Granian HTTP server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/datasette/datasette-proxy-url/releases/tag/0.1.1"&gt;datasette-proxy-url 0.1.1&lt;/a&gt;&lt;/strong&gt; - 2024-01-23&lt;br /&gt;Proxy a URL through a Datasette instance&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="weeknotes-feb-9-tils"&gt;TILs&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://til.simonwillison.net/github-actions/creating-github-labels"&gt;Creating GitHub repository labels with an Actions workflow&lt;/a&gt; - 2024-02-09&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://til.simonwillison.net/llms/colbert-ragatouille"&gt;Exploring ColBERT with RAGatouille&lt;/a&gt; - 2024-01-28&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://til.simonwillison.net/httpx/openai-log-requests-responses"&gt;Logging OpenAI API requests and responses using HTTPX&lt;/a&gt; - 2024-01-26&lt;/li&gt;
&lt;/ul&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datasette"&gt;datasette&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/weeknotes"&gt;weeknotes&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/shot-scraper"&gt;shot-scraper&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm"&gt;llm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quickjs"&gt;quickjs&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/enrichments"&gt;enrichments&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="projects"/><category term="datasette"/><category term="weeknotes"/><category term="shot-scraper"/><category term="llm"/><category term="quickjs"/><category term="enrichments"/></entry></feed>