wip: Working experiment

This commit is contained in:
Jeremy Wall 2025-04-15 21:38:41 -04:00
parent a216275eb5
commit ade221003e
2 changed files with 67 additions and 25 deletions

View File

@ -133,7 +133,7 @@ async fn handle_socket(
)))
.await
{
eprintln!("Error sending bootstrap reference: {:?}", e);
println!("Error sending bootstrap reference: {:?}", e);
continue;
}
}
@ -143,11 +143,11 @@ async fn handle_socket(
.send(Message::Item(ServerMsg::Reference((**reference).clone())))
.await
{
eprintln!("Error sending reference: {:?}", e);
println!("Error sending reference: {:?}", e);
continue;
}
} else {
eprintln!("Reference not found: {}", path);
println!("Reference not found: {}", path);
}
}
Message::Item(ClientMsg::GetObject(address)) => {
@ -156,21 +156,21 @@ async fn handle_socket(
.send(Message::Item(ServerMsg::Object(object.content.clone())))
.await
{
eprintln!("Error sending object: {:?}", e);
println!("Error sending object: {:?}", e);
continue;
}
} else {
eprintln!("Object not found: {}", address);
println!("Object not found: {}", address);
}
}
Message::Ping(items) => {
eprintln!("unhandled ping msg: {:?}", items);
println!("unhandled ping msg: {:?}", items);
}
Message::Pong(items) => {
eprintln!("unhandled pong msg: {:?}", items);
println!("unhandled pong msg: {:?}", items);
}
Message::Close(_close_frame) => {
eprintln!("closing websocket connection at client request");
println!("closing websocket connection at client request");
break;
}
}
@ -206,7 +206,7 @@ pub fn endpoints(
pub async fn serve() {
// run our app with hyper, listening globally on port 3000
let (root_ref, refs, objects) = random_references_and_objects();
println!("Server starting on http://127.0.0.1:3000");
println!("Server ui starting on http://127.0.0.1:3000/ui/");
println!("WebSocket endpoint available at ws://127.0.0.1:3000/api/v1/ws");
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await

View File

@ -8,12 +8,44 @@ export { bootstrap };
* @property {string} content_address
*/
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);
/**
* @typedef {Object} ServerMsg
* @property {Reference?} Reference
* @property {string?} Object
*/
/**
* @param {WebSocket} socket
* @returns {Promise<ServerMsg>}
*/
async function load_bootstrap(socket) {
// Wait for the connection to be established
const data = await send_socket_msg(socket,
JSON.stringify("Bootstrap"));
return data;
}
return await response.json();
/**
* @param {WebSocket} socket
* @param {string} msg
* @returns {Promise<ServerMsg>}
*/
async function send_socket_msg(socket, msg) {
// Send a request for all references
socket.send(msg);
// Wait for the response
/** @type {Promise<String>} */
const stream = await new Promise((resolve, reject) => {
socket.onmessage = (event) => {
resolve(event.data.text());
};
socket.onerror = (_error) => reject(new Error("WebSocket error occurred"));
});
let data = await stream;
return JSON.parse(data);
}
/**
@ -72,7 +104,7 @@ function storeObject(store, reference, root_path) {
* @returns {Promise<Array<Reference>>} An array of references
*/
function load_reference_paths(refStore, reference) {
return new Promise(async (resolve, reject) => {
return new Promise(async (resolve, _reject) => {
let references = [];
references.push(reference);
if (reference.dependents) {
@ -87,23 +119,24 @@ function load_reference_paths(refStore, reference) {
}
/**
* @param {WebSocket} socket
* @param {IDBDatabase} db
* @param {string} storeName
* @param {Array<Reference>} references
*/
async function load_objects_and_store(db, references, storeName) {
async function load_objects_and_store(socket, db, references, storeName) {
let objects = []
for (var ref of references) {
/** @type {Response} */
if (ref.dependents && ref.dependents.length != 0) {
continue; // not a leaf object
}
let response = await fetch("/api/v1/object/" + ref.content_address);
if (!response.ok) {
throw new Error("Network response was not ok: " + response.statusText);
let data = await send_socket_msg(socket, JSON.stringify({ "GetObject": ref.content_address }));
if (!data.Object) {
throw { error: "Not an object" };
}
const object = await response.text();
objects.push({ id: ref.content_address, content: object });
objects.push({ id: ref.content_address, content: data.Object });
}
const objectTrxAndStore = await getStoreAndTransaction(db, storeName);
for (var obj of objects) {
@ -133,7 +166,16 @@ async function bootstrap() {
const objectStoreName = "objects";
const databaseName = "MerkleStore";
const start = new Date().getTime();
const root = await load_bootstrap();
const socket = new WebSocket(`ws://${window.location.host}/api/v1/ws`);
await new Promise((resolve, reject) => {
socket.onopen = () => resolve();
socket.onerror = (error) => reject(new Error("WebSocket connection failed" + error));
});
const data = await load_bootstrap(socket);
if (!data.Reference) {
throw { error: "Not a Reference" };
}
const db = await openDatabase(databaseName, [refStoreName, objectStoreName]);
const refTrxAndStore = await getStoreAndTransaction(db, refStoreName);
@ -143,12 +185,12 @@ async function bootstrap() {
refTrxAndStore.trx.onerror = (event) => reject(event.target.error);
});
const refs = await load_reference_paths(refTrxAndStore.store, root);
const refs = await load_reference_paths(refTrxAndStore.store, data.Reference);
// Wait for the transaction to complete
await transactionComplete;
await load_objects_and_store(db, refs, objectStoreName);
await load_objects_and_store(socket, db, refs, objectStoreName);
const end = new Date().getTime();
return end - start;