wip: javascript benchmarking script

This commit is contained in:
Jeremy Wall 2025-03-30 21:18:08 -04:00
parent 943bff4b3d
commit 2c0453411e
3 changed files with 117 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use std::rc::Rc;
use axum::{extract::Path, routing::get, Json, Router};
use axum::{extract::Path, http::{self, Response}, response::{AppendHeaders, Html, IntoResponse}, routing::get, Json, Router};
use datamodel::Reference;
mod datamodel;
@ -63,6 +63,13 @@ async fn dummy_object(Path(addr): Path<String>) -> String {
format!("I am object {}", addr)
}
async fn get_client_js() -> impl IntoResponse {
(
[(http::header::CONTENT_TYPE, "application/javascript")],
include_str!("../static/client.js"),
)
}
pub fn endpoints() -> Router {
Router::new().nest(
"/api/v1",
@ -78,6 +85,8 @@ pub fn endpoints() -> Router {
.route("/{addr}", get(dummy_object))
),
)
.route("/lib/client.js", get(get_client_js))
.route("/ui/", get(|| async { Html(include_str!("../static/index.html")).into_response() }))
}
// TODO(jwall): Javascript test script

81
static/client.js Normal file
View File

@ -0,0 +1,81 @@
export { bootstrap };
// 1. Record a start time.
// 2. Load the bootstrap document.
// 3. Load all the content_addresses from the bootstrap.
// 4. Record the end time.
async function load_bootstrap() {
let response = await fetch("/api/v1/ref/all/username");
if (!response.ok) {
throw new Error("Network response was not ok: " + response.statusText);
}
return await response.json();
}
/**
* @param {String} dbName
* @param {Array<String>} storeNames
* @returns {Promise<IDBDatabase>}
*/
async function openDatabase(dbName, storeNames) {
return await new Promise((resolve, reject) => {
const request = indexedDB.open(dbName, 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
for (var storeName of storeNames) {
// Create the object store if it doesn't exist
if (!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName);
}
}
};
request.onsuccess = (event) => {
const db = event.target.result;
resolve(db);
};
request.onerror = (event) => {
reject(event.target.error);
};
});
}
/**
* @param {IDBObjectStore} store
* @param {Object} reference
*/
function load_reference_paths(store, reference) {
let root_path = reference.path;
return new Promise(async (resolve, reject) => {
if (reference.dependents) {
for (var dep of reference.dependents) {
await load_reference_paths(store, dep);
}
}
const request = store.put(JSON.stringify(reference), root_path);
request.onerror = (evt) => {
reject(evt.target.error);
console.log("Failed to store object", evt);
};
request.onsuccess = (evt) => {
resolve(evt.target.result);
};
});
}
async function bootstrap() {
const refStoreName = "references"
const objectStoreName = "objects"
const databaseName = "MerkleStore";
const start = new Date().getTime();
let root = await load_bootstrap();
let db = await openDatabase(databaseName, [refStoreName, objectStoreName]);
const transaction = db.transaction([refStoreName], "readwrite");
const store = transaction.objectStore(refStoreName);
load_reference_paths(store, root);
var end = new Date().getTime();
return end - start;
}

26
static/index.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bootstrap Time Display</title>
</head>
<body>
<h1>Bootstrap Time</h1>
<div id="bootstrap-time">Loading...</div>
<script src="/lib/client.js" type="module"></script>
<script type="module">
import { bootstrap } from '/lib/client.js';
document.addEventListener('DOMContentLoaded', async () => {
try {
const bootstrapTime = await bootstrap(); // This function should be defined in your JS file
document.getElementById('bootstrap-time').textContent = `Bootstrap Time: ${bootstrapTime} ms`;
} catch (error) {
console.error('Error loading bootstrap time:', error);
document.getElementById('bootstrap-time').textContent = 'Error loading bootstrap time';
}
});
</script>
</body>
</html>