Last active
April 9, 2024 08:24
-
-
Save SaulDoesCode/032040fcb2b1e6b282934fd11f352e53 to your computer and use it in GitHub Desktop.
proxydb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use dashmap::DashMap; | |
use serde::{Deserialize, Serialize}; | |
use std::fs; | |
use std::path::Path; | |
use tokio::io::{AsyncReadExt, AsyncWriteExt}; | |
#[derive(Serialize, Deserialize)] | |
struct Data { | |
// Your data structure here | |
} | |
struct DiskBackedDashMap { | |
map: DashMap<String, Data>, | |
dir: String, | |
} | |
impl DiskBackedDashMap { | |
async fn new(dir: &str) -> DiskBackedDashMap { | |
let map = DashMap::new(); | |
let dir = dir.to_string(); | |
// Load existing data from disk | |
if let Ok(entries) = fs::read_dir(&dir) { | |
for entry in entries { | |
if let Ok(entry) = entry { | |
let path = entry.path(); | |
if path.is_file() { | |
if let Ok(mut file) = tokio::fs::File::open(&path).await { | |
let mut contents = String::new(); | |
if let Ok(_) = file.read_to_string(&mut contents).await { | |
if let Ok(data) = serde_json::from_str::<Data>(&contents) { | |
let key = entry.file_name().into_string().unwrap(); | |
map.insert(key, data); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
DiskBackedDashMap { map, dir } | |
} | |
async fn get(&self, key: &str) -> Option<Data> { | |
self.map.get(key).map(|v| v.clone()) | |
} | |
async fn set(&self, key: &str, value: Data) { | |
self.map.insert(key.to_string(), value.clone()); | |
let filepath = format!("{}/{}.json", self.dir, key); | |
if let Ok(mut file) = tokio::fs::File::create(filepath).await { | |
let _ = file.write_all(serde_json::to_string(&value).unwrap().as_bytes()).await; | |
} | |
} | |
} | |
// Usage: | |
// #[tokio::main] | |
// async fn main() { | |
// let dbdm = DiskBackedDashMap::new("./data").await; | |
// dbdm.set("test", Data { /* your data here */ }).await; | |
// println!("{:?}", dbdm.get("test").await); | |
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function proxdb(obj, dir) { | |
let index | |
const indexPath = `${dir}/index.json` | |
// Load existing index or create a new one | |
try { | |
const data = localStorage.getItem(indexPath) | |
index = JSON.parse(data) | |
} catch (error) { | |
index = {} | |
} | |
return new Proxy(obj, { | |
get: (target, prop) => { | |
if (target[prop]) return target[prop] | |
try { | |
const filename = index[prop] | |
const data = localStorage.getItem(`${dir}/${filename}.json`) | |
target[prop] = JSON.parse(data) | |
if (typeof target[prop] === 'object' && target[prop] !== null) | |
target[prop] = proxdb(target[prop], dir) | |
return target[prop] | |
} catch (error) { | |
return undefined | |
} | |
}, | |
set: (target, prop, value) => { | |
if (typeof value === 'object' && value !== null) value = proxdb(value, dir) | |
target[prop] = value | |
let filename = index[prop] || prop, filepath = `${dir}/${filename}.json` | |
localStorage.setItem(filepath, JSON.stringify(value)) | |
let oldIndex = { ...index } | |
index[prop] = filename | |
// Update index only if it has changed | |
if (JSON.stringify(oldIndex) !== JSON.stringify(index)) localStorage.setItem(indexPath, JSON.stringify(index)) | |
return true | |
} | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs').promises, path = require('path') | |
async function proxdb(obj, dir) { | |
try { | |
await fs.access(dir) | |
} catch (error) { | |
await fs.mkdir(dir) | |
} | |
let index | |
const indexPath = path.join(dir, 'index.json') | |
// Load existing index or create a new one | |
try { | |
const data = await fs.readFile(indexPath, 'utf8') | |
index = JSON.parse(data) | |
} catch (error) { | |
index = {} | |
} | |
return new Proxy(obj, { | |
get: async (target, prop) => { | |
if (target[prop]) return target[prop] | |
try { | |
const filename = index[prop], data = await fs.readFile(path.join(dir, `${filename}.json`), 'utf8') | |
target[prop] = JSON.parse(data) | |
if (typeof target[prop] === 'object' && target[prop] !== null) | |
target[prop] = await proxdb(target[prop], dir) | |
return target[prop] | |
} catch (error) { | |
return undefined | |
} | |
}, | |
set: async (target, prop, value) => { | |
if (typeof value === 'object' && value !== null) value = await proxdb(value, dir) | |
target[prop] = value | |
let filename = index[prop] || prop, filepath = path.join(dir, `${filename}.json`) | |
await fs.writeFile(filepath, JSON.stringify(value)) | |
let oldIndex = { ...index } | |
index[prop] = filename | |
// Update index only if it has changed | |
if (JSON.stringify(oldIndex) !== JSON.stringify(index)) await fs.writeFile(indexPath, JSON.stringify(index)) | |
return true | |
} | |
}) | |
} | |
// Usage: | |
// (async () => { | |
// const obj = {}; | |
// const proxy = await proxdb(obj, './data'); | |
// proxy.test = { a: 1, b: { c: 2, d: 3 } }; | |
// console.log(await proxy.test); | |
// })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment