Public
Edited
Dec 3, 2023
Importers
Insert cell
Insert cell
class CachedFetch {
constructor() {
this.db = SQLiteDatabaseClient.open();
this.initialize();
}
async initialize() {
const cache = await this.db;
await cache.query(`
CREATE TABLE IF NOT EXISTS cache (
key text PRIMARY KEY,
value text
)`);
}
async importZip(file) {
const array = new Uint8Array(await file.arrayBuffer());
const f = fflate.gunzipSync(array);
this.db = await SQLiteDatabaseClient.open(f);
}
import(file) {
this.db = SQLiteDatabaseClient.open(file);
}
async export() {
const cache = await this.db;
return cache._db.export();
}
async download() {
return DOM.download(
async () => new Blob([await this.export()]),
"cache.db"
);
}
async downloadZip() {
const gzip = fflate.gzipSync(await this.export());
return DOM.download(
new Blob([gzip], { type: "application/gzip" }),
"cache.zip"
);
}
/**
* Returns a hash code from a string
* @param {String} str The string to hash.
* @return {Number} A 32bit integer
* @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
*/
hashCode(str) {
let hash = 0;
for (let i = 0, len = str.length; i < len; i++) {
let chr = str.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
generateKey(url, options) {
const request = new Request(url, options);
return this.hashCode(
JSON.stringify({
url: request.url,
body: options?.body?.toString(),
method: request.method,
headers: request.headers
})
);
}
async fetch(url, options) {
const cache = await this.db;
const key = this.generateKey(url, options);
console.log(key);
const cachedResponse = await cache.query(
"SELECT value FROM cache WHERE key = $1",
[key]
);

if (cachedResponse.length > 0) {
return JSON.parse(cachedResponse[0].value);
}

const response = await fetch(url, options);
const data = await response;
const value = {
body: await data.text()
};
await cache.query("INSERT INTO cache (key, value) VALUES ($1, $2)", [
key,
JSON.stringify(value)
]);
return value;
}
}
Insert cell
cache = new CachedFetch()
Insert cell
viewof file = Inputs.file({ label: "Data" })
Insert cell
cache.importZip(file)
Insert cell
db = await cache.db
Insert cell
db
SELECT count(*) from cache
Insert cell
fflate = import("https://unpkg.com/fflate@0.8.1/esm/browser.js?module")
Insert cell
cache.downloadZip()
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more