Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

Merge pull request #16 from at-microcosm/constellation/filtering

Filter links by linker dids

authored by bad-example.com and committed by GitHub 6eb61e35 b0a66a10

Changed files
+790 -417
constellation
reflector
src
spacedust
who-am-i
src
+163 -133
Cargo.lock
··· 162 162 "proc-macro2", 163 163 "quote", 164 164 "serde", 165 - "syn 2.0.103", 165 + "syn 2.0.106", 166 166 ] 167 167 168 168 [[package]] ··· 204 204 dependencies = [ 205 205 "proc-macro2", 206 206 "quote", 207 - "syn 2.0.103", 207 + "syn 2.0.106", 208 208 "synstructure", 209 209 ] 210 210 ··· 216 216 dependencies = [ 217 217 "proc-macro2", 218 218 "quote", 219 - "syn 2.0.103", 219 + "syn 2.0.106", 220 220 ] 221 221 222 222 [[package]] ··· 274 274 dependencies = [ 275 275 "proc-macro2", 276 276 "quote", 277 - "syn 2.0.103", 277 + "syn 2.0.106", 278 278 ] 279 279 280 280 [[package]] ··· 291 291 dependencies = [ 292 292 "proc-macro2", 293 293 "quote", 294 - "syn 2.0.103", 294 + "syn 2.0.106", 295 295 ] 296 296 297 297 [[package]] ··· 507 507 "derive_utils", 508 508 "proc-macro2", 509 509 "quote", 510 - "syn 2.0.103", 510 + "syn 2.0.106", 511 511 ] 512 512 513 513 [[package]] ··· 603 603 "axum-core", 604 604 "bytes", 605 605 "cookie", 606 + "form_urlencoded", 606 607 "futures-util", 607 608 "headers", 608 609 "http", ··· 612 613 "pin-project-lite", 613 614 "rustversion", 614 615 "serde", 616 + "serde_html_form", 617 + "serde_path_to_error", 615 618 "tower", 616 619 "tower-layer", 617 620 "tower-service", ··· 746 749 "regex", 747 750 "rustc-hash 1.1.0", 748 751 "shlex", 749 - "syn 2.0.103", 752 + "syn 2.0.106", 750 753 "which", 751 754 ] 752 755 ··· 765 768 "regex", 766 769 "rustc-hash 1.1.0", 767 770 "shlex", 768 - "syn 2.0.103", 771 + "syn 2.0.106", 769 772 ] 770 773 771 774 [[package]] ··· 783 786 "regex", 784 787 "rustc-hash 2.1.1", 785 788 "shlex", 786 - "syn 2.0.103", 789 + "syn 2.0.106", 787 790 ] 788 791 789 792 [[package]] ··· 859 862 860 863 [[package]] 861 864 name = "camino" 862 - version = "1.1.9" 865 + version = "1.2.1" 863 866 source = "registry+https://github.com/rust-lang/crates.io-index" 864 - checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" 867 + checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" 865 868 dependencies = [ 866 - "serde", 869 + "serde_core", 867 870 ] 868 871 869 872 [[package]] ··· 1018 1021 "heck", 1019 1022 "proc-macro2", 1020 1023 "quote", 1021 - "syn 2.0.103", 1024 + "syn 2.0.106", 1022 1025 ] 1023 1026 1024 1027 [[package]] ··· 1310 1313 "proc-macro2", 1311 1314 "quote", 1312 1315 "strsim 0.11.1", 1313 - "syn 2.0.103", 1316 + "syn 2.0.106", 1314 1317 ] 1315 1318 1316 1319 [[package]] ··· 1332 1335 dependencies = [ 1333 1336 "darling_core 0.20.11", 1334 1337 "quote", 1335 - "syn 2.0.103", 1338 + "syn 2.0.106", 1336 1339 ] 1337 1340 1338 1341 [[package]] ··· 1372 1375 checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" 1373 1376 dependencies = [ 1374 1377 "data-encoding", 1375 - "syn 2.0.103", 1378 + "syn 1.0.109", 1376 1379 ] 1377 1380 1378 1381 [[package]] ··· 1434 1437 "darling 0.20.11", 1435 1438 "proc-macro2", 1436 1439 "quote", 1437 - "syn 2.0.103", 1440 + "syn 2.0.106", 1438 1441 ] 1439 1442 1440 1443 [[package]] ··· 1444 1447 checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" 1445 1448 dependencies = [ 1446 1449 "derive_builder_core", 1447 - "syn 2.0.103", 1450 + "syn 2.0.106", 1448 1451 ] 1449 1452 1450 1453 [[package]] ··· 1464 1467 dependencies = [ 1465 1468 "proc-macro2", 1466 1469 "quote", 1467 - "syn 2.0.103", 1470 + "syn 2.0.106", 1468 1471 "unicode-xid", 1469 1472 ] 1470 1473 ··· 1476 1479 dependencies = [ 1477 1480 "proc-macro2", 1478 1481 "quote", 1479 - "syn 2.0.103", 1482 + "syn 2.0.106", 1480 1483 ] 1481 1484 1482 1485 [[package]] ··· 1520 1523 dependencies = [ 1521 1524 "proc-macro2", 1522 1525 "quote", 1523 - "syn 2.0.103", 1526 + "syn 2.0.106", 1524 1527 ] 1525 1528 1526 1529 [[package]] ··· 1537 1540 1538 1541 [[package]] 1539 1542 name = "dropshot" 1540 - version = "0.16.2" 1543 + version = "0.16.3" 1541 1544 source = "registry+https://github.com/rust-lang/crates.io-index" 1542 - checksum = "50e8fed669e35e757646ad10f97c4d26dd22cce3da689b307954f7000d2719d0" 1545 + checksum = "eedf902e40c1024b8ed9ca16378a54e9655cdf0e698245ba82d81a3778dcbc54" 1543 1546 dependencies = [ 1544 1547 "async-stream", 1545 1548 "async-trait", ··· 1556 1559 "http-body-util", 1557 1560 "hyper", 1558 1561 "hyper-util", 1559 - "indexmap 2.9.0", 1562 + "indexmap 2.11.4", 1560 1563 "multer", 1561 1564 "openapiv3", 1562 1565 "paste", ··· 1579 1582 "thiserror 2.0.16", 1580 1583 "tokio", 1581 1584 "tokio-rustls 0.25.0", 1582 - "toml", 1585 + "toml 0.9.7", 1583 1586 "uuid", 1584 1587 "version_check", 1585 1588 "waitgroup", ··· 1587 1590 1588 1591 [[package]] 1589 1592 name = "dropshot_endpoint" 1590 - version = "0.16.2" 1593 + version = "0.16.4" 1591 1594 source = "registry+https://github.com/rust-lang/crates.io-index" 1592 - checksum = "acebb687581abdeaa2c89fa448818a5f803b0e68e5d7e7a1cf585a8f3c5c57ac" 1595 + checksum = "89d09440e73a9dcf8a0f7fbd6ab889a7751d59f0fe76e5082a0a6d5623ec6da3" 1593 1596 dependencies = [ 1594 1597 "heck", 1595 1598 "proc-macro2", ··· 1597 1600 "semver", 1598 1601 "serde", 1599 1602 "serde_tokenstream", 1600 - "syn 2.0.103", 1603 + "syn 2.0.106", 1601 1604 ] 1602 1605 1603 1606 [[package]] ··· 1670 1673 "heck", 1671 1674 "proc-macro2", 1672 1675 "quote", 1673 - "syn 2.0.103", 1676 + "syn 2.0.106", 1674 1677 ] 1675 1678 1676 1679 [[package]] ··· 1682 1685 "once_cell", 1683 1686 "proc-macro2", 1684 1687 "quote", 1685 - "syn 2.0.103", 1688 + "syn 2.0.106", 1686 1689 ] 1687 1690 1688 1691 [[package]] ··· 2062 2065 dependencies = [ 2063 2066 "proc-macro2", 2064 2067 "quote", 2065 - "syn 2.0.103", 2068 + "syn 2.0.106", 2066 2069 ] 2067 2070 2068 2071 [[package]] ··· 2187 2190 "futures-core", 2188 2191 "futures-sink", 2189 2192 "http", 2190 - "indexmap 2.9.0", 2193 + "indexmap 2.11.4", 2191 2194 "slab", 2192 2195 "tokio", 2193 2196 "tokio-util", ··· 2557 2560 "js-sys", 2558 2561 "log", 2559 2562 "wasm-bindgen", 2560 - "windows-core 0.61.0", 2563 + "windows-core", 2561 2564 ] 2562 2565 2563 2566 [[package]] ··· 2684 2687 dependencies = [ 2685 2688 "proc-macro2", 2686 2689 "quote", 2687 - "syn 2.0.103", 2690 + "syn 2.0.106", 2688 2691 ] 2689 2692 2690 2693 [[package]] ··· 2727 2730 2728 2731 [[package]] 2729 2732 name = "indexmap" 2730 - version = "2.9.0" 2733 + version = "2.11.4" 2731 2734 source = "registry+https://github.com/rust-lang/crates.io-index" 2732 - checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" 2735 + checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" 2733 2736 dependencies = [ 2734 2737 "equivalent", 2735 2738 "hashbrown 0.15.2", 2736 2739 "serde", 2740 + "serde_core", 2737 2741 ] 2738 2742 2739 2743 [[package]] ··· 2887 2891 dependencies = [ 2888 2892 "proc-macro2", 2889 2893 "quote", 2890 - "syn 2.0.103", 2894 + "syn 2.0.106", 2891 2895 ] 2892 2896 2893 2897 [[package]] ··· 3041 3045 checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 3042 3046 dependencies = [ 3043 3047 "cfg-if", 3044 - "windows-targets 0.52.6", 3048 + "windows-targets 0.48.5", 3045 3049 ] 3046 3050 3047 3051 [[package]] ··· 3264 3268 "spin", 3265 3269 "tokio", 3266 3270 "tokio-util", 3267 - "toml", 3271 + "toml 0.8.23", 3268 3272 "tracing", 3269 3273 "tracing-subscriber", 3270 3274 ] ··· 3354 3358 "http-body-util", 3355 3359 "hyper", 3356 3360 "hyper-util", 3357 - "indexmap 2.9.0", 3361 + "indexmap 2.11.4", 3358 3362 "ipnet", 3359 3363 "metrics", 3360 3364 "metrics-util 0.19.0", ··· 3375 3379 "hyper", 3376 3380 "hyper-rustls", 3377 3381 "hyper-util", 3378 - "indexmap 2.9.0", 3382 + "indexmap 2.11.4", 3379 3383 "ipnet", 3380 3384 "metrics", 3381 3385 "metrics-util 0.20.0", ··· 3737 3741 3738 3742 [[package]] 3739 3743 name = "openapiv3" 3740 - version = "2.0.0" 3744 + version = "2.2.0" 3741 3745 source = "registry+https://github.com/rust-lang/crates.io-index" 3742 - checksum = "cc02deea53ffe807708244e5914f6b099ad7015a207ee24317c22112e17d9c5c" 3746 + checksum = "5c8d427828b22ae1fff2833a03d8486c2c881367f1c336349f307f321e7f4d05" 3743 3747 dependencies = [ 3744 - "indexmap 2.9.0", 3748 + "indexmap 2.11.4", 3745 3749 "serde", 3746 3750 "serde_json", 3747 3751 ] ··· 3769 3773 dependencies = [ 3770 3774 "proc-macro2", 3771 3775 "quote", 3772 - "syn 2.0.103", 3776 + "syn 2.0.106", 3773 3777 ] 3774 3778 3775 3779 [[package]] ··· 3946 3950 "pest_meta", 3947 3951 "proc-macro2", 3948 3952 "quote", 3949 - "syn 2.0.103", 3953 + "syn 2.0.106", 3950 3954 ] 3951 3955 3952 3956 [[package]] ··· 3976 3980 dependencies = [ 3977 3981 "proc-macro2", 3978 3982 "quote", 3979 - "syn 2.0.103", 3983 + "syn 2.0.106", 3980 3984 ] 3981 3985 3982 3986 [[package]] ··· 4094 4098 "proc-macro-crate", 4095 4099 "proc-macro2", 4096 4100 "quote", 4097 - "syn 2.0.103", 4101 + "syn 2.0.106", 4098 4102 ] 4099 4103 4100 4104 [[package]] ··· 4107 4111 "bytes", 4108 4112 "derive_more", 4109 4113 "futures-util", 4110 - "indexmap 2.9.0", 4114 + "indexmap 2.11.4", 4111 4115 "itertools 0.14.0", 4112 4116 "mime", 4113 4117 "num-traits", ··· 4131 4135 dependencies = [ 4132 4136 "darling 0.20.11", 4133 4137 "http", 4134 - "indexmap 2.9.0", 4138 + "indexmap 2.11.4", 4135 4139 "mime", 4136 4140 "proc-macro-crate", 4137 4141 "proc-macro2", 4138 4142 "quote", 4139 4143 "regex", 4140 - "syn 2.0.103", 4144 + "syn 2.0.106", 4141 4145 "thiserror 2.0.16", 4142 4146 ] 4143 4147 ··· 4178 4182 checksum = "6837b9e10d61f45f987d50808f83d1ee3d206c66acf650c3e4ae2e1f6ddedf55" 4179 4183 dependencies = [ 4180 4184 "proc-macro2", 4181 - "syn 2.0.103", 4185 + "syn 2.0.106", 4182 4186 ] 4183 4187 4184 4188 [[package]] ··· 4489 4493 dependencies = [ 4490 4494 "proc-macro2", 4491 4495 "quote", 4492 - "syn 2.0.103", 4496 + "syn 2.0.106", 4493 4497 ] 4494 4498 4495 4499 [[package]] ··· 4871 4875 "proc-macro2", 4872 4876 "quote", 4873 4877 "serde_derive_internals", 4874 - "syn 2.0.103", 4878 + "syn 2.0.106", 4875 4879 ] 4876 4880 4877 4881 [[package]] ··· 4970 4974 4971 4975 [[package]] 4972 4976 name = "serde" 4973 - version = "1.0.219" 4977 + version = "1.0.228" 4974 4978 source = "registry+https://github.com/rust-lang/crates.io-index" 4975 - checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 4979 + checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 4976 4980 dependencies = [ 4981 + "serde_core", 4977 4982 "serde_derive", 4978 4983 ] 4979 4984 ··· 4987 4992 ] 4988 4993 4989 4994 [[package]] 4995 + name = "serde_core" 4996 + version = "1.0.228" 4997 + source = "registry+https://github.com/rust-lang/crates.io-index" 4998 + checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 4999 + dependencies = [ 5000 + "serde_derive", 5001 + ] 5002 + 5003 + [[package]] 4990 5004 name = "serde_derive" 4991 - version = "1.0.219" 5005 + version = "1.0.228" 4992 5006 source = "registry+https://github.com/rust-lang/crates.io-index" 4993 - checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 5007 + checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 4994 5008 dependencies = [ 4995 5009 "proc-macro2", 4996 5010 "quote", 4997 - "syn 2.0.103", 5011 + "syn 2.0.106", 4998 5012 ] 4999 5013 5000 5014 [[package]] ··· 5005 5019 dependencies = [ 5006 5020 "proc-macro2", 5007 5021 "quote", 5008 - "syn 2.0.103", 5022 + "syn 2.0.106", 5009 5023 ] 5010 5024 5011 5025 [[package]] ··· 5015 5029 checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4" 5016 5030 dependencies = [ 5017 5031 "form_urlencoded", 5018 - "indexmap 2.9.0", 5032 + "indexmap 2.11.4", 5019 5033 "itoa", 5020 5034 "ryu", 5021 5035 "serde", ··· 5023 5037 5024 5038 [[package]] 5025 5039 name = "serde_json" 5026 - version = "1.0.141" 5040 + version = "1.0.145" 5027 5041 source = "registry+https://github.com/rust-lang/crates.io-index" 5028 - checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" 5042 + checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" 5029 5043 dependencies = [ 5030 5044 "itoa", 5031 5045 "memchr", 5032 5046 "ryu", 5033 5047 "serde", 5048 + "serde_core", 5034 5049 ] 5035 5050 5036 5051 [[package]] ··· 5066 5081 ] 5067 5082 5068 5083 [[package]] 5084 + name = "serde_spanned" 5085 + version = "1.0.2" 5086 + source = "registry+https://github.com/rust-lang/crates.io-index" 5087 + checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" 5088 + dependencies = [ 5089 + "serde_core", 5090 + ] 5091 + 5092 + [[package]] 5069 5093 name = "serde_tokenstream" 5070 5094 version = "0.2.2" 5071 5095 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5074 5098 "proc-macro2", 5075 5099 "quote", 5076 5100 "serde", 5077 - "syn 2.0.103", 5101 + "syn 2.0.106", 5078 5102 ] 5079 5103 5080 5104 [[package]] ··· 5099 5123 "chrono", 5100 5124 "hex", 5101 5125 "indexmap 1.9.3", 5102 - "indexmap 2.9.0", 5126 + "indexmap 2.11.4", 5103 5127 "serde", 5104 5128 "serde_derive", 5105 5129 "serde_json", ··· 5116 5140 "darling 0.20.11", 5117 5141 "proc-macro2", 5118 5142 "quote", 5119 - "syn 2.0.103", 5143 + "syn 2.0.106", 5120 5144 ] 5121 5145 5122 5146 [[package]] ··· 5125 5149 source = "registry+https://github.com/rust-lang/crates.io-index" 5126 5150 checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" 5127 5151 dependencies = [ 5128 - "indexmap 2.9.0", 5152 + "indexmap 2.11.4", 5129 5153 "itoa", 5130 5154 "ryu", 5131 5155 "serde", ··· 5418 5442 5419 5443 [[package]] 5420 5444 name = "syn" 5421 - version = "2.0.103" 5445 + version = "2.0.106" 5422 5446 source = "registry+https://github.com/rust-lang/crates.io-index" 5423 - checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" 5447 + checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" 5424 5448 dependencies = [ 5425 5449 "proc-macro2", 5426 5450 "quote", ··· 5444 5468 dependencies = [ 5445 5469 "proc-macro2", 5446 5470 "quote", 5447 - "syn 2.0.103", 5471 + "syn 2.0.106", 5448 5472 ] 5449 5473 5450 5474 [[package]] ··· 5530 5554 dependencies = [ 5531 5555 "proc-macro2", 5532 5556 "quote", 5533 - "syn 2.0.103", 5557 + "syn 2.0.106", 5534 5558 ] 5535 5559 5536 5560 [[package]] ··· 5541 5565 dependencies = [ 5542 5566 "proc-macro2", 5543 5567 "quote", 5544 - "syn 2.0.103", 5568 + "syn 2.0.106", 5545 5569 ] 5546 5570 5547 5571 [[package]] ··· 5666 5690 dependencies = [ 5667 5691 "proc-macro2", 5668 5692 "quote", 5669 - "syn 2.0.103", 5693 + "syn 2.0.106", 5670 5694 ] 5671 5695 5672 5696 [[package]] ··· 5757 5781 checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" 5758 5782 dependencies = [ 5759 5783 "serde", 5760 - "serde_spanned", 5761 - "toml_datetime", 5784 + "serde_spanned 0.6.9", 5785 + "toml_datetime 0.6.11", 5762 5786 "toml_edit", 5763 5787 ] 5764 5788 5765 5789 [[package]] 5790 + name = "toml" 5791 + version = "0.9.7" 5792 + source = "registry+https://github.com/rust-lang/crates.io-index" 5793 + checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" 5794 + dependencies = [ 5795 + "indexmap 2.11.4", 5796 + "serde_core", 5797 + "serde_spanned 1.0.2", 5798 + "toml_datetime 0.7.2", 5799 + "toml_parser", 5800 + "toml_writer", 5801 + "winnow", 5802 + ] 5803 + 5804 + [[package]] 5766 5805 name = "toml_datetime" 5767 5806 version = "0.6.11" 5768 5807 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5772 5811 ] 5773 5812 5774 5813 [[package]] 5814 + name = "toml_datetime" 5815 + version = "0.7.2" 5816 + source = "registry+https://github.com/rust-lang/crates.io-index" 5817 + checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" 5818 + dependencies = [ 5819 + "serde_core", 5820 + ] 5821 + 5822 + [[package]] 5775 5823 name = "toml_edit" 5776 5824 version = "0.22.27" 5777 5825 source = "registry+https://github.com/rust-lang/crates.io-index" 5778 5826 checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" 5779 5827 dependencies = [ 5780 - "indexmap 2.9.0", 5828 + "indexmap 2.11.4", 5781 5829 "serde", 5782 - "serde_spanned", 5783 - "toml_datetime", 5830 + "serde_spanned 0.6.9", 5831 + "toml_datetime 0.6.11", 5784 5832 "toml_write", 5785 5833 "winnow", 5786 5834 ] 5787 5835 5788 5836 [[package]] 5837 + name = "toml_parser" 5838 + version = "1.0.3" 5839 + source = "registry+https://github.com/rust-lang/crates.io-index" 5840 + checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" 5841 + dependencies = [ 5842 + "winnow", 5843 + ] 5844 + 5845 + [[package]] 5789 5846 name = "toml_write" 5790 5847 version = "0.1.2" 5791 5848 source = "registry+https://github.com/rust-lang/crates.io-index" 5792 5849 checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" 5793 5850 5794 5851 [[package]] 5852 + name = "toml_writer" 5853 + version = "1.0.3" 5854 + source = "registry+https://github.com/rust-lang/crates.io-index" 5855 + checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" 5856 + 5857 + [[package]] 5795 5858 name = "tower" 5796 5859 version = "0.5.2" 5797 5860 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5857 5920 dependencies = [ 5858 5921 "proc-macro2", 5859 5922 "quote", 5860 - "syn 2.0.103", 5923 + "syn 2.0.106", 5861 5924 ] 5862 5925 5863 5926 [[package]] ··· 5907 5970 dependencies = [ 5908 5971 "proc-macro2", 5909 5972 "quote", 5910 - "syn 2.0.103", 5973 + "syn 2.0.106", 5911 5974 ] 5912 5975 5913 5976 [[package]] ··· 6107 6170 6108 6171 [[package]] 6109 6172 name = "uuid" 6110 - version = "1.16.0" 6173 + version = "1.18.1" 6111 6174 source = "registry+https://github.com/rust-lang/crates.io-index" 6112 - checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" 6175 + checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" 6113 6176 dependencies = [ 6114 6177 "getrandom 0.3.3", 6178 + "js-sys", 6115 6179 "serde", 6180 + "wasm-bindgen", 6116 6181 ] 6117 6182 6118 6183 [[package]] ··· 6227 6292 "log", 6228 6293 "proc-macro2", 6229 6294 "quote", 6230 - "syn 2.0.103", 6295 + "syn 2.0.106", 6231 6296 "wasm-bindgen-shared", 6232 6297 ] 6233 6298 ··· 6262 6327 dependencies = [ 6263 6328 "proc-macro2", 6264 6329 "quote", 6265 - "syn 2.0.103", 6330 + "syn 2.0.106", 6266 6331 "wasm-bindgen-backend", 6267 6332 "wasm-bindgen-shared", 6268 6333 ] ··· 6375 6440 source = "registry+https://github.com/rust-lang/crates.io-index" 6376 6441 checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 6377 6442 dependencies = [ 6378 - "windows-sys 0.59.0", 6443 + "windows-sys 0.48.0", 6379 6444 ] 6380 6445 6381 6446 [[package]] ··· 6390 6455 source = "registry+https://github.com/rust-lang/crates.io-index" 6391 6456 checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" 6392 6457 dependencies = [ 6393 - "windows-core 0.58.0", 6458 + "windows-core", 6394 6459 "windows-targets 0.52.6", 6395 6460 ] 6396 6461 ··· 6400 6465 source = "registry+https://github.com/rust-lang/crates.io-index" 6401 6466 checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" 6402 6467 dependencies = [ 6403 - "windows-implement 0.58.0", 6404 - "windows-interface 0.58.0", 6468 + "windows-implement", 6469 + "windows-interface", 6405 6470 "windows-result 0.2.0", 6406 6471 "windows-strings 0.1.0", 6407 6472 "windows-targets 0.52.6", 6408 6473 ] 6409 6474 6410 6475 [[package]] 6411 - name = "windows-core" 6412 - version = "0.61.0" 6413 - source = "registry+https://github.com/rust-lang/crates.io-index" 6414 - checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" 6415 - dependencies = [ 6416 - "windows-implement 0.60.0", 6417 - "windows-interface 0.59.1", 6418 - "windows-link", 6419 - "windows-result 0.3.4", 6420 - "windows-strings 0.4.2", 6421 - ] 6422 - 6423 - [[package]] 6424 6476 name = "windows-implement" 6425 6477 version = "0.58.0" 6426 6478 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 6428 6480 dependencies = [ 6429 6481 "proc-macro2", 6430 6482 "quote", 6431 - "syn 2.0.103", 6432 - ] 6433 - 6434 - [[package]] 6435 - name = "windows-implement" 6436 - version = "0.60.0" 6437 - source = "registry+https://github.com/rust-lang/crates.io-index" 6438 - checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" 6439 - dependencies = [ 6440 - "proc-macro2", 6441 - "quote", 6442 - "syn 2.0.103", 6483 + "syn 2.0.106", 6443 6484 ] 6444 6485 6445 6486 [[package]] ··· 6450 6491 dependencies = [ 6451 6492 "proc-macro2", 6452 6493 "quote", 6453 - "syn 2.0.103", 6454 - ] 6455 - 6456 - [[package]] 6457 - name = "windows-interface" 6458 - version = "0.59.1" 6459 - source = "registry+https://github.com/rust-lang/crates.io-index" 6460 - checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" 6461 - dependencies = [ 6462 - "proc-macro2", 6463 - "quote", 6464 - "syn 2.0.103", 6494 + "syn 2.0.106", 6465 6495 ] 6466 6496 6467 6497 [[package]] ··· 6668 6698 6669 6699 [[package]] 6670 6700 name = "winnow" 6671 - version = "0.7.11" 6701 + version = "0.7.13" 6672 6702 source = "registry+https://github.com/rust-lang/crates.io-index" 6673 - checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" 6703 + checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" 6674 6704 dependencies = [ 6675 6705 "memchr", 6676 6706 ] ··· 6767 6797 dependencies = [ 6768 6798 "proc-macro2", 6769 6799 "quote", 6770 - "syn 2.0.103", 6800 + "syn 2.0.106", 6771 6801 "synstructure", 6772 6802 ] 6773 6803 ··· 6797 6827 dependencies = [ 6798 6828 "proc-macro2", 6799 6829 "quote", 6800 - "syn 2.0.103", 6830 + "syn 2.0.106", 6801 6831 ] 6802 6832 6803 6833 [[package]] ··· 6808 6838 dependencies = [ 6809 6839 "proc-macro2", 6810 6840 "quote", 6811 - "syn 2.0.103", 6841 + "syn 2.0.106", 6812 6842 ] 6813 6843 6814 6844 [[package]] ··· 6828 6858 dependencies = [ 6829 6859 "proc-macro2", 6830 6860 "quote", 6831 - "syn 2.0.103", 6861 + "syn 2.0.106", 6832 6862 "synstructure", 6833 6863 ] 6834 6864 ··· 6850 6880 dependencies = [ 6851 6881 "proc-macro2", 6852 6882 "quote", 6853 - "syn 2.0.103", 6883 + "syn 2.0.106", 6854 6884 ] 6855 6885 6856 6886 [[package]] ··· 6872 6902 dependencies = [ 6873 6903 "proc-macro2", 6874 6904 "quote", 6875 - "syn 2.0.103", 6905 + "syn 2.0.106", 6876 6906 ] 6877 6907 6878 6908 [[package]]
+1 -1
constellation/Cargo.toml
··· 8 8 anyhow = "1.0.95" 9 9 askama = { version = "0.12.1", features = ["serde-json"] } 10 10 axum = "0.8.1" 11 - axum-extra = { version = "0.10.0", features = ["typed-header"] } 11 + axum-extra = { version = "0.10.0", features = ["query", "typed-header"] } 12 12 axum-metrics = "0.2" 13 13 bincode = "1.3.3" 14 14 clap = { version = "4.5.26", features = ["derive"] }
+2
constellation/src/bin/rocks-restore-from-backup.rs
··· 3 3 use clap::Parser; 4 4 use std::path::PathBuf; 5 5 6 + #[cfg(feature = "rocks")] 6 7 use rocksdb::backup::{BackupEngine, BackupEngineOptions, RestoreOptions}; 7 8 8 9 use std::time; ··· 19 20 to_data_dir: PathBuf, 20 21 } 21 22 23 + #[cfg(feature = "rocks")] 22 24 fn main() -> Result<()> { 23 25 let args = Args::parse(); 24 26
+47 -5
constellation/src/server/mod.rs
··· 11 11 use bincode::Options; 12 12 use serde::{Deserialize, Serialize}; 13 13 use serde_with::serde_as; 14 - use std::collections::HashMap; 14 + use std::collections::{HashMap, HashSet}; 15 15 use std::time::{Duration, UNIX_EPOCH}; 16 16 use tokio::net::{TcpListener, ToSocketAddrs}; 17 17 use tokio::task::block_in_place; ··· 238 238 collection: String, 239 239 path: String, 240 240 cursor: Option<OpaqueApiCursor>, 241 - limit: Option<u64>, 241 + /// Filter links only from these DIDs 242 + /// 243 + /// include multiple times to filter by multiple source DIDs 244 + #[serde(default)] 245 + did: Vec<String>, 246 + /// [deprecated] Filter links only from these DIDs 247 + /// 248 + /// format: comma-separated sequence of DIDs 249 + /// 250 + /// errors: if `did` parameter is also present 251 + /// 252 + /// deprecated: use `did`, which can be repeated multiple times 253 + from_dids: Option<String>, // comma separated: gross 254 + #[serde(default = "get_default_limit")] 255 + limit: u64, 242 256 // TODO: allow reverse (er, forward) order as well 257 + } 258 + fn get_default_limit() -> u64 { 259 + DEFAULT_CURSOR_LIMIT 243 260 } 244 261 #[derive(Template, Serialize)] 245 262 #[template(path = "links.html.j2")] ··· 255 272 } 256 273 fn get_links( 257 274 accept: ExtractAccept, 258 - query: Query<GetLinkItemsQuery>, 275 + query: axum_extra::extract::Query<GetLinkItemsQuery>, // supports multiple param occurrences 259 276 store: impl LinkReader, 260 277 ) -> Result<impl IntoResponse, http::StatusCode> { 261 278 let until = query ··· 265 282 .transpose()? 266 283 .map(|c| c.next); 267 284 268 - let limit = query.limit.unwrap_or(DEFAULT_CURSOR_LIMIT); 285 + let limit = query.limit; 269 286 if limit > DEFAULT_CURSOR_LIMIT_MAX { 270 287 return Err(http::StatusCode::BAD_REQUEST); 271 288 } 272 289 290 + let mut filter_dids: HashSet<Did> = HashSet::from_iter( 291 + query 292 + .did 293 + .iter() 294 + .map(|d| d.trim()) 295 + .filter(|d| !d.is_empty()) 296 + .map(|d| Did(d.to_string())), 297 + ); 298 + 299 + if let Some(comma_joined) = &query.from_dids { 300 + if !filter_dids.is_empty() { 301 + return Err(http::StatusCode::BAD_REQUEST); 302 + } 303 + for did in comma_joined.split(',') { 304 + filter_dids.insert(Did(did.to_string())); 305 + } 306 + } 307 + 273 308 let paged = store 274 - .get_links(&query.target, &query.collection, &query.path, limit, until) 309 + .get_links( 310 + &query.target, 311 + &query.collection, 312 + &query.path, 313 + limit, 314 + until, 315 + &filter_dids, 316 + ) 275 317 .map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)?; 276 318 277 319 let cursor = paged.next.map(|next| {
+15
constellation/src/storage/mem_store.rs
··· 166 166 path: &str, 167 167 limit: u64, 168 168 until: Option<u64>, 169 + filter_dids: &HashSet<Did>, 169 170 ) -> Result<PagedAppendingCollection<RecordId>> { 170 171 let data = self.0.lock().unwrap(); 171 172 let Some(paths) = data.targets.get(&Target::new(target)) else { ··· 183 184 next: None, 184 185 total: 0, 185 186 }); 187 + }; 188 + 189 + let did_rkeys: Vec<_> = if !filter_dids.is_empty() { 190 + did_rkeys 191 + .iter() 192 + .filter(|m| { 193 + Option::<(Did, RKey)>::clone(m) 194 + .map(|(did, _)| filter_dids.contains(&did)) 195 + .unwrap_or(false) 196 + }) 197 + .cloned() 198 + .collect() 199 + } else { 200 + did_rkeys.to_vec() 186 201 }; 187 202 188 203 let total = did_rkeys.len();
+259 -14
constellation/src/storage/mod.rs
··· 1 1 use crate::{ActionableEvent, CountsByCount, Did, RecordId}; 2 2 use anyhow::Result; 3 3 use serde::{Deserialize, Serialize}; 4 - use std::collections::HashMap; 4 + use std::collections::{HashMap, HashSet}; 5 5 6 6 pub mod mem_store; 7 7 pub use mem_store::MemStorage; ··· 59 59 path: &str, 60 60 limit: u64, 61 61 until: Option<u64>, 62 + filter_dids: &HashSet<Did>, 62 63 ) -> Result<PagedAppendingCollection<RecordId>>; 63 64 64 65 fn get_distinct_dids( ··· 145 146 ); 146 147 assert_eq!(storage.get_distinct_did_count("", "", "")?, 0); 147 148 assert_eq!( 148 - storage.get_links("a.com", "app.t.c", ".abc.uri", 100, None)?, 149 + storage.get_links( 150 + "a.com", 151 + "app.t.c", 152 + ".abc.uri", 153 + 100, 154 + None, 155 + &HashSet::default() 156 + )?, 149 157 PagedAppendingCollection { 150 158 version: (0, 0), 151 159 items: vec![], ··· 641 649 0, 642 650 )?; 643 651 assert_eq!( 644 - storage.get_links("a.com", "app.t.c", ".abc.uri", 100, None)?, 652 + storage.get_links( 653 + "a.com", 654 + "app.t.c", 655 + ".abc.uri", 656 + 100, 657 + None, 658 + &HashSet::default() 659 + )?, 645 660 PagedAppendingCollection { 646 661 version: (1, 0), 647 662 items: vec![RecordId { ··· 682 697 0, 683 698 )?; 684 699 } 685 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None)?; 700 + let links = 701 + storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None, &HashSet::default())?; 686 702 let dids = storage.get_distinct_dids("a.com", "app.t.c", ".abc.uri", 2, None)?; 687 703 assert_eq!( 688 704 links, ··· 713 729 total: 5, 714 730 } 715 731 ); 716 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, links.next)?; 732 + let links = storage.get_links( 733 + "a.com", 734 + "app.t.c", 735 + ".abc.uri", 736 + 2, 737 + links.next, 738 + &HashSet::default(), 739 + )?; 717 740 let dids = storage.get_distinct_dids("a.com", "app.t.c", ".abc.uri", 2, dids.next)?; 718 741 assert_eq!( 719 742 links, ··· 744 767 total: 5, 745 768 } 746 769 ); 747 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, links.next)?; 770 + let links = storage.get_links( 771 + "a.com", 772 + "app.t.c", 773 + ".abc.uri", 774 + 2, 775 + links.next, 776 + &HashSet::default(), 777 + )?; 748 778 let dids = storage.get_distinct_dids("a.com", "app.t.c", ".abc.uri", 2, dids.next)?; 749 779 assert_eq!( 750 780 links, ··· 771 801 assert_stats(storage.get_stats()?, 5..=5, 1..=1, 5..=5); 772 802 }); 773 803 804 + test_each_storage!(get_filtered_links, |storage| { 805 + let links = storage.get_links( 806 + "a.com", 807 + "app.t.c", 808 + ".abc.uri", 809 + 2, 810 + None, 811 + &HashSet::from([Did("did:plc:linker".to_string())]), 812 + )?; 813 + assert_eq!( 814 + links, 815 + PagedAppendingCollection { 816 + version: (0, 0), 817 + items: vec![], 818 + next: None, 819 + total: 0, 820 + } 821 + ); 822 + 823 + storage.push( 824 + &ActionableEvent::CreateLinks { 825 + record_id: RecordId { 826 + did: "did:plc:linker".into(), 827 + collection: "app.t.c".into(), 828 + rkey: "asdf".into(), 829 + }, 830 + links: vec![CollectedLink { 831 + target: Link::Uri("a.com".into()), 832 + path: ".abc.uri".into(), 833 + }], 834 + }, 835 + 0, 836 + )?; 837 + 838 + let links = storage.get_links( 839 + "a.com", 840 + "app.t.c", 841 + ".abc.uri", 842 + 2, 843 + None, 844 + &HashSet::from([Did("did:plc:linker".to_string())]), 845 + )?; 846 + assert_eq!( 847 + links, 848 + PagedAppendingCollection { 849 + version: (1, 0), 850 + items: vec![RecordId { 851 + did: "did:plc:linker".into(), 852 + collection: "app.t.c".into(), 853 + rkey: "asdf".into(), 854 + },], 855 + next: None, 856 + total: 1, 857 + } 858 + ); 859 + 860 + let links = storage.get_links( 861 + "a.com", 862 + "app.t.c", 863 + ".abc.uri", 864 + 2, 865 + None, 866 + &HashSet::from([Did("did:plc:someone-else".to_string())]), 867 + )?; 868 + assert_eq!( 869 + links, 870 + PagedAppendingCollection { 871 + version: (0, 0), 872 + items: vec![], 873 + next: None, 874 + total: 0, 875 + } 876 + ); 877 + 878 + storage.push( 879 + &ActionableEvent::CreateLinks { 880 + record_id: RecordId { 881 + did: "did:plc:linker".into(), 882 + collection: "app.t.c".into(), 883 + rkey: "asdf-2".into(), 884 + }, 885 + links: vec![CollectedLink { 886 + target: Link::Uri("a.com".into()), 887 + path: ".abc.uri".into(), 888 + }], 889 + }, 890 + 0, 891 + )?; 892 + storage.push( 893 + &ActionableEvent::CreateLinks { 894 + record_id: RecordId { 895 + did: "did:plc:someone-else".into(), 896 + collection: "app.t.c".into(), 897 + rkey: "asdf".into(), 898 + }, 899 + links: vec![CollectedLink { 900 + target: Link::Uri("a.com".into()), 901 + path: ".abc.uri".into(), 902 + }], 903 + }, 904 + 0, 905 + )?; 906 + 907 + let links = storage.get_links( 908 + "a.com", 909 + "app.t.c", 910 + ".abc.uri", 911 + 2, 912 + None, 913 + &HashSet::from([Did("did:plc:linker".to_string())]), 914 + )?; 915 + assert_eq!( 916 + links, 917 + PagedAppendingCollection { 918 + version: (2, 0), 919 + items: vec![ 920 + RecordId { 921 + did: "did:plc:linker".into(), 922 + collection: "app.t.c".into(), 923 + rkey: "asdf-2".into(), 924 + }, 925 + RecordId { 926 + did: "did:plc:linker".into(), 927 + collection: "app.t.c".into(), 928 + rkey: "asdf".into(), 929 + }, 930 + ], 931 + next: None, 932 + total: 2, 933 + } 934 + ); 935 + 936 + let links = storage.get_links( 937 + "a.com", 938 + "app.t.c", 939 + ".abc.uri", 940 + 2, 941 + None, 942 + &HashSet::from([ 943 + Did("did:plc:linker".to_string()), 944 + Did("did:plc:someone-else".to_string()), 945 + ]), 946 + )?; 947 + assert_eq!( 948 + links, 949 + PagedAppendingCollection { 950 + version: (3, 0), 951 + items: vec![ 952 + RecordId { 953 + did: "did:plc:someone-else".into(), 954 + collection: "app.t.c".into(), 955 + rkey: "asdf".into(), 956 + }, 957 + RecordId { 958 + did: "did:plc:linker".into(), 959 + collection: "app.t.c".into(), 960 + rkey: "asdf-2".into(), 961 + }, 962 + ], 963 + next: Some(1), 964 + total: 3, 965 + } 966 + ); 967 + 968 + let links = storage.get_links( 969 + "a.com", 970 + "app.t.c", 971 + ".abc.uri", 972 + 2, 973 + None, 974 + &HashSet::from([Did("did:plc:someone-unknown".to_string())]), 975 + )?; 976 + assert_eq!( 977 + links, 978 + PagedAppendingCollection { 979 + version: (0, 0), 980 + items: vec![], 981 + next: None, 982 + total: 0, 983 + } 984 + ); 985 + }); 986 + 774 987 test_each_storage!(get_links_exact_multiple, |storage| { 775 988 for i in 1..=4 { 776 989 storage.push( ··· 788 1001 0, 789 1002 )?; 790 1003 } 791 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None)?; 1004 + let links = 1005 + storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None, &HashSet::default())?; 792 1006 assert_eq!( 793 1007 links, 794 1008 PagedAppendingCollection { ··· 809 1023 total: 4, 810 1024 } 811 1025 ); 812 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, links.next)?; 1026 + let links = storage.get_links( 1027 + "a.com", 1028 + "app.t.c", 1029 + ".abc.uri", 1030 + 2, 1031 + links.next, 1032 + &HashSet::default(), 1033 + )?; 813 1034 assert_eq!( 814 1035 links, 815 1036 PagedAppendingCollection { ··· 850 1071 0, 851 1072 )?; 852 1073 } 853 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None)?; 1074 + let links = 1075 + storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None, &HashSet::default())?; 854 1076 assert_eq!( 855 1077 links, 856 1078 PagedAppendingCollection { ··· 885 1107 }, 886 1108 0, 887 1109 )?; 888 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, links.next)?; 1110 + let links = storage.get_links( 1111 + "a.com", 1112 + "app.t.c", 1113 + ".abc.uri", 1114 + 2, 1115 + links.next, 1116 + &HashSet::default(), 1117 + )?; 889 1118 assert_eq!( 890 1119 links, 891 1120 PagedAppendingCollection { ··· 926 1155 0, 927 1156 )?; 928 1157 } 929 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None)?; 1158 + let links = 1159 + storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None, &HashSet::default())?; 930 1160 assert_eq!( 931 1161 links, 932 1162 PagedAppendingCollection { ··· 955 1185 }), 956 1186 0, 957 1187 )?; 958 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, links.next)?; 1188 + let links = storage.get_links( 1189 + "a.com", 1190 + "app.t.c", 1191 + ".abc.uri", 1192 + 2, 1193 + links.next, 1194 + &HashSet::default(), 1195 + )?; 959 1196 assert_eq!( 960 1197 links, 961 1198 PagedAppendingCollection { ··· 989 1226 0, 990 1227 )?; 991 1228 } 992 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None)?; 1229 + let links = 1230 + storage.get_links("a.com", "app.t.c", ".abc.uri", 2, None, &HashSet::default())?; 993 1231 assert_eq!( 994 1232 links, 995 1233 PagedAppendingCollection { ··· 1014 1252 &ActionableEvent::DeactivateAccount("did:plc:asdf-1".into()), 1015 1253 0, 1016 1254 )?; 1017 - let links = storage.get_links("a.com", "app.t.c", ".abc.uri", 2, links.next)?; 1255 + let links = storage.get_links( 1256 + "a.com", 1257 + "app.t.c", 1258 + ".abc.uri", 1259 + 2, 1260 + links.next, 1261 + &HashSet::default(), 1262 + )?; 1018 1263 assert_eq!( 1019 1264 links, 1020 1265 PagedAppendingCollection {
+19 -1
constellation/src/storage/rocks_store.rs
··· 860 860 path: &str, 861 861 limit: u64, 862 862 until: Option<u64>, 863 + filter_dids: &HashSet<Did>, 863 864 ) -> Result<PagedAppendingCollection<RecordId>> { 864 865 let target_key = TargetKey( 865 866 Target(target.to_string()), ··· 876 877 }); 877 878 }; 878 879 879 - let linkers = self.get_target_linkers(&target_id)?; 880 + let mut linkers = self.get_target_linkers(&target_id)?; 881 + if !filter_dids.is_empty() { 882 + let mut did_filter = HashSet::new(); 883 + for did in filter_dids { 884 + let Some(DidIdValue(did_id, active)) = 885 + self.did_id_table.get_id_val(&self.db, did)? 886 + else { 887 + eprintln!("failed to find a did_id for {did:?}"); 888 + continue; 889 + }; 890 + if !active { 891 + eprintln!("excluding inactive did from filtered results"); 892 + continue; 893 + } 894 + did_filter.insert(did_id); 895 + } 896 + linkers.0.retain(|linker| did_filter.contains(&linker.0)); 897 + } 880 898 881 899 let (alive, gone) = linkers.count(); 882 900 let total = alive + gone;
+9 -6
constellation/templates/hello.html.j2
··· 20 20 21 21 <p> 22 22 This server has indexed <span class="stat">{{ stats.linking_records|human_number }}</span> links between <span class="stat">{{ stats.targetables|human_number }}</span> targets and sources from <span class="stat">{{ stats.dids|human_number }}</span> identities over <span class="stat">{{ days_indexed|human_number }}</span> days.<br/> 23 - <small>(indexing new records in real time, backfill still TODO)</small> 23 + <small>(indexing new records in real time, backfill coming soon!)</small> 24 24 </p> 25 25 26 - <p>The API is currently <strong>unstable</strong>. But feel free to use it! If you want to be nice, put your project name and bsky username (or email) in your user-agent header for api requests.</p> 26 + <p>But feel free to use it! If you want to be nice, put your project name and bsky username (or email) in your user-agent header for api requests.</p> 27 27 28 28 29 29 <h2>API Endpoints</h2> ··· 35 35 <h4>Query parameters:</h4> 36 36 37 37 <ul> 38 - <li><code>target</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></li> 39 - <li><code>collection</code>: required. Example: <code>app.bsky.feed.like</code></li> 40 - <li><code>path</code>: required, must url-encode. Example: <code>.subject.uri</code></li> 38 + <li><p><code>target</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li> 39 + <li><p><code>collection</code>: required. Example: <code>app.bsky.feed.like</code></p></li> 40 + <li><p><code>path</code>: required, must url-encode. Example: <code>.subject.uri</code></p></li> 41 + <li><p><code>did</code>: optional, filter links to those from specific users. Include multiple times to filter by multiple users. Example: <code>did=did:plc:vc7f4oafdgxsihk4cry2xpze&did=did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li> 42 + <li><p><code>from_dids</code> [deprecated]: optional. Use <code>did</code> instead. Example: <code>from_dids=did:plc:vc7f4oafdgxsihk4cry2xpze,did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li> 43 + <li><p><code>limit</code>: optional. Default: <code>16</code>. Maximum: <code>100</code></p></li> 41 44 </ul> 42 45 43 46 <p style="margin-bottom: 0"><strong>Try it:</strong></p> 44 - {% call try_it::links("at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r", "app.bsky.feed.like", ".subject.uri") %} 47 + {% call try_it::links("at://did:plc:a4pqq234yw7fqbddawjo7y35/app.bsky.feed.post/3m237ilwc372e", "app.bsky.feed.like", ".subject.uri", [""], 16) %} 45 48 46 49 47 50 <h3 class="route"><code>GET /links/distinct-dids</code></h3>
+1 -1
constellation/templates/links.html.j2
··· 6 6 7 7 {% block content %} 8 8 9 - {% call try_it::links(query.target, query.collection, query.path) %} 9 + {% call try_it::links(query.target, query.collection, query.path, query.did, query.limit) %} 10 10 11 11 <h2> 12 12 Links to <code>{{ query.target }}</code>
+20 -2
constellation/templates/try-it-macros.html.j2
··· 1 - {% macro links(target, collection, path) %} 1 + {% macro links(target, collection, path, dids, limit) %} 2 2 <form method="get" action="/links"> 3 3 <pre class="code"><strong>GET</strong> /links 4 4 ?target= <input type="text" name="target" value="{{ target }}" placeholder="target" /> 5 5 &collection= <input type="text" name="collection" value="{{ collection }}" placeholder="collection" /> 6 - &path= <input type="text" name="path" value="{{ path }}" placeholder="path" /> <button type="submit">get links</button></pre> 6 + &path= <input type="text" name="path" value="{{ path }}" placeholder="path" /> 7 + {%- for did in dids %}{% if !did.is_empty() %} 8 + &did= <input type="text" name="did" value="{{ did }}" placeholder="did:plc:..." />{% endif %}{% endfor %} 9 + <span id="did-placeholder"></span> <button id="add-did">+ did filter</button> 10 + &limit= <input type="number" name="limit" value="{{ limit }}" max="100" placeholder="100" /> <button type="submit">get links</button></pre> 7 11 </form> 12 + <script> 13 + const addDidButton = document.getElementById('add-did'); 14 + const didPlaceholder = document.getElementById('did-placeholder'); 15 + addDidButton.addEventListener('click', e => { 16 + e.preventDefault(); 17 + const i = document.createElement('input'); 18 + i.placeholder = 'did:plc:...'; 19 + i.name = "did" 20 + const p = addDidButton.parentNode; 21 + p.insertBefore(document.createTextNode('&did= '), didPlaceholder); 22 + p.insertBefore(i, didPlaceholder); 23 + p.insertBefore(document.createTextNode('\n '), didPlaceholder); 24 + }); 25 + </script> 8 26 {% endmacro %} 9 27 10 28
+6 -7
reflector/src/main.rs
··· 44 44 Data(parent): Data<&Option<String>>, 45 45 Query(AskQuery { domain }): Query<AskQuery>, 46 46 ) -> Response { 47 - if let Some(parent) = parent { 48 - if let Some(prefix) = domain.strip_suffix(&format!(".{parent}")) { 49 - if !prefix.contains('.') { 50 - // no sub-sub-domains allowed 51 - return Response::builder().body("ok"); 52 - } 53 - } 47 + if let Some(parent) = parent 48 + && let Some(prefix) = domain.strip_suffix(&format!(".{parent}")) 49 + && !prefix.contains('.') 50 + { 51 + // no sub-sub-domains allowed 52 + return Response::builder().body("ok"); 54 53 }; 55 54 Response::builder() 56 55 .status(StatusCode::FORBIDDEN)
+5 -5
spacedust/src/subscriber.rs
··· 42 42 loop { 43 43 tokio::select! { 44 44 l = receiver.recv() => match l { 45 - Ok(link) => if self.filter(&link.properties) { 46 - if let Err(e) = ws_sender.send(link.message.clone()).await { 47 - log::warn!("failed to send link, dropping subscriber: {e:?}"); 48 - break; 49 - } 45 + Ok(link) => if self.filter(&link.properties) 46 + && let Err(e) = ws_sender.send(link.message.clone()).await 47 + { 48 + log::warn!("failed to send link, dropping subscriber: {e:?}"); 49 + break; 50 50 }, 51 51 Err(RecvError::Closed) => self.shutdown.cancel(), 52 52 Err(RecvError::Lagged(n)) => {
+4 -4
who-am-i/src/server.rs
··· 268 268 Some(parent_host), 269 269 ); 270 270 } 271 - if let Some(ref app) = params.app { 272 - if !allowed_hosts.contains(app) { 273 - return err("Login is not allowed for this app", false, Some(app)); 274 - } 271 + if let Some(ref app) = params.app 272 + && !allowed_hosts.contains(app) 273 + { 274 + return err("Login is not allowed for this app", false, Some(app)); 275 275 } 276 276 let parent_origin = url.origin().ascii_serialization(); 277 277 if parent_origin == "null" {