diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index ddff4407b..000000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[build] -rustflags = ["-C", "target-cpu=native"] diff --git a/Cargo.lock b/Cargo.lock index ef894d9c1..047579134 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1171,9 +1171,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "libz-rs-sys", @@ -1301,9 +1301,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "allocator-api2", "equivalent", @@ -1481,7 +1481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "serde", ] @@ -1887,7 +1887,7 @@ checksum = "92e50218e74886659d1d13de8e6a4ff13c7e96924ed0017bc193a1feb8001b18" dependencies = [ "allocator-api2", "bumpalo", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "oxc_data_structures", "rustc-hash", ] @@ -2245,7 +2245,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca" dependencies = [ "fixedbitset", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "indexmap 2.9.0", "serde", ] @@ -2378,7 +2378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b450dad8382b1b95061d5ca1eb792081fb082adf48c678791fe917509596d5f" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.15.4", ] [[package]] @@ -2769,9 +2769,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smawk" diff --git a/README.md b/README.md index 287ffd75d..1af1092cf 100644 --- a/README.md +++ b/README.md @@ -31,17 +31,9 @@

-> **WARNING** -> -> This project is still a work in progress and while it's much better in many ways than its previous version ([kibo v0.5](https://github.com/kibo-money/kibo)), it doesn't yet include all of those datasets. If you're interested in having everything right now, please use the latter until feature parity is achieved. -> -> The explorer part (mempool.space/electrs) is also not viable just yet. -> -> Stay tuned and please be patient, it's a lot of work ! - The Bitcoin Research Kit is a high-performance toolchain designed to parse, index, compute, serve and visualize data from a Bitcoin Core node, enabling users to gain deeper insights into the Bitcoin network. -In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) and [electrs](https://github.com/romanz/electrs) all in one package with a particular focus on simplicity and the self-hosting experience. +In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) (soon) and [electrs](https://github.com/romanz/electrs) (soon) all in one package with a particular focus on simplicity and the self-hosting experience. The toolkit can be used in various ways to accommodate as many needs as possible: diff --git a/crates/brk_server/src/api/query/dts.rs b/crates/brk_server/src/api/query/dts.rs index 9d534dc24..7e3bdce11 100644 --- a/crates/brk_server/src/api/query/dts.rs +++ b/crates/brk_server/src/api/query/dts.rs @@ -2,7 +2,7 @@ use std::{fs, io, path::Path}; use brk_query::{Index, Query}; -use crate::Website; +use crate::{VERSION, Website}; const SCRIPTS: &str = "scripts"; @@ -31,10 +31,16 @@ impl DTS for Query<'static> { let indexes = Index::all(); - let mut contents = "// + let mut contents = format!( + "// // File auto-generated, any modifications will be overwritten -//\n\n" - .to_string(); +// + +export const VERSION = \"v{}\"; + +", + VERSION + ); contents += &indexes .iter() @@ -57,7 +63,7 @@ impl DTS for Query<'static> { contents += "\n\nexport function createVecIdToIndexes() {\n"; - contents += "\n\n return /** @type {const} */ ({\n"; + contents += " return /** @type {const} */ ({\n"; self.vec_trees .id_to_index_to_vec diff --git a/crates/brk_server/src/lib.rs b/crates/brk_server/src/lib.rs index b5907f5c8..e45096f00 100644 --- a/crates/brk_server/src/lib.rs +++ b/crates/brk_server/src/lib.rs @@ -45,10 +45,11 @@ pub struct AppState { websites_path: Option, } +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + const DEV_PATH: &str = "../.."; const DOWNLOADS: &str = "downloads"; const WEBSITES: &str = "websites"; -const VERSION: &str = env!("CARGO_PKG_VERSION"); pub struct Server(AppState); diff --git a/websites/default/scripts/main.js b/websites/default/scripts/main.js index 1d73cfc2f..b7459a1b5 100644 --- a/websites/default/scripts/main.js +++ b/websites/default/scripts/main.js @@ -2189,8 +2189,10 @@ function main() { createKeyDownEventListener(); packages.signals().then((signals) => - vecidToIndexesPromise.then(({ createVecIdToIndexes }) => + vecidToIndexesPromise.then(({ createVecIdToIndexes, VERSION }) => optionsPromise.then(async ({ initOptions }) => { + console.log(`VERSION = ${VERSION}`); + const vecIdToIndexes = createVecIdToIndexes(); if (env.localhost) { diff --git a/websites/default/scripts/options.js b/websites/default/scripts/options.js index 224d816d2..68acf26af 100644 --- a/websites/default/scripts/options.js +++ b/websites/default/scripts/options.js @@ -2795,10 +2795,6 @@ function createPartialOptions(colors) { { name: "Social", tree: [ - { - name: "Github", - url: () => "https://github.com/bitcoinresearchkit/brk", - }, { name: "Nostr", url: () => @@ -2867,6 +2863,10 @@ function createPartialOptions(colors) { url: () => "lightning:lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4", }, + { + name: "Geyser", + url: () => "https://geyser.fund/project/brk", + }, ], }, { diff --git a/websites/default/scripts/service-worker.js b/websites/default/scripts/service-worker.js index 489cce46f..88c62981a 100644 --- a/websites/default/scripts/service-worker.js +++ b/websites/default/scripts/service-worker.js @@ -1,76 +1,81 @@ -const version = "v1"; +const CACHE_NAME = "v1"; /** @type {ServiceWorkerGlobalScope} */ const sw = /** @type {any} */ (self); -sw.addEventListener("install", (_event) => { +sw.addEventListener("install", (event) => { console.log("sw: install"); - sw.skipWaiting(); + event.waitUntil(sw.skipWaiting()); }); sw.addEventListener("activate", (event) => { console.log("sw: active"); event.waitUntil(sw.clients.claim()); + event.waitUntil(caches.delete(CACHE_NAME)); }); +async function indexHTMLOrOffline() { + return caches.match("/index.html").then((cached) => { + if (cached) return cached; + return new Response("Offline and no cached version", { + status: 503, + statusText: "Service Unavailable", + headers: { "Content-Type": "text/plain" }, + }); + }); +} + sw.addEventListener("fetch", (event) => { - let request = event.request; - const method = request.method; - let url = request.url; + const req = event.request; + const url = new URL(req.url); - const { pathname, origin } = new URL(url); - - const slashMatches = url.match(/\//g); - const dotMatches = pathname.split("/").at(-1)?.match(/./g); - const endsWithDotHtml = pathname.endsWith(".html"); - const slashApiSlashMatches = url.match(/\/api\//g); - - if ( - slashMatches && - slashMatches.length <= 3 && - !slashApiSlashMatches && - (!dotMatches || endsWithDotHtml) - ) { - url = `${origin}/`; + // 1) Bypass API calls & non-GETs + if (req.method !== "GET" || url.pathname.startsWith("/api")) { + return; // let the browser handle it } - request = new Request(url, request.mode !== "navigate" ? request : undefined); - console.log(request); - - console.log(`service-worker: fetch ${url}`); - - event.respondWith( - caches.match(request).then(async (cachedResponse) => { - return fetch(request) + // 2) NAVIGATION: network‐first on your shell + if (req.mode === "navigate") { + event.respondWith( + // Always fetch index.html + fetch("/index.html") .then((response) => { - const { status, type } = response; - - if (method !== "GET" || slashApiSlashMatches) { - // API calls are cached in script.js - return response; - } else if ((status === 200 || status === 304) && type === "basic") { - if (status === 200) { - const clonedResponse = response.clone(); - caches.open(version).then((cache) => { - cache.put(request, clonedResponse); - }); + // If we got a valid 2xx back, cache it (optional) and return it + if (response.ok || response.status === 304) { + if (response.ok) { + const clone = response.clone(); + caches + .open(CACHE_NAME) + .then((cache) => cache.put("/index.html", clone)); } return response; - } else { - return cachedResponse || response; } + throw new Error("Non-2xx on shell"); }) - .catch(() => { - console.log("service-worker: offline"); + // On any failure, fall back to the cached shell + .catch(indexHTMLOrOffline), + ); + return; + } - return ( - cachedResponse || - new Response("Offline", { - status: 503, - statusText: "Service Unavailable", - }) - ); - }); - }), + // 3) For all other GETs: network-first, fallback to cache + event.respondWith( + fetch(req) + .then((response) => { + if (response.ok) { + const clone = response.clone(); + caches.open(CACHE_NAME).then((cache) => cache.put(req, clone)); + } + return response; + }) + .catch(async () => { + return caches + .match(req) + .then((cached) => { + return cached || indexHTMLOrOffline(); + }) + .catch(indexHTMLOrOffline); + }) + .catch(indexHTMLOrOffline), ); }); diff --git a/websites/default/scripts/vecid-to-indexes.js b/websites/default/scripts/vecid-to-indexes.js index ce6bb35c5..b2de0f376 100644 --- a/websites/default/scripts/vecid-to-indexes.js +++ b/websites/default/scripts/vecid-to-indexes.js @@ -2,6 +2,8 @@ // File auto-generated, any modifications will be overwritten // +export const VERSION = "v0.0.45"; + /** @typedef {0} DateIndex */ /** @typedef {1} DecadeIndex */ /** @typedef {2} DifficultyEpoch */ @@ -30,8 +32,6 @@ /** @typedef {DateIndex | DecadeIndex | DifficultyEpoch | EmptyOutputIndex | HalvingEpoch | Height | InputIndex | MonthIndex | OpReturnIndex | OutputIndex | P2AIndex | P2MSIndex | P2PK33Index | P2PK65Index | P2PKHIndex | P2SHIndex | P2TRIndex | P2WPKHIndex | P2WSHIndex | QuarterIndex | TxIndex | UnknownOutputIndex | WeekIndex | YearIndex} Index */ export function createVecIdToIndexes() { - - return /** @type {const} */ ({ "0": [0, 1, 2, 5, 7, 19, 22, 23], "0sats-adjusted-spent-output-profit-ratio": [0],