Created
November 15, 2023 14:29
-
-
Save andy0130tw/76352f747f7a1d9b3210e9535db7e4a1 to your computer and use it in GitHub Desktop.
First try on WasmFS using petersalomonsen/wasm-git with emscripten 3.1.49
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// place this at src/routes/git-proxy/[...path]/+server.js | |
// modified from | |
// https://github.com/petersalomonsen/wasm-git/blob/master/examples/webserverwithgithubproxy.js | |
import https from 'node:https' | |
import { Readable } from 'node:stream' | |
import { error } from '@sveltejs/kit' | |
/** | |
* Simple webserver with proxy to github.com | |
*/ | |
/** @type {import('./$types').RequestHandler} */ | |
export function fallback({ params, request }) { | |
const { path: pathname } = params | |
const query = new URL(request.url).searchParams | |
const path = '/' + pathname + '?' + query | |
if (path.indexOf('git-upload') != -1 || | |
path.indexOf('git-receive') != -1) { | |
const options = { | |
hostname: 'github.com', | |
port: 443, | |
path: path, | |
method: request.method, | |
}; | |
console.log(`Proxying ${options.method} request to ${options.hostname} with path ${options.path}`); | |
return new Promise(resolve => { | |
const proxy = https.request(options, incoming => { | |
const readable = Readable.toWeb(incoming) | |
resolve(new Response(readable)) | |
}) | |
if (options.method == 'GET') { | |
proxy.end() | |
} else { | |
const requestBody = | |
/** @type {import('node:stream/web').ReadableStream<Uint8Array>} */ | |
(request.body) | |
Readable.fromWeb(requestBody).pipe(proxy, { end: true }) | |
} | |
}) | |
} else { | |
throw error(404, 'Not found') | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export {} | |
function assertZero(/** @type {any} */n) { | |
if (n !== 0) { | |
throw new Error(`Return value is not zero: ${n}`) | |
} | |
} | |
function calculateTotalSize( | |
/** @type {Record<number, Uint8Array | undefined>} */ map) { | |
let size = 0 | |
for (let buf of Object.values(map)) { | |
if (buf) size += buf.length | |
} | |
return size | |
} | |
// trick into that we are running in web (actually we are) | |
// @ts-ignore | |
self.window = {} | |
const Module = { | |
locateFile(s) { | |
if (s === 'lg2.wasm') { | |
s = 'lg2-wasmfs.wasm' | |
} | |
return '/' + s | |
}, | |
print(s) { | |
postMessage({type: 'print', value: s}) | |
}, | |
printErr(v) { | |
console.error(v) | |
}, | |
} | |
const module = await import('./lg2-wasmfs.js') | |
function makeAsyncFS(backends, JSFILEFS) { | |
function wrapBackendImplAt(ptr, opts) { | |
console.log(backends[ptr]) | |
return backends[ptr] | |
} | |
return { | |
createBackend(opts) { | |
const ptr = JSFILEFS.createBackend() | |
backends[ptr] = wrapBackendImplAt(ptr, opts) | |
return ptr | |
} | |
} | |
} | |
Module.onRuntimeInitialized = async () => { | |
const lg = Module | |
const { | |
FS, | |
JSFILEFS, | |
wasmFS$backends, | |
wasmFS$JSMemoryFiles } = Module | |
console.warn(Object.keys(Module)) | |
console.warn(Object.keys(FS)) | |
const ASYNCFS = makeAsyncFS(wasmFS$backends, JSFILEFS) | |
// to work around WasmFS's bug where newly-mounted FS has empty dir name | |
// causing all operations using CWD to behave weirdly, as of emscripten 3.1.49 | |
assertZero(FS.mount(ASYNCFS, { }, '/.xxx')) | |
assertZero(FS.rename('.xxx', 'working')) | |
assertZero(FS.chdir('/working')) | |
assertZero( | |
FS.writeFile('/home/web_user/.gitconfig', | |
'[user]\n' + | |
'name = Test User\n' + | |
'email = test@example.com')) | |
assertZero(FS.chdir('/working')) | |
console.log('dir', FS.cwd()) | |
const ref = 'ewxrjk/sftpserver' | |
const repoUrl = new URL(`/git-proxy/${ref}.git`, self.location.toString()).toString() | |
lg.callMain(['clone', repoUrl, 'testrepo']) | |
assertZero(FS.chdir('testrepo')) | |
lg.callMain(['log']) | |
postMessage({type: 'readdir', value: FS.readdir('.')}) | |
// console.warn(wasmFS$backends) | |
console.warn('total size', calculateTotalSize(wasmFS$JSMemoryFiles)) | |
} | |
await module.default(Module) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment