bitview: reorg part 6
@@ -4,9 +4,9 @@ version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
@@ -182,9 +182,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.31"
|
||||
version = "0.4.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9611ec0b6acea03372540509035db2f7f1e9f04da5d27728436fa994033c00a0"
|
||||
checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0"
|
||||
dependencies = [
|
||||
"compression-codecs",
|
||||
"compression-core",
|
||||
@@ -283,9 +283,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.75"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
|
||||
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
@@ -293,7 +293,7 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -515,6 +515,14 @@ dependencies = [
|
||||
"brk_structs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brk_bridge"
|
||||
version = "0.0.109"
|
||||
dependencies = [
|
||||
"brk_interface",
|
||||
"brk_structs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brk_bundler"
|
||||
version = "0.0.109"
|
||||
@@ -531,6 +539,7 @@ name = "brk_cli"
|
||||
version = "0.0.109"
|
||||
dependencies = [
|
||||
"bitcoincore-rpc",
|
||||
"brk_bridge",
|
||||
"brk_bundler",
|
||||
"brk_computer",
|
||||
"brk_fetcher",
|
||||
@@ -1070,7 +1079,7 @@ dependencies = [
|
||||
"quick_cache",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sonic-rs 0.5.4",
|
||||
"sonic-rs 0.5.5",
|
||||
"tokio",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
@@ -1183,9 +1192,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.38"
|
||||
version = "1.2.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9"
|
||||
checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -1227,7 +1236,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1335,9 +1344,9 @@ checksum = "ea0095f6103c2a8b44acd6fd15960c801dafebf02e21940360833e0673f48ba7"
|
||||
|
||||
[[package]]
|
||||
name = "compression-codecs"
|
||||
version = "0.4.30"
|
||||
version = "0.4.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64"
|
||||
checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"compression-core",
|
||||
@@ -1507,7 +1516,7 @@ checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3"
|
||||
dependencies = [
|
||||
"dispatch",
|
||||
"nix",
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1640,7 +1649,7 @@ dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1750,7 +1759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2016,9 +2025,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
version = "0.32.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
||||
|
||||
[[package]]
|
||||
name = "guardian"
|
||||
@@ -2632,9 +2641,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
@@ -2855,9 +2864,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
version = "0.37.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -2918,9 +2927,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxc-browserslist"
|
||||
version = "2.1.1"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37c5bf598bf7f55955c737d580cdadaeeda80e0e6430834f6165aef21220e3a2"
|
||||
checksum = "7612127f5fa1ef0f3e98905ddfc10a7fa1df98944b75d774bb3cb4b530663616"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"flate2",
|
||||
@@ -3248,9 +3257,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxc_sourcemap"
|
||||
version = "4.1.5"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6194c58467a15d9dcb5cb852fcad312af57fd46fabd419fae87fcf801f83702"
|
||||
checksum = "05ff280f25901ac054ad8552395ecd6a455e4b9352a94debbc34c433760586ef"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"json-escape-simd",
|
||||
@@ -3855,9 +3864,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.2"
|
||||
version = "1.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
|
||||
checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -3867,9 +3876,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.10"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
|
||||
checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -3983,7 +3992,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4111,7 +4120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b55fb86dfd3a2f5f76ea78310a88f96c4ea21a3031f8d212443d56123fd0521"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4144,9 +4153,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.226"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
@@ -4164,18 +4173,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.226"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.226"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4374,9 +4383,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sonic-rs"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0e0c5c1c429b500b4583e860ed48f9e34968cb1ba49dd16c1e2743678e3fd18"
|
||||
checksum = "22540d56ba14521e4878ad436d498518c59698c39a89d5905c694932f0bf7134"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bumpalo",
|
||||
@@ -4521,7 +4530,7 @@ dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5227,7 +5236,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.0",
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5238,55 +5247,54 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.62.0"
|
||||
version = "0.62.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9579d0e6970fd5250aa29aba5994052385ff55cf7b28a059e484bb79ea842e42"
|
||||
checksum = "49e6c4a1f363c8210c6f77ba24f645c61c6fb941eccf013da691f7e09515b8ac"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core",
|
||||
"windows-future",
|
||||
"windows-link 0.2.0",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a90dd7a7b86859ec4cdf864658b311545ef19dbcf17a672b52ab7cefe80c336f"
|
||||
checksum = "123e712f464a8a60ce1a13f4c446d2d43ab06464cb5842ff68f5c71b6fb7852e"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.0"
|
||||
version = "0.62.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
|
||||
checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2194dee901458cb79e1148a4e9aac2b164cc95fa431891e7b296ff0b2f1d8a6"
|
||||
checksum = "68f3db6b24b120200d649cd4811b4947188ed3a8d2626f7075146c5d178a9a4a"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.0"
|
||||
version = "0.60.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||
checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5295,21 +5303,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.1"
|
||||
version = "0.59.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||
checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
@@ -5323,7 +5325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ce3498fe0aba81e62e477408383196b4b0363db5e0c27646f932676283b43d8"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5332,7 +5334,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5341,7 +5343,7 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5368,16 +5370,16 @@ version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets 0.53.3",
|
||||
"windows-targets 0.53.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.0"
|
||||
version = "0.61.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
|
||||
checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5398,11 +5400,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.3"
|
||||
version = "0.53.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
@@ -5419,7 +5421,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab47f085ad6932defa48855254c758cdd0e2f2d48e62a34118a268d8f345e118"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -45,6 +45,7 @@ allocative = { version = "0.3.4", features = ["parking_lot"] }
|
||||
axum = "0.8.4"
|
||||
bitcoin = { version = "0.32.7", features = ["serde"] }
|
||||
bitcoincore-rpc = "0.19.0"
|
||||
brk_bridge = { version = "0.0.109", path = "crates/brk_bridge" }
|
||||
brk_bundler = { version = "0.0.109", path = "crates/brk_bundler" }
|
||||
brk_cli = { version = "0.0.109", path = "crates/brk_cli" }
|
||||
brk_computer = { version = "0.0.109", path = "crates/brk_computer" }
|
||||
@@ -67,11 +68,11 @@ minreq = { version = "2.14.1", features = ["https", "serde_json"] }
|
||||
parking_lot = "0.12.4"
|
||||
quick_cache = "0.6.16"
|
||||
rayon = "1.11.0"
|
||||
serde = "1.0.226"
|
||||
serde = "1.0.228"
|
||||
serde_bytes = "0.11.19"
|
||||
serde_derive = "1.0.226"
|
||||
serde_derive = "1.0.228"
|
||||
serde_json = { version = "1.0.145", features = ["float_roundtrip"] }
|
||||
sonic-rs = "0.5.4"
|
||||
sonic-rs = "0.5.5"
|
||||
tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
|
||||
# vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]}
|
||||
vecdb = { version = "0.2.16", features = ["derive"]}
|
||||
|
||||
|
Before Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 263 KiB |
|
Before Width: | Height: | Size: 208 KiB |
|
Before Width: | Height: | Size: 386 KiB |
|
Before Width: | Height: | Size: 496 KiB |
|
Before Width: | Height: | Size: 564 KiB |
|
Before Width: | Height: | Size: 592 KiB |
|
Before Width: | Height: | Size: 453 KiB |
|
Before Width: | Height: | Size: 526 KiB |
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "brk_bridge"
|
||||
description = "A generator of bridge files for other languages"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
brk_interface = { workspace = true }
|
||||
brk_structs = { workspace = true }
|
||||
@@ -0,0 +1 @@
|
||||
# brk_bridge
|
||||
@@ -0,0 +1,8 @@
|
||||
fn main() {
|
||||
let profile = std::env::var("PROFILE").unwrap_or_default();
|
||||
|
||||
if profile == "release" {
|
||||
println!("cargo:rustc-flag=-C");
|
||||
println!("cargo:rustc-flag=target-cpu=native");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
fs, io,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use brk_interface::{Index, Interface};
|
||||
use brk_structs::pools;
|
||||
|
||||
use super::VERSION;
|
||||
|
||||
const AUTO_GENERATED_DISCLAIMER: &str = "//
|
||||
// File auto-generated, any modifications will be overwritten
|
||||
//";
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub trait Bridge {
|
||||
fn generate_js_files(&self, packages_path: &Path) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl Bridge for Interface<'static> {
|
||||
fn generate_js_files(&self, packages_path: &Path) -> io::Result<()> {
|
||||
let path = packages_path.join("brk");
|
||||
|
||||
if !fs::exists(&path)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = packages_path.join("generated");
|
||||
fs::create_dir_all(&path)?;
|
||||
|
||||
generate_version_file(&path)?;
|
||||
generate_metrics_file(self, &path)?;
|
||||
generate_pools_file(&path)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_version_file(parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("metrics.js"));
|
||||
|
||||
let contents = format!(
|
||||
"{AUTO_GENERATED_DISCLAIMER}
|
||||
|
||||
export const VERSION = \"v{VERSION}\";
|
||||
"
|
||||
);
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn generate_pools_file(parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("pools.js"));
|
||||
|
||||
let pools = pools();
|
||||
|
||||
let mut contents = format!("{AUTO_GENERATED_DISCLAIMER}\n");
|
||||
|
||||
contents += "
|
||||
/**
|
||||
* @typedef {typeof POOL_ID_TO_POOL_NAME} PoolIdToPoolName
|
||||
* @typedef {keyof PoolIdToPoolName} PoolId
|
||||
*/
|
||||
|
||||
export const POOL_ID_TO_POOL_NAME = /** @type {const} */ ({
|
||||
";
|
||||
|
||||
let mut sorted_pools: Vec<_> = pools.iter().collect();
|
||||
sorted_pools.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
||||
|
||||
contents += &sorted_pools
|
||||
.iter()
|
||||
.map(|pool| {
|
||||
let id = pool.serialized_id();
|
||||
format!(" {id}: \"{}\",", pool.name)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += "\n});\n";
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn generate_metrics_file(interface: &Interface<'static>, parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("metrics.js"));
|
||||
|
||||
let indexes = Index::all();
|
||||
|
||||
let mut contents = format!(
|
||||
"{AUTO_GENERATED_DISCLAIMER}
|
||||
|
||||
/**
|
||||
"
|
||||
);
|
||||
|
||||
contents += &indexes
|
||||
.iter()
|
||||
.map(|i| format!(" * @typedef {{\"{}\"}} {i}", i.serialize_long()))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += &format!(
|
||||
"
|
||||
* @typedef {{{}}} Index",
|
||||
indexes
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" | ")
|
||||
);
|
||||
|
||||
let mut unique_index_groups = BTreeMap::new();
|
||||
|
||||
contents += "
|
||||
*
|
||||
* @typedef {typeof COMPRESSED_METRIC_TO_INDEXES} MetricToIndexes
|
||||
* @typedef {string} Metric
|
||||
*/
|
||||
|
||||
";
|
||||
|
||||
let mut word_to_freq: BTreeMap<_, usize> = BTreeMap::new();
|
||||
interface
|
||||
.metric_to_index_to_vec()
|
||||
.keys()
|
||||
.for_each(|metric| {
|
||||
metric.split("_").for_each(|word| {
|
||||
*word_to_freq.entry(word).or_default() += 1;
|
||||
});
|
||||
});
|
||||
let mut word_to_freq = word_to_freq.into_iter().collect::<Vec<_>>();
|
||||
word_to_freq.sort_unstable_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(b.0)));
|
||||
let words = word_to_freq
|
||||
.into_iter()
|
||||
.map(|(str, _)| str)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
contents += &format!(
|
||||
"const INDEX_TO_WORD = [
|
||||
{}
|
||||
];
|
||||
",
|
||||
words
|
||||
.iter()
|
||||
.map(|w| format!("\"{w}\""))
|
||||
.collect::<Vec<_>>()
|
||||
.join(",\n ")
|
||||
);
|
||||
|
||||
contents += "
|
||||
const WORD_TO_INDEX = {};
|
||||
INDEX_TO_WORD.forEach((word, index) => {
|
||||
WORD_TO_INDEX[word] = index;
|
||||
});
|
||||
|
||||
function lettersToIndex(s) {
|
||||
let result = 0;
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
const value = charToIndex(s.charCodeAt(i));
|
||||
result = result * 52 + value + 1;
|
||||
}
|
||||
return result - 1;
|
||||
}
|
||||
|
||||
function charToIndex(c) {
|
||||
const A = 65, Z = 90, a = 97, z = 122;
|
||||
|
||||
if (c >= A && c <= Z) {
|
||||
return c - A;
|
||||
} else if (c >= a && c <= z) {
|
||||
return c - a + 26;
|
||||
} else {
|
||||
return 255; // Invalid
|
||||
}
|
||||
}
|
||||
|
||||
function compressMetric(metric) {
|
||||
return metric
|
||||
.split('_')
|
||||
.map((word) => {
|
||||
const index = WORD_TO_INDEX[word];
|
||||
if (index === undefined) throw \"bad word\";
|
||||
return indexToLetters(index);
|
||||
})
|
||||
.join('_');
|
||||
}
|
||||
|
||||
function decompressMetric(compressedMetric) {
|
||||
return compressedMetric
|
||||
.split('_')
|
||||
.map((code) => {
|
||||
const index = lettersToIndex(code);
|
||||
return WORDS[index] || code; // Fallback to original if not found
|
||||
})
|
||||
.join('_');
|
||||
}
|
||||
";
|
||||
|
||||
let word_to_base62 = words
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, w)| (w, index_to_letters(i)))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let mut ser_metric_to_indexes = "
|
||||
/** @type {Record<string, Index[]>} */
|
||||
const COMPRESSED_METRIC_TO_INDEXES = {
|
||||
"
|
||||
.to_string();
|
||||
|
||||
interface
|
||||
.metric_to_index_to_vec()
|
||||
.iter()
|
||||
.for_each(|(metric, index_to_vec)| {
|
||||
let indexes = index_to_vec
|
||||
.keys()
|
||||
.map(|i| format!("\"{}\"", i.serialize_long()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let indexes = format!("[{indexes}]");
|
||||
let unique = unique_index_groups.len();
|
||||
let index = index_to_letters(*unique_index_groups.entry(indexes).or_insert(unique));
|
||||
|
||||
let compressed_metric = metric.split('_').fold(String::new(), |mut acc, w| {
|
||||
if !acc.is_empty() {
|
||||
acc.push('_');
|
||||
}
|
||||
acc.push_str(&word_to_base62[w]);
|
||||
acc
|
||||
});
|
||||
|
||||
ser_metric_to_indexes += &format!(" {compressed_metric}: {index},\n");
|
||||
});
|
||||
|
||||
ser_metric_to_indexes += "};
|
||||
";
|
||||
|
||||
let mut sorted_groups: Vec<_> = unique_index_groups.into_iter().collect();
|
||||
sorted_groups.sort_by_key(|(_, index)| *index);
|
||||
sorted_groups.into_iter().for_each(|(group, index)| {
|
||||
let index = index_to_letters(index);
|
||||
contents += &format!("/** @type {{Index[]}} */\nconst {index} = {group};\n");
|
||||
});
|
||||
|
||||
contents += &ser_metric_to_indexes;
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn index_to_letters(mut index: usize) -> String {
|
||||
if index < 52 {
|
||||
return (index_to_char(index) as char).to_string();
|
||||
}
|
||||
let mut result = [0u8; 8];
|
||||
let mut pos = 8;
|
||||
loop {
|
||||
pos -= 1;
|
||||
result[pos] = index_to_char(index % 52);
|
||||
index /= 52;
|
||||
if index == 0 {
|
||||
break;
|
||||
}
|
||||
index -= 1;
|
||||
}
|
||||
unsafe { String::from_utf8_unchecked(result[pos..].to_vec()) }
|
||||
}
|
||||
|
||||
fn index_to_char(index: usize) -> u8 {
|
||||
match index {
|
||||
0..=25 => b'A' + index as u8,
|
||||
26..=51 => b'a' + (index - 26) as u8,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
// fn letters_to_index(s: &str) -> usize {
|
||||
// let mut result = 0;
|
||||
// for byte in s.bytes() {
|
||||
// let value = char_to_index(byte) as usize;
|
||||
// result = result * 52 + value + 1;
|
||||
// }
|
||||
// result - 1
|
||||
// }
|
||||
|
||||
// fn char_to_index(byte: u8) -> u8 {
|
||||
// match byte {
|
||||
// b'A'..=b'Z' => byte - b'A',
|
||||
// b'a'..=b'z' => byte - b'a' + 26,
|
||||
// _ => 255, // Invalid
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,5 @@
|
||||
mod js;
|
||||
|
||||
pub use js::Bridge;
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
@@ -0,0 +1 @@
|
||||
// TODO ?
|
||||
@@ -11,6 +11,7 @@ build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
bitcoincore-rpc = { workspace = true }
|
||||
brk_bridge = { workspace = true }
|
||||
brk_bundler = { workspace = true }
|
||||
brk_computer = { workspace = true }
|
||||
brk_fetcher = { workspace = true }
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
use std::{fs, io, path::Path};
|
||||
|
||||
use brk_interface::{Index, Interface};
|
||||
use brk_server::VERSION;
|
||||
use brk_structs::pools;
|
||||
|
||||
use crate::website::Website;
|
||||
|
||||
const BRIDGE_PATH: &str = "scripts/bridge";
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub trait Bridge {
|
||||
fn generate_bridge_files(&self, website: Website, websites_path: &Path) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl Bridge for Interface<'static> {
|
||||
fn generate_bridge_files(&self, website: Website, websites_path: &Path) -> io::Result<()> {
|
||||
if website.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = websites_path.join(website.to_folder_name());
|
||||
|
||||
if !fs::exists(&path)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = path.join(BRIDGE_PATH);
|
||||
|
||||
fs::create_dir_all(&path)?;
|
||||
|
||||
generate_metrics_file(self, &path)?;
|
||||
generate_pools_file(&path)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_pools_file(parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("pools.js"));
|
||||
|
||||
let pools = pools();
|
||||
|
||||
let mut contents = "//
|
||||
// File auto-generated, any modifications will be overwritten
|
||||
//
|
||||
"
|
||||
.to_string();
|
||||
|
||||
contents += "
|
||||
/** @typedef {ReturnType<typeof createPools>} Pools */
|
||||
/** @typedef {keyof Pools} Pool */
|
||||
|
||||
export function createPools() {
|
||||
return /** @type {const} */ ({
|
||||
";
|
||||
|
||||
let mut sorted_pools: Vec<_> = pools.iter().collect();
|
||||
sorted_pools.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
||||
|
||||
contents += &sorted_pools
|
||||
.iter()
|
||||
.map(|pool| {
|
||||
let id = pool.serialized_id();
|
||||
format!(" {id}: \"{}\",", pool.name)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += "\n });\n}\n";
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn generate_metrics_file(interface: &Interface<'static>, parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("metrics.js"));
|
||||
|
||||
let indexes = Index::all();
|
||||
|
||||
let mut contents = format!(
|
||||
"//
|
||||
// File auto-generated, any modifications will be overwritten
|
||||
//
|
||||
|
||||
export const VERSION = \"v{VERSION}\";
|
||||
|
||||
"
|
||||
);
|
||||
|
||||
contents += &indexes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i_of_i, i)| {
|
||||
// let lowered = i.to_string().to_lowercase();
|
||||
format!("/** @typedef {{{i_of_i}}} {i} */",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += &format!(
|
||||
"\n\n/** @typedef {{{}}} Index */\n",
|
||||
indexes
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" | ")
|
||||
);
|
||||
|
||||
contents += "
|
||||
/** @typedef {ReturnType<typeof createIndexes>} Indexes */
|
||||
|
||||
export function createIndexes() {
|
||||
return {
|
||||
";
|
||||
|
||||
contents += &indexes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i_of_i, i)| {
|
||||
let lowered = i.to_string().to_lowercase();
|
||||
format!(" {lowered}: /** @satisfies {{{i}}} */ ({i_of_i}),",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += " };\n}\n";
|
||||
|
||||
contents += "
|
||||
/** @typedef {ReturnType<typeof createMetricToIndexes>} MetricToIndexes
|
||||
/** @typedef {keyof MetricToIndexes} Metric */
|
||||
|
||||
/**
|
||||
* @returns {Record<any, number[]>}
|
||||
*/
|
||||
export function createMetricToIndexes() {
|
||||
return {
|
||||
";
|
||||
|
||||
interface
|
||||
.id_to_index_to_vec()
|
||||
.iter()
|
||||
.for_each(|(id, index_to_vec)| {
|
||||
let indexes = index_to_vec
|
||||
.keys()
|
||||
.map(|i| (*i as u8).to_string())
|
||||
// .map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
contents += &format!(" \"{id}\": [{indexes}],\n");
|
||||
});
|
||||
|
||||
contents += " };\n}\n";
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use std::{
|
||||
};
|
||||
|
||||
use bitcoincore_rpc::{self, RpcApi};
|
||||
use brk_bridge::Bridge;
|
||||
use brk_bundler::bundle;
|
||||
use brk_computer::Computer;
|
||||
use brk_indexer::Indexer;
|
||||
@@ -18,12 +19,11 @@ use brk_server::{Server, VERSION};
|
||||
use log::info;
|
||||
use vecdb::Exit;
|
||||
|
||||
mod bridge;
|
||||
mod config;
|
||||
mod paths;
|
||||
mod website;
|
||||
|
||||
use crate::{bridge::Bridge, config::Config, paths::*};
|
||||
use crate::{config::Config, paths::*};
|
||||
|
||||
pub fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
@@ -51,97 +51,107 @@ pub fn run() -> color_eyre::Result<()> {
|
||||
|
||||
let mut indexer = Indexer::forced_import(&config.brkdir())?;
|
||||
|
||||
let wait_for_synced_node = |rpc_client: &bitcoincore_rpc::Client| -> color_eyre::Result<()> {
|
||||
let is_synced = || -> color_eyre::Result<bool> {
|
||||
let info = rpc_client.get_blockchain_info()?;
|
||||
Ok(info.headers == info.blocks)
|
||||
let mut computer = Computer::forced_import(&config.brkdir(), &indexer, config.fetcher())?;
|
||||
|
||||
let interface = Interface::build(&parser, &indexer, &computer);
|
||||
|
||||
let website = config.website();
|
||||
|
||||
let downloads_path = config.downloads_dir();
|
||||
|
||||
let future = async {
|
||||
let bundle_path = if website.is_some() {
|
||||
let websites_dev_path = Path::new("../../websites");
|
||||
let packages_dev_path = Path::new("../../packages");
|
||||
|
||||
let websites_path;
|
||||
let packages_path;
|
||||
|
||||
if fs::exists(websites_dev_path)? {
|
||||
websites_path = websites_dev_path.to_path_buf();
|
||||
packages_path = packages_dev_path.to_path_buf();
|
||||
} else {
|
||||
let downloaded_brk_path = downloads_path.join(format!("brk-{VERSION}"));
|
||||
|
||||
let downloaded_websites_path = downloaded_brk_path.join("websites");
|
||||
let downloaded_packages_path = downloaded_brk_path.join("packages");
|
||||
|
||||
if !fs::exists(&downloaded_websites_path)? {
|
||||
info!("Downloading source from Github...");
|
||||
|
||||
let url = format!(
|
||||
"https://github.com/bitcoinresearchkit/brk/archive/refs/tags/v{VERSION}.zip",
|
||||
);
|
||||
|
||||
let response = minreq::get(url).send()?;
|
||||
let bytes = response.as_bytes();
|
||||
let cursor = Cursor::new(bytes);
|
||||
|
||||
let mut zip = zip::ZipArchive::new(cursor).unwrap();
|
||||
|
||||
zip.extract(downloads_path).unwrap();
|
||||
}
|
||||
|
||||
websites_path = downloaded_websites_path;
|
||||
packages_path = downloaded_packages_path;
|
||||
}
|
||||
|
||||
interface.generate_js_files(&packages_path)?;
|
||||
|
||||
Some(bundle(&websites_path, website.to_folder_name(), true).await?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if !is_synced()? {
|
||||
info!("Waiting for node to be synced...");
|
||||
while !is_synced()? {
|
||||
let server = Server::new(interface, bundle_path);
|
||||
|
||||
tokio::spawn(async move {
|
||||
server.serve(true).await.unwrap();
|
||||
});
|
||||
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
wait_for_synced_node(rpc)?;
|
||||
|
||||
let block_count = rpc.get_block_count()?;
|
||||
|
||||
info!("{} blocks found.", block_count + 1);
|
||||
|
||||
let starting_indexes = indexer
|
||||
.index(&parser, rpc, &exit, config.check_collisions())
|
||||
.unwrap();
|
||||
|
||||
computer
|
||||
.compute(&indexer, starting_indexes, &parser, &exit)
|
||||
.unwrap();
|
||||
|
||||
info!("Waiting for new blocks...");
|
||||
|
||||
while block_count == rpc.get_block_count()? {
|
||||
sleep(Duration::from_secs(1))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let mut computer = Computer::forced_import(&config.brkdir(), &indexer, config.fetcher())?;
|
||||
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()?
|
||||
.block_on(async {
|
||||
let interface = Interface::build(&parser, &indexer, &computer);
|
||||
|
||||
let website = config.website();
|
||||
|
||||
let downloads_path = config.downloads_dir();
|
||||
|
||||
let bundle_path = if website.is_some() {
|
||||
let websites_dev_path = Path::new("../../websites");
|
||||
|
||||
let websites_path = if fs::exists(websites_dev_path)? {
|
||||
websites_dev_path.to_path_buf()
|
||||
} else {
|
||||
let downloaded_websites_path =
|
||||
downloads_path.join(format!("brk-{VERSION}")).join("websites");
|
||||
|
||||
if !fs::exists(&downloaded_websites_path)? {
|
||||
info!("Downloading websites from Github...");
|
||||
|
||||
let url = format!(
|
||||
"https://github.com/bitcoinresearchkit/brk/archive/refs/tags/v{VERSION}.zip",
|
||||
);
|
||||
|
||||
let response = minreq::get(url).send()?;
|
||||
let bytes = response.as_bytes();
|
||||
let cursor = Cursor::new(bytes);
|
||||
|
||||
let mut zip = zip::ZipArchive::new(cursor).unwrap();
|
||||
|
||||
zip.extract(downloads_path).unwrap();
|
||||
}
|
||||
|
||||
downloaded_websites_path
|
||||
};
|
||||
|
||||
interface.generate_bridge_files(website, websites_path.as_path())?;
|
||||
|
||||
Some(bundle(&websites_path, website.to_folder_name(), true).await?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let server = Server::new(
|
||||
interface,
|
||||
bundle_path,
|
||||
);
|
||||
|
||||
tokio::spawn(async move {
|
||||
server.serve(true).await.unwrap();
|
||||
});
|
||||
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
loop {
|
||||
wait_for_synced_node(rpc)?;
|
||||
|
||||
let block_count = rpc.get_block_count()?;
|
||||
|
||||
info!("{} blocks found.", block_count + 1);
|
||||
|
||||
let starting_indexes =
|
||||
indexer.index(&parser, rpc, &exit, config.check_collisions()).unwrap();
|
||||
|
||||
computer.compute(&indexer, starting_indexes, &parser, &exit).unwrap();
|
||||
|
||||
info!("Waiting for new blocks...");
|
||||
|
||||
while block_count == rpc.get_block_count()? {
|
||||
sleep(Duration::from_secs(1))
|
||||
}
|
||||
}
|
||||
})
|
||||
.block_on(future)
|
||||
}
|
||||
|
||||
fn wait_for_synced_node(rpc_client: &bitcoincore_rpc::Client) -> color_eyre::Result<()> {
|
||||
let is_synced = || -> color_eyre::Result<bool> {
|
||||
let info = rpc_client.get_blockchain_info()?;
|
||||
Ok(info.headers == info.blocks)
|
||||
};
|
||||
|
||||
if !is_synced()? {
|
||||
info!("Waiting for node to be synced...");
|
||||
while !is_synced()? {
|
||||
sleep(Duration::from_secs(1))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ pub use pagination::{PaginatedIndexParam, PaginationParam};
|
||||
pub use params::{IdParam, Params, ParamsOpt};
|
||||
use vecs::Vecs;
|
||||
|
||||
use crate::vecs::{IdToVec, IndexToVec};
|
||||
use crate::vecs::{IndexToVec, MetricToVec};
|
||||
|
||||
pub fn cached_errors() -> &'static Cache<String, String> {
|
||||
static CACHE: OnceLock<Cache<String, String>> = OnceLock::new();
|
||||
@@ -70,7 +70,7 @@ impl<'a> Interface<'a> {
|
||||
|
||||
let ids_to_vec = self
|
||||
.vecs
|
||||
.index_to_id_to_vec
|
||||
.index_to_metric_to_vec
|
||||
.get(&index)
|
||||
.ok_or(Error::String(format!(
|
||||
"Index \"{}\" isn't a valid index",
|
||||
@@ -111,7 +111,7 @@ impl<'a> Interface<'a> {
|
||||
&format!("\nMaybe you meant one of the following: {matches:#?} ?\n");
|
||||
}
|
||||
|
||||
if let Some(index_to_vec) = self.id_to_index_to_vec().get(id.as_str()) {
|
||||
if let Some(index_to_vec) = self.metric_to_index_to_vec().get(id.as_str()) {
|
||||
message += &format!("\nBut there is a vec named {id} which supports the following indexes: {:#?}\n", index_to_vec.keys());
|
||||
}
|
||||
|
||||
@@ -214,16 +214,16 @@ impl<'a> Interface<'a> {
|
||||
self.format(self.search(¶ms)?, ¶ms.rest)
|
||||
}
|
||||
|
||||
pub fn id_to_index_to_vec(&self) -> &BTreeMap<&str, IndexToVec<'_>> {
|
||||
&self.vecs.id_to_index_to_vec
|
||||
pub fn metric_to_index_to_vec(&self) -> &BTreeMap<&str, IndexToVec<'_>> {
|
||||
&self.vecs.metric_to_index_to_vec
|
||||
}
|
||||
|
||||
pub fn index_to_id_to_vec(&self) -> &BTreeMap<Index, IdToVec<'_>> {
|
||||
&self.vecs.index_to_id_to_vec
|
||||
pub fn index_to_metric_to_vec(&self) -> &BTreeMap<Index, MetricToVec<'_>> {
|
||||
&self.vecs.index_to_metric_to_vec
|
||||
}
|
||||
|
||||
pub fn get_vecid_count(&self) -> usize {
|
||||
self.vecs.id_count
|
||||
pub fn get_metric_count(&self) -> usize {
|
||||
self.vecs.metric_count
|
||||
}
|
||||
|
||||
pub fn get_index_count(&self) -> usize {
|
||||
@@ -242,8 +242,8 @@ impl<'a> Interface<'a> {
|
||||
&self.vecs.accepted_indexes
|
||||
}
|
||||
|
||||
pub fn get_vecids(&self, pagination: PaginationParam) -> &[&str] {
|
||||
self.vecs.ids(pagination)
|
||||
pub fn get_metrics(&self, pagination: PaginationParam) -> &[&str] {
|
||||
self.vecs.metrics(pagination)
|
||||
}
|
||||
|
||||
pub fn get_index_to_vecids(&self, paginated_index: PaginatedIndexParam) -> Vec<&str> {
|
||||
|
||||
@@ -11,16 +11,16 @@ use super::index::Index;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Vecs<'a> {
|
||||
pub id_to_index_to_vec: BTreeMap<&'a str, IndexToVec<'a>>,
|
||||
pub index_to_id_to_vec: BTreeMap<Index, IdToVec<'a>>,
|
||||
pub ids: Vec<&'a str>,
|
||||
pub metric_to_index_to_vec: BTreeMap<&'a str, IndexToVec<'a>>,
|
||||
pub index_to_metric_to_vec: BTreeMap<Index, MetricToVec<'a>>,
|
||||
pub metrics: Vec<&'a str>,
|
||||
pub indexes: Vec<&'static str>,
|
||||
pub accepted_indexes: BTreeMap<&'static str, &'static [&'static str]>,
|
||||
pub index_count: usize,
|
||||
pub id_count: usize,
|
||||
pub metric_count: usize,
|
||||
pub vec_count: usize,
|
||||
id_to_indexes: BTreeMap<&'a str, Vec<&'static str>>,
|
||||
indexes_to_ids: BTreeMap<Index, Vec<&'a str>>,
|
||||
metric_to_indexes: BTreeMap<&'a str, Vec<&'static str>>,
|
||||
index_to_metrics: BTreeMap<Index, Vec<&'a str>>,
|
||||
}
|
||||
|
||||
impl<'a> Vecs<'a> {
|
||||
@@ -33,7 +33,11 @@ impl<'a> Vecs<'a> {
|
||||
.iter_any_collectable()
|
||||
.for_each(|vec| this.insert(vec));
|
||||
|
||||
let mut ids = this.id_to_index_to_vec.keys().cloned().collect::<Vec<_>>();
|
||||
let mut ids = this
|
||||
.metric_to_index_to_vec
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let sort_ids = |ids: &mut Vec<&str>| {
|
||||
ids.sort_unstable_by(|a, b| {
|
||||
@@ -48,26 +52,26 @@ impl<'a> Vecs<'a> {
|
||||
|
||||
sort_ids(&mut ids);
|
||||
|
||||
this.ids = ids;
|
||||
this.id_count = this.id_to_index_to_vec.keys().count();
|
||||
this.index_count = this.index_to_id_to_vec.keys().count();
|
||||
this.metrics = ids;
|
||||
this.metric_count = this.metric_to_index_to_vec.keys().count();
|
||||
this.index_count = this.index_to_metric_to_vec.keys().count();
|
||||
this.vec_count = this
|
||||
.index_to_id_to_vec
|
||||
.index_to_metric_to_vec
|
||||
.values()
|
||||
.map(|tree| tree.len())
|
||||
.sum::<usize>();
|
||||
this.indexes = this
|
||||
.index_to_id_to_vec
|
||||
.index_to_metric_to_vec
|
||||
.keys()
|
||||
.map(|i| i.serialize_long())
|
||||
.collect::<Vec<_>>();
|
||||
this.accepted_indexes = this
|
||||
.index_to_id_to_vec
|
||||
.index_to_metric_to_vec
|
||||
.keys()
|
||||
.map(|i| (i.serialize_long(), i.possible_values()))
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
this.id_to_indexes = this
|
||||
.id_to_index_to_vec
|
||||
this.metric_to_indexes = this
|
||||
.metric_to_index_to_vec
|
||||
.iter()
|
||||
.map(|(id, index_to_vec)| {
|
||||
(
|
||||
@@ -79,12 +83,12 @@ impl<'a> Vecs<'a> {
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
this.indexes_to_ids = this
|
||||
.index_to_id_to_vec
|
||||
this.index_to_metrics = this
|
||||
.index_to_metric_to_vec
|
||||
.iter()
|
||||
.map(|(index, id_to_vec)| (*index, id_to_vec.keys().cloned().collect::<Vec<_>>()))
|
||||
.collect();
|
||||
this.indexes_to_ids
|
||||
this.index_to_metrics
|
||||
.values_mut()
|
||||
.for_each(|ids| sort_ids(ids));
|
||||
|
||||
@@ -101,7 +105,7 @@ impl<'a> Vecs<'a> {
|
||||
})
|
||||
.unwrap();
|
||||
let prev = self
|
||||
.id_to_index_to_vec
|
||||
.metric_to_index_to_vec
|
||||
.entry(name)
|
||||
.or_default()
|
||||
.insert(index, vec);
|
||||
@@ -110,7 +114,7 @@ impl<'a> Vecs<'a> {
|
||||
panic!()
|
||||
}
|
||||
let prev = self
|
||||
.index_to_id_to_vec
|
||||
.index_to_metric_to_vec
|
||||
.entry(index)
|
||||
.or_default()
|
||||
.insert(name, vec);
|
||||
@@ -120,22 +124,22 @@ impl<'a> Vecs<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ids(&self, pagination: PaginationParam) -> &[&'_ str] {
|
||||
let len = self.ids.len();
|
||||
pub fn metrics(&self, pagination: PaginationParam) -> &[&'_ str] {
|
||||
let len = self.metrics.len();
|
||||
let start = pagination.start(len);
|
||||
let end = pagination.end(len);
|
||||
&self.ids[start..end]
|
||||
&self.metrics[start..end]
|
||||
}
|
||||
|
||||
pub fn id_to_indexes(&self, id: String) -> Option<&Vec<&'static str>> {
|
||||
self.id_to_indexes.get(id.as_str())
|
||||
self.metric_to_indexes.get(id.as_str())
|
||||
}
|
||||
|
||||
pub fn index_to_ids(
|
||||
&self,
|
||||
PaginatedIndexParam { index, pagination }: PaginatedIndexParam,
|
||||
) -> Vec<&'a str> {
|
||||
let vec = self.indexes_to_ids.get(&index).unwrap();
|
||||
let vec = self.index_to_metrics.get(&index).unwrap();
|
||||
|
||||
let len = vec.len();
|
||||
let start = pagination.start(len);
|
||||
@@ -149,4 +153,4 @@ impl<'a> Vecs<'a> {
|
||||
pub struct IndexToVec<'a>(BTreeMap<Index, &'a dyn AnyCollectableVec>);
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
pub struct IdToVec<'a>(BTreeMap<&'a str, &'a dyn AnyCollectableVec>);
|
||||
pub struct MetricToVec<'a>(BTreeMap<&'a str, &'a dyn AnyCollectableVec>);
|
||||
|
||||
@@ -40,12 +40,12 @@ Get the count of all existing indexes.
|
||||
}
|
||||
|
||||
#[tool(description = "
|
||||
Get the count of all existing vec ids.
|
||||
Get the count of all existing metrics.
|
||||
")]
|
||||
async fn get_vecid_count(&self) -> Result<CallToolResult, McpError> {
|
||||
info!("mcp: get_vecid_count");
|
||||
async fn get_metric_count(&self) -> Result<CallToolResult, McpError> {
|
||||
info!("mcp: get_metric_count");
|
||||
Ok(CallToolResult::success(vec![
|
||||
Content::json(self.interface.get_vecid_count()).unwrap(),
|
||||
Content::json(self.interface.get_metric_count()).unwrap(),
|
||||
]))
|
||||
}
|
||||
|
||||
@@ -89,9 +89,9 @@ If the `page` param is omitted, it will default to the first page.
|
||||
&self,
|
||||
Parameters(pagination): Parameters<PaginationParam>,
|
||||
) -> Result<CallToolResult, McpError> {
|
||||
info!("mcp: get_vecids");
|
||||
info!("mcp: get_metrics");
|
||||
Ok(CallToolResult::success(vec![
|
||||
Content::json(self.interface.get_vecids(pagination)).unwrap(),
|
||||
Content::json(self.interface.get_metrics(pagination)).unwrap(),
|
||||
]))
|
||||
}
|
||||
|
||||
|
||||
@@ -229,9 +229,9 @@ impl ApiRoutes for Router<AppState> {
|
||||
}),
|
||||
)
|
||||
.route(
|
||||
"/api/vecs/id-count",
|
||||
"/api/vecs/metric-count",
|
||||
get(async |State(app_state): State<AppState>| -> Response {
|
||||
Json(app_state.interface.get_vecid_count()).into_response()
|
||||
Json(app_state.interface.get_metric_count()).into_response()
|
||||
}),
|
||||
)
|
||||
.route(
|
||||
@@ -253,17 +253,17 @@ impl ApiRoutes for Router<AppState> {
|
||||
}),
|
||||
)
|
||||
.route(
|
||||
"/api/vecs/ids",
|
||||
"/api/vecs/metrics",
|
||||
get(
|
||||
async |State(app_state): State<AppState>,
|
||||
Query(pagination): Query<PaginationParam>|
|
||||
-> Response {
|
||||
Json(app_state.interface.get_vecids(pagination)).into_response()
|
||||
Json(app_state.interface.get_metrics(pagination)).into_response()
|
||||
},
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/api/vecs/index-to-ids",
|
||||
"/api/vecs/index-to-metrics",
|
||||
get(
|
||||
async |State(app_state): State<AppState>,
|
||||
Query(paginated_index): Query<PaginatedIndexParam>|
|
||||
|
||||
@@ -93,6 +93,8 @@
|
||||
- _STORE_
|
||||
- save height and version in one file
|
||||
- _STRUCTS_
|
||||
- _GLOBAL_
|
||||
- https://davidlattimore.github.io/posts/2025/09/02/rustforge-wild-performance-tricks.html
|
||||
- __DOCS__
|
||||
- _README_
|
||||
- add a comparison table with alternatives
|
||||
@@ -145,6 +147,7 @@
|
||||
- https://fonts.google.com/specimen/Space+Mono
|
||||
- keep as many files as possible [under 14kb](https://endtimes.dev/why-your-website-should-be-under-14kb-in-size/)
|
||||
- [No classes](https://news.ycombinator.com/item?id=45287155)
|
||||
- [Organic animations](https://courses.joshwcomeau.com/playground/magic-wand-final)
|
||||
- __GLOBAL__
|
||||
- check `TODO`s in codebase
|
||||
- rename `output` to `txout` or `vout`, `input` to `txin` or `vin`
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
generated
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @import { Signal, Signals, Accessor } from "../solidjs-signals/index";
|
||||
*
|
||||
* @import { Index } from "./metrics"
|
||||
*
|
||||
* @typedef {[number, number, number, number]} OHLCTuple
|
||||
*/
|
||||
@@ -6,5 +6,5 @@
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"exclude": ["scripts/packages", "scripts/bridge", "spmething"]
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
@@ -0,0 +1,656 @@
|
||||
declare module 'lean-qr' {
|
||||
interface ImageDataLike {
|
||||
readonly data: Uint8ClampedArray;
|
||||
}
|
||||
|
||||
interface Context2DLike<DataT extends ImageDataLike> {
|
||||
createImageData(width: number, height: number): DataT;
|
||||
putImageData(data: DataT, x: number, y: number): void;
|
||||
}
|
||||
|
||||
interface CanvasLike<DataT extends ImageDataLike> {
|
||||
width: number;
|
||||
height: number;
|
||||
getContext(type: '2d'): Context2DLike<DataT> | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A colour in `[red, green, blue, alpha]` format (all values from 0 to 255).
|
||||
* If alpha is omitted, it is assumed to be 255 (opaque).
|
||||
*/
|
||||
export type RGBA = readonly [number, number, number, number?];
|
||||
|
||||
export interface Bitmap1D {
|
||||
/**
|
||||
* Appends a sequence of bits.
|
||||
*
|
||||
* @param value an integer containing the bits to append (big endian).
|
||||
* @param bits the number of bits to read from `value`. Must be between 1 and 24.
|
||||
*/
|
||||
push(value: number, bits: number): void;
|
||||
}
|
||||
|
||||
export interface StringOptions {
|
||||
/** the text to use for modules which are 'on' (typically black) */
|
||||
on?: string;
|
||||
|
||||
/** the text to use for modules which are 'off' (typically white) */
|
||||
off?: string;
|
||||
|
||||
/** the text to use for linefeeds between rows */
|
||||
lf?: string;
|
||||
|
||||
/** the padding to apply around the output (populated with 'off' modules) */
|
||||
pad?: number;
|
||||
|
||||
/**
|
||||
* the padding to apply on the left and right of the output (populated with 'off' modules)
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padX?: number;
|
||||
|
||||
/**
|
||||
* the padding to apply on the top and bottom of the output (populated with 'off' modules)
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padY?: number;
|
||||
}
|
||||
|
||||
export interface ImageDataOptions {
|
||||
/** the colour to use for modules which are 'on' (typically black) */
|
||||
on?: RGBA;
|
||||
|
||||
/** the colour to use for modules which are 'off' (typically white) */
|
||||
off?: RGBA;
|
||||
|
||||
/** the padding to apply around the output (filled with 'off') */
|
||||
pad?: number;
|
||||
|
||||
/**
|
||||
* the padding to apply on the left and right of the output (filled with 'off')
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padX?: number;
|
||||
|
||||
/**
|
||||
* the padding to apply on the top and bottom of the output (filled with 'off')
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padY?: number;
|
||||
}
|
||||
|
||||
export interface Bitmap2D {
|
||||
/** the width / height of the QR code in modules (excluding any padding) */
|
||||
readonly size: number;
|
||||
|
||||
/**
|
||||
* Read the state of a module from the QR code.
|
||||
*
|
||||
* @param x the x coordinate to read. Can be negative / out of bounds.
|
||||
* @param y the y coordinate to read. Can be negative / out of bounds.
|
||||
* @returns true if the requested module is set (i.e. typically black)
|
||||
*/
|
||||
get(x: number, y: number): boolean;
|
||||
|
||||
/**
|
||||
* Generate a string containing the QR code, suitable for displaying in a
|
||||
* terminal environment. Generally, you should customise on and off to use
|
||||
* the ANSI escapes of your target terminal for better rendering.
|
||||
*
|
||||
* @param options optional configuration for the display.
|
||||
*/
|
||||
toString(options?: Readonly<StringOptions>): string;
|
||||
|
||||
/**
|
||||
* Generate image data containing the QR code, at a scale of 1 pixel per
|
||||
* module. Use this if you need more control than toCanvas allows.
|
||||
*
|
||||
* @param context a context to use for creating the image data.
|
||||
* @param options optional configuration for the display.
|
||||
*/
|
||||
toImageData<DataT extends ImageDataLike>(
|
||||
context: Context2DLike<DataT>,
|
||||
options?: Readonly<ImageDataOptions>,
|
||||
): DataT;
|
||||
|
||||
/**
|
||||
* Generate a `data:image/*` URL for the QR code.
|
||||
*
|
||||
* @param options optional configuration for the output.
|
||||
* @returns a string suitable for use as the `src` of an `img` tag.
|
||||
*/
|
||||
toDataURL(
|
||||
options?: Readonly<
|
||||
ImageDataOptions & {
|
||||
type?: `image/${string}`;
|
||||
scale?: number;
|
||||
}
|
||||
>,
|
||||
): string;
|
||||
|
||||
/**
|
||||
* Populate a given canvas with the QR code, at a scale of 1 pixel per
|
||||
* module. Set image-rendering: pixelated and scale the canvas using CSS
|
||||
* for a large image. Automatically resizes the canvas to fit the QR code
|
||||
* if necessary.
|
||||
*
|
||||
* @param canvas the canvas to populate.
|
||||
* @param options optional configuration for the display.
|
||||
*/
|
||||
toCanvas(
|
||||
canvas: CanvasLike<ImageDataLike>,
|
||||
options?: Readonly<ImageDataOptions>,
|
||||
): void;
|
||||
}
|
||||
|
||||
export type Mask = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
||||
export type Mode = (data: Bitmap1D, version: number) => void;
|
||||
export interface ModeFactory {
|
||||
(value: string): Mode;
|
||||
/** a function which returns true when given a character which the current mode can represent */
|
||||
test(string: string): boolean;
|
||||
/** a function which returns an estimate of the number of bits required to encode a given value */
|
||||
est(value: string, version: number): number;
|
||||
/** an optional ECI which must be active for this mode to be interpreted correctly by a reader */
|
||||
eci?: number;
|
||||
}
|
||||
|
||||
interface ModeAutoOptions {
|
||||
/** a list of modes which can be considered when encoding a message */
|
||||
modes?: ReadonlyArray<ModeFactory>;
|
||||
}
|
||||
|
||||
export const mode: Readonly<{
|
||||
/** automatically picks the most optimal combination of modes for the requested message */
|
||||
auto(value: string, options?: Readonly<ModeAutoOptions>): Mode;
|
||||
/** concatenates multiple modes together */
|
||||
multi(...modes: ReadonlyArray<Mode>): Mode;
|
||||
/** sets the Extended Channel Interpretation for the message from this point onwards */
|
||||
eci(id: number): Mode;
|
||||
/** supports `0-9` and stores 3 characters per 10 bits */
|
||||
numeric: ModeFactory;
|
||||
/** supports `0-9A-Z $%*+-./:` and stores 2 characters per 11 bits */
|
||||
alphaNumeric: ModeFactory;
|
||||
/** arbitrary byte data, typically combined with `eci` */
|
||||
bytes(data: Uint8Array | ReadonlyArray<number>): Mode;
|
||||
/** supports 7-bit ASCII and stores 1 character per 8 bits with no ECI */
|
||||
ascii: ModeFactory;
|
||||
/** supports 8-bit ISO-8859-1 and stores 1 character per 8 bits with ECI 3 */
|
||||
iso8859_1: ModeFactory;
|
||||
/** supports double-byte Shift-JIS characters stores 1 character per 13 bits */
|
||||
shift_jis: ModeFactory;
|
||||
/** supports variable length UTF-8 with ECI 26 */
|
||||
utf8: ModeFactory;
|
||||
}>;
|
||||
|
||||
export type Correction = number & { readonly _: unique symbol };
|
||||
export const correction: Readonly<{
|
||||
/**
|
||||
* minimum possible correction level (same as L)
|
||||
* @deprecated use correction.L
|
||||
*/
|
||||
min: Correction;
|
||||
/** ~7.5% error tolerance, ~25% data overhead */
|
||||
L: Correction;
|
||||
/** ~15% error tolerance, ~60% data overhead */
|
||||
M: Correction;
|
||||
/** ~22.5% error tolerance, ~120% data overhead */
|
||||
Q: Correction;
|
||||
/** ~30% error tolerance, ~190% data overhead */
|
||||
H: Correction;
|
||||
/**
|
||||
* maximum possible correction level (same as H)
|
||||
* @deprecated use correction.H
|
||||
*/
|
||||
max: Correction;
|
||||
}>;
|
||||
|
||||
export interface GenerateOptions extends ModeAutoOptions {
|
||||
/** the minimum correction level to use (higher levels may still be used if the chosen version has space) */
|
||||
minCorrectionLevel?: Correction;
|
||||
/** the maximum correction level to use */
|
||||
maxCorrectionLevel?: Correction;
|
||||
/** the minimum version (size) of code to generate (must be between 1 and 40) */
|
||||
minVersion?: number;
|
||||
/** the maximum version (size) of code to generate (must be between 1 and 40) */
|
||||
maxVersion?: number;
|
||||
/** a mask to use on the QR code (should be left as `null` for ISO compliance but may be changed for artistic effect) */
|
||||
mask?: null | Mask;
|
||||
/** padding bits to use for extra space in the QR code (should be left as the default for ISO compliance but may be changed for artistic effect) */
|
||||
trailer?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a QR code.
|
||||
*
|
||||
* @param data either a string, or a pre-encoded mode.
|
||||
* @param options optional configuration for the QR code.
|
||||
* @returns the requested QR code.
|
||||
*/
|
||||
export type GenerateFn = (
|
||||
data: Mode | string,
|
||||
options?: Readonly<GenerateOptions>,
|
||||
) => Bitmap2D;
|
||||
interface Generate extends GenerateFn {
|
||||
/**
|
||||
* Creates a scoped `generate` function which considers additional modes
|
||||
* when using auto encoding.
|
||||
*
|
||||
* @param modes the modes to add.
|
||||
* @returns a `generate` function which will additionally consider the
|
||||
* given modes when using auto encoding.
|
||||
*
|
||||
* @deprecated this will be removed in version 3. Prefer passing an explicit list of modes when calling `generate`.
|
||||
*/
|
||||
with(...modes: ReadonlyArray<ModeFactory>): GenerateFn;
|
||||
}
|
||||
export const generate: Generate;
|
||||
}
|
||||
|
||||
declare module 'lean-qr/nano' {
|
||||
import type {
|
||||
Correction,
|
||||
Bitmap2D as FullBitmap2D,
|
||||
GenerateOptions as FullGenerateOptions,
|
||||
} from 'lean-qr';
|
||||
import { correction as fullCorrection } from 'lean-qr';
|
||||
|
||||
export type { Correction };
|
||||
|
||||
export const correction: Pick<typeof fullCorrection, 'L' | 'M' | 'Q' | 'H'>;
|
||||
|
||||
export type Bitmap2D = Pick<FullBitmap2D, 'size' | 'get' | 'toCanvas'>;
|
||||
|
||||
export type GenerateOptions = Pick<
|
||||
FullGenerateOptions,
|
||||
'minCorrectionLevel' | 'minVersion'
|
||||
>;
|
||||
|
||||
/**
|
||||
* Generate a QR code.
|
||||
*
|
||||
* @param data either a string, or a pre-encoded mode.
|
||||
* @param options optional configuration for the QR code.
|
||||
* @returns the requested QR code.
|
||||
*/
|
||||
export function generate(
|
||||
data: string,
|
||||
options?: Readonly<GenerateOptions>,
|
||||
): Bitmap2D;
|
||||
}
|
||||
|
||||
declare module 'lean-qr/extras/svg' {
|
||||
import type { Bitmap2D as FullBitmap2D } from 'lean-qr';
|
||||
|
||||
type Bitmap2D = Pick<FullBitmap2D, 'size' | 'get'>;
|
||||
|
||||
export interface SVGOptions {
|
||||
/** the colour to use for modules which are 'on' (typically black) */
|
||||
on?: string;
|
||||
/** the colour to use for modules which are 'off' (typically white) */
|
||||
off?: string;
|
||||
/** the padding to apply around the output (filled with 'off') */
|
||||
pad?: number;
|
||||
/**
|
||||
* the padding to apply on the left and right of the output (filled with 'off')
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padX?: number;
|
||||
/**
|
||||
* the padding to apply on the top and bottom of the output (filled with 'off')
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padY?: number;
|
||||
/** a width to apply to the resulting image (overrides `scale`) */
|
||||
width?: number | null;
|
||||
/** a height to apply to the resulting image (overrides `scale`) */
|
||||
height?: number | null;
|
||||
/** a scale to apply to the resulting image (`scale` pixels = 1 module) */
|
||||
scale?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the raw outline of the QR code for use in an existing SVG.
|
||||
*
|
||||
* @param code the QR code to convert.
|
||||
* @returns a string suitable for passing to the `d` attribute of a `path`.
|
||||
*/
|
||||
export function toSvgPath(code: Bitmap2D): string;
|
||||
|
||||
/**
|
||||
* Generate an SVG element which can be added to the DOM.
|
||||
*
|
||||
* @param code the QR code to convert.
|
||||
* @param options optional configuration for the display.
|
||||
* @returns an SVG element.
|
||||
*/
|
||||
export function toSvg(
|
||||
code: Bitmap2D,
|
||||
target: Document | SVGElement,
|
||||
options?: Readonly<SVGOptions>,
|
||||
): SVGElement;
|
||||
|
||||
/**
|
||||
* Generate an SVG document which can be exported to a file or served from a
|
||||
* web server.
|
||||
*
|
||||
* @param code the QR code to convert.
|
||||
* @param options optional configuration for the display.
|
||||
* @returns an SVG document.
|
||||
*/
|
||||
export function toSvgSource(
|
||||
code: Bitmap2D,
|
||||
options?: Readonly<
|
||||
SVGOptions & {
|
||||
/** `true` to include an XML declaration at the start of the source (for standalone documents which will not be embedded inside another document) */
|
||||
xmlDeclaration?: boolean;
|
||||
}
|
||||
>,
|
||||
): string;
|
||||
|
||||
/**
|
||||
* Generate a `data:image/svg+xml` URL.
|
||||
*
|
||||
* @param code the QR code to convert.
|
||||
* @param options optional configuration for the display.
|
||||
* @returns a string suitable for use as the `src` of an `img` tag.
|
||||
*/
|
||||
export function toSvgDataURL(
|
||||
code: Bitmap2D,
|
||||
options?: Readonly<SVGOptions>,
|
||||
): string;
|
||||
}
|
||||
|
||||
declare module 'lean-qr/extras/node_export' {
|
||||
import type { RGBA, Bitmap2D as FullBitmap2D } from 'lean-qr';
|
||||
|
||||
type Bitmap2D = Pick<FullBitmap2D, 'size' | 'get'>;
|
||||
|
||||
export interface PNGOptions {
|
||||
/** the colour to use for modules which are 'on' (typically black) */
|
||||
on?: RGBA;
|
||||
/** the colour to use for modules which are 'off' (typically white) */
|
||||
off?: RGBA;
|
||||
/** the padding to apply around the output (filled with 'off') */
|
||||
pad?: number;
|
||||
/**
|
||||
* the padding to apply on the left and right of the output (filled with 'off')
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padX?: number;
|
||||
/**
|
||||
* the padding to apply on the top and bottom of the output (filled with 'off')
|
||||
* @deprecated use `pad` instead
|
||||
*/
|
||||
padY?: number;
|
||||
/** a scale to apply to the resulting image (`scale` pixels = 1 module) */
|
||||
scale?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a PNG document which can be exported to a file or served from a
|
||||
* web server.
|
||||
*
|
||||
* @param code the QR code to convert.
|
||||
* @param options optional configuration for the display.
|
||||
* @returns a PNG document.
|
||||
*/
|
||||
export function toPngBuffer(
|
||||
code: Bitmap2D,
|
||||
options?: Readonly<PNGOptions>,
|
||||
): Uint8Array;
|
||||
|
||||
/**
|
||||
* Generate a `data:image/png` URL.
|
||||
*
|
||||
* @param code the QR code to convert.
|
||||
* @param options optional configuration for the display.
|
||||
* @returns a string suitable for use as the `src` of an `img` tag.
|
||||
*/
|
||||
export function toPngDataURL(
|
||||
code: Bitmap2D,
|
||||
options?: Readonly<PNGOptions>,
|
||||
): string;
|
||||
}
|
||||
|
||||
declare module 'lean-qr/extras/react' {
|
||||
import type {
|
||||
Bitmap2D as FullBitmap2D,
|
||||
GenerateOptions,
|
||||
ImageDataOptions,
|
||||
} from 'lean-qr';
|
||||
import type {
|
||||
SVGOptions,
|
||||
toSvgDataURL as toSvgDataURLFn,
|
||||
} from 'lean-qr/extras/svg';
|
||||
|
||||
export interface AsyncFramework<T> {
|
||||
createElement: (
|
||||
type: 'canvas',
|
||||
props: {
|
||||
ref: any;
|
||||
style: { imageRendering: 'pixelated' };
|
||||
className: string;
|
||||
},
|
||||
) => T;
|
||||
useRef<T>(initialValue: T | null): { readonly current: T | null };
|
||||
useEffect(fn: () => void | (() => void), deps: unknown[]): void;
|
||||
}
|
||||
|
||||
interface QRComponentProps {
|
||||
content: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface AsyncQRComponentProps
|
||||
extends ImageDataOptions,
|
||||
GenerateOptions,
|
||||
QRComponentProps {}
|
||||
|
||||
export type AsyncQRComponent<T> = (
|
||||
props: Readonly<AsyncQRComponentProps>,
|
||||
) => T;
|
||||
|
||||
/**
|
||||
* Generate an asynchronous QR component (rendering to a `canvas`).
|
||||
* You should call this just once, in the global scope.
|
||||
*
|
||||
* ```js
|
||||
* import * as React from 'react';
|
||||
* import { generate } from 'lean-qr';
|
||||
* import { makeAsyncComponent } from 'lean-qr/extras/react';
|
||||
* const QR = makeAsyncComponent(React, generate);
|
||||
* ```
|
||||
*
|
||||
* This is not suitable for server-side rendering (use `makeSyncComponent`
|
||||
* instead).
|
||||
*
|
||||
* @param framework the framework to use (e.g. `React`).
|
||||
* @param generate the `generate` function to use
|
||||
* (from `lean-qr` or `lean-qr/nano`).
|
||||
* @param defaultProps optional default properties to apply when the
|
||||
* component is used (overridden by properties set on use).
|
||||
* @returns a component which can be rendered elsewhere.
|
||||
*/
|
||||
export function makeAsyncComponent<T>(
|
||||
framework: Readonly<AsyncFramework<T>>,
|
||||
generate: (
|
||||
data: string,
|
||||
options?: Readonly<GenerateOptions>,
|
||||
) => Pick<FullBitmap2D, 'toCanvas'>,
|
||||
defaultProps?: Readonly<Partial<AsyncQRComponentProps>>,
|
||||
): AsyncQRComponent<T>;
|
||||
|
||||
export interface SyncFramework<T> {
|
||||
createElement: (
|
||||
type: 'img',
|
||||
props: {
|
||||
src: string;
|
||||
style: { imageRendering: 'pixelated' };
|
||||
className: string;
|
||||
},
|
||||
) => T;
|
||||
useMemo<T>(fn: () => T, deps: unknown[]): T;
|
||||
}
|
||||
|
||||
export interface SyncQRComponentProps
|
||||
extends SVGOptions,
|
||||
GenerateOptions,
|
||||
QRComponentProps {}
|
||||
|
||||
export type SyncQRComponent<T> = (props: Readonly<SyncQRComponentProps>) => T;
|
||||
|
||||
/**
|
||||
* Generate a synchronous QR component (rendering to an SVG).
|
||||
* You should call this just once, in the global scope.
|
||||
*
|
||||
* ```js
|
||||
* import * as React from 'react';
|
||||
* import { generate } from 'lean-qr';
|
||||
* import { toSvgDataURL } from 'lean-qr/extras/svg';
|
||||
* import { makeSyncComponent } from 'lean-qr/extras/react';
|
||||
* const QR = makeSyncComponent(React, generate, toSvgDataURL);
|
||||
* ```
|
||||
*
|
||||
* This is best suited for server-side rendering (prefer
|
||||
* `makeAsyncComponent` if you only need client-side rendering).
|
||||
*
|
||||
* @param framework the framework to use (e.g. `React`).
|
||||
* @param generate the `generate` function to use
|
||||
* (from `lean-qr` or `lean-qr/nano`).
|
||||
* @param toSvgDataURL the `toSvgDataURL` function to use
|
||||
* (from `lean-qr/extras/svg`).
|
||||
* @param defaultProps optional default properties to apply when the
|
||||
* component is used (overridden by properties set on use).
|
||||
* @returns a component which can be rendered elsewhere.
|
||||
*/
|
||||
export function makeSyncComponent<T>(
|
||||
framework: Readonly<SyncFramework<T>>,
|
||||
generate: (
|
||||
data: string,
|
||||
options?: Readonly<GenerateOptions>,
|
||||
) => Pick<FullBitmap2D, 'size' | 'get'>,
|
||||
toSvgDataURL: typeof toSvgDataURLFn,
|
||||
defaultProps?: Readonly<Partial<SyncQRComponentProps>>,
|
||||
): SyncQRComponent<T>;
|
||||
}
|
||||
|
||||
declare module 'lean-qr/extras/vue' {
|
||||
import type {
|
||||
Bitmap2D as FullBitmap2D,
|
||||
GenerateOptions,
|
||||
ImageDataOptions,
|
||||
} from 'lean-qr';
|
||||
import type {
|
||||
SVGOptions,
|
||||
toSvgDataURL as toSvgDataURLFn,
|
||||
} from 'lean-qr/extras/svg';
|
||||
|
||||
export interface Framework<T> {
|
||||
h:
|
||||
| ((type: 'canvas', props: { ref: string; style: string }) => T)
|
||||
| ((type: 'img', props: { src: string; style: string }) => T);
|
||||
}
|
||||
|
||||
interface QRComponentProps {
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface VueCanvasComponentProps
|
||||
extends ImageDataOptions,
|
||||
GenerateOptions,
|
||||
QRComponentProps {}
|
||||
|
||||
type VueComponentDefinition<Props, Node> = {
|
||||
props: {
|
||||
[k in keyof Props]: {
|
||||
type: {
|
||||
(): Props[k];
|
||||
required: undefined extends Props[k] ? false : true;
|
||||
};
|
||||
};
|
||||
};
|
||||
render: () => Node;
|
||||
} & ThisType<unknown>;
|
||||
|
||||
/**
|
||||
* Generate a QR component which renders to a `canvas`.
|
||||
* You should call this just once, in the global scope.
|
||||
*
|
||||
* ```js
|
||||
* import { h, defineComponent } from 'vue';
|
||||
* import { generate } from 'lean-qr';
|
||||
* import { makeVueCanvasComponent } from 'lean-qr/extras/vue';
|
||||
* export const QR = defineComponent(makeVueCanvasComponent({ h }, generate));
|
||||
* ```
|
||||
*
|
||||
* This is not suitable for server-side rendering (use `makeSyncComponent`
|
||||
* instead).
|
||||
*
|
||||
* @param framework the framework to use (e.g. `{ h }`).
|
||||
* @param generate the `generate` function to use
|
||||
* (from `lean-qr` or `lean-qr/nano`).
|
||||
* @param defaultProps optional default properties to apply when the
|
||||
* component is used (overridden by properties set on use).
|
||||
* @returns a component which can be rendered elsewhere.
|
||||
*/
|
||||
export function makeVueCanvasComponent<T>(
|
||||
framework: Readonly<Framework<T>>,
|
||||
generate: (
|
||||
data: string,
|
||||
options?: Readonly<GenerateOptions>,
|
||||
) => Pick<FullBitmap2D, 'toCanvas'>,
|
||||
defaultProps?: Readonly<Partial<VueCanvasComponentProps>>,
|
||||
): VueComponentDefinition<Partial<VueCanvasComponentProps>, T>;
|
||||
|
||||
export interface VueSVGComponentProps
|
||||
extends SVGOptions,
|
||||
GenerateOptions,
|
||||
QRComponentProps {}
|
||||
|
||||
/**
|
||||
* Generate a QR component which renders to an SVG.
|
||||
* You should call this just once, in the global scope:
|
||||
*
|
||||
* ```js
|
||||
* import { h, defineComponent } from 'vue';
|
||||
* import { generate } from 'lean-qr';
|
||||
* import { toSvgDataURL } from 'lean-qr/extras/svg';
|
||||
* import { makeVueSvgComponent } from 'lean-qr/extras/vue';
|
||||
* export const QR = defineComponent(makeVueSvgComponent({ h }, generate, toSvgDataURL));
|
||||
* ```
|
||||
*
|
||||
* This is best suited for server-side rendering (prefer
|
||||
* `makeAsyncComponent` if you only need client-side rendering).
|
||||
*
|
||||
* @param framework the framework to use (e.g. `{ h }`).
|
||||
* @param generate the `generate` function to use
|
||||
* (from `lean-qr` or `lean-qr/nano`).
|
||||
* @param toSvgDataURL the `toSvgDataURL` function to use
|
||||
* (from `lean-qr/extras/svg`).
|
||||
* @param defaultProps optional default properties to apply when the
|
||||
* component is used (overridden by properties set on use).
|
||||
* @returns a component which can be rendered elsewhere.
|
||||
*/
|
||||
export function makeVueSvgComponent<T>(
|
||||
framework: Readonly<Framework<T>>,
|
||||
generate: (
|
||||
data: string,
|
||||
options?: Readonly<GenerateOptions>,
|
||||
) => Pick<FullBitmap2D, 'size' | 'get'>,
|
||||
toSvgDataURL: typeof toSvgDataURLFn,
|
||||
defaultProps?: Readonly<Partial<VueSVGComponentProps>>,
|
||||
): VueComponentDefinition<Partial<VueSVGComponentProps>, T>;
|
||||
}
|
||||
|
||||
declare module 'lean-qr/extras/errors' {
|
||||
/**
|
||||
* Convert an error into a human-readable message. This is intended for use
|
||||
* with Lean QR errors, but will return somewhat meaningful messages for
|
||||
* other errors too.
|
||||
*
|
||||
* @param error the error to convert.
|
||||
* @returns a human-readable message explaining the error.
|
||||
*/
|
||||
export function readError(error: unknown): string;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Computation, Queue } from "./core/index.js";
|
||||
import type { Effect } from "./core/index.js";
|
||||
export declare class CollectionQueue extends Queue {
|
||||
_collectionType: number;
|
||||
_nodes: Set<Effect>;
|
||||
_disabled: Computation<boolean>;
|
||||
constructor(type: number);
|
||||
run(type: number): void;
|
||||
notify(node: Effect, type: number, flags: number): any;
|
||||
merge(queue: CollectionQueue): void;
|
||||
}
|
||||
export declare enum BoundaryMode {
|
||||
VISIBLE = "visible",
|
||||
HIDDEN = "hidden"
|
||||
}
|
||||
export declare function createBoundary<T>(fn: () => T, condition: () => BoundaryMode): () => T | undefined;
|
||||
export declare function createSuspense(fn: () => any, fallback: () => any): () => any;
|
||||
export declare function createErrorBoundary<U>(fn: () => any, fallback: (error: unknown, reset: () => void) => U): () => any;
|
||||
export declare function flatten(children: any, options?: {
|
||||
skipNonRendered?: boolean;
|
||||
doNotUnwrap?: boolean;
|
||||
}): any;
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* See https://dev.to/modderme123/super-charging-fine-grained-reactive-performance-47ph
|
||||
* State clean corresponds to a node where all the sources are fully up to date
|
||||
* State check corresponds to a node where some sources (including grandparents) may have changed
|
||||
* State dirty corresponds to a node where the direct parents of a node has changed
|
||||
*/
|
||||
export declare const STATE_CLEAN = 0;
|
||||
export declare const STATE_CHECK = 1;
|
||||
export declare const STATE_DIRTY = 2;
|
||||
export declare const STATE_DISPOSED = 3;
|
||||
export declare const EFFECT_PURE = 0;
|
||||
export declare const EFFECT_RENDER = 1;
|
||||
export declare const EFFECT_USER = 2;
|
||||
export declare const SUPPORTS_PROXY: boolean;
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Nodes for constructing a graph of reactive values and reactive computations.
|
||||
*
|
||||
* - The graph is acyclic.
|
||||
* - The user inputs new values into the graph by calling .write() on one more computation nodes.
|
||||
* - The user retrieves computed results from the graph by calling .read() on one or more computation nodes.
|
||||
* - The library is responsible for running any necessary computations so that .read() is up to date
|
||||
* with all prior .write() calls anywhere in the graph.
|
||||
* - We call the input nodes 'roots' and the output nodes 'leaves' of the graph here.
|
||||
* - Changes flow from roots to leaves. It would be effective but inefficient to immediately
|
||||
* propagate all changes from a root through the graph to descendant leaves. Instead, we defer
|
||||
* change most change propagation computation until a leaf is accessed. This allows us to
|
||||
* coalesce computations and skip altogether recalculating unused sections of the graph.
|
||||
* - Each computation node tracks its sources and its observers (observers are other
|
||||
* elements that have this node as a source). Source and observer links are updated automatically
|
||||
* as observer computations re-evaluate and call get() on their sources.
|
||||
* - Each node stores a cache state (clean/check/dirty) to support the change propagation algorithm:
|
||||
*
|
||||
* In general, execution proceeds in three passes:
|
||||
*
|
||||
* 1. write() propagates changes down the graph to the leaves
|
||||
* direct children are marked as dirty and their deeper descendants marked as check
|
||||
* (no computations are evaluated)
|
||||
* 2. read() requests that parent nodes updateIfNecessary(), which proceeds recursively up the tree
|
||||
* to decide whether the node is clean (parents unchanged) or dirty (parents changed)
|
||||
* 3. updateIfNecessary() evaluates the computation if the node is dirty (the computations are
|
||||
* executed in root to leaf order)
|
||||
*/
|
||||
import { type Flags } from "./flags.js";
|
||||
import { Owner } from "./owner.js";
|
||||
import { type Transition } from "./scheduler.js";
|
||||
export interface SignalOptions<T> {
|
||||
id?: string;
|
||||
name?: string;
|
||||
equals?: ((prev: T, next: T) => boolean) | false;
|
||||
pureWrite?: boolean;
|
||||
unobserved?: () => void;
|
||||
}
|
||||
export interface SourceType {
|
||||
_observers: ObserverType[] | null;
|
||||
_unobserved?: () => void;
|
||||
_updateIfNecessary: () => void;
|
||||
_stateFlags: Flags;
|
||||
_time: number;
|
||||
_transition?: Transition;
|
||||
_cloned?: Computation;
|
||||
}
|
||||
export interface ObserverType {
|
||||
_sources: SourceType[] | null;
|
||||
_notify: (state: number, skipQueue?: boolean) => void;
|
||||
_handlerMask: Flags;
|
||||
_notifyFlags: (mask: Flags, newFlags: Flags) => void;
|
||||
_time: number;
|
||||
_cloned?: Computation;
|
||||
}
|
||||
/**
|
||||
* Returns the current observer.
|
||||
*/
|
||||
export declare function getObserver(): Computation | null;
|
||||
export declare const UNCHANGED: unique symbol;
|
||||
export type UNCHANGED = typeof UNCHANGED;
|
||||
export declare class Computation<T = any> extends Owner implements SourceType, ObserverType {
|
||||
_sources: SourceType[] | null;
|
||||
_observers: ObserverType[] | null;
|
||||
_value: T | undefined;
|
||||
_error: unknown;
|
||||
_compute: null | ((p?: T) => T);
|
||||
_name: string | undefined;
|
||||
_equals: false | ((a: T, b: T) => boolean);
|
||||
_unobserved: (() => void) | undefined;
|
||||
_pureWrite: boolean;
|
||||
/** Whether the computation is an error or has ancestors that are unresolved */
|
||||
_stateFlags: number;
|
||||
/** Which flags raised by sources are handled, vs. being passed through. */
|
||||
_handlerMask: number;
|
||||
_time: number;
|
||||
_forceNotify: boolean;
|
||||
_transition?: Transition | undefined;
|
||||
_cloned?: Computation;
|
||||
constructor(initialValue: T | undefined, compute: null | ((p?: T) => T), options?: SignalOptions<T>);
|
||||
_read(): T;
|
||||
/**
|
||||
* Return the current value of this computation
|
||||
* Automatically re-executes the surrounding computation when the value changes
|
||||
*/
|
||||
read(): T;
|
||||
/**
|
||||
* Return the current value of this computation
|
||||
* Automatically re-executes the surrounding computation when the value changes
|
||||
*
|
||||
* If the computation has any unresolved ancestors, this function waits for the value to resolve
|
||||
* before continuing
|
||||
*/
|
||||
wait(): T;
|
||||
/** Update the computation with a new value. */
|
||||
write(value: T | ((currentValue: T) => T) | UNCHANGED, flags?: number, raw?: boolean): T;
|
||||
/**
|
||||
* Set the current node's state, and recursively mark all of this node's observers as STATE_CHECK
|
||||
*/
|
||||
_notify(state: number, skipQueue?: boolean): void;
|
||||
/**
|
||||
* Notify the computation that one of its sources has changed flags.
|
||||
*
|
||||
* @param mask A bitmask for which flag(s) were changed.
|
||||
* @param newFlags The source's new flags, masked to just the changed ones.
|
||||
*/
|
||||
_notifyFlags(mask: Flags, newFlags: Flags): void;
|
||||
_setError(error: unknown): void;
|
||||
/**
|
||||
* This is the core part of the reactivity system, which makes sure that the values are updated
|
||||
* before they are read. We've also adapted it to return the loading state of the computation,
|
||||
* so that we can propagate that to the computation's observers.
|
||||
*
|
||||
* This function will ensure that the value and states we read from the computation are up to date
|
||||
*/
|
||||
_updateIfNecessary(): void;
|
||||
/**
|
||||
* Remove ourselves from the owner graph and the computation graph
|
||||
*/
|
||||
_disposeNode(): void;
|
||||
}
|
||||
/**
|
||||
* Reruns a computation's _compute function, producing a new value and keeping track of dependencies.
|
||||
*
|
||||
* It handles the updating of sources and observers, disposal of previous executions,
|
||||
* and error handling if the _compute function throws. It also sets the node as loading
|
||||
* if it reads any parents that are currently loading.
|
||||
*/
|
||||
export declare function update<T>(node: Computation<T>): void;
|
||||
export declare function isEqual<T>(a: T, b: T): boolean;
|
||||
/**
|
||||
* Returns the current value stored inside the given compute function without triggering any
|
||||
* dependencies. Use `untrack` if you want to also disable owner tracking.
|
||||
*/
|
||||
export declare function untrack<T>(fn: () => T): T;
|
||||
/**
|
||||
* Returns true if the given functinon contains signals that have been updated since the last time
|
||||
* the parent computation was run.
|
||||
*/
|
||||
export declare function hasUpdated(fn: () => any): boolean;
|
||||
/**
|
||||
* Returns an accessor that is true if the given function contains async signals that are out of date.
|
||||
*/
|
||||
export declare function isPending(fn: () => any): boolean;
|
||||
export declare function isPending(fn: () => any, loadingValue: boolean): boolean;
|
||||
/**
|
||||
* Attempts to resolve value of expression synchronously returning the last resolved value for any async computation.
|
||||
*/
|
||||
export declare function latest<T>(fn: () => T): T;
|
||||
export declare function latest<T, U>(fn: () => T, fallback: U): T | U;
|
||||
/**
|
||||
* Runs the given function in the given observer.
|
||||
*
|
||||
* Warning: Usually there are simpler ways of modeling a problem that avoid using this function
|
||||
*/
|
||||
export declare function runWithObserver<T>(observer: Computation, run: () => T): T | undefined;
|
||||
/**
|
||||
* A convenient wrapper that calls `compute` with the `owner` and `observer` and is guaranteed
|
||||
* to reset the global context after the computation is finished even if an error is thrown.
|
||||
*/
|
||||
export declare function compute<T>(owner: Owner | null, fn: (val: T) => T, observer: Computation<T>): T;
|
||||
export declare function compute<T>(owner: Owner | null, fn: (val: undefined) => T, observer: null): T;
|
||||
@@ -0,0 +1,39 @@
|
||||
import { EFFECT_RENDER, EFFECT_USER } from "./constants.js";
|
||||
import { Computation, type SignalOptions } from "./core.js";
|
||||
import { type Flags } from "./flags.js";
|
||||
/**
|
||||
* Effects are the leaf nodes of our reactive graph. When their sources change, they are
|
||||
* automatically added to the queue of effects to re-execute, which will cause them to fetch their
|
||||
* sources and recompute
|
||||
*/
|
||||
export declare class Effect<T = any> extends Computation<T> {
|
||||
_effect: (val: T, prev: T | undefined) => void | (() => void);
|
||||
_onerror: ((err: unknown, cleanup: () => void) => void) | undefined;
|
||||
_cleanup: (() => void) | undefined;
|
||||
_modified: boolean;
|
||||
_prevValue: T | undefined;
|
||||
_type: typeof EFFECT_RENDER | typeof EFFECT_USER;
|
||||
constructor(initialValue: T, compute: (val?: T) => T, effect: (val: T, prev: T | undefined) => void | (() => void), error?: (err: unknown) => void | (() => void), options?: SignalOptions<T> & {
|
||||
render?: boolean;
|
||||
defer?: boolean;
|
||||
});
|
||||
write(value: T, flags?: number): T;
|
||||
_notify(state: number, skipQueue?: boolean): void;
|
||||
_notifyFlags(mask: Flags, newFlags: Flags): void;
|
||||
_setError(error: unknown): void;
|
||||
_disposeNode(): void;
|
||||
_run(type: number): void;
|
||||
}
|
||||
export declare class EagerComputation<T = any> extends Computation<T> {
|
||||
constructor(initialValue: T, compute: () => T, options?: SignalOptions<T> & {
|
||||
defer?: boolean;
|
||||
});
|
||||
_notify(state: number, skipQueue?: boolean): void;
|
||||
_run(): void;
|
||||
}
|
||||
export declare class FirewallComputation extends Computation {
|
||||
firewall: boolean;
|
||||
constructor(compute: () => void);
|
||||
_notify(state: number, skipQueue?: boolean): void;
|
||||
_run(): void;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export declare class NotReadyError extends Error {
|
||||
}
|
||||
export declare class NoOwnerError extends Error {
|
||||
constructor();
|
||||
}
|
||||
export declare class ContextNotFoundError extends Error {
|
||||
constructor();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export type Flags = number;
|
||||
export declare const ERROR_OFFSET = 0;
|
||||
export declare const ERROR_BIT: number;
|
||||
export declare const ERROR: unique symbol;
|
||||
export declare const LOADING_OFFSET = 1;
|
||||
export declare const LOADING_BIT: number;
|
||||
export declare const LOADING: unique symbol;
|
||||
export declare const UNINITIALIZED_OFFSET = 2;
|
||||
export declare const UNINITIALIZED_BIT: number;
|
||||
export declare const UNINITIALIZED: unique symbol;
|
||||
export declare const DEFAULT_FLAGS: number;
|
||||
@@ -0,0 +1,7 @@
|
||||
export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.js";
|
||||
export { Owner, createContext, getContext, setContext, hasContext, getOwner, onCleanup, type Context, type ContextRecord, type Disposable } from "./owner.js";
|
||||
export { Computation, getObserver, isEqual, untrack, hasUpdated, isPending, latest, UNCHANGED, compute, runWithObserver, type SignalOptions } from "./core.js";
|
||||
export { Effect, EagerComputation } from "./effect.js";
|
||||
export { flush, Queue, incrementClock, transition, ActiveTransition, type IQueue } from "./scheduler.js";
|
||||
export * from "./constants.js";
|
||||
export * from "./flags.js";
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Owner tracking is used to enable nested tracking scopes with automatic cleanup.
|
||||
* We also use owners to also keep track of which error handling context we are in.
|
||||
*
|
||||
* If you write the following
|
||||
*
|
||||
* const a = createOwner(() => {
|
||||
* const b = createOwner(() => {});
|
||||
*
|
||||
* const c = createOwner(() => {
|
||||
* const d = createOwner(() => {});
|
||||
* });
|
||||
*
|
||||
* const e = createOwner(() => {});
|
||||
* });
|
||||
*
|
||||
* The owner tree will look like this:
|
||||
*
|
||||
* a
|
||||
* /|\
|
||||
* b-c-e
|
||||
* |
|
||||
* d
|
||||
*
|
||||
* Following the _nextSibling pointers of each owner will first give you its children, and then its siblings (in reverse).
|
||||
* a -> e -> c -> d -> b
|
||||
*
|
||||
* Note that the owner tree is largely orthogonal to the reactivity tree, and is much closer to the component tree.
|
||||
*/
|
||||
import { type IQueue } from "./scheduler.js";
|
||||
export type ContextRecord = Record<string | symbol, unknown>;
|
||||
export interface Disposable {
|
||||
(): void;
|
||||
}
|
||||
/**
|
||||
* Returns the currently executing parent owner.
|
||||
*/
|
||||
export declare function getOwner(): Owner | null;
|
||||
export declare function setOwner(owner: Owner | null): Owner | null;
|
||||
export declare class Owner {
|
||||
_parent: Owner | null;
|
||||
_nextSibling: Owner | null;
|
||||
_prevSibling: Owner | null;
|
||||
_state: number;
|
||||
_disposal: Disposable | Disposable[] | null;
|
||||
_context: ContextRecord;
|
||||
_queue: IQueue;
|
||||
_childCount: number;
|
||||
id: string | null;
|
||||
constructor(id?: string | null, skipAppend?: boolean);
|
||||
append(child: Owner): void;
|
||||
dispose(this: Owner, self?: boolean): void;
|
||||
_disposeNode(): void;
|
||||
emptyDisposal(): void;
|
||||
getNextChildId(): string;
|
||||
}
|
||||
export interface Context<T> {
|
||||
readonly id: symbol;
|
||||
readonly defaultValue: T | undefined;
|
||||
}
|
||||
/**
|
||||
* Context provides a form of dependency injection. It is used to save from needing to pass
|
||||
* data as props through intermediate components. This function creates a new context object
|
||||
* that can be used with `getContext` and `setContext`.
|
||||
*
|
||||
* A default value can be provided here which will be used when a specific value is not provided
|
||||
* via a `setContext` call.
|
||||
*/
|
||||
export declare function createContext<T>(defaultValue?: T, description?: string): Context<T>;
|
||||
/**
|
||||
* Attempts to get a context value for the given key.
|
||||
*
|
||||
* @throws `NoOwnerError` if there's no owner at the time of call.
|
||||
* @throws `ContextNotFoundError` if a context value has not been set yet.
|
||||
*/
|
||||
export declare function getContext<T>(context: Context<T>, owner?: Owner | null): T;
|
||||
/**
|
||||
* Attempts to set a context value on the parent scope with the given key.
|
||||
*
|
||||
* @throws `NoOwnerError` if there's no owner at the time of call.
|
||||
*/
|
||||
export declare function setContext<T>(context: Context<T>, value?: T, owner?: Owner | null): void;
|
||||
/**
|
||||
* Whether the given context is currently defined.
|
||||
*/
|
||||
export declare function hasContext(context: Context<any>, owner?: Owner | null): boolean;
|
||||
/**
|
||||
* Runs an effect once before the reactive scope is disposed
|
||||
* @param fn an effect that should run only once on cleanup
|
||||
*
|
||||
* @returns the same {@link fn} function that was passed in
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/lifecycle/on-cleanup
|
||||
*/
|
||||
export declare function onCleanup(fn: Disposable): Disposable;
|
||||
@@ -0,0 +1,86 @@
|
||||
import type { Computation, ObserverType, SourceType } from "./core.js";
|
||||
import type { Effect } from "./effect.js";
|
||||
export declare let clock: number;
|
||||
export declare function incrementClock(): void;
|
||||
export declare let ActiveTransition: Transition | null;
|
||||
export declare let Unobserved: SourceType[];
|
||||
export type QueueCallback = (type: number) => void;
|
||||
export interface IQueue {
|
||||
enqueue(type: number, fn: QueueCallback): void;
|
||||
run(type: number): boolean | void;
|
||||
flush(): void;
|
||||
addChild(child: IQueue): void;
|
||||
removeChild(child: IQueue): void;
|
||||
created: number;
|
||||
notify(...args: any[]): boolean;
|
||||
merge(queue: IQueue): void;
|
||||
_parent: IQueue | null;
|
||||
_cloned?: IQueue | undefined;
|
||||
}
|
||||
export declare class Queue implements IQueue {
|
||||
_parent: IQueue | null;
|
||||
_running: boolean;
|
||||
_queues: [QueueCallback[], QueueCallback[]];
|
||||
_children: IQueue[];
|
||||
created: number;
|
||||
enqueue(type: number, fn: QueueCallback): void;
|
||||
run(type: number): void;
|
||||
flush(): void;
|
||||
addChild(child: IQueue): any;
|
||||
removeChild(child: IQueue): any;
|
||||
notify(...args: any[]): boolean;
|
||||
merge(queue: Queue): void;
|
||||
}
|
||||
export declare const globalQueue: Queue;
|
||||
/**
|
||||
* By default, changes are batched on the microtask queue which is an async process. You can flush
|
||||
* the queue synchronously to get the latest updates by calling `flush()`.
|
||||
*/
|
||||
export declare function flush(): void;
|
||||
export declare function removeSourceObservers(node: ObserverType, index: number): void;
|
||||
export declare class Transition implements IQueue {
|
||||
_sources: Map<Computation, Computation>;
|
||||
_pendingNodes: Set<Effect>;
|
||||
_promises: Set<Promise<any>>;
|
||||
_optimistic: Set<(() => void) & {
|
||||
_transition?: Transition;
|
||||
}>;
|
||||
_done: Transition | boolean;
|
||||
_queues: [QueueCallback[], QueueCallback[]];
|
||||
_clonedQueues: Map<Queue, Queue>;
|
||||
_pureQueue: QueueCallback[];
|
||||
_children: IQueue[];
|
||||
_parent: IQueue | null;
|
||||
_running: boolean;
|
||||
_scheduled: boolean;
|
||||
_cloned: Queue;
|
||||
created: number;
|
||||
constructor();
|
||||
enqueue(type: number, fn: QueueCallback): void;
|
||||
run(type: number): void;
|
||||
flush(): void;
|
||||
addChild(child: IQueue): void;
|
||||
removeChild(child: IQueue): void;
|
||||
notify(node: Effect, type: number, flags: number): boolean;
|
||||
merge(queue: Transition): void;
|
||||
schedule(): void;
|
||||
runTransition(fn: () => any | Promise<any>, force?: boolean): void;
|
||||
addOptimistic(fn: (() => void) & {
|
||||
_transition?: Transition;
|
||||
}): void;
|
||||
}
|
||||
/**
|
||||
* Runs the given function in a transition scope, allowing for batch updates and optimizations.
|
||||
* This is useful for grouping multiple state updates together to avoid unnecessary re-renders.
|
||||
*
|
||||
* @param fn A function that receives a resume function to continue the transition.
|
||||
* The resume function can be called with another function to continue the transition.
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/advanced-reactivity/transition
|
||||
*/
|
||||
export declare function transition(fn: (resume: (fn: () => any | Promise<any>) => void) => any | Promise<any> | Iterable<any>): void;
|
||||
export declare function cloneGraph(node: Computation): Computation;
|
||||
export declare function getOGSource<T extends Computation>(input: T): T;
|
||||
export declare function getTransitionSource<T extends Computation>(input: T): T;
|
||||
export declare function getQueue(node: Computation): IQueue;
|
||||
export declare function initialDispose(node: any): void;
|
||||
@@ -0,0 +1,6 @@
|
||||
export { Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, createContext, flush, getContext, setContext, hasContext, getOwner, onCleanup, getObserver, isEqual, untrack, hasUpdated, isPending, latest, runWithObserver, transition, SUPPORTS_PROXY } from "./core/index.js";
|
||||
export type { SignalOptions, Context, ContextRecord, Disposable, IQueue } from "./core/index.js";
|
||||
export { mapArray, repeat, type Maybe } from "./map.js";
|
||||
export * from "./signals.js";
|
||||
export * from "./store/index.js";
|
||||
export { createSuspense, createErrorBoundary, createBoundary, flatten, type BoundaryMode } from "./boundaries.js";
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { Accessor } from "./signals.js";
|
||||
export type Maybe<T> = T | void | null | undefined | false;
|
||||
/**
|
||||
* Reactively transforms an array with a callback function - underlying helper for the `<For>` control flow
|
||||
*
|
||||
* similar to `Array.prototype.map`, but gets the value and index as accessors, transforms only values that changed and returns an accessor and reactively tracks changes to the list.
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/reactive-utilities/map-array
|
||||
*/
|
||||
export declare function mapArray<Item, MappedItem>(list: Accessor<Maybe<readonly Item[]>>, map: (value: Accessor<Item>, index: Accessor<number>) => MappedItem, options?: {
|
||||
keyed?: boolean | ((item: Item) => any);
|
||||
fallback?: Accessor<any>;
|
||||
}): Accessor<MappedItem[]>;
|
||||
/**
|
||||
* Reactively repeats a callback function the count provided - underlying helper for the `<Repeat>` control flow
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/reactive-utilities/repeat
|
||||
*/
|
||||
export declare function repeat(count: Accessor<number>, map: (index: number) => any, options?: {
|
||||
from?: Accessor<number | undefined>;
|
||||
fallback?: Accessor<any>;
|
||||
}): Accessor<any[]>;
|
||||
@@ -0,0 +1,180 @@
|
||||
import type { SignalOptions } from "./core/index.js";
|
||||
import { Owner } from "./core/index.js";
|
||||
import { type Store, type StoreSetter } from "./store/index.js";
|
||||
export type Accessor<T> = () => T;
|
||||
export type Setter<in out T> = {
|
||||
<U extends T>(...args: undefined extends T ? [] : [value: Exclude<U, Function> | ((prev: T) => U)]): undefined extends T ? undefined : U;
|
||||
<U extends T>(value: (prev: T) => U): U;
|
||||
<U extends T>(value: Exclude<U, Function>): U;
|
||||
<U extends T>(value: Exclude<U, Function> | ((prev: T) => U)): U;
|
||||
};
|
||||
export type Signal<T> = [get: Accessor<T>, set: Setter<T>];
|
||||
export type ComputeFunction<Prev, Next extends Prev = Prev> = (v: Prev) => Next;
|
||||
export type EffectFunction<Prev, Next extends Prev = Prev> = (v: Next, p?: Prev) => (() => void) | void;
|
||||
export type EffectBundle<Prev, Next extends Prev = Prev> = {
|
||||
effect: EffectFunction<Prev, Next>;
|
||||
error: (err: unknown, cleanup: () => void) => void;
|
||||
};
|
||||
export interface EffectOptions {
|
||||
name?: string;
|
||||
defer?: boolean;
|
||||
}
|
||||
export interface MemoOptions<T> {
|
||||
name?: string;
|
||||
equals?: false | ((prev: T, next: T) => boolean);
|
||||
}
|
||||
export type NoInfer<T extends any> = [T][T extends any ? 0 : never];
|
||||
/**
|
||||
* Creates a simple reactive state with a getter and setter
|
||||
* ```typescript
|
||||
* const [state: Accessor<T>, setState: Setter<T>] = createSignal<T>(
|
||||
* value: T,
|
||||
* options?: { name?: string, equals?: false | ((prev: T, next: T) => boolean) }
|
||||
* )
|
||||
* ```
|
||||
* @param value initial value of the state; if empty, the state's type will automatically extended with undefined; otherwise you need to extend the type manually if you want setting to undefined not be an error
|
||||
* @param options optional object with a name for debugging purposes and equals, a comparator function for the previous and next value to allow fine-grained control over the reactivity
|
||||
*
|
||||
* @returns ```typescript
|
||||
* [state: Accessor<T>, setState: Setter<T>]
|
||||
* ```
|
||||
* * the Accessor is a function that returns the current value and registers each call to the reactive root
|
||||
* * the Setter is a function that allows directly setting or mutating the value:
|
||||
* ```typescript
|
||||
* const [count, setCount] = createSignal(0);
|
||||
* setCount(count => count + 1);
|
||||
* ```
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/basic-reactivity/create-signal
|
||||
*/
|
||||
export declare function createSignal<T>(): Signal<T | undefined>;
|
||||
export declare function createSignal<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
|
||||
export declare function createSignal<T>(fn: ComputeFunction<T>, initialValue?: T, options?: SignalOptions<T>): Signal<T>;
|
||||
/**
|
||||
* Creates a readonly derived reactive memoized signal
|
||||
* ```typescript
|
||||
* export function createMemo<T>(
|
||||
* compute: (v: T) => T,
|
||||
* value?: T,
|
||||
* options?: { name?: string, equals?: false | ((prev: T, next: T) => boolean) }
|
||||
* ): () => T;
|
||||
* ```
|
||||
* @param compute a function that receives its previous or the initial value, if set, and returns a new value used to react on a computation
|
||||
* @param value an optional initial value for the computation; if set, fn will never receive undefined as first argument
|
||||
* @param options allows to set a name in dev mode for debugging purposes and use a custom comparison function in equals
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/basic-reactivity/create-memo
|
||||
*/
|
||||
export declare function createMemo<Next extends Prev, Prev = Next>(compute: ComputeFunction<undefined | NoInfer<Prev>, Next>): Accessor<Next>;
|
||||
export declare function createMemo<Next extends Prev, Init = Next, Prev = Next>(compute: ComputeFunction<Init | Prev, Next>, value: Init, options?: MemoOptions<Next>): Accessor<Next>;
|
||||
/**
|
||||
* Creates a readonly derived async reactive memoized signal
|
||||
* ```typescript
|
||||
* export function createAsync<T>(
|
||||
* compute: (v: T) => Promise<T> | T,
|
||||
* value?: T,
|
||||
* options?: { name?: string, equals?: false | ((prev: T, next: T) => boolean) }
|
||||
* ): () => T;
|
||||
* ```
|
||||
* @param compute a function that receives its previous or the initial value, if set, and returns a new value used to react on a computation
|
||||
* @param value an optional initial value for the computation; if set, fn will never receive undefined as first argument
|
||||
* @param options allows to set a name in dev mode for debugging purposes and use a custom comparison function in equals
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/basic-reactivity/create-async
|
||||
*/
|
||||
export declare function createAsync<T>(compute: (prev: T | undefined, refreshing: boolean) => Promise<T> | AsyncIterable<T> | T, value?: T, options?: MemoOptions<T>): Accessor<T> & {
|
||||
refresh: () => void;
|
||||
};
|
||||
/**
|
||||
* Creates a reactive effect that runs after the render phase
|
||||
* ```typescript
|
||||
* export function createEffect<T>(
|
||||
* compute: (prev: T) => T,
|
||||
* effect: (v: T, prev: T) => (() => void) | void,
|
||||
* value?: T,
|
||||
* options?: { name?: string }
|
||||
* ): void;
|
||||
* ```
|
||||
* @param compute a function that receives its previous or the initial value, if set, and returns a new value used to react on a computation
|
||||
* @param effect a function that receives the new value and is used to perform side effects, return a cleanup function to run on disposal
|
||||
* @param error an optional function that receives an error if thrown during the computation
|
||||
* @param value an optional initial value for the computation; if set, fn will never receive undefined as first argument
|
||||
* @param options allows to set a name in dev mode for debugging purposes
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/basic-reactivity/create-effect
|
||||
*/
|
||||
export declare function createEffect<Next>(compute: ComputeFunction<undefined | NoInfer<Next>, Next>, effect: EffectFunction<NoInfer<Next>, Next> | EffectBundle<NoInfer<Next>, Next>): void;
|
||||
export declare function createEffect<Next, Init = Next>(compute: ComputeFunction<Init | Next, Next>, effect: EffectFunction<Next, Next> | EffectBundle<Next, Next>, value: Init, options?: EffectOptions): void;
|
||||
/**
|
||||
* Creates a reactive computation that runs during the render phase as DOM elements are created and updated but not necessarily connected
|
||||
* ```typescript
|
||||
* export function createRenderEffect<T>(
|
||||
* compute: (prev: T) => T,
|
||||
* effect: (v: T, prev: T) => (() => void) | void,
|
||||
* value?: T,
|
||||
* options?: { name?: string }
|
||||
* ): void;
|
||||
* ```
|
||||
* @param compute a function that receives its previous or the initial value, if set, and returns a new value used to react on a computation
|
||||
* @param effect a function that receives the new value and is used to perform side effects
|
||||
* @param value an optional initial value for the computation; if set, fn will never receive undefined as first argument
|
||||
* @param options allows to set a name in dev mode for debugging purposes
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/secondary-primitives/create-render-effect
|
||||
*/
|
||||
export declare function createRenderEffect<Next>(compute: ComputeFunction<undefined | NoInfer<Next>, Next>, effect: EffectFunction<NoInfer<Next>, Next>): void;
|
||||
export declare function createRenderEffect<Next, Init = Next>(compute: ComputeFunction<Init | Next, Next>, effect: EffectFunction<Next, Next>, value: Init, options?: EffectOptions): void;
|
||||
/**
|
||||
* Creates a new non-tracked reactive context with manual disposal
|
||||
*
|
||||
* @param fn a function in which the reactive state is scoped
|
||||
* @returns the output of `fn`.
|
||||
*
|
||||
* @description https://docs.solidjs.com/reference/reactive-utilities/create-root
|
||||
*/
|
||||
export declare function createRoot<T>(init: ((dispose: () => void) => T) | (() => T), options?: {
|
||||
id: string;
|
||||
}): T;
|
||||
/**
|
||||
* Runs the given function in the given owner to move ownership of nested primitives and cleanups.
|
||||
* This method untracks the current scope.
|
||||
*
|
||||
* Warning: Usually there are simpler ways of modeling a problem that avoid using this function
|
||||
*/
|
||||
export declare function runWithOwner<T>(owner: Owner | null, run: () => T): T;
|
||||
/**
|
||||
* Returns a promise of the resolved value of a reactive expression
|
||||
* @param fn a reactive expression to resolve
|
||||
*/
|
||||
export declare function resolve<T>(fn: () => T): Promise<T>;
|
||||
/** Allows the user to mark a state change as non-urgent.
|
||||
*
|
||||
* @see {@link https://docs.solidjs.com/reference/advanced-reactivity/transition}
|
||||
*
|
||||
* @returns A tuple containing an accessor for the pending state and a function to start a transition.
|
||||
*/
|
||||
export declare function useTransition(): [
|
||||
get: Accessor<boolean>,
|
||||
start: (fn: (resume: (fn: () => any | Promise<any>) => void) => any | Promise<any> | Iterable<any>) => void
|
||||
];
|
||||
/**
|
||||
* Creates an optimistic store that can be used to optimistically update a value
|
||||
* and then revert it back to the previous value at end of transition.
|
||||
* ```typescript
|
||||
* export function createOptimistic<T>(
|
||||
* fn: (store: T) => void,
|
||||
* initial: T,
|
||||
* options?: { key?: string | ((item: NonNullable<any>) => any); all?: boolean }
|
||||
* ): [get: Store<T>, set: StoreSetter<T>];
|
||||
* ```
|
||||
* @param fn a function that receives the current store and can be used to mutate it directly inside a transition
|
||||
* @param initial The initial value of the signal.
|
||||
* @param options Optional signal options.
|
||||
*
|
||||
* @returns A tuple containing an accessor for the current value and a setter function to apply changes.
|
||||
*/
|
||||
export declare function createOptimistic<T extends object = {}>(initial: T | Store<T>): [get: Store<T>, set: StoreSetter<T>];
|
||||
export declare function createOptimistic<T extends object = {}>(fn: (store: T) => void, initial: T | Store<T>, options?: {
|
||||
key?: string | ((item: NonNullable<any>) => any);
|
||||
all?: boolean;
|
||||
}): [get: Store<T>, set: StoreSetter<T>];
|
||||
@@ -0,0 +1,6 @@
|
||||
export type { Store, StoreSetter, StoreNode, NotWrappable, SolidStore } from "./store.js";
|
||||
export type { Merge, Omit } from "./utils.js";
|
||||
export { isWrappable, createStore, deep, $TRACK, $PROXY, $TARGET } from "./store.js";
|
||||
export { createProjection } from "./projection.js";
|
||||
export { reconcile } from "./reconcile.js";
|
||||
export { snapshot, merge, omit } from "./utils.js";
|
||||
@@ -0,0 +1,7 @@
|
||||
import { type Store, type StoreOptions } from "./store.js";
|
||||
/**
|
||||
* Creates a mutable derived value
|
||||
*
|
||||
* @see {@link https://github.com/solidjs/x-reactivity#createprojection}
|
||||
*/
|
||||
export declare function createProjection<T extends Object>(fn: (draft: T) => void | T, initialValue?: T, options?: StoreOptions): Store<T>;
|
||||
@@ -0,0 +1 @@
|
||||
export declare function reconcile<T extends U, U>(value: T, key: string | ((item: NonNullable<any>) => any), all?: boolean): (state: U) => void;
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Computation } from "../core/index.js";
|
||||
export type Store<T> = Readonly<T>;
|
||||
export type StoreSetter<T> = (fn: (state: T) => T | void) => void;
|
||||
export type StoreOptions = {
|
||||
key?: string | ((item: NonNullable<any>) => any);
|
||||
all?: boolean;
|
||||
};
|
||||
type DataNode = Computation<any>;
|
||||
type DataNodes = Record<PropertyKey, DataNode>;
|
||||
export declare const $TRACK: unique symbol, $DEEP: unique symbol, $TARGET: unique symbol, $PROXY: unique symbol, $DELETED: unique symbol;
|
||||
export declare const STORE_VALUE = "v", STORE_OVERRIDE = "o", STORE_NODE = "n", STORE_HAS = "h", STORE_WRAP = "w", STORE_LOOKUP = "l";
|
||||
export type StoreNode = {
|
||||
[$PROXY]: any;
|
||||
[STORE_VALUE]: Record<PropertyKey, any>;
|
||||
[STORE_OVERRIDE]?: Record<PropertyKey, any>;
|
||||
[STORE_NODE]?: DataNodes;
|
||||
[STORE_HAS]?: DataNodes;
|
||||
[STORE_WRAP]?: (value: any, target?: StoreNode) => any;
|
||||
[STORE_LOOKUP]?: WeakMap<any, any>;
|
||||
};
|
||||
export declare namespace SolidStore {
|
||||
interface Unwrappable {
|
||||
}
|
||||
}
|
||||
export type NotWrappable = string | number | bigint | symbol | boolean | Function | null | undefined | SolidStore.Unwrappable[keyof SolidStore.Unwrappable];
|
||||
export declare function createStoreProxy<T extends object>(value: T, traps?: ProxyHandler<StoreNode>, extend?: Record<PropertyKey, any>): any;
|
||||
export declare const storeLookup: WeakMap<object, any>;
|
||||
export declare function wrap<T extends Record<PropertyKey, any>>(value: T, target?: StoreNode): T;
|
||||
export declare function isWrappable<T>(obj: T | NotWrappable): obj is T;
|
||||
export declare function getKeys(source: Record<PropertyKey, any>, override: Record<PropertyKey, any> | undefined, enumerable?: boolean): PropertyKey[];
|
||||
export declare function getPropertyDescriptor(source: Record<PropertyKey, any>, override: Record<PropertyKey, any> | undefined, property: PropertyKey): PropertyDescriptor | undefined;
|
||||
export declare const storeTraps: ProxyHandler<StoreNode>;
|
||||
export declare function storeSetter<T extends object>(store: Store<T>, fn: (draft: T) => T | void): void;
|
||||
export declare function createStore<T extends object = {}>(store: T | Store<T>): [get: Store<T>, set: StoreSetter<T>];
|
||||
export declare function createStore<T extends object = {}>(fn: (store: T) => void, store: T | Store<T>, options?: StoreOptions): [get: Store<T>, set: StoreSetter<T>];
|
||||
export declare function deep<T extends object>(store: Store<T>): Store<T>;
|
||||
export {};
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Returns a non reactive copy of the store object.
|
||||
* It will attempt to preserver the original reference unless the value has been modified.
|
||||
* @param item store proxy object
|
||||
*/
|
||||
export declare function snapshot<T>(item: T): T;
|
||||
export declare function snapshot<T>(item: T, map?: Map<unknown, unknown>, lookup?: WeakMap<any, any>): T;
|
||||
type DistributeOverride<T, F> = T extends undefined ? F : T;
|
||||
type Override<T, U> = T extends any ? U extends any ? {
|
||||
[K in keyof T]: K extends keyof U ? DistributeOverride<U[K], T[K]> : T[K];
|
||||
} & {
|
||||
[K in keyof U]: K extends keyof T ? DistributeOverride<U[K], T[K]> : U[K];
|
||||
} : T & U : T & U;
|
||||
type OverrideSpread<T, U> = T extends any ? {
|
||||
[K in keyof ({
|
||||
[K in keyof T]: any;
|
||||
} & {
|
||||
[K in keyof U]?: any;
|
||||
} & {
|
||||
[K in U extends any ? keyof U : keyof U]?: any;
|
||||
})]: K extends keyof T ? Exclude<U extends any ? U[K & keyof U] : never, undefined> | T[K] : U extends any ? U[K & keyof U] : never;
|
||||
} : T & U;
|
||||
type Simplify<T> = T extends any ? {
|
||||
[K in keyof T]: T[K];
|
||||
} : T;
|
||||
type _Merge<T extends unknown[], Curr = {}> = T extends [
|
||||
infer Next | (() => infer Next),
|
||||
...infer Rest
|
||||
] ? _Merge<Rest, Override<Curr, Next>> : T extends [...infer Rest, infer Next | (() => infer Next)] ? Override<_Merge<Rest, Curr>, Next> : T extends [] ? Curr : T extends (infer I | (() => infer I))[] ? OverrideSpread<Curr, I> : Curr;
|
||||
export type Merge<T extends unknown[]> = Simplify<_Merge<T>>;
|
||||
export declare function merge<T extends unknown[]>(...sources: T): Merge<T>;
|
||||
export type Omit<T, K extends readonly (keyof T)[]> = {
|
||||
[P in keyof T as Exclude<P, K[number]>]: T[P];
|
||||
};
|
||||
export declare function omit<T extends Record<any, any>, K extends readonly (keyof T)[]>(props: T, ...keys: K): Omit<T, K>;
|
||||
export {};
|
||||
@@ -9,5 +9,5 @@
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext", "WebWorker"],
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"exclude": ["scripts/packages", "scripts/bridge"]
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
pools.js
|
||||
metrics.js
|
||||
@@ -1,64 +0,0 @@
|
||||
// Should be generated by server
|
||||
export const serdeIndex = {
|
||||
/**
|
||||
* @param {Index} v
|
||||
*/
|
||||
serialize(v) {
|
||||
switch (v) {
|
||||
case /** @satisfies {DateIndex} */ (0):
|
||||
return "dateindex";
|
||||
case /** @satisfies {DecadeIndex} */ (1):
|
||||
return "decadeindex";
|
||||
case /** @satisfies {DifficultyEpoch} */ (2):
|
||||
return "difficultyepoch";
|
||||
case /** @satisfies {EmptyOutputIndex} */ (3):
|
||||
return "emptyoutputindex";
|
||||
case /** @satisfies {HalvingEpoch} */ (4):
|
||||
return "halvingepoch";
|
||||
case /** @satisfies {Height} */ (5):
|
||||
return "height";
|
||||
case /** @satisfies {InputIndex} */ (6):
|
||||
return "inputindex";
|
||||
case /** @satisfies {MonthIndex} */ (7):
|
||||
return "monthindex";
|
||||
case /** @satisfies {OpReturnIndex} */ (8):
|
||||
return "opreturnindex";
|
||||
case /** @satisfies {OutputIndex} */ (9):
|
||||
return "outputindex";
|
||||
case /** @satisfies {P2AAddressIndex} */ (10):
|
||||
return "p2aaddressindex";
|
||||
case /** @satisfies {P2MSOutputIndex} */ (11):
|
||||
return "p2msoutputindex";
|
||||
case /** @satisfies {P2PK33AddressIndex} */ (12):
|
||||
return "p2pk33addressindex";
|
||||
case /** @satisfies {P2PK65AddressIndex} */ (13):
|
||||
return "p2pk65addressindex";
|
||||
case /** @satisfies {P2PKHAddressIndex} */ (14):
|
||||
return "p2pkhaddressindex";
|
||||
case /** @satisfies {P2SHAddressIndex} */ (15):
|
||||
return "p2shaddressindex";
|
||||
case /** @satisfies {P2TRAddressIndex} */ (16):
|
||||
return "p2traddressindex";
|
||||
case /** @satisfies {P2WPKHAddressIndex} */ (17):
|
||||
return "p2wpkhaddressindex";
|
||||
case /** @satisfies {P2WSHAddressIndex} */ (18):
|
||||
return "p2wshaddressindex";
|
||||
case /** @satisfies {QuarterIndex} */ (19):
|
||||
return "quarterindex";
|
||||
case /** @satisfies {SemesterIndex} */ (20):
|
||||
return "semesterindex";
|
||||
case /** @satisfies {TxIndex} */ (21):
|
||||
return "txindex";
|
||||
case /** @satisfies {UnknownOutputIndex} */ (22):
|
||||
return "unknownoutputindex";
|
||||
case /** @satisfies {WeekIndex} */ (23):
|
||||
return "weekindex";
|
||||
case /** @satisfies {YearIndex} */ (24):
|
||||
return "yearindex";
|
||||
case /** @satisfies {LoadedAddressIndex} */ (25):
|
||||
return "loadedaddressindex";
|
||||
case /** @satisfies {EmptyAddressIndex} */ (26):
|
||||
return "emptyaddressindex";
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* @import { Signal, Signals, Accessor } from "../solidjs-signals/index";
|
||||
*
|
||||
* @import { DateIndex, DecadeIndex, DifficultyEpoch, Index, HalvingEpoch, Height, MonthIndex, P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2MSOutputIndex, P2AAddressIndex, P2TRAddressIndex, P2WPKHAddressIndex, P2WSHAddressIndex, TxIndex, InputIndex, OutputIndex, WeekIndex, SemesterIndex, YearIndex, MetricToIndexes, QuarterIndex, EmptyOutputIndex, OpReturnIndex, UnknownOutputIndex, EmptyAddressIndex, LoadedAddressIndex } from "./metrics"
|
||||
*
|
||||
* @typedef {[number, number, number, number]} OHLCTuple
|
||||
*
|
||||
* @typedef {any} Metric
|
||||
*/
|
||||