this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

backfill data for the user from the car file

theres no other functionality except the basic car backfill lol

+790 -5
+445 -5
Cargo.lock
··· 129 129 ] 130 130 131 131 [[package]] 132 + name = "anyhow" 133 + version = "1.0.100" 134 + source = "registry+https://github.com/rust-lang/crates.io-index" 135 + checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" 136 + 137 + [[package]] 132 138 name = "ascii" 133 139 version = "1.1.0" 134 140 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 488 494 "multihash", 489 495 "serde", 490 496 "serde_bytes", 491 - "unsigned-varint", 497 + "unsigned-varint 0.8.0", 492 498 ] 493 499 494 500 [[package]] ··· 544 550 version = "0.4.3" 545 551 source = "registry+https://github.com/rust-lang/crates.io-index" 546 552 checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" 553 + 554 + [[package]] 555 + name = "cordyceps" 556 + version = "0.3.4" 557 + source = "registry+https://github.com/rust-lang/crates.io-index" 558 + checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" 559 + dependencies = [ 560 + "loom", 561 + "tracing", 562 + ] 547 563 548 564 [[package]] 549 565 name = "core-foundation" ··· 666 682 ] 667 683 668 684 [[package]] 685 + name = "curve25519-dalek" 686 + version = "4.1.3" 687 + source = "registry+https://github.com/rust-lang/crates.io-index" 688 + checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" 689 + dependencies = [ 690 + "cfg-if", 691 + "cpufeatures", 692 + "curve25519-dalek-derive", 693 + "digest", 694 + "fiat-crypto", 695 + "rustc_version", 696 + "subtle", 697 + "zeroize", 698 + ] 699 + 700 + [[package]] 701 + name = "curve25519-dalek-derive" 702 + version = "0.1.1" 703 + source = "registry+https://github.com/rust-lang/crates.io-index" 704 + checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" 705 + dependencies = [ 706 + "proc-macro2", 707 + "quote", 708 + "syn 2.0.109", 709 + ] 710 + 711 + [[package]] 669 712 name = "darling" 670 713 version = "0.21.3" 671 714 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 785 828 ] 786 829 787 830 [[package]] 831 + name = "derive_more" 832 + version = "1.0.0" 833 + source = "registry+https://github.com/rust-lang/crates.io-index" 834 + checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" 835 + dependencies = [ 836 + "derive_more-impl", 837 + ] 838 + 839 + [[package]] 840 + name = "derive_more-impl" 841 + version = "1.0.0" 842 + source = "registry+https://github.com/rust-lang/crates.io-index" 843 + checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" 844 + dependencies = [ 845 + "proc-macro2", 846 + "quote", 847 + "syn 2.0.109", 848 + "unicode-xid", 849 + ] 850 + 851 + [[package]] 852 + name = "diatomic-waker" 853 + version = "0.2.3" 854 + source = "registry+https://github.com/rust-lang/crates.io-index" 855 + checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" 856 + 857 + [[package]] 788 858 name = "digest" 789 859 version = "0.10.7" 790 860 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 834 904 ] 835 905 836 906 [[package]] 907 + name = "ed25519" 908 + version = "2.2.3" 909 + source = "registry+https://github.com/rust-lang/crates.io-index" 910 + checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" 911 + dependencies = [ 912 + "pkcs8", 913 + "signature", 914 + ] 915 + 916 + [[package]] 917 + name = "ed25519-dalek" 918 + version = "2.2.0" 919 + source = "registry+https://github.com/rust-lang/crates.io-index" 920 + checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" 921 + dependencies = [ 922 + "curve25519-dalek", 923 + "ed25519", 924 + "rand_core 0.6.4", 925 + "serde", 926 + "sha2", 927 + "subtle", 928 + "zeroize", 929 + ] 930 + 931 + [[package]] 837 932 name = "either" 838 933 version = "1.15.0" 839 934 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 970 1065 ] 971 1066 972 1067 [[package]] 1068 + name = "fiat-crypto" 1069 + version = "0.2.9" 1070 + source = "registry+https://github.com/rust-lang/crates.io-index" 1071 + checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" 1072 + 1073 + [[package]] 973 1074 name = "filetime" 974 1075 version = "0.2.26" 975 1076 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1005 1106 dependencies = [ 1006 1107 "futures-core", 1007 1108 "futures-sink", 1008 - "spin", 1109 + "spin 0.9.8", 1009 1110 ] 1010 1111 1011 1112 [[package]] ··· 1040 1141 ] 1041 1142 1042 1143 [[package]] 1144 + name = "futures" 1145 + version = "0.3.31" 1146 + source = "registry+https://github.com/rust-lang/crates.io-index" 1147 + checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 1148 + dependencies = [ 1149 + "futures-channel", 1150 + "futures-core", 1151 + "futures-executor", 1152 + "futures-io", 1153 + "futures-sink", 1154 + "futures-task", 1155 + "futures-util", 1156 + ] 1157 + 1158 + [[package]] 1159 + name = "futures-buffered" 1160 + version = "0.2.12" 1161 + source = "registry+https://github.com/rust-lang/crates.io-index" 1162 + checksum = "a8e0e1f38ec07ba4abbde21eed377082f17ccb988be9d988a5adbf4bafc118fd" 1163 + dependencies = [ 1164 + "cordyceps", 1165 + "diatomic-waker", 1166 + "futures-core", 1167 + "pin-project-lite", 1168 + "spin 0.10.0", 1169 + ] 1170 + 1171 + [[package]] 1043 1172 name = "futures-channel" 1044 1173 version = "0.3.31" 1045 1174 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1084 1213 checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 1085 1214 1086 1215 [[package]] 1216 + name = "futures-lite" 1217 + version = "2.6.1" 1218 + source = "registry+https://github.com/rust-lang/crates.io-index" 1219 + checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" 1220 + dependencies = [ 1221 + "fastrand", 1222 + "futures-core", 1223 + "futures-io", 1224 + "parking", 1225 + "pin-project-lite", 1226 + ] 1227 + 1228 + [[package]] 1087 1229 name = "futures-macro" 1088 1230 version = "0.3.31" 1089 1231 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1112 1254 source = "registry+https://github.com/rust-lang/crates.io-index" 1113 1255 checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 1114 1256 dependencies = [ 1257 + "futures-channel", 1115 1258 "futures-core", 1116 1259 "futures-io", 1117 1260 "futures-macro", ··· 1121 1264 "pin-project-lite", 1122 1265 "pin-utils", 1123 1266 "slab", 1267 + ] 1268 + 1269 + [[package]] 1270 + name = "generator" 1271 + version = "0.8.7" 1272 + source = "registry+https://github.com/rust-lang/crates.io-index" 1273 + checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" 1274 + dependencies = [ 1275 + "cc", 1276 + "cfg-if", 1277 + "libc", 1278 + "log", 1279 + "rustversion", 1280 + "windows", 1124 1281 ] 1125 1282 1126 1283 [[package]] ··· 1494 1651 "js-sys", 1495 1652 "log", 1496 1653 "wasm-bindgen", 1497 - "windows-core", 1654 + "windows-core 0.62.2", 1498 1655 ] 1499 1656 1500 1657 [[package]] ··· 1618 1775 name = "index" 1619 1776 version = "0.1.0" 1620 1777 dependencies = [ 1778 + "base64 0.22.1", 1621 1779 "env_logger", 1780 + "ipld-core", 1622 1781 "jacquard", 1782 + "jacquard-repo", 1623 1783 "log", 1784 + "serde", 1785 + "serde_ipld_dagcbor", 1786 + "serde_json", 1624 1787 "sqlx", 1625 1788 "thiserror 2.0.17", 1626 1789 "tokio", ··· 1707 1870 ] 1708 1871 1709 1872 [[package]] 1873 + name = "iroh-car" 1874 + version = "0.5.1" 1875 + source = "registry+https://github.com/rust-lang/crates.io-index" 1876 + checksum = "cb7f8cd4cb9aa083fba8b52e921764252d0b4dcb1cd6d120b809dbfe1106e81a" 1877 + dependencies = [ 1878 + "anyhow", 1879 + "cid", 1880 + "futures", 1881 + "serde", 1882 + "serde_ipld_dagcbor", 1883 + "thiserror 1.0.69", 1884 + "tokio", 1885 + "unsigned-varint 0.7.2", 1886 + ] 1887 + 1888 + [[package]] 1710 1889 name = "is_terminal_polyfill" 1711 1890 version = "1.70.2" 1712 1891 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1777 1956 "bytes", 1778 1957 "chrono", 1779 1958 "cid", 1959 + "ed25519-dalek", 1780 1960 "getrandom 0.2.16", 1781 1961 "getrandom 0.3.4", 1782 1962 "http", ··· 1905 2085 ] 1906 2086 1907 2087 [[package]] 2088 + name = "jacquard-repo" 2089 + version = "0.9.2" 2090 + source = "registry+https://github.com/rust-lang/crates.io-index" 2091 + checksum = "2ccdadfea11df142fbfb11cf7e5c1f7b8c0548758dedb0ce0eac182777f91f18" 2092 + dependencies = [ 2093 + "bytes", 2094 + "cid", 2095 + "ed25519-dalek", 2096 + "iroh-car", 2097 + "jacquard-common", 2098 + "jacquard-derive", 2099 + "k256", 2100 + "miette", 2101 + "multihash", 2102 + "n0-future", 2103 + "p256", 2104 + "serde", 2105 + "serde_bytes", 2106 + "serde_ipld_dagcbor", 2107 + "sha2", 2108 + "smol_str", 2109 + "thiserror 2.0.17", 2110 + "tokio", 2111 + "trait-variant", 2112 + ] 2113 + 2114 + [[package]] 1908 2115 name = "jiff" 1909 2116 version = "0.2.16" 1910 2117 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2005 2212 "cfg-if", 2006 2213 "ecdsa", 2007 2214 "elliptic-curve", 2215 + "once_cell", 2008 2216 "sha2", 2217 + "signature", 2009 2218 ] 2010 2219 2011 2220 [[package]] ··· 2025 2234 source = "registry+https://github.com/rust-lang/crates.io-index" 2026 2235 checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 2027 2236 dependencies = [ 2028 - "spin", 2237 + "spin 0.9.8", 2029 2238 ] 2030 2239 2031 2240 [[package]] ··· 2095 2304 checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" 2096 2305 2097 2306 [[package]] 2307 + name = "loom" 2308 + version = "0.7.2" 2309 + source = "registry+https://github.com/rust-lang/crates.io-index" 2310 + checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" 2311 + dependencies = [ 2312 + "cfg-if", 2313 + "generator", 2314 + "scoped-tls", 2315 + "tracing", 2316 + "tracing-subscriber", 2317 + ] 2318 + 2319 + [[package]] 2098 2320 name = "lru-cache" 2099 2321 version = "0.1.2" 2100 2322 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2150 2372 "proc-macro2", 2151 2373 "quote", 2152 2374 "syn 1.0.109", 2375 + ] 2376 + 2377 + [[package]] 2378 + name = "matchers" 2379 + version = "0.2.0" 2380 + source = "registry+https://github.com/rust-lang/crates.io-index" 2381 + checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" 2382 + dependencies = [ 2383 + "regex-automata", 2153 2384 ] 2154 2385 2155 2386 [[package]] ··· 2268 2499 dependencies = [ 2269 2500 "core2", 2270 2501 "serde", 2271 - "unsigned-varint", 2502 + "unsigned-varint 0.8.0", 2272 2503 ] 2273 2504 2274 2505 [[package]] ··· 2290 2521 ] 2291 2522 2292 2523 [[package]] 2524 + name = "n0-future" 2525 + version = "0.1.3" 2526 + source = "registry+https://github.com/rust-lang/crates.io-index" 2527 + checksum = "7bb0e5d99e681ab3c938842b96fcb41bf8a7bb4bfdb11ccbd653a7e83e06c794" 2528 + dependencies = [ 2529 + "cfg_aliases", 2530 + "derive_more", 2531 + "futures-buffered", 2532 + "futures-lite", 2533 + "futures-util", 2534 + "js-sys", 2535 + "pin-project", 2536 + "send_wrapper", 2537 + "tokio", 2538 + "tokio-util", 2539 + "wasm-bindgen", 2540 + "wasm-bindgen-futures", 2541 + "web-time", 2542 + ] 2543 + 2544 + [[package]] 2293 2545 name = "ndk-context" 2294 2546 version = "0.1.1" 2295 2547 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2309 2561 dependencies = [ 2310 2562 "memchr", 2311 2563 "minimal-lexical", 2564 + ] 2565 + 2566 + [[package]] 2567 + name = "nu-ansi-term" 2568 + version = "0.50.3" 2569 + source = "registry+https://github.com/rust-lang/crates.io-index" 2570 + checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" 2571 + dependencies = [ 2572 + "windows-sys 0.61.2", 2312 2573 ] 2313 2574 2314 2575 [[package]] ··· 2548 2809 ] 2549 2810 2550 2811 [[package]] 2812 + name = "pin-project" 2813 + version = "1.1.10" 2814 + source = "registry+https://github.com/rust-lang/crates.io-index" 2815 + checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" 2816 + dependencies = [ 2817 + "pin-project-internal", 2818 + ] 2819 + 2820 + [[package]] 2821 + name = "pin-project-internal" 2822 + version = "1.1.10" 2823 + source = "registry+https://github.com/rust-lang/crates.io-index" 2824 + checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" 2825 + dependencies = [ 2826 + "proc-macro2", 2827 + "quote", 2828 + "syn 2.0.109", 2829 + ] 2830 + 2831 + [[package]] 2551 2832 name = "pin-project-lite" 2552 2833 version = "0.2.16" 2553 2834 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3032 3313 checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" 3033 3314 3034 3315 [[package]] 3316 + name = "rustc_version" 3317 + version = "0.4.1" 3318 + source = "registry+https://github.com/rust-lang/crates.io-index" 3319 + checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 3320 + dependencies = [ 3321 + "semver", 3322 + ] 3323 + 3324 + [[package]] 3035 3325 name = "rustix" 3036 3326 version = "1.1.2" 3037 3327 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3131 3421 ] 3132 3422 3133 3423 [[package]] 3424 + name = "scoped-tls" 3425 + version = "1.0.1" 3426 + source = "registry+https://github.com/rust-lang/crates.io-index" 3427 + checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 3428 + 3429 + [[package]] 3134 3430 name = "scopeguard" 3135 3431 version = "1.2.0" 3136 3432 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3161 3457 ] 3162 3458 3163 3459 [[package]] 3460 + name = "send_wrapper" 3461 + version = "0.6.0" 3462 + source = "registry+https://github.com/rust-lang/crates.io-index" 3463 + checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" 3464 + 3465 + [[package]] 3164 3466 name = "serde" 3165 3467 version = "1.0.228" 3166 3468 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3321 3623 ] 3322 3624 3323 3625 [[package]] 3626 + name = "sharded-slab" 3627 + version = "0.1.7" 3628 + source = "registry+https://github.com/rust-lang/crates.io-index" 3629 + checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 3630 + dependencies = [ 3631 + "lazy_static", 3632 + ] 3633 + 3634 + [[package]] 3324 3635 name = "shlex" 3325 3636 version = "1.3.0" 3326 3637 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3418 3729 ] 3419 3730 3420 3731 [[package]] 3732 + name = "spin" 3733 + version = "0.10.0" 3734 + source = "registry+https://github.com/rust-lang/crates.io-index" 3735 + checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" 3736 + 3737 + [[package]] 3421 3738 name = "spki" 3422 3739 version = "0.7.3" 3423 3740 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3829 4146 ] 3830 4147 3831 4148 [[package]] 4149 + name = "thread_local" 4150 + version = "1.1.9" 4151 + source = "registry+https://github.com/rust-lang/crates.io-index" 4152 + checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" 4153 + dependencies = [ 4154 + "cfg-if", 4155 + ] 4156 + 4157 + [[package]] 3832 4158 name = "threadpool" 3833 4159 version = "1.8.1" 3834 4160 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3963 4289 "bytes", 3964 4290 "futures-core", 3965 4291 "futures-sink", 4292 + "futures-util", 3966 4293 "pin-project-lite", 3967 4294 "tokio", 3968 4295 ] ··· 4042 4369 checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" 4043 4370 dependencies = [ 4044 4371 "once_cell", 4372 + "valuable", 4373 + ] 4374 + 4375 + [[package]] 4376 + name = "tracing-log" 4377 + version = "0.2.0" 4378 + source = "registry+https://github.com/rust-lang/crates.io-index" 4379 + checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 4380 + dependencies = [ 4381 + "log", 4382 + "once_cell", 4383 + "tracing-core", 4384 + ] 4385 + 4386 + [[package]] 4387 + name = "tracing-subscriber" 4388 + version = "0.3.20" 4389 + source = "registry+https://github.com/rust-lang/crates.io-index" 4390 + checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" 4391 + dependencies = [ 4392 + "matchers", 4393 + "nu-ansi-term", 4394 + "once_cell", 4395 + "regex-automata", 4396 + "sharded-slab", 4397 + "smallvec", 4398 + "thread_local", 4399 + "tracing", 4400 + "tracing-core", 4401 + "tracing-log", 4045 4402 ] 4046 4403 4047 4404 [[package]] ··· 4128 4485 checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 4129 4486 4130 4487 [[package]] 4488 + name = "unicode-xid" 4489 + version = "0.2.6" 4490 + source = "registry+https://github.com/rust-lang/crates.io-index" 4491 + checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 4492 + 4493 + [[package]] 4494 + name = "unsigned-varint" 4495 + version = "0.7.2" 4496 + source = "registry+https://github.com/rust-lang/crates.io-index" 4497 + checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" 4498 + 4499 + [[package]] 4131 4500 name = "unsigned-varint" 4132 4501 version = "0.8.0" 4133 4502 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4174 4543 version = "0.2.2" 4175 4544 source = "registry+https://github.com/rust-lang/crates.io-index" 4176 4545 checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 4546 + 4547 + [[package]] 4548 + name = "valuable" 4549 + version = "0.1.1" 4550 + source = "registry+https://github.com/rust-lang/crates.io-index" 4551 + checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" 4177 4552 4178 4553 [[package]] 4179 4554 name = "vcpkg" ··· 4381 4756 ] 4382 4757 4383 4758 [[package]] 4759 + name = "windows" 4760 + version = "0.61.3" 4761 + source = "registry+https://github.com/rust-lang/crates.io-index" 4762 + checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" 4763 + dependencies = [ 4764 + "windows-collections", 4765 + "windows-core 0.61.2", 4766 + "windows-future", 4767 + "windows-link 0.1.3", 4768 + "windows-numerics", 4769 + ] 4770 + 4771 + [[package]] 4772 + name = "windows-collections" 4773 + version = "0.2.0" 4774 + source = "registry+https://github.com/rust-lang/crates.io-index" 4775 + checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" 4776 + dependencies = [ 4777 + "windows-core 0.61.2", 4778 + ] 4779 + 4780 + [[package]] 4781 + name = "windows-core" 4782 + version = "0.61.2" 4783 + source = "registry+https://github.com/rust-lang/crates.io-index" 4784 + checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" 4785 + dependencies = [ 4786 + "windows-implement", 4787 + "windows-interface", 4788 + "windows-link 0.1.3", 4789 + "windows-result 0.3.4", 4790 + "windows-strings 0.4.2", 4791 + ] 4792 + 4793 + [[package]] 4384 4794 name = "windows-core" 4385 4795 version = "0.62.2" 4386 4796 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4391 4801 "windows-link 0.2.1", 4392 4802 "windows-result 0.4.1", 4393 4803 "windows-strings 0.5.1", 4804 + ] 4805 + 4806 + [[package]] 4807 + name = "windows-future" 4808 + version = "0.2.1" 4809 + source = "registry+https://github.com/rust-lang/crates.io-index" 4810 + checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" 4811 + dependencies = [ 4812 + "windows-core 0.61.2", 4813 + "windows-link 0.1.3", 4814 + "windows-threading", 4394 4815 ] 4395 4816 4396 4817 [[package]] ··· 4426 4847 version = "0.2.1" 4427 4848 source = "registry+https://github.com/rust-lang/crates.io-index" 4428 4849 checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 4850 + 4851 + [[package]] 4852 + name = "windows-numerics" 4853 + version = "0.2.0" 4854 + source = "registry+https://github.com/rust-lang/crates.io-index" 4855 + checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" 4856 + dependencies = [ 4857 + "windows-core 0.61.2", 4858 + "windows-link 0.1.3", 4859 + ] 4429 4860 4430 4861 [[package]] 4431 4862 name = "windows-registry" ··· 4580 5011 "windows_x86_64_gnu 0.53.1", 4581 5012 "windows_x86_64_gnullvm 0.53.1", 4582 5013 "windows_x86_64_msvc 0.53.1", 5014 + ] 5015 + 5016 + [[package]] 5017 + name = "windows-threading" 5018 + version = "0.1.0" 5019 + source = "registry+https://github.com/rust-lang/crates.io-index" 5020 + checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" 5021 + dependencies = [ 5022 + "windows-link 0.1.3", 4583 5023 ] 4584 5024 4585 5025 [[package]]
+6
Cargo.toml
··· 4 4 edition = "2024" 5 5 6 6 [dependencies] 7 + base64 = "0.22.1" 7 8 env_logger = "0.11.8" 9 + ipld-core = "0.4.2" 8 10 jacquard = "0.9.0" 11 + jacquard-repo = "0.9.2" 9 12 log = "0.4.28" 13 + serde = "1.0.228" 14 + serde_ipld_dagcbor = "0.6.4" 15 + serde_json = { version = "1.0.145", features = ["raw_value"] } 10 16 sqlx = { version = "0.8.6", features = ["runtime-tokio", "postgres"] } 11 17 thiserror = "2.0.17" 12 18 tokio = "1.48.0"
+68
src/backfill/load_car.rs
··· 1 + use jacquard::api::com_atproto; 2 + use jacquard::client::Agent; 3 + use jacquard::types::{did::Did, tid::Tid}; 4 + use jacquard::url::Url; 5 + use jacquard::xrpc::XrpcExt; 6 + use jacquard_repo::commit::Commit; 7 + use jacquard_repo::{BlockStore, MemoryBlockStore, Mst}; 8 + use std::sync::Arc; 9 + use thiserror::Error; 10 + 11 + #[derive(Error, Debug)] 12 + pub enum Error { 13 + #[error("Error loading car file: {}", .0)] 14 + ClientError(#[from] jacquard::error::ClientError), 15 + #[error("Error loading car file: {}", .0)] 16 + RepoError(#[from] jacquard_repo::RepoError), 17 + #[error("Missing root block from car file (malformed car file)")] 18 + MissingRoot, 19 + } 20 + 21 + pub struct Car { 22 + pub storage: MemoryBlockStore, 23 + pub mst: Mst<MemoryBlockStore>, 24 + pub rev: Tid, 25 + } 26 + 27 + impl PartialEq<Tid> for Car { 28 + fn eq(&self, other: &Tid) -> bool { 29 + &self.rev == other 30 + } 31 + } 32 + 33 + use std::cmp::Ordering; 34 + impl PartialOrd<Tid> for Car { 35 + fn partial_cmp(&self, other: &Tid) -> Option<Ordering> { 36 + return match self.rev.compare_to(other) { 37 + 1 => Some(Ordering::Greater), 38 + 0 => Some(Ordering::Equal), 39 + -1 => Some(Ordering::Less), 40 + _ => None, 41 + }; 42 + } 43 + } 44 + 45 + pub async fn load_car(user: Did<'_>, pds: Url) -> Result<Car, Error> { 46 + let agent = Agent::unauthenticated(); 47 + let req = com_atproto::sync::get_repo::GetRepo::new() 48 + .did(user) 49 + .build(); 50 + let res = agent.xrpc(pds).send(&req).await?; 51 + 52 + let car = res.buffer(); 53 + let car = jacquard_repo::car::parse_car_bytes(&car).await?; 54 + 55 + let storage = jacquard_repo::storage::MemoryBlockStore::new_from_blocks(car.blocks); 56 + 57 + let root = storage 58 + .get(&car.root) 59 + .await? 60 + .ok_or_else(|| Error::MissingRoot)?; 61 + let root = Commit::from_cbor(&root)?; 62 + let rev = root.rev().to_owned(); 63 + let root = root.data(); 64 + 65 + let mst = Mst::load(Arc::new(storage.clone()), *root, None); 66 + 67 + Ok(Car { storage, mst, rev }) 68 + }
+138
src/backfill/mod.rs
··· 1 + use std::{cmp::Ordering, str::FromStr}; 2 + 3 + use jacquard::{types::tid::Tid, url::Url}; 4 + use sqlx::{Pool, Postgres, query}; 5 + use thiserror::Error; 6 + 7 + use crate::{ 8 + backfill::{load_car::load_car, parse_car::parse_car}, 9 + config, 10 + }; 11 + 12 + pub mod load_car; 13 + pub mod parse_car; 14 + 15 + const DB_MAX_REQ: usize = 65535; 16 + 17 + #[derive(Error, Debug)] 18 + pub enum Error { 19 + #[error("Error parsing TID: {}", .0)] 20 + TidParse(#[from] jacquard::types::string::AtStrError), 21 + #[error("{}", .0)] 22 + GetCarError(#[from] crate::backfill::load_car::Error), 23 + #[error( 24 + "The database claims to be more up to date than the PDS. 25 + Most likely either the PDS or repo is broken, or the database has been corrupted. 26 + Check your PDS repo is working and/or drop the database." 27 + )] 28 + DbTidTooLow, 29 + #[error("Database error: {}", .0)] 30 + DbError(#[from] sqlx::Error), 31 + #[error("{}", .0)] 32 + ParseCarError(#[from] crate::backfill::parse_car::Error), 33 + } 34 + 35 + /// backfill works as follows (https://docs.bsky.app/docs/advanced-guides/backfill) 36 + /// 37 + /// 1. resolve did -> pds 38 + /// 2. stream com.atproto.sync.subscribeRepos to a buffer 39 + /// 3. get a car file from com.atproto.sync.getRepo (diff if a rev is stored in database) 40 + /// 4. apply car file diff to database (incl rev) 41 + /// 5. start playing events from buffer 42 + /// 1. drop all events from other users 43 + /// 2. drop all events with a lower rev than current rev 44 + /// 3. apply event & update rev 45 + /// 4. (non blocking) get blobs if missing 46 + /// 5. (non blocking) parse for strongref and store strongrefs 47 + /// 6. (non blocking) trigger garbage collection of blobs and strongref 48 + /// 6. once buffer is empty, parse events live 49 + pub async fn backfill(pds: &str, conn: &Pool<Postgres>) -> Result<(), Error> { 50 + let db_rev = if let Some(rev) = query!( 51 + "SELECT (rev) FROM meta WHERE did = $1", 52 + config::USER.to_string() 53 + ) 54 + .fetch_one(conn) 55 + .await 56 + .ok() 57 + .and_then(|x| x.rev) 58 + { 59 + Tid::from_str(&rev)? 60 + } else { 61 + Tid::from_time(0, 0) 62 + }; 63 + 64 + let pds = Url::from_str(&format!("https://{pds}/")).unwrap(); 65 + let car = load_car(config::USER.clone(), pds).await?; 66 + 67 + match car.partial_cmp(&db_rev) { 68 + Some(val) => match val { 69 + // car rev newer than db rev 70 + // continue on; every other branch diverges 71 + Ordering::Greater => {} 72 + // revisions are the same so we can skip backfill 73 + Ordering::Equal => return Ok(()), 74 + // db rev newer than car rev 75 + // this means the db or car file is borked 76 + // panic out and let the user deal with things 77 + Ordering::Less => return Err(Error::DbTidTooLow), 78 + // panic!( 79 + // r"The database claims to be more up to date than the PDS. 80 + // Most likely either the PDS or repo is broken, or the database has been corrupted. 81 + // Check your PDS repo is working and/or drop the database." 82 + // ), 83 + }, 84 + // cant compare rev so assume all is ok and continue 85 + None => {} 86 + }; 87 + 88 + // erase all old records and return if it fails 89 + // we dont use diffs bc theyre complex and the overhead is minimal rn 90 + // only real overhead is network latency which would be ~= anyway 91 + let _ = query!("DELETE FROM records").execute(conn).await?; 92 + 93 + let data = parse_car(&car).await?; 94 + let mut data = data.chunks(DB_MAX_REQ / 4); 95 + 96 + while let Some(data) = data.next() { 97 + let mut query = sqlx::QueryBuilder::new("INSERT INTO records(collection, rkey, record) "); 98 + query.push_values( 99 + data, 100 + |mut b: sqlx::query_builder::Separated<'_, '_, Postgres, &'static str>, data| { 101 + b.push_bind(data.0.0.clone()) 102 + .push_bind(data.0.1.clone()) 103 + .push_bind(data.1.clone()); 104 + }, 105 + ); 106 + 107 + match query.build().execute(conn).await { 108 + Err(err) => { 109 + // couldnt backfill so go nuclear 110 + // this is program startup so its prolly safe lol 111 + println!("Got error \"{}\"\nDeleting records and exiting...", err); 112 + let _ = query!("DELETE FROM records").execute(conn).await?; 113 + panic!() 114 + } 115 + _ => {} 116 + }; 117 + } 118 + 119 + match query!( 120 + "UPDATE meta SET rev = $1 WHERE did = $2", 121 + car.rev.to_string(), 122 + config::USER.to_string() 123 + ) 124 + .execute(conn) 125 + .await 126 + { 127 + Err(err) => { 128 + // couldnt save tid so go nuclear 129 + // this is program startup so its prolly safe lol 130 + println!("Got error \"{}\"\nDeleting records and exiting...", err); 131 + let _ = query!("DELETE FROM records").execute(conn).await?; 132 + panic!() 133 + } 134 + _ => {} 135 + }; 136 + 137 + Ok(()) 138 + }
+69
src/backfill/parse_car.rs
··· 1 + use std::iter::zip; 2 + 3 + use ipld_core::{cid::CidGeneric, ipld::Ipld}; 4 + use jacquard::smol_str::SmolStr; 5 + use jacquard_repo::BlockStore; 6 + use serde_json::Value; 7 + use thiserror::Error; 8 + 9 + use crate::{backfill::load_car::Car, utils::ipld_json::ipld_to_json_value}; 10 + 11 + #[derive(Debug, Error)] 12 + pub enum Error { 13 + #[error("Error getting records from car file: {}", .0)] 14 + RepoError(#[from] jacquard_repo::RepoError), 15 + #[error("Missing CID from car file")] 16 + MissingCid, 17 + #[error("Could not decode record: {}", .0)] 18 + DecodeError(#[from] serde_ipld_dagcbor::DecodeError<std::convert::Infallible>), 19 + #[error("Could not convert into json: {}", .0)] 20 + IpldToJsonError(#[from] crate::utils::ipld_json::Error), 21 + #[error("Could not break {} into a collection and rkey", .0)] 22 + MalformedRecordKey(SmolStr), 23 + } 24 + 25 + pub type AccountData = Vec<((String, String), Value)>; 26 + 27 + pub async fn parse_car(car: &Car) -> Result<AccountData, Error> { 28 + let (keys, records): (Vec<SmolStr>, Vec<CidGeneric<64>>) = 29 + car.mst.leaves().await?.into_iter().unzip(); 30 + 31 + // convert keys into (collection, rkey) 32 + let keys = keys 33 + .into_iter() 34 + .map(|x| { 35 + let mut parts = x.split('/'); 36 + let collection = parts.next(); 37 + let rkey = parts.next(); 38 + if parts.next().is_none() 39 + && let Some(collection) = collection 40 + && let Some(rkey) = rkey 41 + { 42 + Ok::<_, Error>((collection.to_string(), rkey.to_string())) 43 + } else { 44 + Err(Error::MalformedRecordKey(x)) 45 + } 46 + }) 47 + .collect::<Result<Vec<_>, _>>()?; 48 + 49 + // convert records into Value 50 + let records = &records[..]; 51 + let records = car 52 + .storage 53 + .get_many(records) 54 + .await? 55 + .into_iter() 56 + .collect::<Option<Vec<_>>>() 57 + .ok_or_else(|| Error::MissingCid)? 58 + .into_iter() 59 + .map(|x| { 60 + let data = serde_ipld_dagcbor::from_slice::<Ipld>(&x)?; 61 + let value = ipld_to_json_value(&data)?; 62 + Ok::<_, Error>(value) 63 + }) 64 + .collect::<Result<Vec<_>, _>>()?; 65 + 66 + let data = zip(keys, records).collect::<Vec<((_, _), _)>>(); 67 + 68 + Ok(data) 69 + }
+9
src/main.rs
··· 1 1 use sqlx::{Pool, Postgres}; 2 2 3 + use crate::backfill::backfill; 4 + 5 + mod backfill; 3 6 mod config; 4 7 mod db; 5 8 mod utils; ··· 14 17 let pds = match utils::resolver::resolve(&config::USER).await { 15 18 Ok(val) => val, 16 19 Err(err) => panic!("{}", err), 20 + }; 21 + 22 + let backfilled = backfill(&pds, &conn).await; 23 + if let Err(err) = backfilled { 24 + println!("{}", err); 25 + return Err(()); 17 26 }; 18 27 19 28 println!("Completed sucessfully!");
+54
src/utils/ipld_json.rs
··· 1 + use base64::{Engine, prelude::BASE64_STANDARD_NO_PAD}; 2 + use ipld_core::{cid::multibase::Base, ipld::Ipld}; 3 + use log::warn; 4 + use serde_json::{Map, Number, Value, json}; 5 + use thiserror::Error; 6 + 7 + #[derive(Error, Debug)] 8 + pub enum Error { 9 + #[error("CID error: {}", .0)] 10 + CidError(#[from] ipld_core::cid::Error), 11 + #[error("Number too big: {0} > {1} || {0} < {2}", .val, u64::MAX, i64::MIN)] 12 + IntInvalidSize { val: i128 }, 13 + #[error("{} was NaN or Infinity", .0)] 14 + FloatInvalidSize(f64), 15 + } 16 + 17 + /// Convert any decoded IPLD data into serde_json Value 18 + /// 19 + /// This can be used for `sqlx` queries or decoded into plain JSON 20 + /// 21 + /// We can't use bog standard `to_string` or `to_json` functions 22 + /// due to the fact that ATProto DAG-CBOR does not map straight 23 + /// to ATProto JSON (see: `Ipld::Bytes` and `Ipld::Link` in the function definition.) 24 + /// 25 + /// To get an atproto JSON representation in string format call 26 + /// `Value::to_string(&self)` on the Value from this function 27 + pub fn ipld_to_json_value(data: &Ipld) -> Result<Value, Error> { 28 + Ok(match data { 29 + Ipld::Null => Value::Null, 30 + Ipld::Bool(bool) => Value::Bool(*bool), 31 + Ipld::Integer(int) => Value::Number( 32 + Number::from_i128(*int).ok_or_else(|| Error::IntInvalidSize { val: *int })?, 33 + ), 34 + Ipld::Float(float) => { 35 + warn!("Got float in IPLD data: {}", float); 36 + Value::Number(Number::from_f64(*float).ok_or_else(|| Error::FloatInvalidSize(*float))?) 37 + } 38 + Ipld::String(str) => Value::String(str.clone()), 39 + Ipld::Bytes(items) => json!({ "$bytes": BASE64_STANDARD_NO_PAD.encode(items) }), 40 + Ipld::List(iplds) => Value::Array( 41 + iplds 42 + .into_iter() 43 + .map(|x| ipld_to_json_value(x)) 44 + .collect::<Result<Vec<_>, _>>()?, 45 + ), 46 + Ipld::Map(map) => Value::Object( 47 + map.into_iter() 48 + .map(|(k, v)| Ok::<_, Error>((k.clone(), ipld_to_json_value(v)?))) 49 + .collect::<Result<Map<String, Value>, _>>()?, 50 + ), 51 + Ipld::Link(cid) => json!({"$link": 52 + cid.to_string_of_base(Base::Base32Lower)? }), 53 + }) 54 + }
+1
src/utils/mod.rs
··· 1 + pub mod ipld_json; 1 2 pub mod resolver;