diff --git a/package.json b/package.json index ec436ed4..74c6e9a0 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,9 @@ "packages/*" ], "scripts": { - "build": "yarn workspace @snort/shared build && yarn workspace @snort/system build && yarn workspace @snort/system-react build && yarn workspace @snort/app build", - "start": "yarn workspace @snort/shared build && yarn workspace @snort/system build && yarn workspace @snort/system-react build && yarn workspace @snort/app start", - "test": "yarn workspace @snort/shared build && yarn workspace @snort/system build && yarn workspace @snort/app test && yarn workspace @snort/system test" + "build": "yarn workspace @snort/system-query build && yarn workspace @snort/shared build && yarn workspace @snort/system build && yarn workspace @snort/system-react build && yarn workspace @snort/app build", + "start": "arn workspace @snort/system-query build && yarn workspace @snort/shared build && yarn workspace @snort/system build && yarn workspace @snort/system-react build && yarn workspace @snort/app start", + "test": "arn workspace @snort/system-query build && yarn workspace @snort/shared build && yarn workspace @snort/system build && yarn workspace @snort/app test && yarn workspace @snort/system test" }, "devDependencies": { "@cloudflare/workers-types": "^4.20230307.0", diff --git a/packages/app/package.json b/packages/app/package.json index d1d00624..7a8df136 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -12,6 +12,7 @@ "@scure/bip39": "^1.1.1", "@snort/shared": "workspace:*", "@snort/system": "workspace:*", + "@snort/system-query": "workspace:*", "@snort/system-react": "workspace:*", "@szhsin/react-menu": "^3.3.1", "@void-cat/api": "^1.0.4", diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx index 7666afb0..7bce8257 100644 --- a/packages/app/src/index.tsx +++ b/packages/app/src/index.tsx @@ -2,6 +2,9 @@ import "./index.css"; import "@szhsin/react-menu/dist/index.css"; import "./fonts/inter.css"; +import {default as wasmInit} from "@snort/system-query"; +import WasmPath from "@snort/system-query/pkg/system_query_bg.wasm"; + import { StrictMode } from "react"; import * as ReactDOM from "react-dom/client"; import { Provider } from "react-redux"; @@ -69,6 +72,7 @@ export const DefaultPowWorker = new PowWorker("/pow.js"); serviceWorkerRegistration.register(); async function initSite() { + await wasmInit(WasmPath); const login = LoginStore.takeSnapshot(); db.ready = await db.isAvailable(); if (db.ready) { diff --git a/packages/app/webpack.config.js b/packages/app/webpack.config.js index 1708f242..dce59a24 100644 --- a/packages/app/webpack.config.js +++ b/packages/app/webpack.config.js @@ -115,7 +115,7 @@ const config = { use: [MiniCssExtractPlugin.loader, require.resolve("css-loader")], }, { - test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif|webp)$/i, + test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif|webp|wasm)$/i, type: "asset", }, ], @@ -150,7 +150,7 @@ const config = { extensions: ["...", ".tsx", ".ts", ".jsx", ".js"], modules: ["...", __dirname, path.resolve(__dirname, "src")], fallback: { crypto: false }, - }, + } }; module.exports = () => config; diff --git a/packages/system-query/.gitignore b/packages/system-query/.gitignore new file mode 100644 index 00000000..e673575a --- /dev/null +++ b/packages/system-query/.gitignore @@ -0,0 +1,2 @@ +.idea/ +target/ \ No newline at end of file diff --git a/packages/system-query/Cargo.lock b/packages/system-query/Cargo.lock new file mode 100644 index 00000000..036190d1 --- /dev/null +++ b/packages/system-query/Cargo.lock @@ -0,0 +1,244 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-query" +version = "0.1.0" +dependencies = [ + "itertools", + "serde", + "serde-wasm-bindgen", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] diff --git a/packages/system-query/Cargo.toml b/packages/system-query/Cargo.toml new file mode 100644 index 00000000..0ced6b86 --- /dev/null +++ b/packages/system-query/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "system-query" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib"] + +[dependencies] +itertools = "0.11.0" +serde = { version = "1.0.188", features = ["derive"] } +serde-wasm-bindgen = "0.5.0" +wasm-bindgen = "0.2.87" + +[dev-dependencies] +wasm-bindgen-test = "0.3.37" diff --git a/packages/system-query/README.md b/packages/system-query/README.md new file mode 100644 index 00000000..f3891463 --- /dev/null +++ b/packages/system-query/README.md @@ -0,0 +1 @@ +# system-query diff --git a/packages/system-query/package.json b/packages/system-query/package.json new file mode 100644 index 00000000..a5d52590 --- /dev/null +++ b/packages/system-query/package.json @@ -0,0 +1,18 @@ +{ + "name": "@snort/system-query", + "version": "0.1.0", + "packageManager": "yarn@3.6.3", + "scripts": { + "build": "npx -y wasm-pack build -t web -s snort" + }, + "files": [ + "pkg/system_query_bg.wasm", + "pkg/system_query.js", + "pkg/system_query.d.ts" + ], + "module": "pkg/system_query.js", + "types": "pkg/system_query.d.ts", + "devDependencies": { + "wasm-pack": "^0.12.1" + } +} diff --git a/packages/system-query/src/diff.rs b/packages/system-query/src/diff.rs new file mode 100644 index 00000000..948362aa --- /dev/null +++ b/packages/system-query/src/diff.rs @@ -0,0 +1,180 @@ +use itertools::Itertools; +use crate::FlatReqFilter; + +pub fn diff_filter(prev: &Vec, next: &Vec) -> Vec:: { + let mut added: Vec:: = vec![]; + + for n in next.iter() { + if !prev.iter().contains(&n) { + added.push(n.clone()) + } + } + + added +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn simple_diff_same() { + let prev = vec![ + FlatReqFilter { + id: Some("a".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + } + ]; + let next = vec![ + FlatReqFilter { + id: Some("a".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + } + ]; + + let result = diff_filter(&prev, &next); + assert_eq!(result, vec![]) + } + + #[test] + fn simple_diff_add() { + let prev = vec![ + FlatReqFilter { + id: Some("a".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + } + ]; + let next = vec![ + FlatReqFilter { + id: Some("a".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + }, + FlatReqFilter { + id: Some("b".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + }, + ]; + + let result = diff_filter(&prev, &next); + assert_eq!(result, vec![ + FlatReqFilter { + id: Some("b".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + } + ]) + } + + #[test] + fn simple_diff_replace() { + let prev = vec![ + FlatReqFilter { + id: Some("a".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + } + ]; + let next = vec![ + FlatReqFilter { + id: Some("b".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + }, + ]; + + let result = diff_filter(&prev, &next); + assert_eq!(result, vec![ + FlatReqFilter { + id: Some("b".to_owned()), + author: None, + kind: None, + e_tag: None, + p_tag: None, + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: None, + until: None, + limit: None, + } + ]) + } +} \ No newline at end of file diff --git a/packages/system-query/src/expand.rs b/packages/system-query/src/expand.rs new file mode 100644 index 00000000..ea619c12 --- /dev/null +++ b/packages/system-query/src/expand.rs @@ -0,0 +1,182 @@ +use itertools::Itertools; +use crate::{FlatReqFilter, ReqFilter}; + +#[derive(Clone)] +enum StringOrNumberEntry<'a> { + String((&'static str, &'a String)), + Number((&'static str, &'a i32)), +} + +pub fn expand_filter(filter: &ReqFilter) -> Vec { + let mut ret: Vec = Vec::new(); + + let mut inputs: Vec> = vec![]; + if let Some(ids) = &filter.ids { + let t_ids = ids.iter().map(|z| StringOrNumberEntry::String(("id", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(authors) = &filter.authors { + let t_ids = authors.iter().map(|z| StringOrNumberEntry::String(("author", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(kinds) = &filter.kinds { + let t_ids = kinds.iter().map(|z| StringOrNumberEntry::Number(("kind", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(e_tags) = &filter.e_tag { + let t_ids = e_tags.iter().map(|z| StringOrNumberEntry::String(("e_tag", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(p_tags) = &filter.p_tag { + let t_ids = p_tags.iter().map(|z| StringOrNumberEntry::String(("p_tag", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(d_tags) = &filter.d_tag { + let t_ids = d_tags.iter().map(|z| StringOrNumberEntry::String(("d_tag", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(t_tags) = &filter.t_tag { + let t_ids = t_tags.iter().map(|z| StringOrNumberEntry::String(("t_tag", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(r_tags) = &filter.r_tag { + let t_ids = r_tags.iter().map(|z| StringOrNumberEntry::String(("r_tag", z))).collect_vec(); + inputs.push(t_ids); + } + if let Some(search) = &filter.search { + let t_ids = search.iter().map(|z| StringOrNumberEntry::String(("search", z))).collect_vec(); + inputs.push(t_ids); + } + + for p in inputs.iter().multi_cartesian_product() { + ret.push(FlatReqFilter { + id: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("id") { + return Some((*v).to_string()); + } + } + None + }), + author: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("author") { + return Some((*v).to_string()); + } + } + None + }), + kind: p.iter().find_map(|q| { + if let StringOrNumberEntry::Number((k, v)) = q { + if (*k).eq("kind") { + return Some((*v).clone()); + } + } + None + }), + e_tag: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("e_tag") { + return Some((*v).to_string()); + } + } + None + }), + p_tag: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("p_tag") { + return Some((*v).to_string()); + } + } + None + }), + t_tag: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("t_tag") { + return Some((*v).to_string()); + } + } + None + }), + d_tag: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("d_tag") { + return Some((*v).to_string()); + } + } + None + }), + r_tag: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("r_tag") { + return Some((*v).to_string()); + } + } + None + }), + search: p.iter().find_map(|q| { + if let StringOrNumberEntry::String((k, v)) = q { + if (*k).eq("search") { + return Some((*v).to_string()); + } + } + None + }), + since: filter.since, + until: filter.until, + limit: filter.limit, + }) + } + ret +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::ReqFilter; + + #[test] + fn test_expand_filter() { + let input = ReqFilter { + authors: Some(vec!["a".to_owned(), "b".to_owned(), "c".to_owned()]), + kinds: Some(vec![1, 2, 3]), + ids: Some(vec!["x".to_owned(), "y".to_owned()]), + p_tag: Some(vec!["a".to_owned()]), + t_tag: None, + d_tag: None, + r_tag: None, + search: None, + since: Some(99), + until: None, + limit: Some(10), + e_tag: None, + }; + + let output = expand_filter(&input); + output.iter().take(5).for_each(|x| println!("{:?}", x)); + let expected = vec![ + FlatReqFilter { author: Some("a".to_owned()), kind: Some(1), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("a".to_owned()), kind: Some(1), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("a".to_owned()), kind: Some(2), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("a".to_owned()), kind: Some(2), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("a".to_owned()), kind: Some(3), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("a".to_owned()), kind: Some(3), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("b".to_owned()), kind: Some(1), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("b".to_owned()), kind: Some(1), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("b".to_owned()), kind: Some(2), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("b".to_owned()), kind: Some(2), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("b".to_owned()), kind: Some(3), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("b".to_owned()), kind: Some(3), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("c".to_owned()), kind: Some(1), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("c".to_owned()), kind: Some(1), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("c".to_owned()), kind: Some(2), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("c".to_owned()), kind: Some(2), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("c".to_owned()), kind: Some(3), id: Some("x".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + FlatReqFilter { author: Some("c".to_owned()), kind: Some(3), id: Some("y".to_owned()), p_tag: Some("a".to_owned()), t_tag: None, d_tag: None, r_tag: None, search: None, since: Some(99), until: None, limit: Some(10), e_tag: None }, + ]; + assert_eq!(output.len(), expected.len()); + output + .iter() + .for_each(|a| assert!(expected.contains(a))); + } +} \ No newline at end of file diff --git a/packages/system-query/src/lib.rs b/packages/system-query/src/lib.rs new file mode 100644 index 00000000..bcdc5f46 --- /dev/null +++ b/packages/system-query/src/lib.rs @@ -0,0 +1,78 @@ +extern crate wasm_bindgen; + +use serde::{Deserialize, Serialize}; +use wasm_bindgen::prelude::*; + +mod expand; +mod diff; + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub struct ReqFilter { + #[serde(rename = "ids", skip_serializing_if = "Option::is_none")] + pub ids: Option>, + #[serde(rename = "authors", skip_serializing_if = "Option::is_none")] + pub authors: Option>, + #[serde(rename = "kinds", skip_serializing_if = "Option::is_none")] + pub kinds: Option>, + #[serde(rename = "#e", skip_serializing_if = "Option::is_none")] + pub e_tag: Option>, + #[serde(rename = "#p", skip_serializing_if = "Option::is_none")] + pub p_tag: Option>, + #[serde(rename = "#t", skip_serializing_if = "Option::is_none")] + pub t_tag: Option>, + #[serde(rename = "#d", skip_serializing_if = "Option::is_none")] + pub d_tag: Option>, + #[serde(rename = "#r", skip_serializing_if = "Option::is_none")] + pub r_tag: Option>, + #[serde(rename = "search", skip_serializing_if = "Option::is_none")] + pub search: Option>, + #[serde(rename = "since", skip_serializing_if = "Option::is_none")] + pub since: Option, + #[serde(rename = "until", skip_serializing_if = "Option::is_none")] + pub until: Option, + #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] + pub limit: Option, +} + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub struct FlatReqFilter { + #[serde(rename = "ids", skip_serializing_if = "Option::is_none")] + id: Option, + #[serde(rename = "authors", skip_serializing_if = "Option::is_none")] + author: Option, + #[serde(rename = "kinds", skip_serializing_if = "Option::is_none")] + kind: Option, + #[serde(rename = "#e", skip_serializing_if = "Option::is_none")] + e_tag: Option, + #[serde(rename = "#p", skip_serializing_if = "Option::is_none")] + p_tag: Option, + #[serde(rename = "#t", skip_serializing_if = "Option::is_none")] + t_tag: Option, + #[serde(rename = "#d", skip_serializing_if = "Option::is_none")] + d_tag: Option, + #[serde(rename = "#r", skip_serializing_if = "Option::is_none")] + r_tag: Option, + #[serde(rename = "search", skip_serializing_if = "Option::is_none")] + search: Option, + #[serde(rename = "since", skip_serializing_if = "Option::is_none")] + since: Option, + #[serde(rename = "until", skip_serializing_if = "Option::is_none")] + until: Option, + #[serde(rename = "limit", skip_serializing_if = "Option::is_none")] + limit: Option, +} + +#[wasm_bindgen] +pub fn diff_filters(prev: JsValue, next: JsValue) -> Result { + let prev_parsed: Vec = serde_wasm_bindgen::from_value(prev)?; + let next_parsed: Vec = serde_wasm_bindgen::from_value(next)?; + let result = diff::diff_filter(&prev_parsed, &next_parsed); + Ok(serde_wasm_bindgen::to_value(&result)?) +} + +#[wasm_bindgen] +pub fn expand_filter(val: JsValue) -> Result { + let parsed: ReqFilter = serde_wasm_bindgen::from_value(val)?; + let result = expand::expand_filter(&parsed); + Ok(serde_wasm_bindgen::to_value(&result)?) +} \ No newline at end of file diff --git a/packages/system-query/src/utils.rs b/packages/system-query/src/utils.rs new file mode 100644 index 00000000..e69de29b diff --git a/packages/system/package.json b/packages/system/package.json index 434683af..b10f9a48 100644 --- a/packages/system/package.json +++ b/packages/system/package.json @@ -34,6 +34,7 @@ "@noble/hashes": "^1.3.2", "@scure/base": "^1.1.2", "@snort/shared": "^1.0.5", + "@snort/system-query": "workspace:*", "@stablelib/xchacha20": "^1.0.1", "debug": "^4.3.4", "dexie": "^3.2.4", diff --git a/packages/system/src/request-expander.ts b/packages/system/src/request-expander.ts index 669c55a3..2efa1d2c 100644 --- a/packages/system/src/request-expander.ts +++ b/packages/system/src/request-expander.ts @@ -1,4 +1,5 @@ import { ReqFilter } from "./nostr"; +import {expand_filter} from "@snort/system-query"; export interface FlatReqFilter { keys: number; @@ -20,7 +21,7 @@ export interface FlatReqFilter { * Expand a filter into its most fine grained form */ export function expandFilter(f: ReqFilter): Array { - const ret: Array = []; + /*const ret: Array = []; const src = Object.entries(f); const keys = src.filter(([, v]) => Array.isArray(v)).map(a => a[0]); const props = src.filter(([, v]) => !Array.isArray(v)); @@ -46,5 +47,8 @@ export function expandFilter(f: ReqFilter): Array { ...Object.fromEntries(props), }); - return ret; + return ret;*/ + + const ret = expand_filter(f); + return ret as Array; } diff --git a/packages/system/src/request-merger.ts b/packages/system/src/request-merger.ts index a345ef03..7b2f5cac 100644 --- a/packages/system/src/request-merger.ts +++ b/packages/system/src/request-merger.ts @@ -105,7 +105,7 @@ export function flatMerge(all: Array): Array { function mergeFiltersInSet(filters: Array) { return filters.reduce((acc, a) => { Object.entries(a).forEach(([k, v]) => { - if (k === "keys") return; + if (k === "keys" || v === undefined) return; if (DiscriminatorKeys.includes(k)) { acc[k] = v; } else { diff --git a/packages/system/src/request-splitter.ts b/packages/system/src/request-splitter.ts index 7f51295d..931458d4 100644 --- a/packages/system/src/request-splitter.ts +++ b/packages/system/src/request-splitter.ts @@ -1,8 +1,9 @@ import { flatFilterEq } from "./utils"; import { FlatReqFilter } from "./request-expander"; +import { diff_filters } from "@snort/system-query"; export function diffFilters(prev: Array, next: Array, calcRemoved?: boolean) { - const added = []; + /*const added = []; const removed = []; for (const n of next) { @@ -28,5 +29,12 @@ export function diffFilters(prev: Array, next: Array 0, + added: (added as Array), + removed: [] + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index ed4e9b98..8ac893ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2711,6 +2711,7 @@ __metadata: "@scure/bip39": ^1.1.1 "@snort/shared": "workspace:*" "@snort/system": "workspace:*" + "@snort/system-query": "workspace:*" "@snort/system-react": "workspace:*" "@szhsin/react-menu": ^3.3.1 "@types/debug": ^4.1.8 @@ -2822,6 +2823,14 @@ __metadata: languageName: unknown linkType: soft +"@snort/system-query@workspace:*, @snort/system-query@workspace:packages/system-query": + version: 0.0.0-use.local + resolution: "@snort/system-query@workspace:packages/system-query" + dependencies: + wasm-pack: ^0.12.1 + languageName: unknown + linkType: soft + "@snort/system-react@workspace:*, @snort/system-react@workspace:packages/system-react": version: 0.0.0-use.local resolution: "@snort/system-react@workspace:packages/system-react" @@ -4613,6 +4622,15 @@ __metadata: languageName: node linkType: hard +"axios@npm:^0.26.1": + version: 0.26.1 + resolution: "axios@npm:0.26.1" + dependencies: + follow-redirects: ^1.14.8 + checksum: d9eb58ff4bc0b36a04783fc9ff760e9245c829a5a1052ee7ca6013410d427036b1d10d04e7380c02f3508c5eaf3485b1ae67bd2adbfec3683704745c8d7a6e1a + languageName: node + linkType: hard + "axios@npm:^1.2.1": version: 1.5.0 resolution: "axios@npm:1.5.0" @@ -4812,6 +4830,17 @@ __metadata: languageName: node linkType: hard +"binary-install@npm:^1.0.1": + version: 1.1.0 + resolution: "binary-install@npm:1.1.0" + dependencies: + axios: ^0.26.1 + rimraf: ^3.0.2 + tar: ^6.1.11 + checksum: 271344b49f42460f5e3ec29d681cd4b749aaf9592040d49f6ae86d267b997b5fd094fd7a710df4d477fc299a51833b8cb94206595db6c46edea3f1603266a0d2 + languageName: node + linkType: hard + "binaryextensions@npm:^4.15.0, binaryextensions@npm:^4.16.0": version: 4.18.0 resolution: "binaryextensions@npm:4.18.0" @@ -7060,7 +7089,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.8, follow-redirects@npm:^1.15.0": version: 1.15.2 resolution: "follow-redirects@npm:1.15.2" peerDependenciesMeta: @@ -13956,6 +13985,17 @@ __metadata: languageName: node linkType: hard +"wasm-pack@npm:^0.12.1": + version: 0.12.1 + resolution: "wasm-pack@npm:0.12.1" + dependencies: + binary-install: ^1.0.1 + bin: + wasm-pack: run.js + checksum: 497abceb48b15329bb30f614b9ed7b07d82554ff225b93485794fb91b074a98aeda8091146aafe969c7f9615d106c770d215cf916bebf65451978f7222fcbe0b + languageName: node + linkType: hard + "watchpack@npm:^2.4.0": version: 2.4.0 resolution: "watchpack@npm:2.4.0"