castrum 0.9.9 → 0.9.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.lock CHANGED
@@ -2,12 +2,6 @@
2
2
  # It is not intended for manual editing.
3
3
  version = 4
4
4
 
5
- [[package]]
6
- name = "adler2"
7
- version = "2.0.1"
8
- source = "registry+https://github.com/rust-lang/crates.io-index"
9
- checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
10
-
11
5
  [[package]]
12
6
  name = "ahash"
13
7
  version = "0.8.12"
@@ -78,9 +72,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
78
72
 
79
73
  [[package]]
80
74
  name = "aws-lc-rs"
81
- version = "1.17.3"
75
+ version = "1.18.1"
82
76
  source = "registry+https://github.com/rust-lang/crates.io-index"
83
- checksum = "00bdb5da18dac48ca2cc7cd4a98e533e8635a58e2361d13a1a4ee3888e0d72f1"
77
+ checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e"
84
78
  dependencies = [
85
79
  "aws-lc-sys",
86
80
  "untrusted",
@@ -89,9 +83,9 @@ dependencies = [
89
83
 
90
84
  [[package]]
91
85
  name = "aws-lc-sys"
92
- version = "0.43.0"
86
+ version = "0.45.0"
93
87
  source = "registry+https://github.com/rust-lang/crates.io-index"
94
- checksum = "43103168cc76fe62678a375e722fc9cb3a0146159ac5828bc4f0dfd755c2224c"
88
+ checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27"
95
89
  dependencies = [
96
90
  "cc",
97
91
  "cmake",
@@ -100,12 +94,6 @@ dependencies = [
100
94
  "pkg-config",
101
95
  ]
102
96
 
103
- [[package]]
104
- name = "base64"
105
- version = "0.22.1"
106
- source = "registry+https://github.com/rust-lang/crates.io-index"
107
- checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
108
-
109
97
  [[package]]
110
98
  name = "base64"
111
99
  version = "0.23.1"
@@ -120,13 +108,13 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
120
108
 
121
109
  [[package]]
122
110
  name = "bcrypt"
123
- version = "0.16.0"
111
+ version = "0.19.3"
124
112
  source = "registry+https://github.com/rust-lang/crates.io-index"
125
- checksum = "2b1866ecef4f2d06a0bb77880015fdf2b89e25a1c2e5addacb87e459c86dc67e"
113
+ checksum = "a0cd0bd35a28836d528d2b58ad499bc3c5641d59379421b1be9eeb0c2f2b912a"
126
114
  dependencies = [
127
- "base64 0.22.1",
115
+ "base64",
128
116
  "blowfish",
129
- "getrandom 0.2.17",
117
+ "getrandom 0.4.3",
130
118
  "subtle",
131
119
  "zeroize",
132
120
  ]
@@ -146,6 +134,12 @@ version = "0.8.0"
146
134
  source = "registry+https://github.com/rust-lang/crates.io-index"
147
135
  checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
148
136
 
137
+ [[package]]
138
+ name = "bitflags"
139
+ version = "1.3.2"
140
+ source = "registry+https://github.com/rust-lang/crates.io-index"
141
+ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
142
+
149
143
  [[package]]
150
144
  name = "bitflags"
151
145
  version = "2.13.1"
@@ -172,9 +166,9 @@ dependencies = [
172
166
 
173
167
  [[package]]
174
168
  name = "blowfish"
175
- version = "0.9.1"
169
+ version = "0.10.0"
176
170
  source = "registry+https://github.com/rust-lang/crates.io-index"
177
- checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7"
171
+ checksum = "62ce3946557b35e71d1bbe07ec385073ce9eda05043f95de134eb578fcf1a298"
178
172
  dependencies = [
179
173
  "byteorder",
180
174
  "cipher",
@@ -233,11 +227,11 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
233
227
 
234
228
  [[package]]
235
229
  name = "castrum"
236
- version = "0.9.9"
230
+ version = "0.9.11"
237
231
  dependencies = [
238
232
  "argon2",
239
233
  "aws-lc-rs",
240
- "base64 0.23.1",
234
+ "base64",
241
235
  "bcrypt",
242
236
  "brotli",
243
237
  "core_affinity",
@@ -245,6 +239,7 @@ dependencies = [
245
239
  "email_address",
246
240
  "fancy-regex",
247
241
  "fast_chemail",
242
+ "faster-hex",
248
243
  "flate2",
249
244
  "fraction",
250
245
  "getrandom 0.4.3",
@@ -296,11 +291,11 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
296
291
 
297
292
  [[package]]
298
293
  name = "cipher"
299
- version = "0.4.4"
294
+ version = "0.5.2"
300
295
  source = "registry+https://github.com/rust-lang/crates.io-index"
301
- checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
296
+ checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c"
302
297
  dependencies = [
303
- "crypto-common",
298
+ "crypto-common 0.2.2",
304
299
  "inout",
305
300
  ]
306
301
 
@@ -315,9 +310,9 @@ dependencies = [
315
310
 
316
311
  [[package]]
317
312
  name = "convert_case"
318
- version = "0.11.0"
313
+ version = "0.12.0"
319
314
  source = "registry+https://github.com/rust-lang/crates.io-index"
320
- checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49"
315
+ checksum = "1af709f1f33454bf52eadfc8c78b3b9ef9cb26fb54d16dc9cd9a7299f899fd1b"
321
316
  dependencies = [
322
317
  "unicode-segmentation",
323
318
  ]
@@ -386,6 +381,15 @@ dependencies = [
386
381
  "typenum",
387
382
  ]
388
383
 
384
+ [[package]]
385
+ name = "crypto-common"
386
+ version = "0.2.2"
387
+ source = "registry+https://github.com/rust-lang/crates.io-index"
388
+ checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
389
+ dependencies = [
390
+ "hybrid-array",
391
+ ]
392
+
389
393
  [[package]]
390
394
  name = "ctor"
391
395
  version = "1.0.10"
@@ -398,6 +402,46 @@ version = "2.11.0"
398
402
  source = "registry+https://github.com/rust-lang/crates.io-index"
399
403
  checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
400
404
 
405
+ [[package]]
406
+ name = "defmt"
407
+ version = "0.3.100"
408
+ source = "registry+https://github.com/rust-lang/crates.io-index"
409
+ checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad"
410
+ dependencies = [
411
+ "defmt 1.1.1",
412
+ ]
413
+
414
+ [[package]]
415
+ name = "defmt"
416
+ version = "1.1.1"
417
+ source = "registry+https://github.com/rust-lang/crates.io-index"
418
+ checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
419
+ dependencies = [
420
+ "bitflags 1.3.2",
421
+ "defmt-macros",
422
+ ]
423
+
424
+ [[package]]
425
+ name = "defmt-macros"
426
+ version = "1.1.1"
427
+ source = "registry+https://github.com/rust-lang/crates.io-index"
428
+ checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
429
+ dependencies = [
430
+ "defmt-parser",
431
+ "proc-macro2",
432
+ "quote",
433
+ "syn 2.0.119",
434
+ ]
435
+
436
+ [[package]]
437
+ name = "defmt-parser"
438
+ version = "1.0.0"
439
+ source = "registry+https://github.com/rust-lang/crates.io-index"
440
+ checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
441
+ dependencies = [
442
+ "thiserror",
443
+ ]
444
+
401
445
  [[package]]
402
446
  name = "digest"
403
447
  version = "0.10.7"
@@ -405,7 +449,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
405
449
  checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
406
450
  dependencies = [
407
451
  "block-buffer",
408
- "crypto-common",
452
+ "crypto-common 0.1.7",
409
453
  "subtle",
410
454
  ]
411
455
 
@@ -477,6 +521,18 @@ dependencies = [
477
521
  "ascii_utils",
478
522
  ]
479
523
 
524
+ [[package]]
525
+ name = "faster-hex"
526
+ version = "0.10.1"
527
+ source = "registry+https://github.com/rust-lang/crates.io-index"
528
+ checksum = "04839bdf9d8c10f66806fad16b852fc72aab80873aebc3cb69d85b4fa41543ed"
529
+ dependencies = [
530
+ "autocfg",
531
+ "defmt 0.3.100",
532
+ "heapless",
533
+ "serde",
534
+ ]
535
+
480
536
  [[package]]
481
537
  name = "fastrand"
482
538
  version = "2.5.0"
@@ -503,11 +559,11 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
503
559
 
504
560
  [[package]]
505
561
  name = "flate2"
506
- version = "1.1.9"
562
+ version = "1.1.10"
507
563
  source = "registry+https://github.com/rust-lang/crates.io-index"
508
- checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
564
+ checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb"
509
565
  dependencies = [
510
- "miniz_oxide",
566
+ "crc32fast",
511
567
  "zlib-rs",
512
568
  ]
513
569
 
@@ -648,17 +704,6 @@ dependencies = [
648
704
  "version_check",
649
705
  ]
650
706
 
651
- [[package]]
652
- name = "getrandom"
653
- version = "0.2.17"
654
- source = "registry+https://github.com/rust-lang/crates.io-index"
655
- checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
656
- dependencies = [
657
- "cfg-if",
658
- "libc",
659
- "wasi",
660
- ]
661
-
662
707
  [[package]]
663
708
  name = "getrandom"
664
709
  version = "0.3.4"
@@ -684,6 +729,15 @@ dependencies = [
684
729
  "r-efi 6.0.0",
685
730
  ]
686
731
 
732
+ [[package]]
733
+ name = "hash32"
734
+ version = "0.3.1"
735
+ source = "registry+https://github.com/rust-lang/crates.io-index"
736
+ checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
737
+ dependencies = [
738
+ "byteorder",
739
+ ]
740
+
687
741
  [[package]]
688
742
  name = "hashbrown"
689
743
  version = "0.17.1"
@@ -695,6 +749,16 @@ dependencies = [
695
749
  "foldhash",
696
750
  ]
697
751
 
752
+ [[package]]
753
+ name = "heapless"
754
+ version = "0.8.0"
755
+ source = "registry+https://github.com/rust-lang/crates.io-index"
756
+ checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
757
+ dependencies = [
758
+ "hash32",
759
+ "stable_deref_trait",
760
+ ]
761
+
698
762
  [[package]]
699
763
  name = "heck"
700
764
  version = "0.5.0"
@@ -722,6 +786,15 @@ version = "1.10.1"
722
786
  source = "registry+https://github.com/rust-lang/crates.io-index"
723
787
  checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
724
788
 
789
+ [[package]]
790
+ name = "hybrid-array"
791
+ version = "0.4.15"
792
+ source = "registry+https://github.com/rust-lang/crates.io-index"
793
+ checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17"
794
+ dependencies = [
795
+ "typenum",
796
+ ]
797
+
725
798
  [[package]]
726
799
  name = "icu_collections"
727
800
  version = "2.2.0"
@@ -837,18 +910,18 @@ dependencies = [
837
910
 
838
911
  [[package]]
839
912
  name = "inout"
840
- version = "0.1.4"
913
+ version = "0.2.2"
841
914
  source = "registry+https://github.com/rust-lang/crates.io-index"
842
- checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
915
+ checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
843
916
  dependencies = [
844
- "generic-array",
917
+ "hybrid-array",
845
918
  ]
846
919
 
847
920
  [[package]]
848
921
  name = "ipnet"
849
- version = "2.12.0"
922
+ version = "2.12.2"
850
923
  source = "registry+https://github.com/rust-lang/crates.io-index"
851
- checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
924
+ checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0"
852
925
 
853
926
  [[package]]
854
927
  name = "itoa"
@@ -983,9 +1056,9 @@ dependencies = [
983
1056
 
984
1057
  [[package]]
985
1058
  name = "lru"
986
- version = "0.18.4"
1059
+ version = "0.18.5"
987
1060
  source = "registry+https://github.com/rust-lang/crates.io-index"
988
- checksum = "ff9840bcc50b71349309900da0ce7279aa336ae71d73250b07998932c7d97c25"
1061
+ checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5"
989
1062
  dependencies = [
990
1063
  "hashbrown",
991
1064
  ]
@@ -1035,24 +1108,14 @@ dependencies = [
1035
1108
 
1036
1109
  [[package]]
1037
1110
  name = "minijinja"
1038
- version = "2.22.0"
1111
+ version = "2.24.0"
1039
1112
  source = "registry+https://github.com/rust-lang/crates.io-index"
1040
- checksum = "ef84a52be188a1d4124bd717903fdde96ca4705f2b56adfe2d91fcc57fcb6987"
1113
+ checksum = "86886cf6dbf4e614b19c9a1eec9775f021869d7eadde0fc73921a81b90c9b4c9"
1041
1114
  dependencies = [
1042
1115
  "memo-map",
1043
1116
  "serde",
1044
1117
  ]
1045
1118
 
1046
- [[package]]
1047
- name = "miniz_oxide"
1048
- version = "0.8.9"
1049
- source = "registry+https://github.com/rust-lang/crates.io-index"
1050
- checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
1051
- dependencies = [
1052
- "adler2",
1053
- "simd-adler32",
1054
- ]
1055
-
1056
1119
  [[package]]
1057
1120
  name = "munge"
1058
1121
  version = "0.4.7"
@@ -1075,11 +1138,11 @@ dependencies = [
1075
1138
 
1076
1139
  [[package]]
1077
1140
  name = "napi"
1078
- version = "3.12.2"
1141
+ version = "3.13.0"
1079
1142
  source = "registry+https://github.com/rust-lang/crates.io-index"
1080
- checksum = "58c5f4d5375213fdb7be2655e152386e82f026f9a5ba36a75556e11359aafe09"
1143
+ checksum = "3b12638855cec016784a7e17cc4ecbdee7ca8b0a3456aa50640d0ee5ed1a42f8"
1081
1144
  dependencies = [
1082
- "bitflags",
1145
+ "bitflags 2.13.1",
1083
1146
  "ctor",
1084
1147
  "futures",
1085
1148
  "libc",
@@ -1093,15 +1156,15 @@ dependencies = [
1093
1156
 
1094
1157
  [[package]]
1095
1158
  name = "napi-build"
1096
- version = "2.4.1"
1159
+ version = "2.6.0"
1097
1160
  source = "registry+https://github.com/rust-lang/crates.io-index"
1098
- checksum = "60fdf9b392c50e7c4170fa633bd909490ed7835cea4c046776d1a4dd8d2ae0ab"
1161
+ checksum = "b899b545d3aa6dca985939059f258c5488d34e4ecf39c274e20009748f4b846d"
1099
1162
 
1100
1163
  [[package]]
1101
1164
  name = "napi-derive"
1102
- version = "3.6.0"
1165
+ version = "3.6.5"
1103
1166
  source = "registry+https://github.com/rust-lang/crates.io-index"
1104
- checksum = "a49c513341a61a16a10af6efcce46b30d0822ba2d4fb197d24d33dfc199c78d5"
1167
+ checksum = "350057056a30368aa76c11a0d406b0aa61321710be2c36656ab4f6efe0b785a2"
1105
1168
  dependencies = [
1106
1169
  "convert_case",
1107
1170
  "ctor",
@@ -1113,9 +1176,9 @@ dependencies = [
1113
1176
 
1114
1177
  [[package]]
1115
1178
  name = "napi-derive-backend"
1116
- version = "6.0.0"
1179
+ version = "6.1.3"
1117
1180
  source = "registry+https://github.com/rust-lang/crates.io-index"
1118
- checksum = "4747005fa3e2c9989ac45a723a514c5db2411238b72981a3cda4c701a9dfea17"
1181
+ checksum = "4c1c87a71568f3fe5c736b10878ff55064b250bb4ea4b48c8055713e07b9e463"
1119
1182
  dependencies = [
1120
1183
  "convert_case",
1121
1184
  "proc-macro2",
@@ -1126,9 +1189,9 @@ dependencies = [
1126
1189
 
1127
1190
  [[package]]
1128
1191
  name = "napi-sys"
1129
- version = "3.3.0"
1192
+ version = "3.4.0"
1130
1193
  source = "registry+https://github.com/rust-lang/crates.io-index"
1131
- checksum = "85fbf1fa9f1babfe396d74bbbf52b3643770243e8f5b0b46715d4caf7f0dfc9a"
1194
+ checksum = "e22a4f25c16a5c5411d987cd6fbd48313522ae1789ade2d6dd3efdc6d40a0fc8"
1132
1195
  dependencies = [
1133
1196
  "libloading",
1134
1197
  ]
@@ -1379,7 +1442,7 @@ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
1379
1442
  dependencies = [
1380
1443
  "bit-set",
1381
1444
  "bit-vec",
1382
- "bitflags",
1445
+ "bitflags 2.13.1",
1383
1446
  "num-traits",
1384
1447
  "rand",
1385
1448
  "rand_chacha",
@@ -1516,7 +1579,7 @@ version = "0.5.18"
1516
1579
  source = "registry+https://github.com/rust-lang/crates.io-index"
1517
1580
  checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
1518
1581
  dependencies = [
1519
- "bitflags",
1582
+ "bitflags 2.13.1",
1520
1583
  ]
1521
1584
 
1522
1585
  [[package]]
@@ -1632,7 +1695,7 @@ version = "1.1.4"
1632
1695
  source = "registry+https://github.com/rust-lang/crates.io-index"
1633
1696
  checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
1634
1697
  dependencies = [
1635
- "bitflags",
1698
+ "bitflags 2.13.1",
1636
1699
  "errno",
1637
1700
  "libc",
1638
1701
  "linux-raw-sys",
@@ -1730,12 +1793,6 @@ version = "2.0.1"
1730
1793
  source = "registry+https://github.com/rust-lang/crates.io-index"
1731
1794
  checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
1732
1795
 
1733
- [[package]]
1734
- name = "simd-adler32"
1735
- version = "0.3.10"
1736
- source = "registry+https://github.com/rust-lang/crates.io-index"
1737
- checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
1738
-
1739
1796
  [[package]]
1740
1797
  name = "simdutf8"
1741
1798
  version = "0.1.5"
@@ -2012,12 +2069,6 @@ dependencies = [
2012
2069
  "libc",
2013
2070
  ]
2014
2071
 
2015
- [[package]]
2016
- name = "wasi"
2017
- version = "0.11.1+wasi-snapshot-preview1"
2018
- source = "registry+https://github.com/rust-lang/crates.io-index"
2019
- checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
2020
-
2021
2072
  [[package]]
2022
2073
  name = "wasip2"
2023
2074
  version = "1.0.4+wasi-0.2.12"
package/Cargo.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "castrum"
3
3
  # Keep in sync with package.json "version" (single source of truth: the npm package).
4
- version = "0.9.9"
4
+ version = "0.9.11"
5
5
  edition = "2021"
6
6
  # Keep in sync with package.json "license" (cargo-deny rejects a crate with no
7
7
  # license expression).
@@ -45,8 +45,11 @@ sonic-rs = { version = "0.5", features = ["sort_keys"] }
45
45
  # validators (email etc.) are built-in and NOT feature-gated in 0.48.
46
46
  jsonschema = { version = "0.49", default-features = false, features = ["resolve-file"] }
47
47
  aws-lc-rs = "1"
48
- # NOTE: base64 0.23 enables SIMD (SSE/AVX) by default via the `simd-unsafe`
49
- # feature (part of `default`); no explicit feature is needed.
48
+ # NOTE: base64 0.23 compiles its SIMD `engine::simd::Simd` (AVX2/NEON, Muła
49
+ # kernels) by default via the `simd-unsafe` feature (part of `default`). Our
50
+ # `rust/crypto/base64.rs` selects that engine for the hot cores on x86_64 /
51
+ # aarch64, with the scalar `GeneralPurpose` fallback elsewhere; the wire
52
+ # contract (PAD/NO_PAD configs, byte-identical output) is unchanged.
50
53
  base64 = "0.23"
51
54
  crc32fast = "1"
52
55
  httparse = "1"
@@ -72,7 +75,21 @@ mimalloc = { version = "0.1", features = ["local_dynamic_tls"] }
72
75
  core_affinity = "0.8"
73
76
 
74
77
  parking_lot = "0.12"
78
+ # xxhash-rust: seeded streaming Xxh3 (ingress ip_trust rate_key, tiny 1-17
79
+ # byte IPs) AND the public one-shot xxh3_64. Measured: the scalar core
80
+ # sustains a FLAT ~30GB/s from 64B to 1MB (no size pathology); the ~2x gap to
81
+ # Bun.hash.xxHash3 at >= 1KB is Bun's AVX2 width, not a scaling issue, and
82
+ # ignex already delegates the public hash to Bun under Bun — see
83
+ # docs/bun-builtins-decision-matrix.md.
75
84
  xxhash-rust = { version = "0.8", features = ["xxh3"] }
85
+ # faster-hex: SIMD (runtime-dispatched SSE -> AVX2) lowercase hex encode/decode
86
+ # with byte-exact semantics parity vs our HEX_VAL_LUT (case-insensitive decode,
87
+ # reject [^0-9a-fA-F], odd-length error) — verified exhaustively (65,536 pairs).
88
+ # Replaces the per-byte table loops that lost ~3-6x to Buffer.toString("hex").
89
+ # 0.10.1+ carries the RUSTSEC-2026-0306 fix (the unbounded AVX2 read in
90
+ # `hex_decode_unchecked`; 0.3.0..=0.10.0 are affected); keep this requirement at
91
+ # or above the fixed release so `cargo deny` / OSV stay green.
92
+ faster-hex = "0.10.1"
76
93
  ipnet = "2"
77
94
  # 0.18.2+ carries the RUSTSEC-2026-0253 fix (0.16.x is affected); keep this
78
95
  # requirement at or above the fixed release so `cargo deny` / OSV stay green.
@@ -95,7 +112,7 @@ num-cmp = "0.1"
95
112
  # argon2id password hashing (password-hash/rand features are default-on).
96
113
  argon2 = "0.5"
97
114
  # bcrypt password hashing (pure-Rust, Blowfish-based).
98
- bcrypt = "0.16"
115
+ bcrypt = "0.19"
99
116
  # PBKDF2-HMAC-SHA256 (RustCrypto) — pure-Rust KDF.
100
117
  pbkdf2 = "0.12"
101
118
  # sha2 is consumed ONLY by pbkdf2 (digest 0.10). Do NOT bump to 0.11: that
@@ -106,7 +123,14 @@ sha2 = "0.10"
106
123
  # HTML templating (fast, safe, no eval).
107
124
  minijinja = "2"
108
125
  # gzip via the memory-safe zlib-rs backend (pure Rust, no C).
109
- flate2 = { version = "1", default-features = false, features = ["zlib-rs"] }
126
+ # `runtime_detection` is REQUIRED: flate2 1.1.10 moved `zlib-rs/std` (zlib-rs's
127
+ # runtime CPU-feature detection, i.e. its SIMD dispatch) behind this opt-in
128
+ # feature, which only `default` enables. Building with `default-features =
129
+ # false` and `zlib-rs` alone silently drops to zlib-rs's scalar path — measured
130
+ # 5.5x slower gzipCompress (16 MiB: ~2.2 s vs ~0.4 s in a debug build). Do NOT
131
+ # remove it, and do NOT lower the version: 1.1.9 did not have the feature (it
132
+ # hard-enabled `zlib-rs/std`).
133
+ flate2 = { version = "1.1.10", default-features = false, features = ["zlib-rs", "runtime_detection"] }
110
134
  # brotli compression (pure Rust port).
111
135
  brotli = "8"
112
136
 
package/README.md CHANGED
@@ -187,8 +187,11 @@ For coverage floors, the typecheck/test configs, and the full test matrix, see
187
187
  ## Publishing
188
188
 
189
189
  The package ships **all platform addons in a single tarball**. Push a `v*` tag
190
- and CI builds + publishes every platform to npm; or use `bun run release:manual`
191
- for a quick single-platform release:
190
+ and `.github/workflows/release.yml` verifies the tag against
191
+ `package.json`/`Cargo.toml`, runs the quality gates, builds every platform
192
+ through the reusable `build-addons.yml`, publishes to npm with provenance, and
193
+ attaches the same `.node` files + `SHA256SUMS` to a GitHub release. Or use
194
+ `bun run release:manual` for a quick single-platform release:
192
195
 
193
196
  ```bash
194
197
  bun run release minor # bump + verify + commit + tag (CI publishes)
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -351,10 +351,14 @@ callbacks — keep it that way.
351
351
  These are not optional — they are what make the C-ABI surface safe on Bun (no
352
352
  napi-style unwind guard exists for raw `extern "C"`).
353
353
 
354
- 1. **`panic_guard` every fallible/allocating core** (`std::panic::catch_unwind`
355
- in `rust/ffi/`, `AssertUnwindSafe` for captured `&mut [u8]`). An uncaught
356
- panic unwinding through `extern "C"` kills the whole Bun process — this is
357
- what happened under `11-concurrent-burst`.
354
+ 1. **Guard every export body with `c_abi!`** (`rust/ffi/util.rs`, which wraps
355
+ `panic_guard` / `std::panic::catch_unwind`; `AssertUnwindSafe` for captured
356
+ `&mut [u8]`). An uncaught panic unwinding through `extern "C"` is undefined
357
+ behaviour and kills the whole Bun process — this is what happened under
358
+ `11-concurrent-burst`. Use `panic_guard` directly only for a sub-expression
359
+ that should fall back while the rest of the body continues. The
360
+ `every_c_abi_export_is_panic_guarded` test fails the build if a new
361
+ `#[no_mangle]` export has neither.
358
362
  2. **Bind-time self-test for EVERY new symbol** (`src/native/ffi/selfTest`).
359
363
  `bun:ffi` is experimental upstream; the self-test + napi fallback is the
360
364
  safety net. No symbol ships without a self-test vector.
@@ -84,9 +84,13 @@ mod tests {
84
84
  ## 2. Expose it over the C ABI (bun:ffi primary)
85
85
 
86
86
  Add the `#[no_mangle] extern "C"` export in `rust/ffi/<domain>.rs`. Every
87
- fallible / allocating export **must** route its core through `panic_guard`
88
- (defined in `rust/ffi/util.rs`) so an uncaught panic can't unwind through
89
- `extern "C"` and kill the process.
87
+ export body **must** be wrapped in the `c_abi!(fallback, { ... })` macro
88
+ (`rust/ffi/util.rs`), which runs it under `panic_guard`/`catch_unwind` so an
89
+ uncaught panic can't unwind through `extern "C"` and kill the process. Use
90
+ `panic_guard` directly only for a sub-expression that should fall back while the
91
+ rest of the body continues. `ffi/tests.rs`'s
92
+ `every_c_abi_export_is_panic_guarded` fails the build if a new export is
93
+ unprotected.
90
94
 
91
95
  Rules (see `docs/FFI_BUN_GUIDE.md` for the full contract):
92
96
  - Keep signatures **scalar + `(ptr,len)`** — no struct-by-value, no variadics.
@@ -117,10 +121,9 @@ Rules (see `docs/FFI_BUN_GUIDE.md` for the full contract):
117
121
  #[no_mangle]
118
122
  pub unsafe extern "C" fn castrum_fnv1a64(data: *const u8, len: usize) -> u64 {
119
123
  if data.is_null() { return 0; }
120
- panic_guard(
121
- || crate::crypto::hashing::fnv1a64_bytes(std::slice::from_raw_parts(data, len)),
122
- 0,
123
- )
124
+ c_abi!(0, {
125
+ crate::crypto::hashing::fnv1a64_bytes(std::slice::from_raw_parts(data, len))
126
+ })
124
127
  }
125
128
  ```
126
129
 
@@ -204,8 +207,8 @@ bun run bench:startup # if you touched the transport/loade
204
207
  ## Checklist
205
208
 
206
209
  - [ ] Pure-Rust core in the right domain folder with `#[cfg(test)] mod tests`
207
- - [ ] `#[no_mangle] extern "C"` export with `panic_guard` + null checks +
208
- correct `u64_fast`/cstring ABI
210
+ - [ ] `#[no_mangle] extern "C"` export with `c_abi!` + null checks + correct
211
+ `u64_fast`/cstring ABI
209
212
  - [ ] Symbol in the `ffi.ts` dlopen map + `BunFFI` interface method
210
213
  - [ ] Per-domain `selfTest*` vector in the same `ffi/build/*.ts` file
211
214
  - [ ] Public `rust.*` wrapper with JSDoc (+ `*Into` pooled variant if hot)
package/docs/REPO_MAP.md CHANGED
@@ -291,12 +291,16 @@ consumed.
291
291
 
292
292
  - Package name `castrum` (unscoped, public). Native binary name `castrum`
293
293
  (declared in package.json `napi.binaryName` + Cargo.toml — keep in sync).
294
- - **Multi-platform (recommended)**: push a `v*` tag → `.github/workflows/ci.yml`
295
- builds each platform addon, the `publish` job downloads them into
296
- `./artifacts`, stages them, and runs `npm publish` (npm Trusted Publishing /
297
- OIDC — preferred, no long-lived token; the job also targets the `NPM_TOKEN`
298
- environment as a fallback secret. Needs the Trusted Publisher configured on
299
- npmjs.com).
294
+ - **Multi-platform (recommended)**: push a `v*` tag → `.github/workflows/release.yml`.
295
+ It verifies the tag matches `package.json`/`Cargo.toml`/`Cargo.lock`, runs
296
+ fmt/clippy/tests + the JS gates, then calls the reusable
297
+ `.github/workflows/build-addons.yml` (the same matrix CI uses) to build every
298
+ platform addon. The `publish` job downloads them into `./artifacts`, stages
299
+ them, and runs `npm publish` (npm Trusted Publishing / OIDC — preferred, no
300
+ long-lived token; the job also targets the `NPM_TOKEN` environment as a
301
+ fallback secret. Needs the Trusted Publisher configured on npmjs.com).
302
+ A final job creates the GitHub release with the `.node` files + `SHA256SUMS`.
303
+ CI itself no longer publishes (or runs on tags), so the two cannot race.
300
304
  - **Manual single-platform**: `bun run release:manual`
301
305
  (syncs package.json ↔ Cargo.toml ↔ CHANGELOG, tags, builds, publishes with
302
306
  `CASTRUM_PUBLISH_ALLOW_PARTIAL=1`). `--dry-run` plans only.