From ff573d1e145d13447106e05b45c8feeeef47ca4d Mon Sep 17 00:00:00 2001 From: Ian Thomas Date: Thu, 19 Feb 2026 13:09:36 +0000 Subject: [PATCH] Support use of local CORS proxy when serving the wasm deployments --- wasm/.gitignore | 2 +- wasm/CMakeLists.txt | 6 ++---- wasm/README.md | 9 +++++++++ wasm/cockle-deploy/CMakeLists.txt | 2 +- wasm/cockle-deploy/package.json | 8 ++++---- wasm/cockle-deploy/rspack.config.js | 2 +- wasm/cockle-deploy/src/defs.ts | 1 + wasm/cockle-deploy/src/deployment.ts | 11 ++++++++--- wasm/cockle-deploy/src/index.ts | 19 +++++++++++++++++-- wasm/cockle-deploy/tsconfig.json | 2 +- wasm/lite-deploy/CMakeLists.txt | 2 +- wasm/serve/CMakeLists.txt | 8 ++++++++ wasm/serve/{ => dist}/index.html | 0 wasm/serve/package.json | 17 +++++++++++++++++ 14 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 wasm/serve/CMakeLists.txt rename wasm/serve/{ => dist}/index.html (100%) create mode 100644 wasm/serve/package.json diff --git a/wasm/.gitignore b/wasm/.gitignore index 8f8b10f..838f04a 100644 --- a/wasm/.gitignore +++ b/wasm/.gitignore @@ -11,6 +11,6 @@ package-lock.json cockle/ lite-deploy/package.json recipe/em-forge-recipes/ -serve/*/ +serve/dist/*/ test/assets/*/ test/lib/ diff --git a/wasm/CMakeLists.txt b/wasm/CMakeLists.txt index a6d0df5..63d2b54 100644 --- a/wasm/CMakeLists.txt +++ b/wasm/CMakeLists.txt @@ -7,17 +7,15 @@ option(USE_COCKLE_RELEASE "Use latest cockle release rather than repo main branc add_subdirectory(recipe) add_subdirectory(cockle-deploy) add_subdirectory(lite-deploy) +add_subdirectory(serve) add_subdirectory(test) # Build everything (package, cockle and lite deployments, tests). -add_custom_target(build ALL DEPENDS build-recipe build-cockle build-lite build-test) +add_custom_target(build ALL DEPENDS build-recipe build-cockle build-lite build-serve build-test) # Rebuild after change in C++ code. add_custom_target(rebuild DEPENDS rebuild-recipe rebuild-cockle rebuild-lite rebuild-test) -# Serve both cockle and JupyterLite deployments. -add_custom_target(serve COMMAND npx static-handler --cors --coop --coep --corp serve) - if (USE_COCKLE_RELEASE) execute_process(COMMAND npm view @jupyterlite/cockle version OUTPUT_VARIABLE COCKLE_BRANCH) set(COCKLE_BRANCH "v${COCKLE_BRANCH}") diff --git a/wasm/README.md b/wasm/README.md index 75b828c..b8f94a8 100644 --- a/wasm/README.md +++ b/wasm/README.md @@ -65,6 +65,15 @@ Note that the `source` for the `git2cpp` package is the local filesystem rather version number of the current Emscripten-forge recipe rather than the version of the local `git2cpp` source code which can be checked using `git2cpp -v` at the `cockle`/`terminal` command line. +If you want to remotely access git servers using `git2cpp` subcommands such as `clone`, `fetch` +and `push`, then serve with a local CORS proxy using: + +```bash +make serve-with-cors +``` + +which will use the CORS proxy on `http://localhost:8881/`. + ## Rebuild After making changes to the local `git2cpp` source code you can rebuild the WebAssembly package, diff --git a/wasm/cockle-deploy/CMakeLists.txt b/wasm/cockle-deploy/CMakeLists.txt index 6a11bf9..ff5d26d 100644 --- a/wasm/cockle-deploy/CMakeLists.txt +++ b/wasm/cockle-deploy/CMakeLists.txt @@ -3,7 +3,7 @@ project(git2cpp-wasm-cockle-deploy) include("../common.cmake") -set(SERVE_DIR "../serve/cockle") +set(SERVE_DIR "../serve/dist/cockle") add_custom_target(build-cockle DEPENDS build-recipe cockle diff --git a/wasm/cockle-deploy/package.json b/wasm/cockle-deploy/package.json index 2700383..0c93ce2 100644 --- a/wasm/cockle-deploy/package.json +++ b/wasm/cockle-deploy/package.json @@ -3,11 +3,11 @@ "scripts": { "build": "rspack build", "postbuild": "npm run postbuild:wasm && npm run postbuild:index", - "postbuild:wasm": "node node_modules/@jupyterlite/cockle/lib/tools/prepare_wasm.js --copy ../serve/cockle/", - "postbuild:index": "cp assets/index.html ../serve/cockle/" + "postbuild:wasm": "node node_modules/@jupyterlite/cockle/lib/tools/prepare_wasm.js --copy ../serve/dist/cockle/", + "postbuild:index": "cp assets/index.html ../serve/dist/cockle/" }, - "main": "../serve/cockle/index.js", - "types": "../serve/cockle/index.d.ts", + "main": "../serve/dist/cockle/index.js", + "types": "../serve/dist/cockle/index.d.ts", "keywords": [], "author": "", "license": "ISC", diff --git a/wasm/cockle-deploy/rspack.config.js b/wasm/cockle-deploy/rspack.config.js index d6e29ff..7db8166 100644 --- a/wasm/cockle-deploy/rspack.config.js +++ b/wasm/cockle-deploy/rspack.config.js @@ -24,6 +24,6 @@ module.exports = { }, output: { filename: 'bundle.js', - path: path.resolve(__dirname, '../serve/cockle'), + path: path.resolve(__dirname, '../serve/dist/cockle'), } }; diff --git a/wasm/cockle-deploy/src/defs.ts b/wasm/cockle-deploy/src/defs.ts index a44acd7..4675963 100644 --- a/wasm/cockle-deploy/src/defs.ts +++ b/wasm/cockle-deploy/src/defs.ts @@ -6,5 +6,6 @@ export namespace IDeployment { browsingContextId: string; shellManager: IShellManager; targetDiv: HTMLElement; + useLocalCors?: string; } } diff --git a/wasm/cockle-deploy/src/deployment.ts b/wasm/cockle-deploy/src/deployment.ts index e10b1ca..b98a27f 100644 --- a/wasm/cockle-deploy/src/deployment.ts +++ b/wasm/cockle-deploy/src/deployment.ts @@ -1,4 +1,4 @@ -import { Shell } from '@jupyterlite/cockle' +import { IShell, Shell } from '@jupyterlite/cockle' import { FitAddon } from '@xterm/addon-fit' import { Terminal } from '@xterm/xterm' import { IDeployment } from './defs' @@ -22,13 +22,18 @@ export class Deployment { const { baseUrl, browsingContextId, shellManager } = options; - this._shell = new Shell({ + const shellOptions: IShell.IOptions = { browsingContextId, baseUrl, wasmBaseUrl: baseUrl, shellManager, outputCallback: this.outputCallback.bind(this), - }) + }; + if (options.useLocalCors) { + shellOptions.environment = { GIT_CORS_PROXY: options.useLocalCors }; + } + + this._shell = new Shell(shellOptions); } async start(): Promise { diff --git a/wasm/cockle-deploy/src/index.ts b/wasm/cockle-deploy/src/index.ts index ac63e63..95b6ab7 100644 --- a/wasm/cockle-deploy/src/index.ts +++ b/wasm/cockle-deploy/src/index.ts @@ -1,13 +1,28 @@ import { ShellManager } from '@jupyterlite/cockle'; import "./style/deployment.css" +import { IDeployment } from './defs'; import { Deployment } from "./deployment"; document.addEventListener("DOMContentLoaded", async () => { const baseUrl = window.location.href; const shellManager = new ShellManager(); const browsingContextId = await shellManager.installServiceWorker(baseUrl); - const targetDiv: HTMLElement = document.getElementById('targetdiv')!; - const playground = new Deployment({ baseUrl, browsingContextId, shellManager, targetDiv }); + + const options: IDeployment.IOptions = { + baseUrl, browsingContextId, shellManager, targetDiv + } + + // See if a local CORS proxy is available where we are expecting it by checking if it is there. + // This isn't good practice but is OK for local manual testing. + try { + const corsProxy = "http://localhost:8881/" + const response = await fetch(corsProxy); + if (response.ok && response.type == "cors") { + options.useLocalCors = corsProxy; + } + } catch (error) {} + + const playground = new Deployment(options); await playground.start(); }) diff --git a/wasm/cockle-deploy/tsconfig.json b/wasm/cockle-deploy/tsconfig.json index 89b3e89..4ab9763 100644 --- a/wasm/cockle-deploy/tsconfig.json +++ b/wasm/cockle-deploy/tsconfig.json @@ -13,7 +13,7 @@ "noUnusedLocals": true, "preserveWatchOutput": true, "resolveJsonModule": true, - "outDir": "../serve/cockle", + "outDir": "../serve/dist/cockle", "rootDir": "src", "strict": true, "strictNullChecks": true, diff --git a/wasm/lite-deploy/CMakeLists.txt b/wasm/lite-deploy/CMakeLists.txt index eb43121..f07c7f7 100644 --- a/wasm/lite-deploy/CMakeLists.txt +++ b/wasm/lite-deploy/CMakeLists.txt @@ -3,7 +3,7 @@ project(git2cpp-wasm-lite-deploy) include("../common.cmake") -set(SERVE_DIR "../serve/lite") +set(SERVE_DIR "../serve/dist/lite") add_custom_target(build-lite DEPENDS build-recipe cockle diff --git a/wasm/serve/CMakeLists.txt b/wasm/serve/CMakeLists.txt new file mode 100644 index 0000000..fab98ac --- /dev/null +++ b/wasm/serve/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.28) +project(git2cpp-wasm) + +add_custom_target(build-serve COMMAND npm install) + +# Serve both cockle and JupyterLite deployments. +add_custom_target(serve COMMAND npm run serve) +add_custom_target(serve-with-cors COMMAND npm run serve-with-cors) diff --git a/wasm/serve/index.html b/wasm/serve/dist/index.html similarity index 100% rename from wasm/serve/index.html rename to wasm/serve/dist/index.html diff --git a/wasm/serve/package.json b/wasm/serve/package.json new file mode 100644 index 0000000..93c2a33 --- /dev/null +++ b/wasm/serve/package.json @@ -0,0 +1,17 @@ +{ + "name": "serve", + "version": "1.0.0", + "license": "BSD-3-Clause", + "private": true, + "scripts": { + "serve": "npm run serve:basic", + "serve-with-cors": "COCKLE_LOCAL_CORS=1 concurrently 'npm run serve:basic' 'npm run serve:cors'", + "serve:basic": "npx static-handler --cors --coop --coep --corp dist", + "serve:cors": "HOST=localhost PORT=8881 node node_modules/cors-anywhere/server.js " + }, + "devDependencies": { + "concurrently": "^9.2.1", + "cors-anywhere": "^0.4.4", + "static-handler": "^0.5.3" + } +}