@fedify/fedify 2.0.0-pr.490.2 → 2.0.0-pr.559.4

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 (267) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +64 -37
  3. package/dist/{builder-4syLV1-z.js → builder-DTlQwmVF.js} +10 -3
  4. package/dist/{client-BsGzbnV-.d.ts → client-CUTUGgvJ.d.ts} +18 -18
  5. package/dist/{client-pY7-3icS.js → client-Dg7OfUDA.js} +28 -23
  6. package/dist/{client-94iWEfQa.d.cts → client-by-PEGAJ.d.cts} +18 -18
  7. package/dist/compat/mod.cjs +1 -1
  8. package/dist/compat/mod.d.cts +6 -10
  9. package/dist/compat/mod.d.ts +6 -10
  10. package/dist/compat/mod.js +1 -1
  11. package/dist/compat/transformers.test.js +22 -21
  12. package/dist/{context-PxGADCsD.d.cts → context-B6X-7loD.d.cts} +206 -74
  13. package/dist/{context-V-XS2_6O.d.ts → context-CJaICYPw.d.ts} +206 -74
  14. package/dist/context-CZ5llAss.js +109 -0
  15. package/dist/deno-DGx1JZHr.js +124 -0
  16. package/dist/{testing-BslrM_9E.js → dist-B5f6a8Tt.js} +90 -110
  17. package/dist/{docloader-DndkGj0O.js → docloader-D8UHsyqD.js} +3 -3
  18. package/dist/{esm-VlKMJQqV.js → esm-DGl7uK1r.js} +1 -1
  19. package/dist/federation/builder.test.js +7 -5
  20. package/dist/federation/collection.test.js +2 -3
  21. package/dist/federation/handler.test.js +24 -23
  22. package/dist/federation/idempotency.test.js +59 -22
  23. package/dist/federation/inbox.test.js +4 -3
  24. package/dist/federation/keycache.test.js +4 -4
  25. package/dist/federation/kv.test.js +56 -3
  26. package/dist/federation/middleware.test.js +307 -93
  27. package/dist/federation/mod.cjs +9 -10
  28. package/dist/federation/mod.d.cts +7 -11
  29. package/dist/federation/mod.d.ts +7 -11
  30. package/dist/federation/mod.js +8 -11
  31. package/dist/federation/mq.test.js +167 -16
  32. package/dist/federation/negotiation.test.js +2 -3
  33. package/dist/federation/retry.test.js +2 -3
  34. package/dist/federation/router.test.js +2 -2
  35. package/dist/federation/send.test.js +93 -11
  36. package/dist/{webfinger/handler.test.js → federation/webfinger.test.js} +24 -22
  37. package/dist/{federation-CRpdnOMS.cjs → federation-CE0CJ_0G.cjs} +116 -10
  38. package/dist/{federation-jcR8-ZxP.js → federation-D6FVaeAR.js} +122 -16
  39. package/dist/{http-YhR_TMMQ.js → http-CL3G0rnf.js} +126 -9
  40. package/dist/{http-M8k5mKc0.d.cts → http-ClB3pLcL.d.cts} +1 -1
  41. package/dist/{http-Dxpqz4hE.cjs → http-DKBUv5zZ.cjs} +139 -16
  42. package/dist/{http-BbO0ejuk.d.ts → http-DLBDPal9.d.ts} +1 -1
  43. package/dist/{http-DH47B-h3.js → http-LGtYlSfN.js} +3 -2
  44. package/dist/{inbox-CEyHvxOo.js → inbox-DbtWQY2D.js} +2 -1
  45. package/dist/{key-x7E5PYI0.js → key-BCtt1Ugy.js} +3 -3
  46. package/dist/{keycache-BRXuBDuy.js → keycache-DRxpZ5r9.js} +1 -1
  47. package/dist/{keys-DLk_8H-l.js → keys-ZbcByPg9.js} +1 -1
  48. package/dist/{kv-Bxr0Q87_.d.cts → kv-B4vFhIYL.d.cts} +30 -1
  49. package/dist/{kv-BKNZ-Tb-.d.ts → kv-CYySNrsn.d.ts} +30 -1
  50. package/dist/{kv-CRZrzyXm.js → kv-QzKcOQgP.js} +22 -0
  51. package/dist/{kv-cache-HFnFIjSD.js → kv-cache-0786BfqY.js} +3 -3
  52. package/dist/{kv-cache-DN9pfMBe.js → kv-cache-B__dHl7g.js} +15 -2
  53. package/dist/{kv-cache-BMpfJFTx.cjs → kv-cache-DCJojeTn.cjs} +3 -3
  54. package/dist/{ld-CRPaU6c8.js → ld-QlZPwGEH.js} +4 -3
  55. package/dist/middleware-B3jUPnDa.js +12 -0
  56. package/dist/middleware-BFiwWMA2.cjs +12 -0
  57. package/dist/middleware-DMx6DyIw.js +26 -0
  58. package/dist/{middleware-DfLpMu7C.js → middleware-Dm58nObp.js} +280 -166
  59. package/dist/{middleware-BIqFwRwI.js → middleware-WokE4qxc.js} +245 -178
  60. package/dist/{middleware-Ck7O6mb0.cjs → middleware-hWyKOO_6.cjs} +332 -206
  61. package/dist/{mod-DMpuiKXi.d.cts → mod-BHXq4Q3x.d.cts} +7 -7
  62. package/dist/{mod-DgxG-byT.d.cts → mod-BrS8tiad.d.cts} +2 -2
  63. package/dist/mod-CoMP50Rf.d.ts +64 -0
  64. package/dist/{mod-BoRKfJPE.d.cts → mod-DScazwCW.d.cts} +4 -4
  65. package/dist/mod-DTzN6Pv3.d.cts +62 -0
  66. package/dist/{mod-aAE2wOWV.d.ts → mod-DZmuPaKv.d.ts} +7 -7
  67. package/dist/{mod-D5Z2tISD.d.ts → mod-jOa7W503.d.ts} +2 -2
  68. package/dist/{mod-Cdo6SYlJ.d.ts → mod-xKJ57rwu.d.ts} +4 -4
  69. package/dist/mod.cjs +12 -93
  70. package/dist/mod.d.cts +11 -15
  71. package/dist/mod.d.ts +11 -15
  72. package/dist/mod.js +11 -15
  73. package/dist/nodeinfo/client.test.js +3 -4
  74. package/dist/nodeinfo/handler.test.js +22 -21
  75. package/dist/nodeinfo/mod.cjs +2 -2
  76. package/dist/nodeinfo/mod.d.cts +2 -2
  77. package/dist/nodeinfo/mod.d.ts +2 -2
  78. package/dist/nodeinfo/mod.js +2 -2
  79. package/dist/nodeinfo/types.test.js +2 -3
  80. package/dist/otel/exporter.test.js +893 -0
  81. package/dist/otel/mod.cjs +256 -0
  82. package/dist/otel/mod.d.cts +230 -0
  83. package/dist/otel/mod.d.ts +232 -0
  84. package/dist/otel/mod.js +255 -0
  85. package/dist/{owner-kQRGVXG1.d.ts → owner-BgI8C-VY.d.ts} +1 -2
  86. package/dist/{owner-B4HbyP8s.d.cts → owner-C-zfmVAD.d.cts} +1 -2
  87. package/dist/{owner-CIWnopkT.js → owner-Cejm-F7S.js} +2 -2
  88. package/dist/{proof-D-5ri6rf.js → proof-BOQBHd-i.js} +3 -2
  89. package/dist/{proof-fEwcA7LA.cjs → proof-Bmi8ZIcW.cjs} +24 -25
  90. package/dist/{proof-C8-2l0zH.js → proof-CnaEQ_Ev.js} +4 -5
  91. package/dist/router-D9eI0s4b.js +118 -0
  92. package/dist/{send-CPGk9QKZ.js → send-jFxXfsN8.js} +38 -4
  93. package/dist/sig/http.test.js +6 -7
  94. package/dist/sig/key.test.js +5 -5
  95. package/dist/sig/ld.test.js +6 -6
  96. package/dist/sig/mod.cjs +3 -5
  97. package/dist/sig/mod.d.cts +3 -5
  98. package/dist/sig/mod.d.ts +3 -5
  99. package/dist/sig/mod.js +3 -5
  100. package/dist/sig/owner.test.js +6 -7
  101. package/dist/sig/proof.test.js +6 -6
  102. package/dist/testing/mod.d.ts +173 -7006
  103. package/dist/testing/mod.js +4 -3
  104. package/dist/{transformers-CoBS-oFG.cjs → transformers-BjBg6Lag.cjs} +2 -2
  105. package/dist/{transformers-BFT6d7J5.js → transformers-N_ip_y4P.js} +2 -2
  106. package/dist/{types-BtUjyi5y.js → types-8l28uC8o.js} +30 -25
  107. package/dist/{types-CWgzGaqk.cjs → types-B6z6CqIz.cjs} +30 -25
  108. package/dist/{types-C2XVl6gj.js → types-CPz01LGH.js} +3 -3
  109. package/dist/utils/docloader.test.js +7 -8
  110. package/dist/utils/kv-cache.test.js +5 -3
  111. package/dist/utils/mod.cjs +3 -5
  112. package/dist/utils/mod.d.cts +3 -4
  113. package/dist/utils/mod.d.ts +3 -4
  114. package/dist/utils/mod.js +3 -5
  115. package/dist/vocab/mod.cjs +8 -81
  116. package/dist/vocab/mod.d.cts +1 -4
  117. package/dist/vocab/mod.d.ts +1 -4
  118. package/dist/vocab/mod.js +1 -5
  119. package/package.json +27 -27
  120. package/dist/actor-BT-e5fn9.js +0 -146
  121. package/dist/actor-B_gRMloq.js +0 -41647
  122. package/dist/actor-CBfPjuWj.cjs +0 -42079
  123. package/dist/actor-DqFajh9s.d.ts +0 -130
  124. package/dist/actor-f2NtjyCg.d.cts +0 -128
  125. package/dist/fixtures/activitypub.academy/users/brauca_darradiul.json +0 -83
  126. package/dist/fixtures/example.com/announce.json +0 -6
  127. package/dist/fixtures/example.com/collection.json +0 -19
  128. package/dist/fixtures/example.com/create.json +0 -6
  129. package/dist/fixtures/example.com/cross-origin-actor.json +0 -6
  130. package/dist/fixtures/example.com/hong-gildong.json +0 -11
  131. package/dist/fixtures/example.com/invite.json +0 -7
  132. package/dist/fixtures/example.com/key.json +0 -7
  133. package/dist/fixtures/example.com/key2.json +0 -6
  134. package/dist/fixtures/example.com/object.json +0 -6
  135. package/dist/fixtures/example.com/orderedcollectionpage.json +0 -24
  136. package/dist/fixtures/example.com/paged/a.json +0 -13
  137. package/dist/fixtures/example.com/paged/b.json +0 -16
  138. package/dist/fixtures/example.com/paged-collection.json +0 -6
  139. package/dist/fixtures/example.com/person.json +0 -22
  140. package/dist/fixtures/example.com/person2.json +0 -40
  141. package/dist/fixtures/example.com/test.json +0 -5
  142. package/dist/fixtures/example.com/users/handle.json +0 -16
  143. package/dist/fixtures/example.com/wrong-type.json +0 -3
  144. package/dist/fixtures/media.example.com/avatars/test-avatar.jpg.json +0 -6
  145. package/dist/fixtures/oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd.json +0 -24
  146. package/dist/fixtures/remote.domain/users/bob.json +0 -20
  147. package/dist/fixtures/server.example/users/alice.json +0 -20
  148. package/dist/fixtures/w3id.org/identity/v1.json +0 -152
  149. package/dist/fixtures/w3id.org/security/data-integrity/v1.json +0 -74
  150. package/dist/fixtures/w3id.org/security/multikey/v1.json +0 -35
  151. package/dist/fixtures/w3id.org/security/v1.json +0 -50
  152. package/dist/fixtures/wizard.casa/users/hongminhee.json +0 -69
  153. package/dist/fixtures/www.w3.org/ns/activitystreams.json +0 -379
  154. package/dist/fixtures/www.w3.org/ns/did/v1.json +0 -58
  155. package/dist/lookup-BTqtVATt.cjs +0 -266
  156. package/dist/lookup-DOSnR912.js +0 -254
  157. package/dist/lookup-Dj9-mgOn.js +0 -42184
  158. package/dist/middleware-CxswDtQn.js +0 -15
  159. package/dist/middleware-CyITsnX0.js +0 -26
  160. package/dist/middleware-Z8lc_drL.cjs +0 -15
  161. package/dist/mod-BlVovdcy.d.ts +0 -309
  162. package/dist/mod-BxRCHTz-.d.cts +0 -307
  163. package/dist/mod-C58MZ7Wx.d.cts +0 -113
  164. package/dist/mod-CcDPcLJW.d.cts +0 -1
  165. package/dist/mod-Ds0mpFZU.d.ts +0 -115
  166. package/dist/mod-bjzj5QIb.d.ts +0 -2
  167. package/dist/otel-1BmGPuZc.js +0 -64
  168. package/dist/src/vocab/accept.yaml +0 -15
  169. package/dist/src/vocab/activity.yaml +0 -98
  170. package/dist/src/vocab/add.yaml +0 -16
  171. package/dist/src/vocab/announce.yaml +0 -30
  172. package/dist/src/vocab/application.yaml +0 -324
  173. package/dist/src/vocab/arrive.yaml +0 -15
  174. package/dist/src/vocab/article.yaml +0 -46
  175. package/dist/src/vocab/audio.yaml +0 -11
  176. package/dist/src/vocab/block.yaml +0 -16
  177. package/dist/src/vocab/chatmessage.yaml +0 -50
  178. package/dist/src/vocab/collection.yaml +0 -154
  179. package/dist/src/vocab/collectionpage.yaml +0 -55
  180. package/dist/src/vocab/create.yaml +0 -28
  181. package/dist/src/vocab/dataintegrityproof.yaml +0 -56
  182. package/dist/src/vocab/delete.yaml +0 -27
  183. package/dist/src/vocab/didservice.yaml +0 -22
  184. package/dist/src/vocab/dislike.yaml +0 -14
  185. package/dist/src/vocab/document.yaml +0 -31
  186. package/dist/src/vocab/emoji.yaml +0 -12
  187. package/dist/src/vocab/emojireact.yaml +0 -17
  188. package/dist/src/vocab/endpoints.yaml +0 -85
  189. package/dist/src/vocab/event.yaml +0 -11
  190. package/dist/src/vocab/export.yaml +0 -9
  191. package/dist/src/vocab/flag.yaml +0 -15
  192. package/dist/src/vocab/follow.yaml +0 -19
  193. package/dist/src/vocab/group.yaml +0 -324
  194. package/dist/src/vocab/hashtag.yaml +0 -14
  195. package/dist/src/vocab/ignore.yaml +0 -14
  196. package/dist/src/vocab/image.yaml +0 -9
  197. package/dist/src/vocab/intransitiveactivity.yaml +0 -15
  198. package/dist/src/vocab/invite.yaml +0 -14
  199. package/dist/src/vocab/join.yaml +0 -14
  200. package/dist/src/vocab/key.yaml +0 -28
  201. package/dist/src/vocab/leave.yaml +0 -14
  202. package/dist/src/vocab/like.yaml +0 -16
  203. package/dist/src/vocab/link.yaml +0 -101
  204. package/dist/src/vocab/listen.yaml +0 -12
  205. package/dist/src/vocab/mention.yaml +0 -9
  206. package/dist/src/vocab/move.yaml +0 -15
  207. package/dist/src/vocab/multikey.yaml +0 -36
  208. package/dist/src/vocab/note.yaml +0 -48
  209. package/dist/src/vocab/object.yaml +0 -404
  210. package/dist/src/vocab/offer.yaml +0 -15
  211. package/dist/src/vocab/orderedcollection.yaml +0 -39
  212. package/dist/src/vocab/orderedcollectionpage.yaml +0 -50
  213. package/dist/src/vocab/organization.yaml +0 -324
  214. package/dist/src/vocab/page.yaml +0 -11
  215. package/dist/src/vocab/person.yaml +0 -324
  216. package/dist/src/vocab/place.yaml +0 -75
  217. package/dist/src/vocab/profile.yaml +0 -26
  218. package/dist/src/vocab/propertyvalue.yaml +0 -32
  219. package/dist/src/vocab/question.yaml +0 -103
  220. package/dist/src/vocab/read.yaml +0 -13
  221. package/dist/src/vocab/reject.yaml +0 -14
  222. package/dist/src/vocab/relationship.yaml +0 -52
  223. package/dist/src/vocab/remove.yaml +0 -14
  224. package/dist/src/vocab/service.yaml +0 -324
  225. package/dist/src/vocab/source.yaml +0 -26
  226. package/dist/src/vocab/tentativeaccept.yaml +0 -14
  227. package/dist/src/vocab/tentativereject.yaml +0 -14
  228. package/dist/src/vocab/tombstone.yaml +0 -24
  229. package/dist/src/vocab/travel.yaml +0 -16
  230. package/dist/src/vocab/undo.yaml +0 -26
  231. package/dist/src/vocab/update.yaml +0 -58
  232. package/dist/src/vocab/video.yaml +0 -11
  233. package/dist/src/vocab/view.yaml +0 -13
  234. package/dist/testing/docloader.test.js +0 -22
  235. package/dist/vocab/actor.test.js +0 -5963
  236. package/dist/vocab/lookup.test.d.ts +0 -3
  237. package/dist/vocab/lookup.test.js +0 -476
  238. package/dist/vocab/type.test.d.ts +0 -3
  239. package/dist/vocab/type.test.js +0 -24
  240. package/dist/vocab/vocab.test.d.ts +0 -3
  241. package/dist/vocab/vocab.test.js +0 -9397
  242. package/dist/vocab-BCWe1Ih5.d.ts +0 -14905
  243. package/dist/vocab-ByUp-A2_.js +0 -260
  244. package/dist/vocab-CeDBzu-f.d.cts +0 -14903
  245. package/dist/vocab-X_X5T8D3.cjs +0 -296
  246. package/dist/webfinger/handler.test.d.ts +0 -3
  247. package/dist/webfinger/lookup.test.d.ts +0 -3
  248. package/dist/webfinger/lookup.test.js +0 -193
  249. package/dist/webfinger/mod.cjs +0 -8
  250. package/dist/webfinger/mod.d.cts +0 -2
  251. package/dist/webfinger/mod.d.ts +0 -4
  252. package/dist/webfinger/mod.js +0 -8
  253. package/dist/webfinger-C72Y8lrh.js +0 -4
  254. package/dist/webfinger-vAtLmxOF.cjs +0 -4
  255. /package/dist/{collection-BzWsN9pB.js → collection-CcnIw1qY.js} +0 -0
  256. /package/dist/{testing/docloader.test.d.ts → federation/webfinger.test.d.ts} +0 -0
  257. /package/dist/{mod-CVgZgliM.d.ts → mod-1E3W847c.d.ts} +0 -0
  258. /package/dist/{mod-B-hUPT2N.d.cts → mod-C81L6_lQ.d.cts} +0 -0
  259. /package/dist/{negotiation-C4nFufNk.js → negotiation-5NPJL6zp.js} +0 -0
  260. /package/dist/{nodeinfo-BnthBobC.js → nodeinfo-BlLsRSiT.js} +0 -0
  261. /package/dist/{nodeinfo-CdN0rEnZ.cjs → nodeinfo-DuMYTpbZ.cjs} +0 -0
  262. /package/dist/{vocab/actor.test.d.ts → otel/exporter.test.d.ts} +0 -0
  263. /package/dist/{retry-CfF8Gn4d.js → retry-D4GJ670a.js} +0 -0
  264. /package/dist/{sig-C34-oHBl.js → sig-CwuONEzF.js} +0 -0
  265. /package/dist/{sig-YYj5tCnr.cjs → sig-DeXX2xnj.cjs} +0 -0
  266. /package/dist/{utils-DyRU1gdZ.cjs → utils-Db0ZmjcD.cjs} +0 -0
  267. /package/dist/{utils-D-Va7aXC.js → utils-Wranxuoe.js} +0 -0
@@ -3,22 +3,21 @@
3
3
  const { URLPattern } = require("urlpattern-polyfill");
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
- const require_transformers = require('./transformers-CoBS-oFG.cjs');
7
- const require_lookup = require('./lookup-BTqtVATt.cjs');
8
- const require_actor = require('./actor-CBfPjuWj.cjs');
9
- const require_http = require('./http-Dxpqz4hE.cjs');
10
- const require_proof = require('./proof-fEwcA7LA.cjs');
11
- const require_types = require('./types-CWgzGaqk.cjs');
12
- const require_kv_cache = require('./kv-cache-BMpfJFTx.cjs');
13
- const require_vocab = require('./vocab-X_X5T8D3.cjs');
6
+ const require_transformers = require('./transformers-BjBg6Lag.cjs');
7
+ const require_http = require('./http-DKBUv5zZ.cjs');
8
+ const require_proof = require('./proof-Bmi8ZIcW.cjs');
9
+ const require_types = require('./types-B6z6CqIz.cjs');
10
+ const require_kv_cache = require('./kv-cache-DCJojeTn.cjs');
14
11
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
12
+ const __fedify_vocab = require_chunk.__toESM(require("@fedify/vocab"));
15
13
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
16
- const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
17
14
  const es_toolkit = require_chunk.__toESM(require("es-toolkit"));
18
15
  const uri_template_router = require_chunk.__toESM(require("uri-template-router"));
19
16
  const url_template = require_chunk.__toESM(require("url-template"));
20
17
  const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
21
18
  const __opentelemetry_semantic_conventions = require_chunk.__toESM(require("@opentelemetry/semantic-conventions"));
19
+ const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
20
+ const __fedify_webfinger = require_chunk.__toESM(require("@fedify/webfinger"));
22
21
  const node_url = require_chunk.__toESM(require("node:url"));
23
22
 
24
23
  //#region src/federation/inbox.ts
@@ -42,7 +41,7 @@ var InboxListenerSet = class InboxListenerSet {
42
41
  if (inboxListeners == null) return null;
43
42
  while (true) {
44
43
  if (inboxListeners.has(cls)) break;
45
- if (cls === require_actor.Activity) return null;
44
+ if (cls === __fedify_vocab.Activity) return null;
46
45
  cls = globalThis.Object.getPrototypeOf(cls);
47
46
  }
48
47
  const listener = inboxListeners.get(cls);
@@ -63,7 +62,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
63
62
  ]);
64
63
  let cacheKey = null;
65
64
  if (activity.id != null) {
66
- const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, require_actor.getTypeId(activity).href);
65
+ const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, (0, __fedify_vocab.getTypeId)(activity).href);
67
66
  const strategy = idempotencyStrategy ?? "per-inbox";
68
67
  let keyString;
69
68
  if (typeof strategy === "function") {
@@ -142,7 +141,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
142
141
  return "enqueued";
143
142
  }
144
143
  tracerProvider = tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
145
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
144
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
146
145
  return await tracer.startActiveSpan("activitypub.dispatch_inbox_listener", { kind: __opentelemetry_api.SpanKind.INTERNAL }, async (span$1) => {
147
146
  const dispatched = inboxListeners?.dispatchWithClass(activity);
148
147
  if (dispatched == null) {
@@ -152,7 +151,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
152
151
  });
153
152
  span$1.setStatus({
154
153
  code: __opentelemetry_api.SpanStatusCode.UNSET,
155
- message: `Unsupported activity type: ${require_actor.getTypeId(activity).href}`
154
+ message: `Unsupported activity type: ${(0, __fedify_vocab.getTypeId)(activity).href}`
156
155
  });
157
156
  span$1.end();
158
157
  return "unsupportedActivity";
@@ -160,7 +159,7 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
160
159
  const { class: cls, listener } = dispatched;
161
160
  span$1.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
162
161
  try {
163
- await listener(inboxContextFactory(recipient, json, activity?.id?.href, require_actor.getTypeId(activity).href), activity);
162
+ await listener(inboxContextFactory(recipient, json, activity?.id?.href, (0, __fedify_vocab.getTypeId)(activity).href), activity);
164
163
  } catch (error) {
165
164
  try {
166
165
  await inboxErrorHandler?.(ctx, error);
@@ -324,6 +323,7 @@ var FederationBuilderImpl = class {
324
323
  inboxListeners;
325
324
  inboxErrorHandler;
326
325
  sharedInboxKeyDispatcher;
326
+ outboxPermanentFailureHandler;
327
327
  idempotencyStrategy;
328
328
  collectionTypeIds;
329
329
  collectionCallbacks;
@@ -339,7 +339,7 @@ var FederationBuilderImpl = class {
339
339
  this.collectionTypeIds = {};
340
340
  }
341
341
  async build(options) {
342
- const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-Z8lc_drL.cjs"));
342
+ const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-BFiwWMA2.cjs"));
343
343
  const f = new FederationImpl$1(options);
344
344
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
345
345
  f.router = this.router.clone();
@@ -361,11 +361,12 @@ var FederationBuilderImpl = class {
361
361
  f.inboxListeners = this.inboxListeners?.clone();
362
362
  f.inboxErrorHandler = this.inboxErrorHandler;
363
363
  f.sharedInboxKeyDispatcher = this.sharedInboxKeyDispatcher;
364
+ f.outboxPermanentFailureHandler = this.outboxPermanentFailureHandler;
364
365
  f.idempotencyStrategy = this.idempotencyStrategy;
365
366
  return f;
366
367
  }
367
368
  _getTracer() {
368
- return __opentelemetry_api.trace.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
369
+ return __opentelemetry_api.trace.getTracer(require_http.deno_default.name, require_http.deno_default.version);
369
370
  }
370
371
  setActorDispatcher(path, dispatcher) {
371
372
  if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
@@ -385,7 +386,7 @@ var FederationBuilderImpl = class {
385
386
  const actor$1 = await dispatcher(context$2, identifier);
386
387
  span.setAttribute("activitypub.actor.id", (actor$1?.id ?? context$2.getActorUri(identifier)).href);
387
388
  if (actor$1 == null) span.setStatus({ code: __opentelemetry_api.SpanStatusCode.ERROR });
388
- else span.setAttribute("activitypub.actor.type", require_actor.getTypeId(actor$1).href);
389
+ else span.setAttribute("activitypub.actor.type", (0, __fedify_vocab.getTypeId)(actor$1).href);
389
390
  return actor$1;
390
391
  } catch (error) {
391
392
  span.setStatus({
@@ -508,7 +509,7 @@ var FederationBuilderImpl = class {
508
509
  const object = await dispatcher(ctx, values);
509
510
  span.setAttribute("activitypub.object.id", (object?.id ?? ctx.getObjectUri(cls, values)).href);
510
511
  if (object == null) span.setStatus({ code: __opentelemetry_api.SpanStatusCode.ERROR });
511
- else span.setAttribute("activitypub.object.type", require_actor.getTypeId(object).href);
512
+ else span.setAttribute("activitypub.object.type", (0, __fedify_vocab.getTypeId)(object).href);
512
513
  return object;
513
514
  } catch (e) {
514
515
  span.setStatus({
@@ -842,6 +843,9 @@ var FederationBuilderImpl = class {
842
843
  const path = this.router.build(`collection:${routeName}`, values) ?? this.router.build(`orderedCollection:${routeName}`, values);
843
844
  return path;
844
845
  }
846
+ setOutboxPermanentFailureHandler(handler) {
847
+ this.outboxPermanentFailureHandler = handler;
848
+ }
845
849
  /**
846
850
  * Converts a name (string or symbol) to a unique string identifier.
847
851
  * For symbols, generates and caches a UUID if not already present.
@@ -923,10 +927,10 @@ var KvKeyCache = class {
923
927
  const serialized = await this.kv.get([...this.prefix, keyId.href]);
924
928
  if (serialized == null) return void 0;
925
929
  try {
926
- return await require_actor.CryptographicKey.fromJsonLd(serialized, this.options);
930
+ return await __fedify_vocab.CryptographicKey.fromJsonLd(serialized, this.options);
927
931
  } catch {
928
932
  try {
929
- return await require_actor.Multikey.fromJsonLd(serialized, this.options);
933
+ return await __fedify_vocab.Multikey.fromJsonLd(serialized, this.options);
930
934
  } catch {
931
935
  await this.kv.delete([...this.prefix, keyId.href]);
932
936
  return void 0;
@@ -1112,7 +1116,7 @@ async function handleObject(request, { values, context: context$2, objectDispatc
1112
1116
  async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context: context$2, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound }) {
1113
1117
  const spanName = name.trim().replace(/\s+/g, "_");
1114
1118
  tracerProvider = tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
1115
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
1119
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
1116
1120
  const url = new URL(request.url);
1117
1121
  const cursor = url.searchParams.get("cursor");
1118
1122
  if (collectionCallbacks == null) return await onNotFound(request);
@@ -1126,7 +1130,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
1126
1130
  kind: __opentelemetry_api.SpanKind.SERVER,
1127
1131
  attributes: {
1128
1132
  "activitypub.collection.id": baseUri.href,
1129
- "activitypub.collection.type": require_actor.OrderedCollection.typeId.href
1133
+ "activitypub.collection.type": __fedify_vocab.OrderedCollection.typeId.href
1130
1134
  }
1131
1135
  }, async (span) => {
1132
1136
  if (totalItems != null) span.setAttribute("activitypub.collection.total_items", Number(totalItems));
@@ -1150,7 +1154,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
1150
1154
  }
1151
1155
  });
1152
1156
  if (itemsOrResponse instanceof Response) return itemsOrResponse;
1153
- collection = new require_actor.OrderedCollection({
1157
+ collection = new __fedify_vocab.OrderedCollection({
1154
1158
  id: baseUri,
1155
1159
  totalItems: totalItems == null ? null : Number(totalItems),
1156
1160
  items: filterCollectionItems(itemsOrResponse, name, filterPredicate)
@@ -1164,7 +1168,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
1164
1168
  last = new URL(context$2.url);
1165
1169
  last.searchParams.set("cursor", lastCursor);
1166
1170
  }
1167
- collection = new require_actor.OrderedCollection({
1171
+ collection = new __fedify_vocab.OrderedCollection({
1168
1172
  id: baseUri,
1169
1173
  totalItems: totalItems == null ? null : Number(totalItems),
1170
1174
  first,
@@ -1178,7 +1182,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
1178
1182
  kind: __opentelemetry_api.SpanKind.SERVER,
1179
1183
  attributes: {
1180
1184
  "activitypub.collection.id": uri.href,
1181
- "activitypub.collection.type": require_actor.OrderedCollectionPage.typeId.href,
1185
+ "activitypub.collection.type": __fedify_vocab.OrderedCollectionPage.typeId.href,
1182
1186
  "fedify.collection.cursor": cursor
1183
1187
  }
1184
1188
  }, async (span) => {
@@ -1214,7 +1218,7 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
1214
1218
  }
1215
1219
  const partOf = new URL(context$2.url);
1216
1220
  partOf.searchParams.delete("cursor");
1217
- collection = new require_actor.OrderedCollectionPage({
1221
+ collection = new __fedify_vocab.OrderedCollectionPage({
1218
1222
  id: uri,
1219
1223
  prev,
1220
1224
  next,
@@ -1262,7 +1266,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
1262
1266
  let logged = false;
1263
1267
  for (const item of items) {
1264
1268
  let mappedItem;
1265
- if (item instanceof require_actor.Object || item instanceof require_actor.Link || item instanceof URL) mappedItem = item;
1269
+ if (item instanceof __fedify_vocab.Object || item instanceof __fedify_vocab.Link || item instanceof URL) mappedItem = item;
1266
1270
  else if (item.id == null) continue;
1267
1271
  else mappedItem = item.id;
1268
1272
  if (filterPredicate != null && !filterPredicate(item)) {
@@ -1289,7 +1293,7 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
1289
1293
  */
1290
1294
  async function handleInbox(request, options) {
1291
1295
  const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
1292
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
1296
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
1293
1297
  return await tracer.startActiveSpan("activitypub.inbox", {
1294
1298
  kind: options.queue == null ? __opentelemetry_api.SpanKind.SERVER : __opentelemetry_api.SpanKind.PRODUCER,
1295
1299
  attributes: { "activitypub.shared_inbox": options.recipient == null }
@@ -1417,14 +1421,14 @@ async function handleInboxInternal(request, parameters, span) {
1417
1421
  recipient,
1418
1422
  json
1419
1423
  });
1420
- activity = await require_actor.Activity.fromJsonLd(jsonWithoutSig, ctx);
1424
+ activity = await __fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
1421
1425
  } else {
1422
1426
  logger$1.debug("Linked Data Signatures are not verified.", {
1423
1427
  recipient,
1424
1428
  json
1425
1429
  });
1426
1430
  try {
1427
- activity = await require_proof.verifyObject(require_actor.Activity, jsonWithoutSig, {
1431
+ activity = await require_proof.verifyObject(__fedify_vocab.Activity, jsonWithoutSig, {
1428
1432
  contextLoader: ctx.contextLoader,
1429
1433
  documentLoader: ctx.documentLoader,
1430
1434
  keyCache,
@@ -1487,10 +1491,10 @@ async function handleInboxInternal(request, parameters, span) {
1487
1491
  } else logger$1.debug("HTTP Signatures are verified.", { recipient });
1488
1492
  httpSigKey = key;
1489
1493
  }
1490
- activity = await require_actor.Activity.fromJsonLd(jsonWithoutSig, ctx);
1494
+ activity = await __fedify_vocab.Activity.fromJsonLd(jsonWithoutSig, ctx);
1491
1495
  }
1492
1496
  if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
1493
- span.setAttribute("activitypub.activity.type", require_actor.getTypeId(activity).href);
1497
+ span.setAttribute("activitypub.activity.type", (0, __fedify_vocab.getTypeId)(activity).href);
1494
1498
  span.addEvent("activitypub.activity.received", {
1495
1499
  "activitypub.activity.json": JSON.stringify(json),
1496
1500
  "activitypub.activity.verified": activity != null,
@@ -1570,7 +1574,7 @@ async function _handleCustomCollection(request, { name, values, context: context
1570
1574
  verifyDefined(callbacks);
1571
1575
  await authIfNeeded(context$2, values, callbacks);
1572
1576
  const cursor = new URL(request.url).searchParams.get("cursor");
1573
- return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider, require_actor.Collection, require_actor.CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
1577
+ return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider, __fedify_vocab.Collection, __fedify_vocab.CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
1574
1578
  }
1575
1579
  /**
1576
1580
  * Handles an ordered collection request.
@@ -1588,7 +1592,7 @@ async function _handleOrderedCollection(request, { name, values, context: contex
1588
1592
  verifyDefined(callbacks);
1589
1593
  await authIfNeeded(context$2, values, callbacks);
1590
1594
  const cursor = new URL(request.url).searchParams.get("cursor");
1591
- return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider, require_actor.OrderedCollection, require_actor.OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
1595
+ return await new CustomCollectionHandler(name, values, context$2, callbacks, tracerProvider, __fedify_vocab.OrderedCollection, __fedify_vocab.OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
1592
1596
  }
1593
1597
  /**
1594
1598
  * Handling custom collections with support for pagination and filtering.
@@ -1648,7 +1652,7 @@ var CustomCollectionHandler = class {
1648
1652
  this.CollectionPage = CollectionPage$1;
1649
1653
  this.filterPredicate = filterPredicate;
1650
1654
  this.name = this.name.trim().replace(/\s+/g, "_");
1651
- this.#tracer = this.tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
1655
+ this.#tracer = this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
1652
1656
  this.#id = new URL(this.context.url);
1653
1657
  this.#dispatcher = callbacks.dispatcher.bind(callbacks);
1654
1658
  }
@@ -2038,139 +2042,6 @@ function handleNodeInfoJrd(_request, context$2) {
2038
2042
  return Promise.resolve(response);
2039
2043
  }
2040
2044
 
2041
- //#endregion
2042
- //#region src/webfinger/handler.ts
2043
- const logger = (0, __logtape_logtape.getLogger)([
2044
- "fedify",
2045
- "webfinger",
2046
- "server"
2047
- ]);
2048
- /**
2049
- * Handles a WebFinger request. You would not typically call this function
2050
- * directly, but instead use {@link Federation.fetch} method.
2051
- * @param request The WebFinger request to handle.
2052
- * @param parameters The parameters for handling the request.
2053
- * @returns The response to the request.
2054
- */
2055
- async function handleWebFinger(request, options) {
2056
- if (options.tracer == null) return await handleWebFingerInternal(request, options);
2057
- return await options.tracer.startActiveSpan("webfinger.handle", { kind: __opentelemetry_api.SpanKind.SERVER }, async (span) => {
2058
- try {
2059
- const response = await handleWebFingerInternal(request, options);
2060
- span.setStatus({ code: response.ok ? __opentelemetry_api.SpanStatusCode.UNSET : __opentelemetry_api.SpanStatusCode.ERROR });
2061
- return response;
2062
- } catch (error) {
2063
- span.setStatus({
2064
- code: __opentelemetry_api.SpanStatusCode.ERROR,
2065
- message: String(error)
2066
- });
2067
- throw error;
2068
- } finally {
2069
- span.end();
2070
- }
2071
- });
2072
- }
2073
- async function handleWebFingerInternal(request, { context: context$2, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
2074
- if (actorDispatcher == null) {
2075
- logger.error("Actor dispatcher is not set.");
2076
- return await onNotFound(request);
2077
- }
2078
- const resource = context$2.url.searchParams.get("resource");
2079
- if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
2080
- span?.setAttribute("webfinger.resource", resource);
2081
- let resourceUrl;
2082
- try {
2083
- resourceUrl = new URL(resource);
2084
- } catch (e) {
2085
- if (e instanceof TypeError) return new Response("Invalid resource URL.", { status: 400 });
2086
- throw e;
2087
- }
2088
- span?.setAttribute("webfinger.resource.scheme", resourceUrl.protocol.replace(/:$/, ""));
2089
- async function mapUsernameToIdentifier(username) {
2090
- if (actorHandleMapper == null) {
2091
- logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
2092
- return username;
2093
- }
2094
- const identifier$1 = await actorHandleMapper(context$2, username);
2095
- if (identifier$1 == null) {
2096
- logger.error("Actor {username} not found.", { username });
2097
- return null;
2098
- }
2099
- return identifier$1;
2100
- }
2101
- let identifier = null;
2102
- const uriParsed = context$2.parseUri(resourceUrl);
2103
- if (uriParsed?.type != "actor") {
2104
- const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
2105
- if (match == null) {
2106
- const result = await actorAliasMapper?.(context$2, resourceUrl);
2107
- if (result == null) return await onNotFound(request);
2108
- if ("identifier" in result) identifier = result.identifier;
2109
- else identifier = await mapUsernameToIdentifier(result.username);
2110
- } else {
2111
- const portMatch = /:\d+$/.exec(match[2]);
2112
- const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
2113
- if (normalizedHost != context$2.url.host && normalizedHost != host) return await onNotFound(request);
2114
- else {
2115
- identifier = await mapUsernameToIdentifier(match[1]);
2116
- resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
2117
- }
2118
- }
2119
- } else identifier = uriParsed.identifier;
2120
- if (identifier == null) return await onNotFound(request);
2121
- const actor = await actorDispatcher(context$2, identifier);
2122
- if (actor == null) {
2123
- logger.error("Actor {identifier} not found.", { identifier });
2124
- return await onNotFound(request);
2125
- }
2126
- const links = [{
2127
- rel: "self",
2128
- href: context$2.getActorUri(identifier).href,
2129
- type: "application/activity+json"
2130
- }];
2131
- for (const url of actor.urls) if (url instanceof require_actor.Link && url.href != null) links.push({
2132
- rel: url.rel ?? "http://webfinger.net/rel/profile-page",
2133
- href: url.href.href,
2134
- type: url.mediaType == null ? void 0 : url.mediaType
2135
- });
2136
- else if (url instanceof URL) links.push({
2137
- rel: "http://webfinger.net/rel/profile-page",
2138
- href: url.href
2139
- });
2140
- for await (const image of actor.getIcons()) {
2141
- if (image.url?.href == null) continue;
2142
- const link = {
2143
- rel: "http://webfinger.net/rel/avatar",
2144
- href: image.url.href.toString()
2145
- };
2146
- if (image.mediaType != null) link.type = image.mediaType;
2147
- links.push(link);
2148
- }
2149
- if (webFingerLinksDispatcher != null) {
2150
- const customLinks = await webFingerLinksDispatcher(context$2, resourceUrl);
2151
- if (customLinks != null) for (const link of customLinks) links.push(link);
2152
- }
2153
- const aliases = [];
2154
- if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
2155
- aliases.push(`acct:${actor.preferredUsername}@${host ?? context$2.url.host}`);
2156
- if (host != null && host !== context$2.url.host) aliases.push(`acct:${actor.preferredUsername}@${context$2.url.host}`);
2157
- }
2158
- if (resourceUrl.href !== context$2.getActorUri(identifier).href) aliases.push(context$2.getActorUri(identifier).href);
2159
- if (resourceUrl.protocol === "acct:" && host != null && host !== context$2.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
2160
- const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
2161
- aliases.push(`acct:${username}@${host}`);
2162
- }
2163
- const jrd = {
2164
- subject: resourceUrl.href,
2165
- aliases,
2166
- links
2167
- };
2168
- return new Response(JSON.stringify(jrd), { headers: {
2169
- "Content-Type": "application/jrd+json",
2170
- "Access-Control-Allow-Origin": "*"
2171
- } });
2172
- }
2173
-
2174
2045
  //#endregion
2175
2046
  //#region src/federation/retry.ts
2176
2047
  /**
@@ -2239,7 +2110,7 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
2239
2110
  */
2240
2111
  function sendActivity(options) {
2241
2112
  const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
2242
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
2113
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
2243
2114
  return tracer.startActiveSpan("activitypub.send_activity", {
2244
2115
  kind: __opentelemetry_api.SpanKind.CLIENT,
2245
2116
  attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
@@ -2315,7 +2186,7 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
2315
2186
  statusText: response.statusText,
2316
2187
  error
2317
2188
  });
2318
- throw new Error(`Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`);
2189
+ throw new SendActivityError(inbox, response.status, `Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`, error);
2319
2190
  }
2320
2191
  span.addEvent("activitypub.activity.sent", {
2321
2192
  "activitypub.activity.json": JSON.stringify(activity),
@@ -2323,6 +2194,172 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
2323
2194
  "activitypub.activity.id": activityId ?? ""
2324
2195
  });
2325
2196
  }
2197
+ /**
2198
+ * An error that is thrown when an activity fails to send to a remote inbox.
2199
+ * It contains structured information about the failure, including the HTTP
2200
+ * status code, the inbox URL, and the response body.
2201
+ * @since 2.0.0
2202
+ */
2203
+ var SendActivityError = class extends Error {
2204
+ /**
2205
+ * The inbox URL that the activity was being sent to.
2206
+ */
2207
+ inbox;
2208
+ /**
2209
+ * The HTTP status code returned by the inbox.
2210
+ */
2211
+ statusCode;
2212
+ /**
2213
+ * The response body from the inbox, if any.
2214
+ */
2215
+ responseBody;
2216
+ /**
2217
+ * Creates a new {@link SendActivityError}.
2218
+ * @param inbox The inbox URL.
2219
+ * @param statusCode The HTTP status code.
2220
+ * @param message The error message.
2221
+ * @param responseBody The response body.
2222
+ */
2223
+ constructor(inbox, statusCode, message, responseBody) {
2224
+ super(message);
2225
+ this.name = "SendActivityError";
2226
+ this.inbox = inbox;
2227
+ this.statusCode = statusCode;
2228
+ this.responseBody = responseBody;
2229
+ }
2230
+ };
2231
+
2232
+ //#endregion
2233
+ //#region src/federation/webfinger.ts
2234
+ const logger = (0, __logtape_logtape.getLogger)([
2235
+ "fedify",
2236
+ "webfinger",
2237
+ "server"
2238
+ ]);
2239
+ /**
2240
+ * Handles a WebFinger request. You would not typically call this function
2241
+ * directly, but instead use {@link Federation.fetch} method.
2242
+ * @param request The WebFinger request to handle.
2243
+ * @param parameters The parameters for handling the request.
2244
+ * @returns The response to the request.
2245
+ */
2246
+ async function handleWebFinger(request, options) {
2247
+ if (options.tracer == null) return await handleWebFingerInternal(request, options);
2248
+ return await options.tracer.startActiveSpan("webfinger.handle", { kind: __opentelemetry_api.SpanKind.SERVER }, async (span) => {
2249
+ try {
2250
+ const response = await handleWebFingerInternal(request, options);
2251
+ span.setStatus({ code: response.ok ? __opentelemetry_api.SpanStatusCode.UNSET : __opentelemetry_api.SpanStatusCode.ERROR });
2252
+ return response;
2253
+ } catch (error) {
2254
+ span.setStatus({
2255
+ code: __opentelemetry_api.SpanStatusCode.ERROR,
2256
+ message: String(error)
2257
+ });
2258
+ throw error;
2259
+ } finally {
2260
+ span.end();
2261
+ }
2262
+ });
2263
+ }
2264
+ async function handleWebFingerInternal(request, { context: context$2, host, actorDispatcher, actorHandleMapper, actorAliasMapper, onNotFound, span, webFingerLinksDispatcher }) {
2265
+ if (actorDispatcher == null) {
2266
+ logger.error("Actor dispatcher is not set.");
2267
+ return await onNotFound(request);
2268
+ }
2269
+ const resource = context$2.url.searchParams.get("resource");
2270
+ if (resource == null) return new Response("Missing resource parameter.", { status: 400 });
2271
+ span?.setAttribute("webfinger.resource", resource);
2272
+ let resourceUrl;
2273
+ try {
2274
+ resourceUrl = new URL(resource);
2275
+ } catch (e) {
2276
+ if (e instanceof TypeError) return new Response("Invalid resource URL.", { status: 400 });
2277
+ throw e;
2278
+ }
2279
+ span?.setAttribute("webfinger.resource.scheme", resourceUrl.protocol.replace(/:$/, ""));
2280
+ async function mapUsernameToIdentifier(username) {
2281
+ if (actorHandleMapper == null) {
2282
+ logger.error("No actor handle mapper is set; use the WebFinger username {username} as the actor's internal identifier.", { username });
2283
+ return username;
2284
+ }
2285
+ const identifier$1 = await actorHandleMapper(context$2, username);
2286
+ if (identifier$1 == null) {
2287
+ logger.error("Actor {username} not found.", { username });
2288
+ return null;
2289
+ }
2290
+ return identifier$1;
2291
+ }
2292
+ let identifier = null;
2293
+ const uriParsed = context$2.parseUri(resourceUrl);
2294
+ if (uriParsed?.type != "actor") {
2295
+ const match = /^acct:([^@]+)@([^@]+)$/.exec(resource);
2296
+ if (match == null) {
2297
+ const result = await actorAliasMapper?.(context$2, resourceUrl);
2298
+ if (result == null) return await onNotFound(request);
2299
+ if ("identifier" in result) identifier = result.identifier;
2300
+ else identifier = await mapUsernameToIdentifier(result.username);
2301
+ } else {
2302
+ const portMatch = /:\d+$/.exec(match[2]);
2303
+ const normalizedHost = portMatch == null ? (0, node_url.domainToASCII)(match[2].toLowerCase()) : (0, node_url.domainToASCII)(match[2].substring(0, portMatch.index).toLowerCase()) + portMatch[0];
2304
+ if (normalizedHost != context$2.url.host && normalizedHost != host) return await onNotFound(request);
2305
+ else {
2306
+ identifier = await mapUsernameToIdentifier(match[1]);
2307
+ resourceUrl = new URL(`acct:${match[1]}@${normalizedHost}`);
2308
+ }
2309
+ }
2310
+ } else identifier = uriParsed.identifier;
2311
+ if (identifier == null) return await onNotFound(request);
2312
+ const actor = await actorDispatcher(context$2, identifier);
2313
+ if (actor == null) {
2314
+ logger.error("Actor {identifier} not found.", { identifier });
2315
+ return await onNotFound(request);
2316
+ }
2317
+ const links = [{
2318
+ rel: "self",
2319
+ href: context$2.getActorUri(identifier).href,
2320
+ type: "application/activity+json"
2321
+ }];
2322
+ for (const url of actor.urls) if (url instanceof __fedify_vocab.Link && url.href != null) links.push({
2323
+ rel: url.rel ?? "http://webfinger.net/rel/profile-page",
2324
+ href: url.href.href,
2325
+ type: url.mediaType == null ? void 0 : url.mediaType
2326
+ });
2327
+ else if (url instanceof URL) links.push({
2328
+ rel: "http://webfinger.net/rel/profile-page",
2329
+ href: url.href
2330
+ });
2331
+ for await (const image of actor.getIcons()) {
2332
+ if (image.url?.href == null) continue;
2333
+ links.push({
2334
+ rel: "http://webfinger.net/rel/avatar",
2335
+ href: image.url.href.toString(),
2336
+ ...image.mediaType != null && { type: image.mediaType }
2337
+ });
2338
+ }
2339
+ if (webFingerLinksDispatcher != null) {
2340
+ const customLinks = await webFingerLinksDispatcher(context$2, resourceUrl);
2341
+ if (customLinks != null) for (const link of customLinks) links.push(link);
2342
+ }
2343
+ const aliases = [];
2344
+ if (resourceUrl.protocol != "acct:" && actor.preferredUsername != null) {
2345
+ aliases.push(`acct:${actor.preferredUsername}@${host ?? context$2.url.host}`);
2346
+ if (host != null && host !== context$2.url.host) aliases.push(`acct:${actor.preferredUsername}@${context$2.url.host}`);
2347
+ }
2348
+ if (resourceUrl.href !== context$2.getActorUri(identifier).href) aliases.push(context$2.getActorUri(identifier).href);
2349
+ if (resourceUrl.protocol === "acct:" && host != null && host !== context$2.url.host && !resourceUrl.href.endsWith(`@${host}`)) {
2350
+ const username = resourceUrl.href.replace(/^acct:/, "").replace(/@.*$/, "");
2351
+ aliases.push(`acct:${username}@${host}`);
2352
+ }
2353
+ const jrd = {
2354
+ subject: resourceUrl.href,
2355
+ aliases,
2356
+ links
2357
+ };
2358
+ return new Response(JSON.stringify(jrd), { headers: {
2359
+ "Content-Type": "application/jrd+json",
2360
+ "Access-Control-Allow-Origin": "*"
2361
+ } });
2362
+ }
2326
2363
 
2327
2364
  //#endregion
2328
2365
  //#region src/federation/middleware.ts
@@ -2352,6 +2389,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2352
2389
  allowPrivateAddress;
2353
2390
  userAgent;
2354
2391
  onOutboxError;
2392
+ permanentFailureStatusCodes;
2355
2393
  signatureTimeWindow;
2356
2394
  skipSignatureVerification;
2357
2395
  outboxRetryPolicy;
@@ -2433,6 +2471,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2433
2471
  }));
2434
2472
  this.userAgent = userAgent;
2435
2473
  this.onOutboxError = options.onOutboxError;
2474
+ this.permanentFailureStatusCodes = options.permanentFailureStatusCodes ?? [404, 410];
2436
2475
  this.signatureTimeWindow = options.signatureTimeWindow ?? { hours: 1 };
2437
2476
  this.skipSignatureVerification = options.skipSignatureVerification ?? false;
2438
2477
  this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy();
@@ -2446,7 +2485,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2446
2485
  this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
2447
2486
  }
2448
2487
  _getTracer() {
2449
- return this.tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
2488
+ return this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
2450
2489
  }
2451
2490
  async _startQueueInternal(ctxData, signal, queue) {
2452
2491
  if (this.inboxQueue == null && this.outboxQueue == null) return;
@@ -2546,7 +2585,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2546
2585
  keyId: new URL(keyId),
2547
2586
  privateKey: await require_http.importJwk(privateKey, "private")
2548
2587
  })));
2549
- const activity = await require_actor.Activity.fromJsonLd(message.activity, {
2588
+ const activity = await __fedify_vocab.Activity.fromJsonLd(message.activity, {
2550
2589
  contextLoader: this.contextLoaderFactory({
2551
2590
  allowPrivateAddress: this.allowPrivateAddress,
2552
2591
  userAgent: this.userAgent
@@ -2563,6 +2602,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2563
2602
  }) });
2564
2603
  await this.sendActivity(keys, message.inboxes, activity, {
2565
2604
  collectionSync: message.collectionSync,
2605
+ orderingKey: message.orderingKey,
2566
2606
  context: context$2
2567
2607
  });
2568
2608
  }
@@ -2608,19 +2648,50 @@ var FederationImpl = class extends FederationBuilderImpl {
2608
2648
  message: String(error)
2609
2649
  });
2610
2650
  const loaderOptions = this.#getLoaderOptions(message.baseUrl);
2611
- const activity = await require_actor.Activity.fromJsonLd(message.activity, {
2651
+ const activity = await __fedify_vocab.Activity.fromJsonLd(message.activity, {
2612
2652
  contextLoader: this.contextLoaderFactory(loaderOptions),
2613
2653
  documentLoader: rsaKeyPair == null ? this.documentLoaderFactory(loaderOptions) : this.authenticatedDocumentLoaderFactory(rsaKeyPair, loaderOptions),
2614
2654
  tracerProvider: this.tracerProvider
2615
2655
  });
2616
2656
  try {
2617
- this.onOutboxError?.(error, activity);
2657
+ await this.onOutboxError?.(error, activity);
2618
2658
  } catch (error$1) {
2619
2659
  logger$1.error("An unexpected error occurred in onError handler:\n{error}", {
2620
2660
  ...logData,
2621
2661
  error: error$1
2622
2662
  });
2623
2663
  }
2664
+ if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
2665
+ logger$1.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
2666
+ ...logData,
2667
+ status: error.statusCode
2668
+ });
2669
+ if (this.outboxPermanentFailureHandler != null) {
2670
+ const ctx = this.#createContext(new URL(message.baseUrl), _, { documentLoader: this.documentLoaderFactory(loaderOptions) });
2671
+ try {
2672
+ await this.outboxPermanentFailureHandler(ctx, {
2673
+ inbox: new URL(message.inbox),
2674
+ activity,
2675
+ error,
2676
+ statusCode: error.statusCode,
2677
+ actorIds: (message.actorIds ?? []).flatMap((id) => {
2678
+ try {
2679
+ return [new URL(id)];
2680
+ } catch {
2681
+ logger$1.warn("Invalid actorId URL in OutboxMessage: {id}", { id });
2682
+ return [];
2683
+ }
2684
+ })
2685
+ });
2686
+ } catch (handlerError) {
2687
+ logger$1.error("An unexpected error occurred in outboxPermanentFailureHandler:\n{error}", {
2688
+ ...logData,
2689
+ error: handlerError
2690
+ });
2691
+ }
2692
+ }
2693
+ return;
2694
+ }
2624
2695
  if (this.outboxQueue?.nativeRetrial) {
2625
2696
  logger$1.error("Failed to send activity {activityId} to {inbox}; backend will handle retry:\n{error}", {
2626
2697
  ...logData,
@@ -2662,8 +2733,8 @@ var FederationImpl = class extends FederationBuilderImpl {
2662
2733
  const identity = await this.sharedInboxKeyDispatcher(context$2);
2663
2734
  if (identity != null) context$2 = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity || "handle" in identity ? await context$2.getDocumentLoader(identity) : context$2.getDocumentLoader(identity) });
2664
2735
  }
2665
- const activity = await require_actor.Activity.fromJsonLd(message.activity, context$2);
2666
- span.setAttribute("activitypub.activity.type", require_actor.getTypeId(activity).href);
2736
+ const activity = await __fedify_vocab.Activity.fromJsonLd(message.activity, context$2);
2737
+ span.setAttribute("activitypub.activity.type", (0, __fedify_vocab.getTypeId)(activity).href);
2667
2738
  if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
2668
2739
  const cacheKey = activity.id == null ? null : [
2669
2740
  ...this.kvPrefixes.activityIdempotence,
@@ -2692,7 +2763,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2692
2763
  });
2693
2764
  span$1.setStatus({
2694
2765
  code: __opentelemetry_api.SpanStatusCode.ERROR,
2695
- message: `Unsupported activity type: ${require_actor.getTypeId(activity).href}`
2766
+ message: `Unsupported activity type: ${(0, __fedify_vocab.getTypeId)(activity).href}`
2696
2767
  });
2697
2768
  span$1.end();
2698
2769
  return;
@@ -2700,7 +2771,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2700
2771
  const { class: cls, listener } = dispatched;
2701
2772
  span$1.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
2702
2773
  try {
2703
- await listener(context$2.toInboxContext(message.identifier, message.activity, activity.id?.href, require_actor.getTypeId(activity).href), activity);
2774
+ await listener(context$2.toInboxContext(message.identifier, message.activity, activity.id?.href, (0, __fedify_vocab.getTypeId)(activity).href), activity);
2704
2775
  } catch (error) {
2705
2776
  try {
2706
2777
  await this.inboxErrorHandler?.(context$2, error);
@@ -2811,7 +2882,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2811
2882
  "federation",
2812
2883
  "outbox"
2813
2884
  ]);
2814
- const { immediate, collectionSync, context: ctx } = options;
2885
+ const { immediate, collectionSync, orderingKey, context: ctx } = options;
2815
2886
  if (activity.id == null) throw new TypeError("The activity to send must have an id.");
2816
2887
  if (activity.actorId == null) throw new TypeError("The activity to send must have at least one actor property.");
2817
2888
  else if (keys.length < 1) throw new TypeError("The keys must not be empty.");
@@ -2872,7 +2943,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2872
2943
  keys,
2873
2944
  activity: jsonLd,
2874
2945
  activityId: activity.id?.href,
2875
- activityType: require_actor.getTypeId(activity).href,
2946
+ activityType: (0, __fedify_vocab.getTypeId)(activity).href,
2876
2947
  inbox: new URL(inbox),
2877
2948
  sharedInbox: inboxes[inbox].sharedInbox,
2878
2949
  headers: collectionSync == null ? void 0 : new Headers({ "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) }),
@@ -2899,6 +2970,8 @@ var FederationImpl = class extends FederationBuilderImpl {
2899
2970
  __opentelemetry_api.propagation.inject(__opentelemetry_api.context.active(), carrier);
2900
2971
  const messages = [];
2901
2972
  for (const inbox in inboxes) {
2973
+ const inboxOrigin = new URL(inbox).origin;
2974
+ const messageOrderingKey = orderingKey == null ? void 0 : `${orderingKey}\n${inboxOrigin}`;
2902
2975
  const message = {
2903
2976
  type: "outbox",
2904
2977
  id: crypto.randomUUID(),
@@ -2906,19 +2979,36 @@ var FederationImpl = class extends FederationBuilderImpl {
2906
2979
  keys: keyJwkPairs,
2907
2980
  activity: jsonLd,
2908
2981
  activityId: activity.id?.href,
2909
- activityType: require_actor.getTypeId(activity).href,
2982
+ activityType: (0, __fedify_vocab.getTypeId)(activity).href,
2910
2983
  inbox,
2911
2984
  sharedInbox: inboxes[inbox].sharedInbox,
2985
+ actorIds: [...inboxes[inbox].actorIds],
2912
2986
  started: (/* @__PURE__ */ new Date()).toISOString(),
2913
2987
  attempt: 0,
2914
2988
  headers: collectionSync == null ? {} : { "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) },
2989
+ orderingKey: messageOrderingKey,
2915
2990
  traceContext: carrier
2916
2991
  };
2917
- messages.push(message);
2992
+ messages.push({
2993
+ message,
2994
+ orderingKey: messageOrderingKey
2995
+ });
2918
2996
  }
2919
2997
  const { outboxQueue } = this;
2920
2998
  if (outboxQueue.enqueueMany == null) {
2921
- const promises = messages.map((m) => outboxQueue.enqueue(m));
2999
+ const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
3000
+ const results = await Promise.allSettled(promises);
3001
+ const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
3002
+ if (errors.length > 0) {
3003
+ logger$1.error("Failed to enqueue activity {activityId} to send later: {errors}", {
3004
+ activityId: activity.id.href,
3005
+ errors
3006
+ });
3007
+ if (errors.length > 1) throw new AggregateError(errors, `Failed to enqueue activity ${activityId} to send later.`);
3008
+ throw errors[0];
3009
+ }
3010
+ } else if (orderingKey != null) {
3011
+ const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
2922
3012
  const results = await Promise.allSettled(promises);
2923
3013
  const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
2924
3014
  if (errors.length > 0) {
@@ -2930,7 +3020,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2930
3020
  throw errors[0];
2931
3021
  }
2932
3022
  } else try {
2933
- await outboxQueue.enqueueMany(messages);
3023
+ await outboxQueue.enqueueMany(messages.map((m) => m.message));
2934
3024
  } catch (error) {
2935
3025
  logger$1.error("Failed to enqueue activity {activityId} to send later: {error}", {
2936
3026
  activityId: activity.id.href,
@@ -3461,12 +3551,12 @@ var ContextImpl = class ContextImpl {
3461
3551
  for (const keyPair of keyPairs) {
3462
3552
  const newPair = {
3463
3553
  ...keyPair,
3464
- cryptographicKey: new require_actor.CryptographicKey({
3554
+ cryptographicKey: new __fedify_vocab.CryptographicKey({
3465
3555
  id: keyPair.keyId,
3466
3556
  owner,
3467
3557
  publicKey: keyPair.publicKey
3468
3558
  }),
3469
- multikey: new require_actor.Multikey({
3559
+ multikey: new __fedify_vocab.Multikey({
3470
3560
  id: keyPair.keyId,
3471
3561
  controller: owner,
3472
3562
  publicKey: keyPair.publicKey
@@ -3552,7 +3642,7 @@ var ContextImpl = class ContextImpl {
3552
3642
  return this.federation.authenticatedDocumentLoaderFactory(identity);
3553
3643
  }
3554
3644
  lookupObject(identifier, options = {}) {
3555
- return require_vocab.lookupObject(identifier, {
3645
+ return (0, __fedify_vocab.lookupObject)(identifier, {
3556
3646
  ...options,
3557
3647
  documentLoader: options.documentLoader ?? this.documentLoader,
3558
3648
  contextLoader: options.contextLoader ?? this.contextLoader,
@@ -3562,7 +3652,7 @@ var ContextImpl = class ContextImpl {
3562
3652
  });
3563
3653
  }
3564
3654
  traverseCollection(collection, options = {}) {
3565
- return require_vocab.traverseCollection(collection, {
3655
+ return (0, __fedify_vocab.traverseCollection)(collection, {
3566
3656
  ...options,
3567
3657
  documentLoader: options.documentLoader ?? this.documentLoader,
3568
3658
  contextLoader: options.contextLoader ?? this.contextLoader
@@ -3580,7 +3670,7 @@ var ContextImpl = class ContextImpl {
3580
3670
  });
3581
3671
  }
3582
3672
  lookupWebFinger(resource, options = {}) {
3583
- return require_lookup.lookupWebFinger(resource, {
3673
+ return (0, __fedify_webfinger.lookupWebFinger)(resource, {
3584
3674
  ...options,
3585
3675
  userAgent: options.userAgent ?? this.federation.userAgent,
3586
3676
  tracerProvider: options.tracerProvider ?? this.tracerProvider,
@@ -3588,11 +3678,11 @@ var ContextImpl = class ContextImpl {
3588
3678
  });
3589
3679
  }
3590
3680
  sendActivity(sender, recipients, activity, options = {}) {
3591
- const tracer = this.tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
3681
+ const tracer = this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
3592
3682
  return tracer.startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
3593
3683
  kind: this.federation.outboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.CLIENT : __opentelemetry_api.SpanKind.PRODUCER,
3594
3684
  attributes: {
3595
- "activitypub.activity.type": require_actor.getTypeId(activity).href,
3685
+ "activitypub.activity.type": (0, __fedify_vocab.getTypeId)(activity).href,
3596
3686
  "activitypub.activity.to": activity.toIds.map((to) => to.href),
3597
3687
  "activitypub.activity.cc": activity.toIds.map((cc) => cc.href),
3598
3688
  "activitypub.activity.bto": activity.btoIds.map((bto) => bto.href),
@@ -3646,20 +3736,25 @@ var ContextImpl = class ContextImpl {
3646
3736
  } else keys = [sender];
3647
3737
  if (keys.length < 1) throw new TypeError("The sender's keys must not be empty.");
3648
3738
  for (const { privateKey } of keys) require_http.validateCryptoKey(privateKey, "private");
3649
- const opts = { context: this };
3650
3739
  let expandedRecipients;
3740
+ let collectionSync;
3651
3741
  if (Array.isArray(recipients)) expandedRecipients = recipients;
3652
3742
  else if (recipients === "followers") {
3653
3743
  if (identifier == null) throw new Error("If recipients is \"followers\", sender must be an actor identifier or username.");
3654
3744
  expandedRecipients = [];
3655
3745
  for await (const recipient of this.getFollowers(identifier)) expandedRecipients.push(recipient);
3656
3746
  if (options.syncCollection) try {
3657
- opts.collectionSync = this.getFollowersUri(identifier).href;
3747
+ collectionSync = this.getFollowersUri(identifier).href;
3658
3748
  } catch (error) {
3659
- if (error instanceof RouterError) opts.collectionSync = void 0;
3660
- else throw error;
3749
+ if (!(error instanceof RouterError)) throw error;
3661
3750
  }
3662
3751
  } else expandedRecipients = [recipients];
3752
+ const opts = {
3753
+ context: this,
3754
+ orderingKey: options.orderingKey,
3755
+ collectionSync,
3756
+ immediate: options.immediate
3757
+ };
3663
3758
  span.setAttribute("activitypub.inboxes", expandedRecipients.length);
3664
3759
  for (const activityTransformer of this.federation.activityTransformers) activity = activityTransformer(activity, this);
3665
3760
  span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
@@ -3704,12 +3799,13 @@ var ContextImpl = class ContextImpl {
3704
3799
  contextLoader: this.contextLoader
3705
3800
  }),
3706
3801
  activityId: activity.id?.href,
3707
- activityType: require_actor.getTypeId(activity).href,
3802
+ activityType: (0, __fedify_vocab.getTypeId)(activity).href,
3708
3803
  collectionSync: opts.collectionSync,
3804
+ orderingKey: options.orderingKey,
3709
3805
  traceContext: carrier
3710
3806
  };
3711
3807
  if (!this.federation.manuallyStartQueue) this.federation._startQueueInternal(this.data);
3712
- this.federation.fanoutQueue.enqueue(message);
3808
+ this.federation.fanoutQueue.enqueue(message, { orderingKey: options.orderingKey });
3713
3809
  }
3714
3810
  async *getFollowers(identifier) {
3715
3811
  if (this.federation.followersCallbacks == null) throw new Error("No followers collection dispatcher registered.");
@@ -3734,10 +3830,10 @@ var ContextImpl = class ContextImpl {
3734
3830
  }
3735
3831
  routeActivity(recipient, activity, options = {}) {
3736
3832
  const tracerProvider = this.tracerProvider ?? this.tracerProvider;
3737
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
3833
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
3738
3834
  return tracer.startActiveSpan("activitypub.inbox", {
3739
3835
  kind: this.federation.inboxQueue == null || options.immediate ? __opentelemetry_api.SpanKind.INTERNAL : __opentelemetry_api.SpanKind.PRODUCER,
3740
- attributes: { "activitypub.activity.type": require_actor.getTypeId(activity).href }
3836
+ attributes: { "activitypub.activity.type": (0, __fedify_vocab.getTypeId)(activity).href }
3741
3837
  }, async (span) => {
3742
3838
  if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
3743
3839
  if (activity.toIds.length > 0) span.setAttribute("activitypub.activity.to", activity.toIds.map((to) => to.href));
@@ -3771,7 +3867,7 @@ var ContextImpl = class ContextImpl {
3771
3867
  const contextLoader = options.contextLoader ?? this.contextLoader;
3772
3868
  const json = await activity.toJsonLd({ contextLoader });
3773
3869
  const keyCache = new KvKeyCache(this.federation.kv, this.federation.kvPrefixes.publicKey, this);
3774
- const verified = await require_proof.verifyObject(require_actor.Activity, json, {
3870
+ const verified = await require_proof.verifyObject(__fedify_vocab.Activity, json, {
3775
3871
  contextLoader,
3776
3872
  documentLoader: options.documentLoader ?? this.documentLoader,
3777
3873
  tracerProvider: options.tracerProvider ?? this.tracerProvider,
@@ -3797,7 +3893,7 @@ var ContextImpl = class ContextImpl {
3797
3893
  activityId: activity.id.href
3798
3894
  });
3799
3895
  return false;
3800
- } else if (!(fetched instanceof require_actor.Activity)) {
3896
+ } else if (!(fetched instanceof __fedify_vocab.Activity)) {
3801
3897
  logger$1.debug("Fetched object is not an Activity.", {
3802
3898
  recipient,
3803
3899
  activity: await fetched.toJsonLd({ contextLoader })
@@ -3952,7 +4048,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
3952
4048
  });
3953
4049
  }
3954
4050
  forwardActivity(forwarder, recipients, options) {
3955
- const tracer = this.tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
4051
+ const tracer = this.tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
3956
4052
  return tracer.startActiveSpan("activitypub.outbox", {
3957
4053
  kind: this.federation.outboxQueue == null || options?.immediate ? __opentelemetry_api.SpanKind.CLIENT : __opentelemetry_api.SpanKind.PRODUCER,
3958
4054
  attributes: { "activitypub.activity.type": this.activityType }
@@ -4004,7 +4100,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
4004
4100
  if (!require_proof.hasSignature(this.activity)) {
4005
4101
  let hasProof;
4006
4102
  try {
4007
- const activity = await require_actor.Activity.fromJsonLd(this.activity, this);
4103
+ const activity = await __fedify_vocab.Activity.fromJsonLd(this.activity, this);
4008
4104
  hasProof = await activity.getProof() != null;
4009
4105
  } catch {
4010
4106
  hasProof = false;
@@ -4061,8 +4157,10 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
4061
4157
  }
4062
4158
  const carrier = {};
4063
4159
  __opentelemetry_api.propagation.inject(__opentelemetry_api.context.active(), carrier);
4160
+ const orderingKey = options?.orderingKey;
4064
4161
  const messages = [];
4065
4162
  for (const inbox in inboxes) {
4163
+ const inboxUrl = new URL(inbox);
4066
4164
  const message = {
4067
4165
  type: "outbox",
4068
4166
  id: crypto.randomUUID(),
@@ -4076,13 +4174,29 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
4076
4174
  started: (/* @__PURE__ */ new Date()).toISOString(),
4077
4175
  attempt: 0,
4078
4176
  headers: {},
4177
+ orderingKey: orderingKey == null ? void 0 : `${orderingKey}\n${inboxUrl.origin}`,
4079
4178
  traceContext: carrier
4080
4179
  };
4081
- messages.push(message);
4180
+ messages.push({
4181
+ message,
4182
+ orderingKey: message.orderingKey
4183
+ });
4082
4184
  }
4083
4185
  const { outboxQueue } = this.federation;
4084
4186
  if (outboxQueue.enqueueMany == null) {
4085
- const promises = messages.map((m) => outboxQueue.enqueue(m));
4187
+ const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
4188
+ const results = await Promise.allSettled(promises);
4189
+ const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
4190
+ if (errors.length > 0) {
4191
+ logger$1.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
4192
+ activityId: this.activityId,
4193
+ errors
4194
+ });
4195
+ if (errors.length > 1) throw new AggregateError(errors, `Failed to enqueue activity ${this.activityId} to forward later.`);
4196
+ throw errors[0];
4197
+ }
4198
+ } else if (orderingKey != null) {
4199
+ const promises = messages.map((m) => outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey }));
4086
4200
  const results = await Promise.allSettled(promises);
4087
4201
  const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
4088
4202
  if (errors.length > 0) {
@@ -4094,7 +4208,7 @@ var InboxContextImpl = class InboxContextImpl extends ContextImpl {
4094
4208
  throw errors[0];
4095
4209
  }
4096
4210
  } else try {
4097
- await outboxQueue.enqueueMany(messages);
4211
+ await outboxQueue.enqueueMany(messages.map((m) => m.message));
4098
4212
  } catch (error) {
4099
4213
  logger$1.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
4100
4214
  activityId: this.activityId,
@@ -4193,6 +4307,12 @@ Object.defineProperty(exports, 'RouterError', {
4193
4307
  return RouterError;
4194
4308
  }
4195
4309
  });
4310
+ Object.defineProperty(exports, 'SendActivityError', {
4311
+ enumerable: true,
4312
+ get: function () {
4313
+ return SendActivityError;
4314
+ }
4315
+ });
4196
4316
  Object.defineProperty(exports, 'buildCollectionSynchronizationHeader', {
4197
4317
  enumerable: true,
4198
4318
  get: function () {
@@ -4223,6 +4343,12 @@ Object.defineProperty(exports, 'digest', {
4223
4343
  return digest;
4224
4344
  }
4225
4345
  });
4346
+ Object.defineProperty(exports, 'handleWebFinger', {
4347
+ enumerable: true,
4348
+ get: function () {
4349
+ return handleWebFinger;
4350
+ }
4351
+ });
4226
4352
  Object.defineProperty(exports, 'respondWithObject', {
4227
4353
  enumerable: true,
4228
4354
  get: function () {