@fedify/fedify 2.4.0-pr.936.41 → 2.4.1

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.
Files changed (244) hide show
  1. package/README.md +50 -39
  2. package/dist/{assert-CJ1KXcvv.mjs → assert-D1Eafmd_.mjs} +1 -1
  3. package/dist/{assert_equals-BV7oLMxm.mjs → assert_equals-Z6IcEbWU.mjs} +2 -28
  4. package/dist/assert_exists-cffSpJ7X.mjs +28 -0
  5. package/dist/assert_false-CPdRnc3E.mjs +23 -0
  6. package/dist/assert_greater_or_equal-BlafOF4-.mjs +31 -0
  7. package/dist/{assert_instance_of-Q9KTBnrf.mjs → assert_instance_of-mrXWWNY-.mjs} +1 -1
  8. package/dist/{assert_not_equals-EPJPoxuf.mjs → assert_not_equals-CpPK2t89.mjs} +2 -1
  9. package/dist/assert_rejects-CTptdYck.mjs +39 -0
  10. package/dist/{assert_strict_equals-Ec20AUwa.mjs → assert_strict_equals-CYvBmkpC.mjs} +2 -1
  11. package/dist/{assert_throws-NiFfqbnH.mjs → assert_throws-BYITOvPO.mjs} +2 -1
  12. package/dist/assertion_error-B-cx0fFA.mjs +31 -0
  13. package/dist/audience-CHQ-FlLD.mjs +95 -0
  14. package/dist/{builder-DonuxRl_.mjs → builder-C1o3n_ih.mjs} +169 -14
  15. package/dist/{circuit-breaker-CBGyz5F7.mjs → circuit-breaker-XJ53md4S.mjs} +224 -17
  16. package/dist/circuit-breaker-test-utils-DW6YC_Pe.mjs +14 -0
  17. package/dist/{client-CjF5IYQS.mjs → client-CEnNz8O7.mjs} +144 -8
  18. package/dist/{codec-BBga-FWI.mjs → codec-C6rTrpIp.mjs} +26 -3
  19. package/dist/{collection-BIhlldqK.mjs → collection-CnnP1UAv.mjs} +1 -1
  20. package/dist/compat/mod.cjs +1 -1
  21. package/dist/compat/mod.d.cts +1 -1
  22. package/dist/compat/mod.d.ts +1 -1
  23. package/dist/compat/mod.js +1 -1
  24. package/dist/compat/outgoing-jsonld.test.mjs +71 -3
  25. package/dist/compat/public-audience.test.mjs +14 -5
  26. package/dist/compat/secured-document.test.d.mts +2 -0
  27. package/dist/compat/secured-document.test.mjs +58 -0
  28. package/dist/compat/transformers.test.mjs +5 -5
  29. package/dist/compound-proof-DoFNbS9M.mjs +989 -0
  30. package/dist/{context-Zii1f5xS.d.ts → context-7NyiqIcg.d.ts} +1600 -25
  31. package/dist/{context-BJXxPElm.mjs → context-8Tu9kea0.mjs} +21 -63
  32. package/dist/{context-lxX6I7as.d.cts → context-tsYPJ2Ew.d.cts} +1600 -25
  33. package/dist/{deno-BHzKn9Ig.mjs → deno-D7MEaAg-.mjs} +1 -1
  34. package/dist/dist-DJQM4u7i.mjs +189 -0
  35. package/dist/docloader-uYfrT5sv.mjs +87 -0
  36. package/dist/{esm-yYQfPhIY.mjs → esm-BHXXx4Wx.mjs} +13 -6
  37. package/dist/federation/audience.test.d.mts +2 -0
  38. package/dist/federation/audience.test.mjs +130 -0
  39. package/dist/federation/builder.test.mjs +54 -5
  40. package/dist/federation/circuit-breaker.test.mjs +838 -7
  41. package/dist/federation/collection.test.mjs +3 -3
  42. package/dist/federation/compound-fanout.test.d.mts +2 -0
  43. package/dist/federation/compound-fanout.test.mjs +228 -0
  44. package/dist/federation/handler-compound-proof.test.d.mts +2 -0
  45. package/dist/federation/handler-compound-proof.test.mjs +384 -0
  46. package/dist/federation/handler.test.mjs +385 -15
  47. package/dist/federation/hashlink-media.test.d.mts +2 -0
  48. package/dist/federation/hashlink-media.test.mjs +422 -0
  49. package/dist/federation/idempotency.test.mjs +6 -6
  50. package/dist/federation/inbox-report.test.d.mts +2 -0
  51. package/dist/federation/inbox-report.test.mjs +475 -0
  52. package/dist/federation/inbox.test.mjs +3 -3
  53. package/dist/federation/keycache.test.mjs +246 -14
  54. package/dist/federation/kv.test.mjs +3 -3
  55. package/dist/federation/metrics.test.mjs +5 -5
  56. package/dist/federation/middleware.test.mjs +967 -35
  57. package/dist/federation/mod.cjs +18 -261
  58. package/dist/federation/mod.d.cts +5 -5
  59. package/dist/federation/mod.d.ts +5 -5
  60. package/dist/federation/mod.js +279 -1
  61. package/dist/federation/mq.test.mjs +123 -47
  62. package/dist/federation/negotiation.test.mjs +4 -4
  63. package/dist/federation/outgoing-proof.test.d.mts +2 -0
  64. package/dist/federation/outgoing-proof.test.mjs +931 -0
  65. package/dist/federation/portable-actor.test.d.mts +2 -0
  66. package/dist/federation/portable-actor.test.mjs +496 -0
  67. package/dist/federation/portable-chain.test.d.mts +2 -0
  68. package/dist/federation/portable-chain.test.mjs +370 -0
  69. package/dist/federation/portable-collection.test.d.mts +2 -0
  70. package/dist/federation/portable-collection.test.mjs +832 -0
  71. package/dist/federation/portable-delivery.test.d.mts +2 -0
  72. package/dist/federation/portable-delivery.test.mjs +746 -0
  73. package/dist/federation/portable-gateway-keys.test.d.mts +2 -0
  74. package/dist/federation/portable-gateway-keys.test.mjs +686 -0
  75. package/dist/federation/portable-inbox.test.d.mts +2 -0
  76. package/dist/federation/portable-inbox.test.mjs +1535 -0
  77. package/dist/federation/portable-parse-uri.test.d.mts +2 -0
  78. package/dist/federation/portable-parse-uri.test.mjs +348 -0
  79. package/dist/federation/portable-route-activity.test.d.mts +2 -0
  80. package/dist/federation/portable-route-activity.test.mjs +259 -0
  81. package/dist/federation/portable.test.d.mts +2 -0
  82. package/dist/federation/portable.test.mjs +1072 -0
  83. package/dist/federation/retry.test.mjs +4 -3
  84. package/dist/federation/router.test.mjs +9 -159
  85. package/dist/federation/send.test.mjs +245 -27
  86. package/dist/federation/tasks/codec.test.mjs +4 -4
  87. package/dist/federation/tasks/enqueue.test.mjs +42 -4
  88. package/dist/federation/tasks/tasks.test.mjs +7 -6
  89. package/dist/federation/temporal.test.mjs +4 -4
  90. package/dist/federation/webfinger.test.mjs +275 -12
  91. package/dist/{middleware-FrSMAYEx.cjs → federation-4rvjH8Md.cjs} +8663 -3725
  92. package/dist/http-B_wV17Ij.js +6527 -0
  93. package/dist/{http-CPVMUgsW.mjs → http-CNzz4a_O.mjs} +397 -168
  94. package/dist/http-riIBL3-C.cjs +10630 -0
  95. package/dist/key-C1nv7_jD.d.ts +1125 -0
  96. package/dist/key-DYxuyd-s.d.cts +1125 -0
  97. package/dist/key-hMoNKe7p.mjs +951 -0
  98. package/dist/key-owner-evidence-APB6NpSk.mjs +108 -0
  99. package/dist/keycache-D-MNltOk.mjs +221 -0
  100. package/dist/{kv-D6hNiMTK.d.ts → kv-B2mzK5tl.d.cts} +3 -2
  101. package/dist/{kv-gJ8LYbxX.d.cts → kv-B2mzK5tl.d.ts} +3 -2
  102. package/dist/kv-DBRWVx3Q.mjs +104 -0
  103. package/dist/{kv-cache-DQ29C4XL.cjs → kv-cache-BjK2Y9Wu.cjs} +55 -19
  104. package/dist/{kv-cache-KyGqJqSp.mjs → kv-cache-CetcQsQa.mjs} +1 -1
  105. package/dist/{kv-cache-5bnX3-Jq.js → kv-cache-DVJLXeI0.js} +54 -16
  106. package/dist/{ld-Cj9F_5AP.mjs → ld-CW_8GOEC.mjs} +44 -12
  107. package/dist/map-local-context-conflict-DOYEEJ3u.mjs +204 -0
  108. package/dist/map-local-create-note-B0SeXJms.mjs +214 -0
  109. package/dist/{metrics-DMk-nTxI.mjs → metrics-CBugc7uM.mjs} +3 -2
  110. package/dist/metrics-DVKYY6K1.d.cts +36 -0
  111. package/dist/metrics-DoRtI0qU.d.ts +36 -0
  112. package/dist/{middleware-CvwTUgnP.mjs → middleware-CEQBUZaH.mjs} +3157 -272
  113. package/dist/{middleware-Y-kpsp6S.js → middleware-CjdyJcGd.js} +5530 -1120
  114. package/dist/{middleware-CEctxBN6.mjs → middleware-D0PeYTxA.mjs} +1 -1
  115. package/dist/{mod-gOlPDuT8.d.cts → mod-BojP2Bw3.d.cts} +1 -1
  116. package/dist/mod-CavhAgLw.d.cts +320 -0
  117. package/dist/mod-CtpF2BU5.d.ts +320 -0
  118. package/dist/{mod-BtEaIEcD.d.cts → mod-DEZXwV6J.d.ts} +10 -4
  119. package/dist/{mod-UMmveiO0.d.ts → mod-Dw-nPxQh.d.cts} +10 -4
  120. package/dist/{mod-DLc2Ot6f.d.ts → mod-Xj5P4s4d.d.ts} +1 -1
  121. package/dist/mod.cjs +40 -39
  122. package/dist/mod.d.cts +10 -11
  123. package/dist/mod.d.ts +10 -11
  124. package/dist/mod.js +9 -9
  125. package/dist/{mq-llHKivST.mjs → mq-Dm1Wmtm-.mjs} +6 -0
  126. package/dist/nodeinfo/client.test.mjs +139 -4
  127. package/dist/nodeinfo/handler.test.mjs +5 -5
  128. package/dist/nodeinfo/mod.cjs +1 -1
  129. package/dist/nodeinfo/mod.d.cts +1 -1
  130. package/dist/nodeinfo/mod.d.ts +1 -1
  131. package/dist/nodeinfo/mod.js +1 -1
  132. package/dist/nodeinfo/types.test.mjs +4 -4
  133. package/dist/otel/exporter.test.mjs +3 -3
  134. package/dist/otel/mod.cjs +0 -1
  135. package/dist/otel/mod.d.cts +1 -1
  136. package/dist/otel/mod.d.ts +1 -1
  137. package/dist/{outgoing-jsonld-URuqsICz.mjs → outgoing-jsonld-4IJqPYos.mjs} +12 -10
  138. package/dist/owner--VRABJfK.mjs +267 -0
  139. package/dist/{owner-DEvZuyOE.d.cts → owner-BF0L9cMt.d.cts} +11 -0
  140. package/dist/{owner-CnngXDNJ.d.ts → owner-BSzr5-I8.d.ts} +11 -0
  141. package/dist/portable-collection-BVQYFfEq.mjs +418 -0
  142. package/dist/portable-collection-CiKz-t9W.cjs +686 -0
  143. package/dist/portable-collection-CnSD193J.js +670 -0
  144. package/dist/portable-key-BjUXSULt.mjs +549 -0
  145. package/dist/portable-key-id-Ca30-hOa.mjs +248 -0
  146. package/dist/proof-kTlg91Kb.mjs +1299 -0
  147. package/dist/{public-audience-Cr5MsnMq.mjs → public-audience--klBIOk1.mjs} +15 -10
  148. package/dist/router-u5O5KCQr.mjs +156 -0
  149. package/dist/runtime/mod.cjs +1 -1
  150. package/dist/runtime/mod.js +1 -1
  151. package/dist/secured-document-CxzZZ9nL.mjs +35 -0
  152. package/dist/send-DohrDmGq.mjs +495 -0
  153. package/dist/sig/accept.test.mjs +1 -1
  154. package/dist/sig/compound-proof-discovery.test.d.mts +2 -0
  155. package/dist/sig/compound-proof-discovery.test.mjs +331 -0
  156. package/dist/sig/compound-proof-producer.test.d.mts +2 -0
  157. package/dist/sig/compound-proof-producer.test.mjs +107 -0
  158. package/dist/sig/compound-proof-verification.test.d.mts +2 -0
  159. package/dist/sig/compound-proof-verification.test.mjs +833 -0
  160. package/dist/sig/compound-proof.test.d.mts +2 -0
  161. package/dist/sig/compound-proof.test.mjs +411 -0
  162. package/dist/sig/http.test.mjs +759 -31
  163. package/dist/sig/key-owner-evidence.test.d.mts +2 -0
  164. package/dist/sig/key-owner-evidence.test.mjs +100 -0
  165. package/dist/sig/key.test.mjs +220 -8
  166. package/dist/sig/ld.test.mjs +65 -7
  167. package/dist/sig/mitra-receive-interop.test.d.mts +2 -0
  168. package/dist/sig/mitra-receive-interop.test.mjs +260 -0
  169. package/dist/sig/mitra-send-interop.test.d.mts +2 -0
  170. package/dist/sig/mitra-send-interop.test.mjs +461 -0
  171. package/dist/sig/mod.cjs +18 -16
  172. package/dist/sig/mod.d.cts +4 -4
  173. package/dist/sig/mod.d.ts +4 -4
  174. package/dist/sig/mod.js +3 -3
  175. package/dist/sig/owner.test.mjs +108 -9
  176. package/dist/sig/portable-collection.test.d.mts +2 -0
  177. package/dist/sig/portable-collection.test.mjs +697 -0
  178. package/dist/sig/portable-interop.test.d.mts +2 -0
  179. package/dist/sig/portable-interop.test.mjs +156 -0
  180. package/dist/sig/portable-key-id.test.d.mts +2 -0
  181. package/dist/sig/portable-key-id.test.mjs +67 -0
  182. package/dist/sig/portable-key.test.d.mts +2 -0
  183. package/dist/sig/portable-key.test.mjs +1439 -0
  184. package/dist/sig/proof.test.mjs +1753 -16
  185. package/dist/sig/tootik-request-interop.test.d.mts +2 -0
  186. package/dist/sig/tootik-request-interop.test.mjs +190 -0
  187. package/dist/sig/tootik-send-interop.test.d.mts +2 -0
  188. package/dist/sig/tootik-send-interop.test.mjs +331 -0
  189. package/dist/sig/verification.test.d.mts +2 -0
  190. package/dist/sig/verification.test.mjs +310 -0
  191. package/dist/std__assert-DvMDRPes.mjs +8 -0
  192. package/dist/{testing-CO7ftO8A.mjs → tasks-IG3pHfvZ.mjs} +2 -2
  193. package/dist/{temporal-fsXO5IvD.mjs → temporal-VKyzJSNt.mjs} +3 -3
  194. package/dist/testing/context.test.d.mts +2 -0
  195. package/dist/testing/context.test.mjs +19 -0
  196. package/dist/testing/kv.test.d.mts +2 -0
  197. package/dist/testing/kv.test.mjs +101 -0
  198. package/dist/testing/mod.d.mts +1617 -48
  199. package/dist/testing/mod.mjs +6 -3
  200. package/dist/testing-t8xDeJZ5.mjs +8 -0
  201. package/dist/{transformers-DGwl-hD1.cjs → transformers-BalCrSsr.cjs} +0 -1
  202. package/dist/{types-DC1pNgJA.js → types-_S2_MeLF.js} +144 -8
  203. package/dist/{types-CPym83zc.cjs → types-poIao40f.cjs} +160 -7
  204. package/dist/utils/docloader.test.mjs +530 -8
  205. package/dist/utils/kv-cache.test.mjs +2 -2
  206. package/dist/utils/mod.cjs +1 -1
  207. package/dist/utils/mod.d.cts +1 -1
  208. package/dist/utils/mod.d.ts +1 -1
  209. package/dist/utils/mod.js +1 -1
  210. package/dist/verification-C3954hQh.mjs +5 -0
  211. package/dist/verification-Dpfcw8ml.mjs +105 -0
  212. package/dist/vocab/cjs.test.mjs +1 -1
  213. package/package.json +8 -8
  214. package/dist/assert_rejects-EgstcQy5.mjs +0 -82
  215. package/dist/docloader-e1khNUKy.mjs +0 -49
  216. package/dist/http-CsmQ-BQ4.js +0 -2483
  217. package/dist/http-VyDTd4G3.d.cts +0 -553
  218. package/dist/http-hlIjmewS.cjs +0 -2694
  219. package/dist/http-lf8Hsd91.d.ts +0 -553
  220. package/dist/key-DfPsX8hv.mjs +0 -453
  221. package/dist/keycache-_DHqz5z_.mjs +0 -97
  222. package/dist/metrics-CoUJLQhZ.d.cts +0 -276
  223. package/dist/metrics-Dc4jR-IC.d.ts +0 -276
  224. package/dist/mod-B0hW12_O.d.cts +0 -307
  225. package/dist/mod-COIAjwRS.d.ts +0 -307
  226. package/dist/owner-Br9YYzn_.mjs +0 -120
  227. package/dist/proof-B4ngoaNQ.mjs +0 -316
  228. package/dist/proof-B6E0XUXJ.js +0 -1415
  229. package/dist/proof-NN4xCQGL.cjs +0 -1562
  230. package/dist/send-CxHKUNzv.mjs +0 -239
  231. package/dist/std__assert-B2NnY9bq.mjs +0 -79
  232. package/dist/temporal-polyfill-BCdTHexd.cjs +0 -3565
  233. /package/dist/{accept-8PiolDP7.mjs → accept-CPVqki78.mjs} +0 -0
  234. /package/dist/{activity-listener-BtTSxZWA.mjs → activity-listener-C-BSbKI7.mjs} +0 -0
  235. /package/dist/{client-CAM_bQXx.d.cts → client-D-XP_Ccb.d.cts} +0 -0
  236. /package/dist/{client-CSddvgWN.d.ts → client-D-XP_Ccb.d.ts} +0 -0
  237. /package/dist/{keys-Dbyd7bhl.mjs → keys-DIJNHW-Y.mjs} +0 -0
  238. /package/dist/{kv-CXBAok3k.mjs → kv-DCHkaJ9-.mjs} +0 -0
  239. /package/dist/{negotiation-RuwrPFqi.mjs → negotiation-CCocWT_N.mjs} +0 -0
  240. /package/dist/{retry-DgFqeS5k.mjs → retry-zX5xw5e0.mjs} +0 -0
  241. /package/dist/{chunk-D5IdezsZ.js → rolldown-runtime-BC-Eo5Mj.js} +0 -0
  242. /package/dist/{chunk-Czpeue4M.cjs → rolldown-runtime-Dmm3t92W.cjs} +0 -0
  243. /package/dist/{transformers-DXze6FUB.js → transformers-DAtXl_Kc.js} +0 -0
  244. /package/dist/{types-CrtdVuDP.mjs → types-DE_LV1JB.mjs} +0 -0
@@ -1,11 +1,12 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { t as MemoryKvStore } from "../kv-CXBAok3k.mjs";
5
- import { t as assertEquals } from "../assert_equals-BV7oLMxm.mjs";
6
- import { t as assertInstanceOf } from "../assert_instance_of-Q9KTBnrf.mjs";
7
- import { t as assert } from "../assert-CJ1KXcvv.mjs";
8
- import { t as KvKeyCache } from "../keycache-_DHqz5z_.mjs";
4
+ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
5
+ import { t as ManualClockKvStore } from "../kv-DBRWVx3Q.mjs";
6
+ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
7
+ import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
8
+ import { t as assert } from "../assert-D1Eafmd_.mjs";
9
+ import { t as KvKeyCache } from "../keycache-D-MNltOk.mjs";
9
10
  import { CryptographicKey, Multikey } from "@fedify/vocab";
10
11
  import { test } from "@fedify/fixture";
11
12
  //#region src/federation/keycache.test.ts
@@ -13,25 +14,41 @@ test("KvKeyCache.set()", async () => {
13
14
  const kv = new MemoryKvStore();
14
15
  const cache = new KvKeyCache(kv, ["pk"]);
15
16
  await cache.set(new URL("https://example.com/key"), new CryptographicKey({ id: new URL("https://example.com/key") }));
16
- assertEquals(await kv.get(["pk", "https://example.com/key"]), {
17
+ assertEquals(await kv.get([
18
+ "pk",
19
+ "2",
20
+ "https://example.com/key"
21
+ ]), {
17
22
  "@context": "https://w3id.org/security/v1",
18
23
  id: "https://example.com/key",
19
24
  type: "CryptographicKey"
20
25
  });
21
26
  await cache.set(new URL("https://example.com/key2"), new Multikey({ id: new URL("https://example.com/key2") }));
22
- assertEquals(await kv.get(["pk", "https://example.com/key2"]), {
27
+ assertEquals(await kv.get([
28
+ "pk",
29
+ "2",
30
+ "https://example.com/key2"
31
+ ]), {
23
32
  "@context": "https://w3id.org/security/multikey/v1",
24
33
  id: "https://example.com/key2",
25
34
  type: "Multikey"
26
35
  });
27
36
  await cache.set(new URL("https://example.com/null"), null);
28
37
  assert(cache.nullKeys.has("https://example.com/null"));
29
- assertEquals(await kv.get(["pk", "https://example.com/null"]), null);
38
+ assertEquals(await kv.get([
39
+ "pk",
40
+ "2",
41
+ "https://example.com/null"
42
+ ]), null);
30
43
  });
31
44
  test("KvKeyCache.get()", async () => {
32
45
  const kv = new MemoryKvStore();
33
46
  const cache = new KvKeyCache(kv, ["pk"]);
34
- await kv.set(["pk", "https://example.com/key"], {
47
+ await kv.set([
48
+ "pk",
49
+ "2",
50
+ "https://example.com/key"
51
+ ], {
35
52
  "@context": "https://w3id.org/security/v1",
36
53
  id: "https://example.com/key",
37
54
  type: "CryptographicKey"
@@ -39,7 +56,11 @@ test("KvKeyCache.get()", async () => {
39
56
  const cryptoKey = await cache.get(new URL("https://example.com/key"));
40
57
  assertInstanceOf(cryptoKey, CryptographicKey);
41
58
  assertEquals(cryptoKey?.id?.href, "https://example.com/key");
42
- await kv.set(["pk", "https://example.com/key2"], {
59
+ await kv.set([
60
+ "pk",
61
+ "2",
62
+ "https://example.com/key2"
63
+ ], {
43
64
  "@context": "https://w3id.org/security/multikey/v1",
44
65
  id: "https://example.com/key2",
45
66
  type: "Multikey"
@@ -49,7 +70,11 @@ test("KvKeyCache.get()", async () => {
49
70
  assertEquals(multikey?.id?.href, "https://example.com/key2");
50
71
  cache.nullKeys.set("https://example.com/null", Temporal.Now.instant().add(Temporal.Duration.from({ minutes: 10 })));
51
72
  assertEquals(await cache.get(new URL("https://example.com/null")), null);
52
- await kv.set(["pk", "https://example.com/null2"], null);
73
+ await kv.set([
74
+ "pk",
75
+ "2",
76
+ "https://example.com/null2"
77
+ ], null);
53
78
  assertEquals(await new KvKeyCache(kv, ["pk"]).get(new URL("https://example.com/null2")), null);
54
79
  });
55
80
  test("KvKeyCache fetch error metadata", async () => {
@@ -78,17 +103,224 @@ test("KvKeyCache fetch error metadata", async () => {
78
103
  await cache.setFetchError(keyId, null);
79
104
  assertEquals(await cache.getFetchError(keyId), void 0);
80
105
  });
106
+ test("KvKeyCache reads legacy fetch errors", async () => {
107
+ const kv = new MemoryKvStore();
108
+ const keyId = new URL("https://example.com/key");
109
+ await kv.set([
110
+ "pk",
111
+ "__fetchError",
112
+ keyId.href
113
+ ], {
114
+ errorName: "FetchError",
115
+ errorMessage: "Legacy failure"
116
+ });
117
+ const result = await new KvKeyCache(kv, ["pk"]).getFetchError(keyId);
118
+ assert(result != null && "error" in result);
119
+ assertEquals(result.error.constructor, Error);
120
+ assertEquals(result.error.name, "FetchError");
121
+ assertEquals(result.error.message, "Legacy failure");
122
+ assertEquals(result.error.cause, void 0);
123
+ });
124
+ test("KvKeyCache keeps unknown error types generic", async () => {
125
+ class CustomError extends Error {}
126
+ const kv = new MemoryKvStore();
127
+ const keyId = new URL("https://example.com/key");
128
+ const error = new CustomError("Custom failure");
129
+ error.name = "FetchError";
130
+ await new KvKeyCache(kv, ["pk"]).setFetchError(keyId, { error });
131
+ const result = await new KvKeyCache(kv, ["pk"]).getFetchError(keyId);
132
+ assert(result != null && "error" in result);
133
+ assertEquals(result.error.constructor, Error);
134
+ assertEquals(result.error.name, "FetchError");
135
+ assertEquals(result.error.message, "Custom failure");
136
+ });
81
137
  test("KvKeyCache unavailable entries expire", async () => {
82
- const cache = new KvKeyCache(new MemoryKvStore(), ["pk"], { unavailableKeyTtl: Temporal.Duration.from({ milliseconds: 1 }) });
138
+ const kv = new ManualClockKvStore();
139
+ const unavailableKeyTtl = Temporal.Duration.from({ minutes: 10 });
140
+ const cache = new KvKeyCache(kv, ["pk"], { unavailableKeyTtl });
83
141
  const keyId = new URL("https://example.com/expired");
84
142
  await cache.set(keyId, null);
85
143
  await cache.setFetchError(keyId, {
86
144
  status: 410,
87
145
  response: new Response(null, { status: 410 })
88
146
  });
89
- await new Promise((resolve) => setTimeout(resolve, 10));
147
+ kv.advance({ minutes: 20 });
148
+ const later = new KvKeyCache(kv, ["pk"], { unavailableKeyTtl });
149
+ assertEquals(await later.get(keyId), void 0);
150
+ assertEquals(await later.getFetchError(keyId), void 0);
151
+ });
152
+ test("KvKeyCache.keyTtl defaults to 30 days", () => {
153
+ assertEquals(new KvKeyCache(new MemoryKvStore(), ["pk"]).keyTtl.total("day"), 30);
154
+ });
155
+ test("KvKeyCache.keyTtl is configurable", () => {
156
+ assertEquals(new KvKeyCache(new MemoryKvStore(), ["pk"], { keyTtl: Temporal.Duration.from({ days: 7 }) }).keyTtl.total("day"), 7);
157
+ });
158
+ test("KvKeyCache cached keys expire after keyTtl", async () => {
159
+ const kv = new ManualClockKvStore();
160
+ const cache = new KvKeyCache(kv, ["pk"], { keyTtl: Temporal.Duration.from({ days: 30 }) });
161
+ const keyId = new URL("https://example.com/key");
162
+ await cache.set(keyId, new CryptographicKey({ id: keyId }));
163
+ assert(await kv.get([
164
+ "pk",
165
+ "2",
166
+ keyId.href
167
+ ]) != null);
168
+ assertInstanceOf(await cache.get(keyId), CryptographicKey);
169
+ kv.advance({ days: 31 });
170
+ assertEquals(await kv.get([
171
+ "pk",
172
+ "2",
173
+ keyId.href
174
+ ]), void 0);
90
175
  assertEquals(await cache.get(keyId), void 0);
91
- assertEquals(await cache.getFetchError(keyId), void 0);
176
+ assertEquals(cache.nullKeys.has(keyId.href), false);
177
+ await cache.set(keyId, new CryptographicKey({ id: keyId }));
178
+ const refetched = await cache.get(keyId);
179
+ assertInstanceOf(refetched, CryptographicKey);
180
+ assertEquals(refetched.id?.href, keyId.href);
181
+ });
182
+ test("KvKeyCache.get() ignores entries from an earlier generation", async () => {
183
+ const kv = new MemoryKvStore();
184
+ const cache = new KvKeyCache(kv, ["pk"]);
185
+ await kv.set(["pk", "https://example.com/key"], {
186
+ "@context": "https://w3id.org/security/v1",
187
+ id: "https://example.com/key",
188
+ owner: "https://example.com/impersonated",
189
+ type: "CryptographicKey"
190
+ });
191
+ assertEquals(await cache.get(new URL("https://example.com/key")), void 0);
192
+ });
193
+ test("KvKeyCache.compatibleKeyScope() keeps each purpose apart", async () => {
194
+ const cache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
195
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z6Mk/actor#main-key");
196
+ const http = cache.compatibleKeyScope("httpSignature");
197
+ await http.set(keyId, new CryptographicKey({ id: keyId }));
198
+ await cache.compatibleKeyScope("multikey").set(keyId, null);
199
+ assertInstanceOf(await http.get(keyId), CryptographicKey);
200
+ assertEquals(await cache.compatibleKeyScope("multikey").get(keyId), null);
201
+ assertEquals(await cache.compatibleKeyScope("cryptographicKey").get(keyId), void 0);
202
+ assertEquals(await cache.get(keyId), void 0);
203
+ await http.delete(keyId);
204
+ assertEquals(await http.get(keyId), void 0);
205
+ });
206
+ test("KvKeyCache.compatibleKeyScope() entries expire", async () => {
207
+ const kv = new ManualClockKvStore();
208
+ let now = Temporal.Instant.fromEpochMilliseconds(0);
209
+ const scope = new KvKeyCache(kv, ["pk"], {
210
+ now: () => now,
211
+ keyTtl: Temporal.Duration.from({ days: 30 }),
212
+ unavailableKeyTtl: Temporal.Duration.from({ minutes: 10 })
213
+ }).compatibleKeyScope("httpSignature");
214
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
215
+ const nullId = new URL("https://gw.example/.well-known/apgateway/did:key:z/b");
216
+ const expiringId = new URL("https://gw.example/.well-known/apgateway/did:key:z/c");
217
+ await scope.set(keyId, new CryptographicKey({ id: keyId }));
218
+ await scope.set(nullId, null);
219
+ await scope.set(expiringId, new CryptographicKey({ id: expiringId }), { expires: now.add({ minutes: 5 }) });
220
+ now = now.add({ minutes: 5 });
221
+ assertInstanceOf(await scope.get(keyId), CryptographicKey);
222
+ assertEquals(await scope.get(nullId), null);
223
+ assertEquals(await scope.get(expiringId), void 0);
224
+ now = now.add({ minutes: 5 });
225
+ assertEquals(await scope.get(nullId), void 0);
226
+ now = Temporal.Instant.fromEpochMilliseconds(0).add({ hours: 1 });
227
+ assertEquals(await scope.get(keyId), void 0);
228
+ kv.advance({ hours: 1 });
229
+ assertEquals(await kv.get([
230
+ "pk",
231
+ "__compatible",
232
+ "httpSignature",
233
+ keyId.href
234
+ ]), void 0);
235
+ });
236
+ test("KvKeyCache.compatibleKeyScope() drops an entry replaced by an expired one", async () => {
237
+ const kv = new MemoryKvStore();
238
+ const now = Temporal.Now.instant();
239
+ const scope = new KvKeyCache(kv, ["pk"], { now: () => now }).compatibleKeyScope("httpSignature");
240
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
241
+ await scope.set(keyId, new CryptographicKey({ id: keyId }));
242
+ await scope.set(keyId, new CryptographicKey({ id: keyId }), { expires: now });
243
+ assertEquals(await scope.get(keyId), void 0);
244
+ });
245
+ test("KvKeyCache.compatibleKeyScope() ignores malformed entries", async () => {
246
+ const kv = new MemoryKvStore();
247
+ const cache = new KvKeyCache(kv, ["pk"]);
248
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
249
+ const entryKey = [
250
+ "pk",
251
+ "__compatible",
252
+ "multikey",
253
+ keyId.href
254
+ ];
255
+ await kv.set(entryKey, { key: "garbage" });
256
+ assertEquals(await cache.compatibleKeyScope("multikey").get(keyId), void 0);
257
+ assertEquals(await kv.get(entryKey), void 0);
258
+ const httpEntryKey = [
259
+ "pk",
260
+ "__compatible",
261
+ "httpSignature",
262
+ keyId.href
263
+ ];
264
+ await kv.set(httpEntryKey, {
265
+ key: await new CryptographicKey({ id: keyId }).toJsonLd(),
266
+ expires: 1e300
267
+ });
268
+ assertEquals(await cache.compatibleKeyScope("httpSignature").get(keyId), void 0);
269
+ assertEquals(await kv.get(httpEntryKey), void 0);
270
+ });
271
+ test("KvKeyCache.compatibleKeyScope() keeps the owners of keys", async () => {
272
+ const kv = new MemoryKvStore();
273
+ const now = Temporal.Instant.fromEpochMilliseconds(0);
274
+ const scope = new KvKeyCache(kv, ["pk"], {
275
+ now: () => now,
276
+ keyTtl: Temporal.Duration.from({ minutes: 5 })
277
+ }).compatibleKeyScope("httpSignature");
278
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
279
+ const owner = {
280
+ "@id": "ap://did:key:z/a",
281
+ "@type": ["urn:example:Actor"]
282
+ };
283
+ assertEquals(await scope.set(keyId, new CryptographicKey({ id: keyId }), {
284
+ expires: now.add({ hours: 1 }),
285
+ owner
286
+ }), now.add({ minutes: 5 }));
287
+ const entry = await scope.getEntry(keyId);
288
+ assertInstanceOf(entry?.key, CryptographicKey);
289
+ assertEquals(entry?.owner, owner);
290
+ assertEquals(entry?.expires, now.add({ minutes: 5 }));
291
+ const entryKey = [
292
+ "pk",
293
+ "__compatible",
294
+ "httpSignature",
295
+ keyId.href
296
+ ];
297
+ await kv.set(entryKey, JSON.parse(JSON.stringify(await kv.get(entryKey))));
298
+ assertEquals((await scope.getEntry(keyId))?.owner, owner);
299
+ await kv.set(entryKey, {
300
+ ...await kv.get(entryKey) ?? {},
301
+ owner: "bogus"
302
+ });
303
+ const malformed = await scope.getEntry(keyId);
304
+ assertInstanceOf(malformed?.key, CryptographicKey);
305
+ assertEquals(malformed?.owner, void 0);
306
+ await scope.set(keyId, new CryptographicKey({ id: keyId }), { owner: {
307
+ ...owner,
308
+ "urn:example:padding": "x".repeat(64 * 1024)
309
+ } });
310
+ const oversized = await scope.getEntry(keyId);
311
+ assertInstanceOf(oversized?.key, CryptographicKey);
312
+ assertEquals(oversized?.owner, void 0);
313
+ assertEquals(await scope.set(keyId, null, { owner }), void 0);
314
+ assertEquals(await kv.get(entryKey), {
315
+ key: null,
316
+ expires: 6e5
317
+ });
318
+ assertEquals(await scope.getEntry(keyId), null);
319
+ assertEquals(await scope.set(keyId, new CryptographicKey({ id: keyId }), {
320
+ expires: now,
321
+ owner
322
+ }), void 0);
323
+ assertEquals(await scope.getEntry(keyId), void 0);
92
324
  });
93
325
  //#endregion
94
326
  export {};
@@ -1,9 +1,9 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { t as MemoryKvStore } from "../kv-CXBAok3k.mjs";
5
- import { t as assertEquals } from "../assert_equals-BV7oLMxm.mjs";
6
- import "../std__assert-B2NnY9bq.mjs";
4
+ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
5
+ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
6
+ import "../std__assert-DvMDRPes.mjs";
7
7
  import { test } from "@fedify/fixture";
8
8
  //#region src/federation/kv.test.ts
9
9
  test("MemoryKvStore", async (t) => {
@@ -1,12 +1,12 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { t as assertEquals } from "../assert_equals-BV7oLMxm.mjs";
5
- import "../std__assert-B2NnY9bq.mjs";
6
- import { t as assertRejects } from "../assert_rejects-EgstcQy5.mjs";
7
- import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-DMk-nTxI.mjs";
8
- import { createTestMeterProvider, test } from "@fedify/fixture";
4
+ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
5
+ import "../std__assert-DvMDRPes.mjs";
6
+ import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
7
+ import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-CBugc7uM.mjs";
9
8
  import { FetchError } from "@fedify/vocab-runtime";
9
+ import { createTestMeterProvider, test } from "@fedify/fixture";
10
10
  import { DataPointType, MeterProvider, MetricReader } from "@opentelemetry/sdk-metrics";
11
11
  //#region src/federation/metrics.test.ts
12
12
  var TestMetricReader = class extends MetricReader {