Readme

WASM Binary Host

https://maxm-wasmblobhost.web.val.run/

Where should you host your WASM blobs to use in vals? Host them here!

Upload with curl:

curl -X POST -H "Content-Type: application/wasm" \
  --data-binary @main.wasm https://maxm-wasmBlobHost.web.val.run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource https://esm.sh/react */
import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo?v=27";
import { blob } from "https://esm.town/v/std/blob?v=12";
import { Buffer } from "node:buffer";
import { createHash } from "node:crypto";
import base32Encode from "npm:base32-encode";
import { renderToString } from "npm:react-dom/server";
const { author, name } = extractValInfo(import.meta.url);
const WASM_BLOB_PREFIX = `${author}-${name}-wasm-wasm-blob-v1-`;
async function readAllBytes(stream: ReadableStream<Uint8Array>): Promise<Buffer> {
const reader = stream.getReader();
const chunks: Uint8Array[] = [];
let result: ReadableStreamReadResult<Uint8Array>;
while (!(result = await reader.read()).done) {
chunks.push(result.value);
}
// Concatenate all chunks into one Buffer
const concatenated = Buffer.concat(chunks.map(chunk => Buffer.from(chunk)));
return concatenated;
}
function getSha256Hash(buffer: Buffer): string {
return base32Encode(
createHash("sha256").update(buffer).digest().slice(0, 20),
"RFC4648",
{ padding: false },
).toLowerCase();
}
function trimPrefix(str, prefix) {
if (str.startsWith(prefix)) {
return str.slice(prefix.length);
}
return str;
}
function trimSuffix(str, suffix) {
if (str.endsWith(suffix)) {
return str.slice(0, -suffix.length);
}
return str;
}
const keyToURL = (key: string) => {
return `https://${author}-${name.toLowerCase()}.web.val.run/${trimPrefix(key, WASM_BLOB_PREFIX)}.wasm`;
};
const urlToKey = (url: string) => {
return WASM_BLOB_PREFIX
+ trimSuffix(trimPrefix(url, `https://${author}-${name.toLowerCase()}.web.val.run/`), ".wasm");
};
function formatBytes(bytes: number): string {
if (bytes === 0) return "0B";
const k = 1024;
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
const formatted = parseFloat((bytes / Math.pow(k, i)).toFixed(2));
return `${formatted}${sizes[i]}`;
}
function relativeTimeFromNow(dateString: string): string {
const now = new Date();
const date = new Date(dateString);
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
if (diffInSeconds < 60) {
return `${diffInSeconds}s ago`;
} else if (diffInSeconds < 3600) {
const diffInMinutes = Math.floor(diffInSeconds / 60);
return `${diffInMinutes}m ago`;
} else if (diffInSeconds < 86400) {
const diffInHours = Math.floor(diffInSeconds / 3600);
return `${diffInHours}h ago`;
} else {
const diffInDays = Math.floor(diffInSeconds / 86400);
return `${diffInDays}d ago`;
}
}
export default async function(req: Request): Promise<Response> {
if (req.method === "POST") {
const body = await readAllBytes(req.body);
// Check to be sure the binary body starts with "\0asm"
if (!body.slice(0, 4).equals(Buffer.from([0x00, 0x61, 0x73, 0x6D]))) {
return new Response("The request body is not a WASM binary", { status: 400 });
}
const key = WASM_BLOB_PREFIX + getSha256Hash(body);
await blob.set(key, body);
console.log(keyToURL(key));
return Response.json({ url: keyToURL(key) });
}
const url = new URL(req.url);
if (url.pathname === "/") {
const files = await blob.list(WASM_BLOB_PREFIX);
return new Response(
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
maxm-wasmblobhost.web.val.run
v81
May 24, 2024