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],