+163
-133
Cargo.lock
+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
+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"] }
+239
-238
constellation/src/bin/rocks-link-stats.rs
+239
-238
constellation/src/bin/rocks-link-stats.rs
···
1
-
use bincode::config::Options;
2
-
use clap::Parser;
3
-
use serde::Serialize;
4
-
use std::collections::HashMap;
5
-
use std::path::PathBuf;
1
+
// use bincode::config::Options;
2
+
// use clap::Parser;
3
+
// use serde::Serialize;
4
+
// use std::collections::HashMap;
5
+
// use std::path::PathBuf;
6
6
7
-
use tokio_util::sync::CancellationToken;
7
+
// use tokio_util::sync::CancellationToken;
8
8
9
-
use constellation::storage::rocks_store::{
10
-
Collection, DidId, RKey, RPath, Target, TargetKey, TargetLinkers, _bincode_opts,
11
-
};
12
-
use constellation::storage::RocksStorage;
13
-
use constellation::Did;
9
+
// use constellation::storage::rocks_store::{
10
+
// Collection, DidId, RKey, RPath, Target, TargetKey, TargetLinkers, _bincode_opts,
11
+
// };
12
+
// use constellation::storage::RocksStorage;
13
+
// use constellation::Did;
14
14
15
-
use links::parse_any_link;
16
-
use rocksdb::IteratorMode;
17
-
use std::time;
15
+
// use links::parse_any_link;
16
+
// use rocksdb::IteratorMode;
17
+
// use std::time;
18
18
19
-
/// Aggregate links in the at-mosphere
20
-
#[derive(Parser, Debug)]
21
-
#[command(version, about, long_about = None)]
22
-
struct Args {
23
-
/// where is rocksdb's data
24
-
#[arg(short, long)]
25
-
data: PathBuf,
26
-
/// slow down so we don't kill the firehose consumer, if running concurrently
27
-
#[arg(short, long)]
28
-
limit: Option<u64>,
29
-
}
19
+
// xxxx/// Aggregate links in the at-mosphere
20
+
// #[derive(Parser, Debug)]
21
+
// #[command(version, about, long_about = None)]
22
+
// struct Args {
23
+
// /// where is rocksdb's data
24
+
// #[arg(short, long)]
25
+
// data: PathBuf,
26
+
// /// slow down so we don't kill the firehose consumer, if running concurrently
27
+
// #[arg(short, long)]
28
+
// limit: Option<u64>,
29
+
// }
30
30
31
-
type LinkType = String;
31
+
// type LinkType = String;
32
32
33
-
#[derive(Debug, Eq, Hash, PartialEq, Serialize)]
34
-
struct SourceLink(Collection, RPath, LinkType, Option<Collection>); // last is target collection, if it's an at-uri link with a collection
33
+
// #[derive(Debug, Eq, Hash, PartialEq, Serialize)]
34
+
// struct SourceLink(Collection, RPath, LinkType, Option<Collection>); // last is target collection, if it's an at-uri link with a collection
35
35
36
-
#[derive(Debug, Serialize)]
37
-
struct SourceSample {
38
-
did: String,
39
-
rkey: String,
40
-
}
36
+
// #[derive(Debug, Serialize)]
37
+
// struct SourceSample {
38
+
// did: String,
39
+
// rkey: String,
40
+
// }
41
41
42
-
#[derive(Debug, Default, Serialize)]
43
-
struct Bucket {
44
-
count: u64,
45
-
sum: u64,
46
-
sample: Option<SourceSample>,
47
-
}
42
+
// #[derive(Debug, Default, Serialize)]
43
+
// struct Bucket {
44
+
// count: u64,
45
+
// sum: u64,
46
+
// sample: Option<SourceSample>,
47
+
// }
48
48
49
-
#[derive(Debug, Default, Serialize)]
50
-
struct Buckets([Bucket; 23]);
49
+
// #[derive(Debug, Default, Serialize)]
50
+
// struct Buckets([Bucket; 23]);
51
51
52
-
const BUCKETS: [u64; 23] = [
53
-
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 32, 64, 128, 256, 512, 1024, 4096, 16_384, 65_535,
54
-
262_144, 1_048_576,
55
-
];
52
+
// const BUCKETS: [u64; 23] = [
53
+
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 32, 64, 128, 256, 512, 1024, 4096, 16_384, 65_535,
54
+
// 262_144, 1_048_576,
55
+
// ];
56
56
57
-
// b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b12, b16, b32, b64, b128, b256, b512, b1024, b4096, b16384, b65535, b262144, bmax
57
+
// xxx// b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b12, b16, b32, b64, b128, b256, b512, b1024, b4096, b16384, b65535, b262144, bmax
58
58
59
-
static DID_IDS_CF: &str = "did_ids";
60
-
static TARGET_IDS_CF: &str = "target_ids";
61
-
static TARGET_LINKERS_CF: &str = "target_links";
59
+
// static DID_IDS_CF: &str = "did_ids";
60
+
// static TARGET_IDS_CF: &str = "target_ids";
61
+
// static TARGET_LINKERS_CF: &str = "target_links";
62
62
63
-
const REPORT_INTERVAL: usize = 50_000;
63
+
// const REPORT_INTERVAL: usize = 50_000;
64
64
65
-
type Stats = HashMap<SourceLink, Buckets>;
65
+
// type Stats = HashMap<SourceLink, Buckets>;
66
66
67
-
#[derive(Debug, Serialize)]
68
-
struct Printable {
69
-
collection: String,
70
-
path: String,
71
-
link_type: String,
72
-
target_collection: Option<String>,
73
-
buckets: Buckets,
74
-
}
67
+
// #[derive(Debug, Serialize)]
68
+
// struct Printable {
69
+
// collection: String,
70
+
// path: String,
71
+
// link_type: String,
72
+
// target_collection: Option<String>,
73
+
// buckets: Buckets,
74
+
// }
75
75
76
-
#[derive(Debug, Default)]
77
-
struct ErrStats {
78
-
failed_to_get_sample: usize,
79
-
failed_to_read_target_id: usize,
80
-
failed_to_deserialize_target_key: usize,
81
-
failed_to_parse_target_as_link: usize,
82
-
failed_to_get_links: usize,
83
-
failed_to_deserialize_linkers: usize,
84
-
}
76
+
// #[derive(Debug, Default)]
77
+
// struct ErrStats {
78
+
// failed_to_get_sample: usize,
79
+
// failed_to_read_target_id: usize,
80
+
// failed_to_deserialize_target_key: usize,
81
+
// failed_to_parse_target_as_link: usize,
82
+
// failed_to_get_links: usize,
83
+
// failed_to_deserialize_linkers: usize,
84
+
// }
85
85
86
-
fn thousands(n: usize) -> String {
87
-
n.to_string()
88
-
.as_bytes()
89
-
.rchunks(3)
90
-
.rev()
91
-
.map(std::str::from_utf8)
92
-
.collect::<Result<Vec<&str>, _>>()
93
-
.unwrap()
94
-
.join(",")
95
-
}
86
+
// fn thousands(n: usize) -> String {
87
+
// n.to_string()
88
+
// .as_bytes()
89
+
// .rchunks(3)
90
+
// .rev()
91
+
// .map(std::str::from_utf8)
92
+
// .collect::<Result<Vec<&str>, _>>()
93
+
// .unwrap()
94
+
// .join(",")
95
+
// }
96
96
97
-
fn main() {
98
-
let args = Args::parse();
97
+
// fn main() {
98
+
// let args = Args::parse();
99
99
100
-
let limit = args.limit.map(|amount| {
101
-
ratelimit::Ratelimiter::builder(amount, time::Duration::from_secs(1))
102
-
.max_tokens(amount)
103
-
.initial_available(amount)
104
-
.build()
105
-
.unwrap()
106
-
});
100
+
// let limit = args.limit.map(|amount| {
101
+
// ratelimit::Ratelimiter::builder(amount, time::Duration::from_secs(1))
102
+
// .max_tokens(amount)
103
+
// .initial_available(amount)
104
+
// .build()
105
+
// .unwrap()
106
+
// });
107
107
108
-
eprintln!("starting rocksdb...");
109
-
let rocks = RocksStorage::open_readonly(args.data).unwrap();
110
-
eprintln!("rocks ready.");
108
+
// eprintln!("starting rocksdb...");
109
+
// let rocks = RocksStorage::open_readonly(args.data).unwrap();
110
+
// eprintln!("rocks ready.");
111
111
112
-
let RocksStorage { ref db, .. } = rocks;
112
+
// let RocksStorage { ref db, .. } = rocks;
113
113
114
-
let stay_alive = CancellationToken::new();
115
-
ctrlc::set_handler({
116
-
let mut desperation: u8 = 0;
117
-
let stay_alive = stay_alive.clone();
118
-
move || match desperation {
119
-
0 => {
120
-
eprintln!("ok, shutting down...");
121
-
stay_alive.cancel();
122
-
desperation += 1;
123
-
}
124
-
1.. => panic!("fine, panicking!"),
125
-
}
126
-
})
127
-
.unwrap();
114
+
// let stay_alive = CancellationToken::new();
115
+
// ctrlc::set_handler({
116
+
// let mut desperation: u8 = 0;
117
+
// let stay_alive = stay_alive.clone();
118
+
// move || match desperation {
119
+
// 0 => {
120
+
// eprintln!("ok, shutting down...");
121
+
// stay_alive.cancel();
122
+
// desperation += 1;
123
+
// }
124
+
// 1.. => panic!("fine, panicking!"),
125
+
// }
126
+
// })
127
+
// .unwrap();
128
128
129
-
let mut stats = Stats::new();
130
-
let mut err_stats: ErrStats = Default::default();
129
+
// let mut stats = Stats::new();
130
+
// let mut err_stats: ErrStats = Default::default();
131
131
132
-
let did_ids_cf = db.cf_handle(DID_IDS_CF).unwrap();
133
-
let target_id_cf = db.cf_handle(TARGET_IDS_CF).unwrap();
134
-
let target_links_cf = db.cf_handle(TARGET_LINKERS_CF).unwrap();
132
+
// let did_ids_cf = db.cf_handle(DID_IDS_CF).unwrap();
133
+
// let target_id_cf = db.cf_handle(TARGET_IDS_CF).unwrap();
134
+
// let target_links_cf = db.cf_handle(TARGET_LINKERS_CF).unwrap();
135
135
136
-
let t0 = time::Instant::now();
137
-
let mut t_prev = t0;
136
+
// let t0 = time::Instant::now();
137
+
// let mut t_prev = t0;
138
138
139
-
let mut i = 0;
140
-
for item in db.iterator_cf(&target_id_cf, IteratorMode::Start) {
141
-
if stay_alive.is_cancelled() {
142
-
break;
143
-
}
139
+
// let mut i = 0;
140
+
// for item in db.iterator_cf(&target_id_cf, IteratorMode::Start) {
141
+
// if stay_alive.is_cancelled() {
142
+
// break;
143
+
// }
144
144
145
-
if let Some(ref limiter) = limit {
146
-
if let Err(dur) = limiter.try_wait() {
147
-
std::thread::sleep(dur)
148
-
}
149
-
}
145
+
// if let Some(ref limiter) = limit {
146
+
// if let Err(dur) = limiter.try_wait() {
147
+
// std::thread::sleep(dur)
148
+
// }
149
+
// }
150
150
151
-
if i > 0 && i % REPORT_INTERVAL == 0 {
152
-
let now = time::Instant::now();
153
-
let rate = (REPORT_INTERVAL as f32) / (now.duration_since(t_prev).as_secs_f32());
154
-
eprintln!(
155
-
"{i}\t({}k)\t{:.2}\t{rate:.1}/s",
156
-
thousands(i / 1000),
157
-
t0.elapsed().as_secs_f32()
158
-
);
159
-
t_prev = now;
160
-
}
161
-
i += 1;
151
+
// if i > 0 && i % REPORT_INTERVAL == 0 {
152
+
// let now = time::Instant::now();
153
+
// let rate = (REPORT_INTERVAL as f32) / (now.duration_since(t_prev).as_secs_f32());
154
+
// eprintln!(
155
+
// "{i}\t({}k)\t{:.2}\t{rate:.1}/s",
156
+
// thousands(i / 1000),
157
+
// t0.elapsed().as_secs_f32()
158
+
// );
159
+
// t_prev = now;
160
+
// }
161
+
// i += 1;
162
162
163
-
let Ok((target_key, target_id)) = item else {
164
-
err_stats.failed_to_read_target_id += 1;
165
-
continue;
166
-
};
163
+
// let Ok((target_key, target_id)) = item else {
164
+
// err_stats.failed_to_read_target_id += 1;
165
+
// continue;
166
+
// };
167
167
168
-
let Ok(TargetKey(Target(target), collection, rpath)) =
169
-
_bincode_opts().deserialize(&target_key)
170
-
else {
171
-
err_stats.failed_to_deserialize_target_key += 1;
172
-
continue;
173
-
};
168
+
// let Ok(TargetKey(Target(target), collection, rpath)) =
169
+
// _bincode_opts().deserialize(&target_key)
170
+
// else {
171
+
// err_stats.failed_to_deserialize_target_key += 1;
172
+
// continue;
173
+
// };
174
174
175
-
let source = {
176
-
let Some(parsed) = parse_any_link(&target) else {
177
-
err_stats.failed_to_parse_target_as_link += 1;
178
-
continue;
179
-
};
180
-
SourceLink(
181
-
collection,
182
-
rpath,
183
-
parsed.name().into(),
184
-
parsed.at_uri_collection().map(Collection),
185
-
)
186
-
};
175
+
// let source = {
176
+
// let Some(parsed) = parse_any_link(&target) else {
177
+
// err_stats.failed_to_parse_target_as_link += 1;
178
+
// continue;
179
+
// };
180
+
// SourceLink(
181
+
// collection,
182
+
// rpath,
183
+
// parsed.name().into(),
184
+
// parsed.at_uri_collection().map(Collection),
185
+
// )
186
+
// };
187
187
188
-
let Ok(Some(links_raw)) = db.get_cf(&target_links_cf, &target_id) else {
189
-
err_stats.failed_to_get_links += 1;
190
-
continue;
191
-
};
192
-
let Ok(linkers) = _bincode_opts().deserialize::<TargetLinkers>(&links_raw) else {
193
-
err_stats.failed_to_deserialize_linkers += 1;
194
-
continue;
195
-
};
196
-
let (n, _) = linkers.count();
188
+
// let Ok(Some(links_raw)) = db.get_cf(&target_links_cf, &target_id) else {
189
+
// err_stats.failed_to_get_links += 1;
190
+
// continue;
191
+
// };
192
+
// let Ok(linkers) = _bincode_opts().deserialize::<TargetLinkers>(&links_raw) else {
193
+
// err_stats.failed_to_deserialize_linkers += 1;
194
+
// continue;
195
+
// };
196
+
// let (n, _) = linkers.count();
197
197
198
-
if n == 0 {
199
-
continue;
200
-
}
198
+
// if n == 0 {
199
+
// continue;
200
+
// }
201
201
202
-
let mut bucket = 0;
203
-
for edge in BUCKETS {
204
-
if n <= edge || bucket == 22 {
205
-
break;
206
-
}
207
-
bucket += 1;
208
-
}
202
+
// let mut bucket = 0;
203
+
// for edge in BUCKETS {
204
+
// if n <= edge || bucket == 22 {
205
+
// break;
206
+
// }
207
+
// bucket += 1;
208
+
// }
209
209
210
-
let b = &mut stats.entry(source).or_default().0[bucket];
211
-
b.count += 1;
212
-
b.sum += n;
213
-
if b.sample.is_none() {
214
-
let (DidId(did_id), RKey(k)) = &linkers.0[(n - 1) as usize];
215
-
if let Ok(Some(did_bytes)) = db.get_cf(&did_ids_cf, did_id.to_be_bytes()) {
216
-
if let Ok(Did(did)) = _bincode_opts().deserialize(&did_bytes) {
217
-
b.sample = Some(SourceSample {
218
-
did,
219
-
rkey: k.clone(),
220
-
});
221
-
} else {
222
-
err_stats.failed_to_get_sample += 1;
223
-
}
224
-
} else {
225
-
err_stats.failed_to_get_sample += 1;
226
-
}
227
-
}
210
+
// let b = &mut stats.entry(source).or_default().0[bucket];
211
+
// b.count += 1;
212
+
// b.sum += n;
213
+
// if b.sample.is_none() {
214
+
// let (DidId(did_id), RKey(k)) = &linkers.0[(n - 1) as usize];
215
+
// if let Ok(Some(did_bytes)) = db.get_cf(&did_ids_cf, did_id.to_be_bytes()) {
216
+
// if let Ok(Did(did)) = _bincode_opts().deserialize(&did_bytes) {
217
+
// b.sample = Some(SourceSample {
218
+
// did,
219
+
// rkey: k.clone(),
220
+
// });
221
+
// } else {
222
+
// err_stats.failed_to_get_sample += 1;
223
+
// }
224
+
// } else {
225
+
// err_stats.failed_to_get_sample += 1;
226
+
// }
227
+
// }
228
228
229
-
// if i >= 40_000 {
230
-
// break;
231
-
// }
232
-
}
229
+
// // if i >= 40_000 {
230
+
// // break;
231
+
// // }
232
+
// }
233
233
234
-
let dt = t0.elapsed();
234
+
// let dt = t0.elapsed();
235
235
236
-
eprintln!("gathering stats for output...");
236
+
// eprintln!("gathering stats for output...");
237
237
238
-
let itemified = stats
239
-
.into_iter()
240
-
.map(
241
-
|(
242
-
SourceLink(Collection(collection), RPath(path), link_type, target_collection),
243
-
buckets,
244
-
)| Printable {
245
-
collection,
246
-
path,
247
-
link_type,
248
-
target_collection: target_collection.map(|Collection(c)| c),
249
-
buckets,
250
-
},
251
-
)
252
-
.collect::<Vec<_>>();
238
+
// let itemified = stats
239
+
// .into_iter()
240
+
// .map(
241
+
// |(
242
+
// SourceLink(Collection(collection), RPath(path), link_type, target_collection),
243
+
// buckets,
244
+
// )| Printable {
245
+
// collection,
246
+
// path,
247
+
// link_type,
248
+
// target_collection: target_collection.map(|Collection(c)| c),
249
+
// buckets,
250
+
// },
251
+
// )
252
+
// .collect::<Vec<_>>();
253
253
254
-
match serde_json::to_string(&itemified) {
255
-
Ok(s) => println!("{s}"),
256
-
Err(e) => eprintln!("failed to serialize results: {e:?}"),
257
-
}
254
+
// match serde_json::to_string(&itemified) {
255
+
// Ok(s) => println!("{s}"),
256
+
// Err(e) => eprintln!("failed to serialize results: {e:?}"),
257
+
// }
258
258
259
-
eprintln!(
260
-
"{} summarizing {} link targets in {:.1}s",
261
-
if stay_alive.is_cancelled() {
262
-
"STOPPED"
263
-
} else {
264
-
"FINISHED"
265
-
},
266
-
thousands(i),
267
-
dt.as_secs_f32()
268
-
);
269
-
eprintln!("{err_stats:?}");
270
-
eprintln!("bye.");
271
-
}
259
+
// eprintln!(
260
+
// "{} summarizing {} link targets in {:.1}s",
261
+
// if stay_alive.is_cancelled() {
262
+
// "STOPPED"
263
+
// } else {
264
+
// "FINISHED"
265
+
// },
266
+
// thousands(i),
267
+
// dt.as_secs_f32()
268
+
// );
269
+
// eprintln!("{err_stats:?}");
270
+
// eprintln!("bye.");
271
+
// }
272
272
273
-
// scan plan
273
+
// xxx// scan plan
274
274
275
-
// buckets (backlink count)
276
-
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 32, 64, 128, 256, 512, 1024, 4096, 16384, 65535, 262144, 1048576+
277
-
// by
278
-
// - collection
279
-
// - json path
280
-
// - link type
281
-
// samples for each bucket for each variation
275
+
// xxx// buckets (backlink count)
276
+
// xxx// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 32, 64, 128, 256, 512, 1024, 4096, 16384, 65535, 262144, 1048576+
277
+
// xxx// by
278
+
// xxx// - collection
279
+
// xxx// - json path
280
+
// xxx// - link type
281
+
// xxx// samples for each bucket for each variation
282
+
fn main() {}
+2
constellation/src/bin/rocks-restore-from-backup.rs
+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
+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
+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
+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
+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
+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
+1
-1
constellation/templates/links.html.j2
+20
-2
constellation/templates/try-it-macros.html.j2
+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
+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
+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
+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" {