@fedify/fedify 2.4.0-pr.936.41 → 2.5.0-dev.2271

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-Bda6LK7A.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-B-9mXxFW.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-oR5aJKpU.mjs} +1 -1
  34. package/dist/dist-DJQM4u7i.mjs +189 -0
  35. package/dist/docloader-DBoYbvYW.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 +215 -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-CkZiAcWY.cjs} +8640 -3722
  92. package/dist/http-B5JT115n.cjs +10630 -0
  93. package/dist/http-DydWCB7R.js +6527 -0
  94. package/dist/{http-CPVMUgsW.mjs → http-siciWkmx.mjs} +397 -168
  95. package/dist/key-BspPiXqn.mjs +951 -0
  96. package/dist/key-C1nv7_jD.d.ts +1125 -0
  97. package/dist/key-DYxuyd-s.d.cts +1125 -0
  98. package/dist/key-owner-evidence-APB6NpSk.mjs +108 -0
  99. package/dist/keycache-Da8A8mZa.mjs +200 -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-KyGqJqSp.mjs → kv-cache-BF1hnW65.mjs} +1 -1
  104. package/dist/{kv-cache-5bnX3-Jq.js → kv-cache-CTQr1tbn.js} +54 -16
  105. package/dist/{kv-cache-DQ29C4XL.cjs → kv-cache-DCac1nEU.cjs} +55 -19
  106. package/dist/{ld-Cj9F_5AP.mjs → ld-CzaP-hJl.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-CYg9yxBL.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-Y-kpsp6S.js → middleware-CsDDXKuL.js} +5493 -1103
  113. package/dist/{middleware-CvwTUgnP.mjs → middleware-D7_LO-Vs.mjs} +3157 -272
  114. package/dist/{middleware-CEctxBN6.mjs → middleware-DWjrfpcz.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-DEvZuyOE.d.cts → owner-BF0L9cMt.d.cts} +11 -0
  139. package/dist/{owner-CnngXDNJ.d.ts → owner-BSzr5-I8.d.ts} +11 -0
  140. package/dist/owner-DYgfTFHy.mjs +267 -0
  141. package/dist/portable-collection-BpsVsRov.js +670 -0
  142. package/dist/portable-collection-C74P1vtC.mjs +418 -0
  143. package/dist/portable-collection-DZd2bm7M.cjs +686 -0
  144. package/dist/portable-key-BIMLrAP4.mjs +549 -0
  145. package/dist/portable-key-id-Ca30-hOa.mjs +248 -0
  146. package/dist/proof-Dxy6ByqI.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-C4dDpAxm.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 +702 -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-D0KJI4NF.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-Da8A8mZa.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 () => {
@@ -79,16 +104,192 @@ test("KvKeyCache fetch error metadata", async () => {
79
104
  assertEquals(await cache.getFetchError(keyId), void 0);
80
105
  });
81
106
  test("KvKeyCache unavailable entries expire", async () => {
82
- const cache = new KvKeyCache(new MemoryKvStore(), ["pk"], { unavailableKeyTtl: Temporal.Duration.from({ milliseconds: 1 }) });
107
+ const kv = new ManualClockKvStore();
108
+ const unavailableKeyTtl = Temporal.Duration.from({ minutes: 10 });
109
+ const cache = new KvKeyCache(kv, ["pk"], { unavailableKeyTtl });
83
110
  const keyId = new URL("https://example.com/expired");
84
111
  await cache.set(keyId, null);
85
112
  await cache.setFetchError(keyId, {
86
113
  status: 410,
87
114
  response: new Response(null, { status: 410 })
88
115
  });
89
- await new Promise((resolve) => setTimeout(resolve, 10));
116
+ kv.advance({ minutes: 20 });
117
+ const later = new KvKeyCache(kv, ["pk"], { unavailableKeyTtl });
118
+ assertEquals(await later.get(keyId), void 0);
119
+ assertEquals(await later.getFetchError(keyId), void 0);
120
+ });
121
+ test("KvKeyCache.keyTtl defaults to 30 days", () => {
122
+ assertEquals(new KvKeyCache(new MemoryKvStore(), ["pk"]).keyTtl.total("day"), 30);
123
+ });
124
+ test("KvKeyCache.keyTtl is configurable", () => {
125
+ assertEquals(new KvKeyCache(new MemoryKvStore(), ["pk"], { keyTtl: Temporal.Duration.from({ days: 7 }) }).keyTtl.total("day"), 7);
126
+ });
127
+ test("KvKeyCache cached keys expire after keyTtl", async () => {
128
+ const kv = new ManualClockKvStore();
129
+ const cache = new KvKeyCache(kv, ["pk"], { keyTtl: Temporal.Duration.from({ days: 30 }) });
130
+ const keyId = new URL("https://example.com/key");
131
+ await cache.set(keyId, new CryptographicKey({ id: keyId }));
132
+ assert(await kv.get([
133
+ "pk",
134
+ "2",
135
+ keyId.href
136
+ ]) != null);
137
+ assertInstanceOf(await cache.get(keyId), CryptographicKey);
138
+ kv.advance({ days: 31 });
139
+ assertEquals(await kv.get([
140
+ "pk",
141
+ "2",
142
+ keyId.href
143
+ ]), void 0);
90
144
  assertEquals(await cache.get(keyId), void 0);
91
- assertEquals(await cache.getFetchError(keyId), void 0);
145
+ assertEquals(cache.nullKeys.has(keyId.href), false);
146
+ await cache.set(keyId, new CryptographicKey({ id: keyId }));
147
+ const refetched = await cache.get(keyId);
148
+ assertInstanceOf(refetched, CryptographicKey);
149
+ assertEquals(refetched.id?.href, keyId.href);
150
+ });
151
+ test("KvKeyCache.get() ignores entries from an earlier generation", async () => {
152
+ const kv = new MemoryKvStore();
153
+ const cache = new KvKeyCache(kv, ["pk"]);
154
+ await kv.set(["pk", "https://example.com/key"], {
155
+ "@context": "https://w3id.org/security/v1",
156
+ id: "https://example.com/key",
157
+ owner: "https://example.com/impersonated",
158
+ type: "CryptographicKey"
159
+ });
160
+ assertEquals(await cache.get(new URL("https://example.com/key")), void 0);
161
+ });
162
+ test("KvKeyCache.compatibleKeyScope() keeps each purpose apart", async () => {
163
+ const cache = new KvKeyCache(new MemoryKvStore(), ["pk"]);
164
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z6Mk/actor#main-key");
165
+ const http = cache.compatibleKeyScope("httpSignature");
166
+ await http.set(keyId, new CryptographicKey({ id: keyId }));
167
+ await cache.compatibleKeyScope("multikey").set(keyId, null);
168
+ assertInstanceOf(await http.get(keyId), CryptographicKey);
169
+ assertEquals(await cache.compatibleKeyScope("multikey").get(keyId), null);
170
+ assertEquals(await cache.compatibleKeyScope("cryptographicKey").get(keyId), void 0);
171
+ assertEquals(await cache.get(keyId), void 0);
172
+ await http.delete(keyId);
173
+ assertEquals(await http.get(keyId), void 0);
174
+ });
175
+ test("KvKeyCache.compatibleKeyScope() entries expire", async () => {
176
+ const kv = new ManualClockKvStore();
177
+ let now = Temporal.Instant.fromEpochMilliseconds(0);
178
+ const scope = new KvKeyCache(kv, ["pk"], {
179
+ now: () => now,
180
+ keyTtl: Temporal.Duration.from({ days: 30 }),
181
+ unavailableKeyTtl: Temporal.Duration.from({ minutes: 10 })
182
+ }).compatibleKeyScope("httpSignature");
183
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
184
+ const nullId = new URL("https://gw.example/.well-known/apgateway/did:key:z/b");
185
+ const expiringId = new URL("https://gw.example/.well-known/apgateway/did:key:z/c");
186
+ await scope.set(keyId, new CryptographicKey({ id: keyId }));
187
+ await scope.set(nullId, null);
188
+ await scope.set(expiringId, new CryptographicKey({ id: expiringId }), { expires: now.add({ minutes: 5 }) });
189
+ now = now.add({ minutes: 5 });
190
+ assertInstanceOf(await scope.get(keyId), CryptographicKey);
191
+ assertEquals(await scope.get(nullId), null);
192
+ assertEquals(await scope.get(expiringId), void 0);
193
+ now = now.add({ minutes: 5 });
194
+ assertEquals(await scope.get(nullId), void 0);
195
+ now = Temporal.Instant.fromEpochMilliseconds(0).add({ hours: 1 });
196
+ assertEquals(await scope.get(keyId), void 0);
197
+ kv.advance({ hours: 1 });
198
+ assertEquals(await kv.get([
199
+ "pk",
200
+ "__compatible",
201
+ "httpSignature",
202
+ keyId.href
203
+ ]), void 0);
204
+ });
205
+ test("KvKeyCache.compatibleKeyScope() drops an entry replaced by an expired one", async () => {
206
+ const kv = new MemoryKvStore();
207
+ const now = Temporal.Now.instant();
208
+ const scope = new KvKeyCache(kv, ["pk"], { now: () => now }).compatibleKeyScope("httpSignature");
209
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
210
+ await scope.set(keyId, new CryptographicKey({ id: keyId }));
211
+ await scope.set(keyId, new CryptographicKey({ id: keyId }), { expires: now });
212
+ assertEquals(await scope.get(keyId), void 0);
213
+ });
214
+ test("KvKeyCache.compatibleKeyScope() ignores malformed entries", async () => {
215
+ const kv = new MemoryKvStore();
216
+ const cache = new KvKeyCache(kv, ["pk"]);
217
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
218
+ const entryKey = [
219
+ "pk",
220
+ "__compatible",
221
+ "multikey",
222
+ keyId.href
223
+ ];
224
+ await kv.set(entryKey, { key: "garbage" });
225
+ assertEquals(await cache.compatibleKeyScope("multikey").get(keyId), void 0);
226
+ assertEquals(await kv.get(entryKey), void 0);
227
+ const httpEntryKey = [
228
+ "pk",
229
+ "__compatible",
230
+ "httpSignature",
231
+ keyId.href
232
+ ];
233
+ await kv.set(httpEntryKey, {
234
+ key: await new CryptographicKey({ id: keyId }).toJsonLd(),
235
+ expires: 1e300
236
+ });
237
+ assertEquals(await cache.compatibleKeyScope("httpSignature").get(keyId), void 0);
238
+ assertEquals(await kv.get(httpEntryKey), void 0);
239
+ });
240
+ test("KvKeyCache.compatibleKeyScope() keeps the owners of keys", async () => {
241
+ const kv = new MemoryKvStore();
242
+ const now = Temporal.Instant.fromEpochMilliseconds(0);
243
+ const scope = new KvKeyCache(kv, ["pk"], {
244
+ now: () => now,
245
+ keyTtl: Temporal.Duration.from({ minutes: 5 })
246
+ }).compatibleKeyScope("httpSignature");
247
+ const keyId = new URL("https://gw.example/.well-known/apgateway/did:key:z/a");
248
+ const owner = {
249
+ "@id": "ap://did:key:z/a",
250
+ "@type": ["urn:example:Actor"]
251
+ };
252
+ assertEquals(await scope.set(keyId, new CryptographicKey({ id: keyId }), {
253
+ expires: now.add({ hours: 1 }),
254
+ owner
255
+ }), now.add({ minutes: 5 }));
256
+ const entry = await scope.getEntry(keyId);
257
+ assertInstanceOf(entry?.key, CryptographicKey);
258
+ assertEquals(entry?.owner, owner);
259
+ assertEquals(entry?.expires, now.add({ minutes: 5 }));
260
+ const entryKey = [
261
+ "pk",
262
+ "__compatible",
263
+ "httpSignature",
264
+ keyId.href
265
+ ];
266
+ await kv.set(entryKey, JSON.parse(JSON.stringify(await kv.get(entryKey))));
267
+ assertEquals((await scope.getEntry(keyId))?.owner, owner);
268
+ await kv.set(entryKey, {
269
+ ...await kv.get(entryKey) ?? {},
270
+ owner: "bogus"
271
+ });
272
+ const malformed = await scope.getEntry(keyId);
273
+ assertInstanceOf(malformed?.key, CryptographicKey);
274
+ assertEquals(malformed?.owner, void 0);
275
+ await scope.set(keyId, new CryptographicKey({ id: keyId }), { owner: {
276
+ ...owner,
277
+ "urn:example:padding": "x".repeat(64 * 1024)
278
+ } });
279
+ const oversized = await scope.getEntry(keyId);
280
+ assertInstanceOf(oversized?.key, CryptographicKey);
281
+ assertEquals(oversized?.owner, void 0);
282
+ assertEquals(await scope.set(keyId, null, { owner }), void 0);
283
+ assertEquals(await kv.get(entryKey), {
284
+ key: null,
285
+ expires: 6e5
286
+ });
287
+ assertEquals(await scope.getEntry(keyId), null);
288
+ assertEquals(await scope.set(keyId, new CryptographicKey({ id: keyId }), {
289
+ expires: now,
290
+ owner
291
+ }), void 0);
292
+ assertEquals(await scope.getEntry(keyId), void 0);
92
293
  });
93
294
  //#endregion
94
295
  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-CYg9yxBL.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 {