@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,38 +3,40 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Activity, Announce, Create, Invite, Multikey, Note, Object as Object$1, Offer, Person, RouterError, getTypeId, lookupObject } from "../lookup-Dj9-mgOn.js";
6
+ import { mockDocumentLoader, test } from "../dist-B5f6a8Tt.js";
7
7
  import { assertEquals } from "../assert_equals-DSbWqCm3.js";
8
8
  import { assert } from "../assert-MZs1qjMx.js";
9
9
  import { assertInstanceOf } from "../assert_instance_of-DHz7EHNU.js";
10
- import { MemoryKvStore } from "../kv-CRZrzyXm.js";
11
- import { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, createFederation } from "../middleware-BIqFwRwI.js";
12
- import "../client-pY7-3icS.js";
13
- import "../types-C2XVl6gj.js";
14
- import "../actor-BT-e5fn9.js";
15
- import "../key-x7E5PYI0.js";
16
- import { signRequest, verifyRequest } from "../http-DH47B-h3.js";
17
- import { detachSignature, signJsonLd, verifyJsonLd } from "../ld-CRPaU6c8.js";
18
- import { doesActorOwnKey } from "../owner-CIWnopkT.js";
19
- import { signObject, verifyObject } from "../proof-D-5ri6rf.js";
20
- import { fetchDocumentLoader, getAuthenticatedDocumentLoader } from "../docloader-DndkGj0O.js";
21
- import "../kv-cache-DN9pfMBe.js";
22
- import "../inbox-CEyHvxOo.js";
23
- import "../builder-4syLV1-z.js";
24
- import "../collection-BzWsN9pB.js";
25
- import "../keycache-BRXuBDuy.js";
26
- import "../negotiation-C4nFufNk.js";
27
- import "../retry-CfF8Gn4d.js";
28
- import "../send-CPGk9QKZ.js";
29
- import { mockDocumentLoader, test } from "../testing-BslrM_9E.js";
10
+ import { MemoryKvStore } from "../kv-QzKcOQgP.js";
11
+ import "../deno-DGx1JZHr.js";
12
+ import { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, createFederation } from "../middleware-WokE4qxc.js";
13
+ import "../client-Dg7OfUDA.js";
14
+ import { RouterError } from "../router-D9eI0s4b.js";
15
+ import "../types-CPz01LGH.js";
16
+ import "../key-BCtt1Ugy.js";
17
+ import { signRequest, verifyRequest } from "../http-LGtYlSfN.js";
18
+ import { detachSignature, signJsonLd, verifyJsonLd } from "../ld-QlZPwGEH.js";
19
+ import { doesActorOwnKey } from "../owner-Cejm-F7S.js";
20
+ import { signObject, verifyObject } from "../proof-BOQBHd-i.js";
21
+ import { fetchDocumentLoader, getAuthenticatedDocumentLoader } from "../docloader-D8UHsyqD.js";
22
+ import "../kv-cache-B__dHl7g.js";
23
+ import "../inbox-DbtWQY2D.js";
24
+ import "../builder-DTlQwmVF.js";
25
+ import "../collection-CcnIw1qY.js";
26
+ import "../keycache-DRxpZ5r9.js";
27
+ import "../negotiation-5NPJL6zp.js";
28
+ import "../retry-D4GJ670a.js";
29
+ import "../send-jFxXfsN8.js";
30
30
  import { assertStrictEquals } from "../std__assert-DWivtrGR.js";
31
31
  import { assertFalse, assertRejects } from "../assert_rejects-Ce45JcFg.js";
32
32
  import { assertThrows } from "../assert_throws-BNXdRGWP.js";
33
33
  import { assertNotEquals } from "../assert_not_equals-C80BG-_5.js";
34
- import { ed25519Multikey, ed25519PrivateKey, ed25519PublicKey, rsaPrivateKey2, rsaPrivateKey3, rsaPublicKey2, rsaPublicKey3 } from "../keys-DLk_8H-l.js";
35
- import { esm_default } from "../esm-VlKMJQqV.js";
34
+ import { ed25519Multikey, ed25519PrivateKey, ed25519PublicKey, rsaPrivateKey2, rsaPrivateKey3, rsaPublicKey2, rsaPublicKey3 } from "../keys-ZbcByPg9.js";
35
+ import { esm_default } from "../esm-DGl7uK1r.js";
36
+ import * as vocab from "@fedify/vocab";
37
+ import { getTypeId, lookupObject } from "@fedify/vocab";
36
38
 
37
- //#region src/testing/fixtures/example.com/create.json
39
+ //#region ../fixture/src/fixtures/example.com/create.json
38
40
  var __context$2 = "https://www.w3.org/ns/activitystreams";
39
41
  var type$2 = "Create";
40
42
  var id$2 = "https://example.com/create";
@@ -47,7 +49,7 @@ var create_default = {
47
49
  };
48
50
 
49
51
  //#endregion
50
- //#region src/testing/fixtures/example.com/person.json
52
+ //#region ../fixture/src/fixtures/example.com/person.json
51
53
  var __context$1 = ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"];
52
54
  var id$1 = "https://example.com/person";
53
55
  var type$1 = "Person";
@@ -71,7 +73,7 @@ var person_default = {
71
73
  };
72
74
 
73
75
  //#endregion
74
- //#region src/testing/fixtures/example.com/person2.json
76
+ //#region ../fixture/src/fixtures/example.com/person2.json
75
77
  var __context = [
76
78
  "https://www.w3.org/ns/activitystreams",
77
79
  "https://w3id.org/security/v1",
@@ -257,7 +259,7 @@ test({
257
259
  assertStrictEquals(ctx.federation, federation);
258
260
  assertThrows(() => ctx.getNodeInfoUri(), RouterError);
259
261
  assertThrows(() => ctx.getActorUri("handle"), RouterError);
260
- assertThrows(() => ctx.getObjectUri(Note, {
262
+ assertThrows(() => ctx.getObjectUri(vocab.Note, {
261
263
  handle: "handle",
262
264
  id: "id"
263
265
  }), RouterError);
@@ -274,7 +276,7 @@ test({
274
276
  assertEquals(ctx.parseUri(null), null);
275
277
  assertEquals(await ctx.getActorKeyPairs("handle"), []);
276
278
  await assertRejects(() => ctx.getDocumentLoader({ identifier: "handle" }), Error, "No actor key pairs dispatcher registered");
277
- await assertRejects(() => ctx.sendActivity({ identifier: "handle" }, [], new Create({})), Error, "No actor key pairs dispatcher registered");
279
+ await assertRejects(() => ctx.sendActivity({ identifier: "handle" }, [], new vocab.Create({})), Error, "No actor key pairs dispatcher registered");
278
280
  federation.setNodeInfoDispatcher("/nodeinfo/2.1", () => ({
279
281
  software: {
280
282
  name: "Example",
@@ -289,7 +291,7 @@ test({
289
291
  }));
290
292
  ctx = federation.createContext(new URL("https://example.com/"), 123);
291
293
  assertEquals(ctx.getNodeInfoUri(), new URL("https://example.com/nodeinfo/2.1"));
292
- federation.setActorDispatcher("/users/{identifier}", () => new Person({})).setKeyPairsDispatcher(() => [{
294
+ federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({})).setKeyPairsDispatcher(() => [{
293
295
  privateKey: rsaPrivateKey2,
294
296
  publicKey: rsaPublicKey2.publicKey
295
297
  }, {
@@ -313,7 +315,7 @@ test({
313
315
  id: new URL("https://example.com/users/handle#main-key"),
314
316
  owner: new URL("https://example.com/users/handle")
315
317
  }),
316
- multikey: new Multikey({
318
+ multikey: new vocab.Multikey({
317
319
  id: new URL("https://example.com/users/handle#main-key"),
318
320
  controller: new URL("https://example.com/users/handle"),
319
321
  publicKey: rsaPublicKey2.publicKey
@@ -326,7 +328,7 @@ test({
326
328
  id: new URL("https://example.com/users/handle#key-2"),
327
329
  owner: new URL("https://example.com/users/handle")
328
330
  }),
329
- multikey: new Multikey({
331
+ multikey: new vocab.Multikey({
330
332
  id: new URL("https://example.com/users/handle#key-2"),
331
333
  controller: new URL("https://example.com/users/handle"),
332
334
  publicKey: ed25519PublicKey.publicKey
@@ -354,8 +356,8 @@ test({
354
356
  document: true
355
357
  });
356
358
  assertEquals(await ctx.lookupObject("https://example.com/object"), null);
357
- await assertRejects(() => ctx.sendActivity({ identifier: "handle" }, [], new Create({})), TypeError, "The activity to send must have at least one actor property.");
358
- await ctx.sendActivity({ identifier: "handle" }, [], new Create({ actor: new URL("https://example.com/users/handle") }));
359
+ await assertRejects(() => ctx.sendActivity({ identifier: "handle" }, [], new vocab.Create({})), TypeError, "The activity to send must have at least one actor property.");
360
+ await ctx.sendActivity({ identifier: "handle" }, [], new vocab.Create({ actor: new URL("https://example.com/users/handle") }));
359
361
  esm_default.get("https://example.com/object", () => new Response(JSON.stringify({
360
362
  "@context": "https://www.w3.org/ns/activitystreams",
361
363
  type: "Object",
@@ -368,21 +370,21 @@ test({
368
370
  contextLoaderFactory: () => mockDocumentLoader
369
371
  });
370
372
  const ctx2 = federation2.createContext(new URL("https://example.com/"), 123);
371
- assertEquals(await ctx2.lookupObject("https://example.com/object"), new Object$1({
373
+ assertEquals(await ctx2.lookupObject("https://example.com/object"), new vocab.Object({
372
374
  id: new URL("https://example.com/object"),
373
375
  name: "Fetched object"
374
376
  }));
375
- federation.setObjectDispatcher(Note, "/users/{identifier}/notes/{id}", (_ctx, values) => {
376
- return new Note({ summary: `Note ${values.id} by ${values.identifier}` });
377
+ federation.setObjectDispatcher(vocab.Note, "/users/{identifier}/notes/{id}", (_ctx, values) => {
378
+ return new vocab.Note({ summary: `Note ${values.id} by ${values.identifier}` });
377
379
  });
378
380
  ctx = federation.createContext(new URL("https://example.com/"), 123);
379
- assertEquals(ctx.getObjectUri(Note, {
381
+ assertEquals(ctx.getObjectUri(vocab.Note, {
380
382
  identifier: "john",
381
383
  id: "123"
382
384
  }), new URL("https://example.com/users/john/notes/123"));
383
385
  assertEquals(ctx.parseUri(new URL("https://example.com/users/john/notes/123")), {
384
386
  type: "object",
385
- class: Note,
387
+ class: vocab.Note,
386
388
  typeId: new URL("https://www.w3.org/ns/activitystreams#Note"),
387
389
  values: {
388
390
  identifier: "john",
@@ -485,7 +487,7 @@ test({
485
487
  }
486
488
  }));
487
489
  assertEquals(ctx.getNodeInfoUri(), new URL("https://ap.example.com/nodeinfo/2.1"));
488
- federation.setActorDispatcher("/users/{identifier}", () => new Person({}));
490
+ federation.setActorDispatcher("/users/{identifier}", () => new vocab.Person({}));
489
491
  assertEquals(ctx.getActorUri("handle"), new URL("https://ap.example.com/users/handle"));
490
492
  assertEquals(ctx.parseUri(new URL("https://ap.example.com/users/handle")), {
491
493
  type: "actor",
@@ -497,16 +499,16 @@ test({
497
499
  handle: "handle",
498
500
  identifier: "handle"
499
501
  });
500
- federation.setObjectDispatcher(Note, "/users/{identifier}/notes/{id}", (_ctx, values) => {
501
- return new Note({ summary: `Note ${values.id} by ${values.identifier}` });
502
+ federation.setObjectDispatcher(vocab.Note, "/users/{identifier}/notes/{id}", (_ctx, values) => {
503
+ return new vocab.Note({ summary: `Note ${values.id} by ${values.identifier}` });
502
504
  });
503
- assertEquals(ctx.getObjectUri(Note, {
505
+ assertEquals(ctx.getObjectUri(vocab.Note, {
504
506
  identifier: "john",
505
507
  id: "123"
506
508
  }), new URL("https://ap.example.com/users/john/notes/123"));
507
509
  assertEquals(ctx.parseUri(new URL("https://ap.example.com/users/john/notes/123")), {
508
510
  type: "object",
509
- class: Note,
511
+ class: vocab.Note,
510
512
  typeId: new URL("https://www.w3.org/ns/activitystreams#Note"),
511
513
  values: {
512
514
  identifier: "john",
@@ -515,7 +517,7 @@ test({
515
517
  });
516
518
  assertEquals(ctx.parseUri(new URL("https://example.com:1234/users/john/notes/123")), {
517
519
  type: "object",
518
- class: Note,
520
+ class: vocab.Note,
519
521
  typeId: new URL("https://www.w3.org/ns/activitystreams#Note"),
520
522
  values: {
521
523
  identifier: "john",
@@ -702,7 +704,7 @@ test({
702
704
  assertEquals(ctx.hostname, "example.com");
703
705
  assertEquals(ctx.data, 123);
704
706
  await assertRejects(() => ctx.getActor("someone"), Error);
705
- await assertRejects(() => ctx.getObject(Note, {
707
+ await assertRejects(() => ctx.getObject(vocab.Note, {
706
708
  handle: "someone",
707
709
  id: "123"
708
710
  }), Error);
@@ -733,23 +735,23 @@ test({
733
735
  assertEquals(await signedCtx2.getSignedKeyOwner(), expectedOwner);
734
736
  assertEquals(await signedCtx2.getSignedKey(), rsaPublicKey3);
735
737
  assertEquals(await signedCtx2.getSignedKeyOwner(), expectedOwner);
736
- federation.setActorDispatcher("/users/{identifier}", (_ctx, identifier) => new Person({ preferredUsername: identifier }));
738
+ federation.setActorDispatcher("/users/{identifier}", (_ctx, identifier) => new vocab.Person({ preferredUsername: identifier }));
737
739
  const ctx2 = federation.createContext(req, 789);
738
740
  assertEquals(ctx2.request, req);
739
741
  assertEquals(ctx2.url, new URL("https://example.com/"));
740
742
  assertEquals(ctx2.data, 789);
741
- assertEquals(await ctx2.getActor("john"), new Person({ preferredUsername: "john" }));
742
- federation.setObjectDispatcher(Note, "/users/{identifier}/notes/{id}", (_ctx, values) => {
743
- return new Note({ summary: `Note ${values.id} by ${values.identifier}` });
743
+ assertEquals(await ctx2.getActor("john"), new vocab.Person({ preferredUsername: "john" }));
744
+ federation.setObjectDispatcher(vocab.Note, "/users/{identifier}/notes/{id}", (_ctx, values) => {
745
+ return new vocab.Note({ summary: `Note ${values.id} by ${values.identifier}` });
744
746
  });
745
747
  const ctx3 = federation.createContext(req, 123);
746
748
  assertEquals(ctx3.request, req);
747
749
  assertEquals(ctx3.url, new URL("https://example.com/"));
748
750
  assertEquals(ctx3.data, 123);
749
- assertEquals(await ctx2.getObject(Note, {
751
+ assertEquals(await ctx2.getObject(vocab.Note, {
750
752
  identifier: "john",
751
753
  id: "123"
752
- }), new Note({ summary: "Note 123 by john" }));
754
+ }), new vocab.Note({ summary: "Note 123 by john" }));
753
755
  });
754
756
  await t.step("RequestContext.clone()", () => {
755
757
  const federation = createFederation({ kv });
@@ -797,7 +799,7 @@ test("Federation.fetch()", async (t) => {
797
799
  });
798
800
  federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => {
799
801
  dispatches.push(identifier);
800
- return new Person({
802
+ return new vocab.Person({
801
803
  id: ctx.getActorUri(identifier),
802
804
  inbox: ctx.getInboxUri(identifier),
803
805
  preferredUsername: identifier
@@ -811,7 +813,7 @@ test("Federation.fetch()", async (t) => {
811
813
  federation.setInboxDispatcher("/users/{identifier}/inbox", () => {
812
814
  return { items: [] };
813
815
  });
814
- federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(Create, (_ctx, activity) => {
816
+ federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(vocab.Create, (_ctx, activity) => {
815
817
  inbox.push(activity.id.toString());
816
818
  return;
817
819
  });
@@ -969,7 +971,7 @@ test("Federation.setInboxListeners()", async (t) => {
969
971
  }
970
972
  });
971
973
  const inbox = [];
972
- federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(Create, (ctx, create) => {
974
+ federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(vocab.Create, (ctx, create) => {
973
975
  inbox.push([ctx, create]);
974
976
  });
975
977
  let response = await federation.fetch(new Request("https://example.com/inbox", {
@@ -978,7 +980,7 @@ test("Federation.setInboxListeners()", async (t) => {
978
980
  }), { contextData: void 0 });
979
981
  assertEquals(inbox, []);
980
982
  assertEquals(response.status, 404);
981
- federation.setActorDispatcher("/users/{identifier}", (_, identifier) => identifier === "john" ? new Person({}) : null).setKeyPairsDispatcher(() => [{
983
+ federation.setActorDispatcher("/users/{identifier}", (_, identifier) => identifier === "john" ? new vocab.Person({}) : null).setKeyPairsDispatcher(() => [{
982
984
  privateKey: rsaPrivateKey2,
983
985
  publicKey: rsaPublicKey2.publicKey
984
986
  }]);
@@ -986,7 +988,7 @@ test("Federation.setInboxListeners()", async (t) => {
986
988
  documentLoader: mockDocumentLoader,
987
989
  contextLoader: mockDocumentLoader
988
990
  };
989
- const activity = () => new Create({
991
+ const activity = () => new vocab.Create({
990
992
  id: new URL("https://example.com/activities/" + crypto.randomUUID()),
991
993
  actor: new URL("https://example.com/person2")
992
994
  });
@@ -1103,18 +1105,18 @@ test("Federation.setInboxListeners()", async (t) => {
1103
1105
  };
1104
1106
  }
1105
1107
  });
1106
- federation.setActorDispatcher("/users/{identifier}", (_, identifier) => identifier === "john" ? new Person({}) : null).setKeyPairsDispatcher(() => [{
1108
+ federation.setActorDispatcher("/users/{identifier}", (_, identifier) => identifier === "john" ? new vocab.Person({}) : null).setKeyPairsDispatcher(() => [{
1107
1109
  privateKey: rsaPrivateKey2,
1108
1110
  publicKey: rsaPublicKey2.publicKey
1109
1111
  }]);
1110
1112
  const error = /* @__PURE__ */ new Error("test");
1111
1113
  const errors = [];
1112
- federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(Create, () => {
1114
+ federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(vocab.Create, () => {
1113
1115
  throw error;
1114
1116
  }).onError((_, e) => {
1115
1117
  errors.push(e);
1116
1118
  });
1117
- const activity = new Create({ actor: new URL("https://example.com/person") });
1119
+ const activity = new vocab.Create({ actor: new URL("https://example.com/person") });
1118
1120
  let request = new Request("https://example.com/users/john/inbox", {
1119
1121
  method: "POST",
1120
1122
  headers: {
@@ -1173,8 +1175,8 @@ test("FederationImpl.sendActivity()", async (t) => {
1173
1175
  let json = await cl.request.json();
1174
1176
  if (await verifyJsonLd(json, options)) verified.push("ld");
1175
1177
  json = detachSignature(json);
1176
- let activity = await verifyObject(Activity, json, options);
1177
- if (activity == null) activity = await Activity.fromJsonLd(json, options);
1178
+ let activity = await verifyObject(vocab.Activity, json, options);
1179
+ if (activity == null) activity = await vocab.Activity.fromJsonLd(json, options);
1178
1180
  else verified.push("proof");
1179
1181
  const key = await verifyRequest(request, options);
1180
1182
  if (key != null && await doesActorOwnKey(activity, key, options)) verified.push("http");
@@ -1188,7 +1190,7 @@ test("FederationImpl.sendActivity()", async (t) => {
1188
1190
  });
1189
1191
  const context = federation.createContext(new URL("https://example.com/"));
1190
1192
  await t.step("success", async () => {
1191
- const activity = new Create({
1193
+ const activity = new vocab.Create({
1192
1194
  id: new URL("https://example.com/activity/1"),
1193
1195
  actor: new URL("https://example.com/person")
1194
1196
  });
@@ -1263,7 +1265,7 @@ test("FederationImpl.processQueuedTask()", async (t) => {
1263
1265
  kv,
1264
1266
  queue
1265
1267
  });
1266
- federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(Create, () => {
1268
+ federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(vocab.Create, () => {
1267
1269
  throw new Error("Intended error for testing");
1268
1270
  });
1269
1271
  await assertRejects(() => federation.processQueuedTask(void 0, {
@@ -1325,7 +1327,7 @@ test("FederationImpl.processQueuedTask()", async (t) => {
1325
1327
  kv,
1326
1328
  queue
1327
1329
  });
1328
- federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(Create, () => {
1330
+ federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(vocab.Create, () => {
1329
1331
  throw new Error("Intended error for testing");
1330
1332
  });
1331
1333
  const outboxMessage = {
@@ -1381,6 +1383,166 @@ test("FederationImpl.processQueuedTask()", async (t) => {
1381
1383
  }]);
1382
1384
  });
1383
1385
  });
1386
+ test("FederationImpl.processQueuedTask() permanent failure", async (t) => {
1387
+ esm_default.spyGlobal();
1388
+ esm_default.post("https://gone.example/inbox", {
1389
+ status: 410,
1390
+ body: "Gone"
1391
+ });
1392
+ esm_default.post("https://notfound.example/inbox", {
1393
+ status: 404,
1394
+ body: "Not Found"
1395
+ });
1396
+ esm_default.post("https://error.example/inbox", {
1397
+ status: 500,
1398
+ body: "Internal Server Error"
1399
+ });
1400
+ esm_default.post("https://legal.example/inbox", {
1401
+ status: 451,
1402
+ body: "Unavailable For Legal Reasons"
1403
+ });
1404
+ function setup(options = {}) {
1405
+ const kv = new MemoryKvStore();
1406
+ const queuedMessages = [];
1407
+ const queue = {
1408
+ ...options.nativeRetrial ? { nativeRetrial: true } : {},
1409
+ enqueue(message, _options) {
1410
+ queuedMessages.push(message);
1411
+ return Promise.resolve();
1412
+ },
1413
+ listen(_handler, _options) {
1414
+ return Promise.resolve();
1415
+ }
1416
+ };
1417
+ const federation = new FederationImpl({
1418
+ kv,
1419
+ queue,
1420
+ ...options.permanentFailureStatusCodes ? { permanentFailureStatusCodes: options.permanentFailureStatusCodes } : {}
1421
+ });
1422
+ federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
1423
+ return {
1424
+ federation,
1425
+ queuedMessages
1426
+ };
1427
+ }
1428
+ function createOutboxMessage(inbox, activityId, actorIds) {
1429
+ return {
1430
+ type: "outbox",
1431
+ id: crypto.randomUUID(),
1432
+ baseUrl: "https://example.com",
1433
+ keys: [],
1434
+ activity: {
1435
+ "@context": "https://www.w3.org/ns/activitystreams",
1436
+ type: "Create",
1437
+ id: activityId,
1438
+ actor: "https://example.com/users/alice",
1439
+ object: {
1440
+ type: "Note",
1441
+ content: "test"
1442
+ }
1443
+ },
1444
+ activityType: "https://www.w3.org/ns/activitystreams#Create",
1445
+ inbox,
1446
+ sharedInbox: false,
1447
+ ...actorIds != null ? { actorIds } : {},
1448
+ started: (/* @__PURE__ */ new Date()).toISOString(),
1449
+ attempt: 0,
1450
+ headers: {},
1451
+ traceContext: {}
1452
+ };
1453
+ }
1454
+ await t.step("410 Gone triggers permanent failure handler", async () => {
1455
+ const { federation, queuedMessages } = setup();
1456
+ let handlerCalled = false;
1457
+ let handlerValues = {};
1458
+ federation.setOutboxPermanentFailureHandler((_ctx, values) => {
1459
+ handlerCalled = true;
1460
+ handlerValues = { ...values };
1461
+ });
1462
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://gone.example/inbox", "https://example.com/activity/1", ["https://gone.example/users/bob", "https://gone.example/users/charlie"]));
1463
+ assert(handlerCalled, "Permanent failure handler should be called");
1464
+ assertEquals(handlerValues.inbox, new URL("https://gone.example/inbox"));
1465
+ assertEquals(handlerValues.statusCode, 410);
1466
+ assertInstanceOf(handlerValues.activity, vocab.Create);
1467
+ assertEquals(handlerValues.actorIds, [new URL("https://gone.example/users/bob"), new URL("https://gone.example/users/charlie")]);
1468
+ assertEquals(queuedMessages, []);
1469
+ });
1470
+ await t.step("404 Not Found triggers permanent failure handler", async () => {
1471
+ const { federation, queuedMessages } = setup();
1472
+ let handlerCalled = false;
1473
+ let handlerStatusCode = 0;
1474
+ federation.setOutboxPermanentFailureHandler((_ctx, values) => {
1475
+ handlerCalled = true;
1476
+ handlerStatusCode = values.statusCode;
1477
+ });
1478
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://notfound.example/inbox", "https://example.com/activity/2", ["https://notfound.example/users/bob"]));
1479
+ assert(handlerCalled, "Permanent failure handler should be called");
1480
+ assertEquals(handlerStatusCode, 404);
1481
+ assertEquals(queuedMessages, []);
1482
+ });
1483
+ await t.step("500 error does NOT trigger permanent failure handler", async () => {
1484
+ const { federation, queuedMessages } = setup();
1485
+ let handlerCalled = false;
1486
+ federation.setOutboxPermanentFailureHandler(() => {
1487
+ handlerCalled = true;
1488
+ });
1489
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://error.example/inbox", "https://example.com/activity/3", ["https://error.example/users/bob"]));
1490
+ assertFalse(handlerCalled, "Permanent failure handler should NOT be called");
1491
+ assertEquals(queuedMessages.length, 1);
1492
+ assertEquals(queuedMessages[0].attempt, 1);
1493
+ });
1494
+ await t.step("custom permanentFailureStatusCodes", async () => {
1495
+ const { federation, queuedMessages } = setup({ permanentFailureStatusCodes: [
1496
+ 404,
1497
+ 410,
1498
+ 451
1499
+ ] });
1500
+ let handlerCalled = false;
1501
+ let handlerStatusCode = 0;
1502
+ federation.setOutboxPermanentFailureHandler((_ctx, values) => {
1503
+ handlerCalled = true;
1504
+ handlerStatusCode = values.statusCode;
1505
+ });
1506
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://legal.example/inbox", "https://example.com/activity/4", ["https://legal.example/users/bob"]));
1507
+ assert(handlerCalled, "Permanent failure handler should be called for 451");
1508
+ assertEquals(handlerStatusCode, 451);
1509
+ assertEquals(queuedMessages, []);
1510
+ });
1511
+ await t.step("handler exception is caught and logged", async () => {
1512
+ const { federation, queuedMessages } = setup();
1513
+ federation.setOutboxPermanentFailureHandler(() => {
1514
+ throw new Error("Handler error that should be ignored");
1515
+ });
1516
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://gone.example/inbox", "https://example.com/activity/5", ["https://gone.example/users/bob"]));
1517
+ assertEquals(queuedMessages, []);
1518
+ });
1519
+ await t.step("permanent failure skips retry without handler registered", async () => {
1520
+ const { federation, queuedMessages } = setup();
1521
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://gone.example/inbox", "https://example.com/activity/6", []));
1522
+ assertEquals(queuedMessages, []);
1523
+ });
1524
+ await t.step("nativeRetrial: permanent failure does not re-throw", async () => {
1525
+ const { federation, queuedMessages } = setup({ nativeRetrial: true });
1526
+ let handlerCalled = false;
1527
+ federation.setOutboxPermanentFailureHandler(() => {
1528
+ handlerCalled = true;
1529
+ });
1530
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://gone.example/inbox", "https://example.com/activity/7", ["https://gone.example/users/bob"]));
1531
+ assert(handlerCalled, "Permanent failure handler should be called");
1532
+ assertEquals(queuedMessages, []);
1533
+ });
1534
+ await t.step("actorIds missing from message defaults to empty array", async () => {
1535
+ const { federation, queuedMessages } = setup();
1536
+ let handlerActorIds = [];
1537
+ federation.setOutboxPermanentFailureHandler((_ctx, values) => {
1538
+ handlerActorIds = values.actorIds;
1539
+ });
1540
+ await federation.processQueuedTask(void 0, createOutboxMessage("https://gone.example/inbox", "https://example.com/activity/8"));
1541
+ assertEquals(handlerActorIds, []);
1542
+ assertEquals(queuedMessages, []);
1543
+ });
1544
+ esm_default.hardReset();
1545
+ });
1384
1546
  test("ContextImpl.lookupObject()", async (t) => {
1385
1547
  esm_default.spyGlobal();
1386
1548
  esm_default.get("begin:https://localhost/.well-known/webfinger", {
@@ -1410,7 +1572,7 @@ test("ContextImpl.lookupObject()", async (t) => {
1410
1572
  });
1411
1573
  const ctx = federation.createContext(new URL("https://example.com/"));
1412
1574
  const result = await ctx.lookupObject("@test@localhost");
1413
- assertInstanceOf(result, Person);
1575
+ assertInstanceOf(result, vocab.Person);
1414
1576
  assertEquals(result.id, new URL("https://localhost/actor"));
1415
1577
  assertEquals(result.preferredUsername, "test");
1416
1578
  });
@@ -1459,8 +1621,8 @@ test("ContextImpl.sendActivity()", async (t) => {
1459
1621
  let json = await cl.request.json();
1460
1622
  if (await verifyJsonLd(json, options)) verified.push("ld");
1461
1623
  json = detachSignature(json);
1462
- let activity = await verifyObject(Activity, json, options);
1463
- if (activity == null) activity = await Activity.fromJsonLd(json, options);
1624
+ let activity = await verifyObject(vocab.Activity, json, options);
1625
+ if (activity == null) activity = await vocab.Activity.fromJsonLd(json, options);
1464
1626
  else verified.push("proof");
1465
1627
  const key = await verifyRequest(request, options);
1466
1628
  if (key != null && await doesActorOwnKey(activity, key, options)) verified.push("http");
@@ -1475,7 +1637,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1475
1637
  federation.setActorDispatcher("/{identifier}", async (ctx, identifier) => {
1476
1638
  if (identifier !== "1") return null;
1477
1639
  const keys = await ctx.getActorKeyPairs(identifier);
1478
- return new Person({
1640
+ return new vocab.Person({
1479
1641
  id: ctx.getActorUri(identifier),
1480
1642
  preferredUsername: "john",
1481
1643
  publicKey: keys[0].cryptographicKey,
@@ -1496,7 +1658,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1496
1658
  inboxId: new URL("https://example.com/inbox")
1497
1659
  }] }));
1498
1660
  await t.step("success", async () => {
1499
- const activity = new Create({ actor: new URL("https://example.com/person") });
1661
+ const activity = new vocab.Create({ actor: new URL("https://example.com/person") });
1500
1662
  const ctx = new ContextImpl({
1501
1663
  data: void 0,
1502
1664
  federation,
@@ -1585,7 +1747,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1585
1747
  federation2.setActorDispatcher("/{identifier}", async (ctx, identifier) => {
1586
1748
  if (identifier !== "john") return null;
1587
1749
  const keys = await ctx.getActorKeyPairs(identifier);
1588
- return new Person({
1750
+ return new vocab.Person({
1589
1751
  id: ctx.getActorUri(identifier),
1590
1752
  preferredUsername: "john",
1591
1753
  publicKey: keys[0].cryptographicKey,
@@ -1609,7 +1771,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1609
1771
  contextLoader: fetchDocumentLoader
1610
1772
  });
1611
1773
  await t.step("fanout: \"force\"", async () => {
1612
- const activity = new Create({
1774
+ const activity = new vocab.Create({
1613
1775
  id: new URL("https://example.com/activity/1"),
1614
1776
  actor: new URL("https://example.com/person")
1615
1777
  });
@@ -1633,12 +1795,13 @@ test("ContextImpl.sendActivity()", async (t) => {
1633
1795
  sharedInbox: false
1634
1796
  } },
1635
1797
  keys: queue.messages[0].type === "fanout" ? queue.messages[0].keys : [],
1798
+ orderingKey: void 0,
1636
1799
  traceContext: {}
1637
1800
  }]);
1638
1801
  });
1639
1802
  queue.clear();
1640
1803
  await t.step("fanout: \"skip\"", async () => {
1641
- const activity = new Create({
1804
+ const activity = new vocab.Create({
1642
1805
  id: new URL("https://example.com/activity/1"),
1643
1806
  actor: new URL("https://example.com/person")
1644
1807
  });
@@ -1653,7 +1816,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1653
1816
  });
1654
1817
  queue.clear();
1655
1818
  await t.step("fanout: \"auto\"", async () => {
1656
- const activity = new Create({
1819
+ const activity = new vocab.Create({
1657
1820
  id: new URL("https://example.com/activity/1"),
1658
1821
  actor: new URL("https://example.com/person")
1659
1822
  });
@@ -1702,7 +1865,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1702
1865
  documentLoader: fetchDocumentLoader,
1703
1866
  contextLoader: fetchDocumentLoader
1704
1867
  });
1705
- const activity = new Create({
1868
+ const activity = new vocab.Create({
1706
1869
  id: new URL("https://example.com/activity/1"),
1707
1870
  actor: ctx.getActorUri("1"),
1708
1871
  to: ctx.getFollowersUri("1")
@@ -1719,7 +1882,7 @@ test("ContextImpl.sendActivity()", async (t) => {
1719
1882
  documentLoader: fetchDocumentLoader,
1720
1883
  contextLoader: fetchDocumentLoader
1721
1884
  });
1722
- const activity = new Create({
1885
+ const activity = new vocab.Create({
1723
1886
  id: new URL("https://example.com/activity/2"),
1724
1887
  actor: ctx.getActorUri("1"),
1725
1888
  to: ctx.getFollowersUri("1")
@@ -1730,6 +1893,57 @@ test("ContextImpl.sendActivity()", async (t) => {
1730
1893
  });
1731
1894
  assertNotEquals(collectionSyncHeader, null);
1732
1895
  });
1896
+ queue.clear();
1897
+ await t.step("orderingKey with fanout: \"force\"", async () => {
1898
+ const activity = new vocab.Create({
1899
+ id: new URL("https://example.com/activity/ordering-1"),
1900
+ actor: new URL("https://example.com/person")
1901
+ });
1902
+ await ctx2.sendActivity({ username: "john" }, {
1903
+ id: new URL("https://example.com/recipient"),
1904
+ inboxId: new URL("https://example.com/inbox")
1905
+ }, activity, {
1906
+ fanout: "force",
1907
+ orderingKey: "https://example.com/note/1"
1908
+ });
1909
+ assertEquals(queue.messages.length, 1);
1910
+ const fanoutMessage = queue.messages[0];
1911
+ assertEquals(fanoutMessage.type, "fanout");
1912
+ if (fanoutMessage.type === "fanout") assertEquals(fanoutMessage.orderingKey, "https://example.com/note/1");
1913
+ });
1914
+ queue.clear();
1915
+ await t.step("orderingKey with fanout: \"skip\"", async () => {
1916
+ const activity = new vocab.Create({
1917
+ id: new URL("https://example.com/activity/ordering-2"),
1918
+ actor: new URL("https://example.com/person")
1919
+ });
1920
+ await ctx2.sendActivity({ username: "john" }, {
1921
+ id: new URL("https://example.com/recipient"),
1922
+ inboxId: new URL("https://example.com/inbox")
1923
+ }, activity, {
1924
+ fanout: "skip",
1925
+ orderingKey: "https://example.com/note/2"
1926
+ });
1927
+ assertEquals(queue.messages.length, 1);
1928
+ const outboxMessage = queue.messages[0];
1929
+ assertEquals(outboxMessage.type, "outbox");
1930
+ if (outboxMessage.type === "outbox") assertEquals(outboxMessage.orderingKey, "https://example.com/note/2\nhttps://example.com");
1931
+ });
1932
+ queue.clear();
1933
+ await t.step("orderingKey not specified", async () => {
1934
+ const activity = new vocab.Create({
1935
+ id: new URL("https://example.com/activity/ordering-3"),
1936
+ actor: new URL("https://example.com/person")
1937
+ });
1938
+ await ctx2.sendActivity({ username: "john" }, {
1939
+ id: new URL("https://example.com/recipient"),
1940
+ inboxId: new URL("https://example.com/inbox")
1941
+ }, activity, { fanout: "force" });
1942
+ assertEquals(queue.messages.length, 1);
1943
+ const fanoutMessage2 = queue.messages[0];
1944
+ assertEquals(fanoutMessage2.type, "fanout");
1945
+ if (fanoutMessage2.type === "fanout") assertEquals(fanoutMessage2.orderingKey, void 0);
1946
+ });
1733
1947
  esm_default.hardReset();
1734
1948
  });
1735
1949
  test({
@@ -1741,7 +1955,7 @@ test({
1741
1955
  async fn() {
1742
1956
  const federation = new FederationImpl({ kv: new MemoryKvStore() });
1743
1957
  const activities = [];
1744
- federation.setInboxListeners("/u/{identifier}/i", "/i").on(Offer, (ctx$1, offer) => {
1958
+ federation.setInboxListeners("/u/{identifier}/i", "/i").on(vocab.Offer, (ctx$1, offer) => {
1745
1959
  activities.push([ctx$1.recipient, offer]);
1746
1960
  });
1747
1961
  const ctx = new ContextImpl({
@@ -1751,52 +1965,52 @@ test({
1751
1965
  documentLoader: mockDocumentLoader,
1752
1966
  contextLoader: fetchDocumentLoader
1753
1967
  });
1754
- assertFalse(await ctx.routeActivity(null, new Offer({ actor: new URL("https://example.com/person") })));
1968
+ assertFalse(await ctx.routeActivity(null, new vocab.Offer({ actor: new URL("https://example.com/person") })));
1755
1969
  assertEquals(activities, []);
1756
- const signedOffer = await signObject(new Offer({ actor: new URL("https://example.com/person2") }), ed25519PrivateKey, ed25519Multikey.id);
1970
+ const signedOffer = await signObject(new vocab.Offer({ actor: new URL("https://example.com/person2") }), ed25519PrivateKey, ed25519Multikey.id);
1757
1971
  assert(await ctx.routeActivity(null, signedOffer));
1758
1972
  assertEquals(activities, [[null, signedOffer]]);
1759
- const signedInvite = await signObject(new Invite({ actor: new URL("https://example.com/person2") }), ed25519PrivateKey, ed25519Multikey.id);
1973
+ const signedInvite = await signObject(new vocab.Invite({ actor: new URL("https://example.com/person2") }), ed25519PrivateKey, ed25519Multikey.id);
1760
1974
  assert(await ctx.routeActivity("id", signedInvite));
1761
1975
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1762
- assertFalse(await ctx.routeActivity(null, new Create({
1976
+ assertFalse(await ctx.routeActivity(null, new vocab.Create({
1763
1977
  id: new URL("https://example.com/not-found"),
1764
1978
  actor: new URL("https://example.com/person")
1765
1979
  })));
1766
1980
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1767
- assertFalse(await ctx.routeActivity(null, new Create({
1981
+ assertFalse(await ctx.routeActivity(null, new vocab.Create({
1768
1982
  id: new URL("https://example.com/person"),
1769
1983
  actor: new URL("https://example.com/person")
1770
1984
  })));
1771
1985
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1772
- assertFalse(await ctx.routeActivity(null, new Announce({
1986
+ assertFalse(await ctx.routeActivity(null, new vocab.Announce({
1773
1987
  id: new URL("https://example.com/announce#diffrent-id"),
1774
1988
  actor: new URL("https://example.com/person")
1775
1989
  })));
1776
1990
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1777
- assertFalse(await ctx.routeActivity(null, new Announce({
1991
+ assertFalse(await ctx.routeActivity(null, new vocab.Announce({
1778
1992
  id: new URL("https://example.com/announce"),
1779
1993
  actor: new URL("https://example.com/person")
1780
1994
  })));
1781
1995
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1782
- assertFalse(await ctx.routeActivity(null, new Create({
1996
+ assertFalse(await ctx.routeActivity(null, new vocab.Create({
1783
1997
  id: new URL("https://example.com/cross-origin-actor"),
1784
1998
  actor: new URL("https://cross-origin.com/actor")
1785
1999
  })));
1786
2000
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1787
- assert(await ctx.routeActivity(null, new Create({
2001
+ assert(await ctx.routeActivity(null, new vocab.Create({
1788
2002
  id: new URL("https://example.com/create"),
1789
2003
  actor: new URL("https://example.com/person")
1790
2004
  })));
1791
2005
  assertEquals(activities, [[null, signedOffer], ["id", signedInvite]]);
1792
- assert(await ctx.routeActivity(null, new Invite({
2006
+ assert(await ctx.routeActivity(null, new vocab.Invite({
1793
2007
  id: new URL("https://example.com/invite"),
1794
2008
  actor: new URL("https://example.com/person")
1795
2009
  })));
1796
2010
  assertEquals(activities, [
1797
2011
  [null, signedOffer],
1798
2012
  ["id", signedInvite],
1799
- [null, new Invite({
2013
+ [null, new vocab.Invite({
1800
2014
  id: new URL("https://example.com/invite"),
1801
2015
  actor: new URL("https://example.com/person"),
1802
2016
  object: new URL("https://example.com/object")
@@ -1818,15 +2032,15 @@ test("ContextImpl.getCollectionUri()", () => {
1818
2032
  const dispatcher = (_ctx, _values) => ({ items: [] });
1819
2033
  let url;
1820
2034
  const strName = "registered";
1821
- federation.setCollectionDispatcher(strName, Object$1, "/string-route/{id}", dispatcher);
2035
+ federation.setCollectionDispatcher(strName, vocab.Object, "/string-route/{id}", dispatcher);
1822
2036
  url = ctx.getCollectionUri(strName, values);
1823
2037
  assertEquals(url.href, `${base}/string-route/123`);
1824
2038
  const unnamedSymName = Symbol(strName);
1825
- federation.setCollectionDispatcher(unnamedSymName, Object$1, "/symbol-route/{id}", dispatcher);
2039
+ federation.setCollectionDispatcher(unnamedSymName, vocab.Object, "/symbol-route/{id}", dispatcher);
1826
2040
  url = ctx.getCollectionUri(unnamedSymName, values);
1827
2041
  assertEquals(url.href, `${base}/symbol-route/123`);
1828
2042
  const namedSymName = Symbol.for(strName);
1829
- federation.setCollectionDispatcher(namedSymName, Object$1, "/named-symbol-route/{id}", dispatcher);
2043
+ federation.setCollectionDispatcher(namedSymName, vocab.Object, "/named-symbol-route/{id}", dispatcher);
1830
2044
  url = ctx.getCollectionUri(namedSymName, values);
1831
2045
  assertEquals(url.href, `${base}/named-symbol-route/123`);
1832
2046
  const notReg = "not-registered";
@@ -1848,8 +2062,8 @@ test("InboxContextImpl.forwardActivity()", async (t) => {
1848
2062
  let json = await cl.request.json();
1849
2063
  if (await verifyJsonLd(json, options)) verified.push("ld");
1850
2064
  json = detachSignature(json);
1851
- let activity = await verifyObject(Activity, json, options);
1852
- if (activity == null) activity = await Activity.fromJsonLd(json, options);
2065
+ let activity = await verifyObject(vocab.Activity, json, options);
2066
+ if (activity == null) activity = await vocab.Activity.fromJsonLd(json, options);
1853
2067
  else verified.push("proof");
1854
2068
  const key = await verifyRequest(request, options);
1855
2069
  if (key != null && await doesActorOwnKey(activity, key, options)) verified.push("http");
@@ -1908,7 +2122,7 @@ test("InboxContextImpl.forwardActivity()", async (t) => {
1908
2122
  assertEquals(verified, []);
1909
2123
  });
1910
2124
  await t.step("Object Integrity Proofs", async () => {
1911
- const activity = await signObject(new Create({
2125
+ const activity = await signObject(new vocab.Create({
1912
2126
  id: new URL("https://example.com/activity"),
1913
2127
  actor: new URL("https://example.com/person2")
1914
2128
  }), ed25519PrivateKey, ed25519Multikey.id, {