diff --git a/README.md b/README.md index 4c2bbd2..38a967d 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,9 @@ Make sure you have emscripten, git, and the various C build tools installed. The sudo apt install make cmake emscripten autoconf automake libtool pkg-config wget xxd ``` -The build script will generate `client/out/libcurl.js` as well as `client/out/libcurl_module.mjs`, which is an ES6 module. You can supply the following arguments to the build script to control the build: +The build script will generate `client/out/libcurl.js` as well as `client/out/libcurl.mjs`, which is an ES6 module. You can supply the following arguments to the build script to control the build: - `release` - Use all optimizations. -- `single_file` - Include the WASM binary in the outputted JS using base64. +- `single_file` - Include the WASM binary in the outputted JS using base64. - `all` - Build twice, once normally, and once as a single file. ## Javascript API: @@ -34,12 +34,19 @@ The build script will generate `client/out/libcurl.js` as well as `client/out/li To import the library, follow the build instructions in the previous section, and copy `client/out/libcurl.js` and `client/out/libcurl.wasm` to a directory of your choice. After the script is loaded, call `libcurl.load_wasm`, specifying the url of the `libcurl.wasm` file. ```html - + +``` + +Alternatively, prebuilt versions can be found on NPM and jsDelivr. You can use the following URLs to load libcurl.js from a third party CDN. +``` +https://cdn.jsdelivr.net/npm/libcurl.js@latest/libcurl.js +https://cdn.jsdelivr.net/npm/libcurl.js@latest/libcurl.wasm ``` To know when libcurl.js has finished loading, you can use the `libcurl_load` DOM event. ```js document.addEventListener("libcurl_load", ()=>{ + libcurl.set_websocket(`wss://${location.hostname}/ws/`); console.log("libcurl.js ready!"); }); ``` @@ -63,14 +70,12 @@ Most of the standard Fetch API's features are supported, with the exception of: To use WebSockets, create a `libcurl.WebSocket` object, which works identically to the regular [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) object. ```js let ws = new libcurl.WebSocket("wss://echo.websocket.org"); -ws.binaryType = "arraybuffer"; ws.addEventListener("open", () => { console.log("ws connected!"); ws.send("hello".repeat(128)); }); ws.addEventListener("message", (event) => { - let text = new TextDecoder().decode(event.data); - console.log(text); + console.log(event.data); }); ``` @@ -79,6 +84,7 @@ You can change the URL of the websocket proxy by using `libcurl.set_websocket`. ```js libcurl.set_websocket("ws://localhost:6001/"); ``` +If the websocket proxy URL is not set and one of the other API functions is called, an error will be thrown. ## Proxy Server: The proxy server consists of a standard [Wisp](https://github.com/MercuryWorkshop/wisp-protocol) server, allowing multiple TCP connections to share the same websocket. diff --git a/client/build.sh b/client/build.sh index c9e1a53..76bf163 100755 --- a/client/build.sh +++ b/client/build.sh @@ -82,7 +82,7 @@ sed -i "/__extra_libraries__/r $JAVSCRIPT_DIR/messages.js" $OUT_FILE sed -i "/__extra_libraries__/r $JAVSCRIPT_DIR/websocket.js" $OUT_FILE #apply patches -python3 scripts/patcher.py $FRAGMENTS_DIR $OUT_FILE +python3 tools/patch_js.py $FRAGMENTS_DIR $OUT_FILE #generate es6 module cp $OUT_FILE $ES6_FILE diff --git a/client/index.html b/client/index.html index a52feab..37c5d40 100644 --- a/client/index.html +++ b/client/index.html @@ -6,6 +6,7 @@ diff --git a/client/javascript/main.js b/client/javascript/main.js index 851fbdf..7821043 100644 --- a/client/javascript/main.js +++ b/client/javascript/main.js @@ -1,17 +1,35 @@ -//everything is wrapped in a function to prevent emscripten from polluting the global scope -window.libcurl = (function() { +/* +ading2210/libcurl.js - A port of libcurl to WASM for the browser. +Copyright (C) 2023 ading2210 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ if (typeof window === "undefined") { throw new Error("NodeJS is not supported. This only works inside the browser."); } +//everything is wrapped in a function to prevent emscripten from polluting the global scope +window.libcurl = (function() { + //emscripten compiled code is inserted here /* __emscripten_output__ */ //extra client code goes here /* __extra_libraries__ */ -var websocket_url = `wss://${location.hostname}/ws/`; +var websocket_url = null; var event_loop = null; var active_requests = 0; var wasm_ready = false; @@ -20,6 +38,9 @@ function check_loaded() { if (!wasm_ready) { throw new Error("wasm not loaded yet, please call libcurl.load_wasm first"); } + if (!websocket_url) { + throw new Error("websocket proxy url not set, please call libcurl.set_websocket"); + } } //a case insensitive dictionary for request headers @@ -50,10 +71,6 @@ class HeadersDict { } } -function is_str(obj) { - return typeof obj === 'string' || obj instanceof String; -} - function allocate_str(str) { return allocate(intArrayFromString(str), ALLOC_NORMAL); } @@ -247,7 +264,7 @@ async function libcurl_fetch(url, params={}) { } function set_websocket_url(url) { - check_loaded(); + websocket_url = url; if (!Module.websocket) { document.addEventListener("libcurl_load", () => { set_websocket_url(url); @@ -257,7 +274,6 @@ function set_websocket_url(url) { } function main() { - console.log("emscripten module loaded"); wasm_ready = true; _init_curl(); set_websocket_url(websocket_url); diff --git a/client/javascript/websocket.js b/client/javascript/websocket.js index 26f9094..d60fb22 100644 --- a/client/javascript/websocket.js +++ b/client/javascript/websocket.js @@ -3,6 +3,7 @@ class CurlWebSocket extends EventTarget { constructor(url, protocols=[]) { super(); + check_loaded(); if (!url.startsWith("wss://") && !url.startsWith("ws://")) { throw new SyntaxError("invalid url"); } diff --git a/client/npm/package.json b/client/package.json similarity index 91% rename from client/npm/package.json rename to client/package.json index 16d300c..a4f4d97 100644 --- a/client/npm/package.json +++ b/client/package.json @@ -1,8 +1,8 @@ { "name": "libcurl.js", - "version": "0.1.0", + "version": "0.1.1", "description": "An experimental port of libcurl to WebAssembly for use in the browser.", - "main": "index.js", + "main": "libcurl.mjs", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/client/publish.sh b/client/publish.sh index 1287029..58ae332 100755 --- a/client/publish.sh +++ b/client/publish.sh @@ -1,9 +1,10 @@ #!/bin/bash #publish libcurl.js as an npm package -#run build.sh first -cp npm/* out +./build.sh all + +cp package.json out cp ../README.md out cd out npm publish \ No newline at end of file diff --git a/client/scripts/patcher.py b/client/tools/patch_js.py similarity index 100% rename from client/scripts/patcher.py rename to client/tools/patch_js.py