@fedify/fedify 2.0.0-dev.1566 → 2.0.0-dev.159

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 (297) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +66 -30
  3. package/dist/{assert_rejects-DiIiJbZn.js → assert_rejects-Ce45JcFg.js} +1 -1
  4. package/dist/{assert_is_error-BPGph1Jx.js → assert_throws-BNXdRGWP.js} +31 -1
  5. package/dist/{builder-B2I70zuM.js → builder-oZcZfn1d.js} +15 -8
  6. package/dist/chunk-DqRYRqnO.cjs +34 -0
  7. package/dist/client-94iWEfQa.d.cts +222 -0
  8. package/dist/{client-DF8anIB5.d.ts → client-BivSNrEg.d.ts} +3 -75
  9. package/dist/{client-BVDUd3WA.js → client-CgMTXmAD.js} +3 -22
  10. package/dist/compat/mod.cjs +10 -0
  11. package/dist/compat/mod.d.cts +7 -0
  12. package/dist/compat/mod.d.ts +6 -12
  13. package/dist/compat/mod.js +5 -5
  14. package/dist/compat/transformers.test.js +21 -20
  15. package/dist/compat-DmDDELst.cjs +4 -0
  16. package/dist/compat-nxUqe4Z-.js +4 -0
  17. package/dist/context-Bns6uTJq.js +109 -0
  18. package/dist/{context-9gCpIkiz.d.ts → context-CYZ2i00R.d.ts} +321 -129
  19. package/dist/context-D2MrtLch.d.cts +2447 -0
  20. package/dist/deno-CGe3r5lB.js +117 -0
  21. package/dist/{testing-CWE5Nn0S.js → dist-B5f6a8Tt.js} +90 -111
  22. package/dist/{authdocloader-BilVqAPe.js → docloader-Bh4ZzxTs.js} +17 -8
  23. package/dist/{esm-eH43VACi.js → esm-DGl7uK1r.js} +32 -17
  24. package/dist/federation/builder.test.js +12 -13
  25. package/dist/federation/collection.test.js +6 -9
  26. package/dist/federation/handler.test.js +115 -148
  27. package/dist/federation/idempotency.test.js +202 -0
  28. package/dist/federation/inbox.test.js +5 -6
  29. package/dist/federation/keycache.test.js +4 -5
  30. package/dist/federation/kv.test.js +61 -9
  31. package/dist/federation/middleware.test.js +311 -131
  32. package/dist/federation/mod.cjs +25 -0
  33. package/dist/federation/mod.d.cts +7 -0
  34. package/dist/federation/mod.d.ts +7 -13
  35. package/dist/federation/mod.js +11 -16
  36. package/dist/federation/mq.test.js +9 -10
  37. package/dist/federation/negotiation.test.js +25 -0
  38. package/dist/federation/retry.test.js +2 -4
  39. package/dist/federation/router.test.js +6 -8
  40. package/dist/federation/send.test.js +55 -15
  41. package/dist/{webfinger/handler.test.js → federation/webfinger.test.js} +27 -26
  42. package/dist/federation-B431K2gm.cjs +266 -0
  43. package/dist/{federation-CMX7WzeL.js → federation-BbZwNNWj.js} +31 -9
  44. package/dist/http-AW19epBO.cjs +1222 -0
  45. package/dist/{http-BE2S7wC2.js → http-CN7c23sh.js} +4 -3
  46. package/dist/{http-Cdjyj7h1.js → http-CZ24XIWJ.js} +375 -15
  47. package/dist/http-ClB3pLcL.d.cts +253 -0
  48. package/dist/{http-DqSNLFNY.d.ts → http-DLBDPal9.d.ts} +2 -2
  49. package/dist/{inbox-CtcEN1S1.js → inbox-DLgz90Tj.js} +25 -7
  50. package/dist/{key-q4xxkABj.js → key-fb8Ovh-p.js} +3 -2
  51. package/dist/{keycache-CtCHz6HR.js → keycache-DRxpZ5r9.js} +1 -1
  52. package/dist/{keys-BiuLoxwK.js → keys-ZbcByPg9.js} +2 -1
  53. package/dist/{kv-C7sopW2E.d.ts → kv-CtOmTRNc.d.ts} +30 -1
  54. package/dist/kv-D8q9fLkA.d.cts +110 -0
  55. package/dist/{kv-CRZrzyXm.js → kv-QzKcOQgP.js} +22 -0
  56. package/dist/kv-cache-8rnKI8DT.cjs +134 -0
  57. package/dist/kv-cache-BEeqyGER.js +107 -0
  58. package/dist/kv-cache-DGCF5il_.js +122 -0
  59. package/dist/{ld-PkXepnwg.js → ld-9If_eMWm.js} +6 -4
  60. package/dist/{middleware-BQHcEUgM.js → middleware-BpTxdimj.js} +230 -327
  61. package/dist/middleware-DR-CCeAc.cjs +12 -0
  62. package/dist/{middleware-HDts7zkt.js → middleware-DdBvEeAn.js} +272 -271
  63. package/dist/middleware-DrwTlwzK.js +12 -0
  64. package/dist/middleware-psDtCgD-.cjs +4242 -0
  65. package/dist/middleware-vXfeY_vA.js +26 -0
  66. package/dist/mod-BrS8tiad.d.cts +266 -0
  67. package/dist/mod-C81L6_lQ.d.cts +1 -0
  68. package/dist/mod-CJgbdSqb.d.ts +109 -0
  69. package/dist/mod-CNNTHyBC.d.cts +80 -0
  70. package/dist/mod-CS-MS7gZ.d.cts +62 -0
  71. package/dist/{mod-Bqxcp7eN.d.ts → mod-D_cmv2il.d.ts} +4 -4
  72. package/dist/mod-DcPRcifg.d.cts +107 -0
  73. package/dist/mod-DqFSzJA0.d.ts +64 -0
  74. package/dist/{mod-Drmz72EK.d.ts → mod-jOa7W503.d.ts} +3 -3
  75. package/dist/mod.cjs +55 -0
  76. package/dist/mod.d.cts +11 -0
  77. package/dist/mod.d.ts +11 -17
  78. package/dist/mod.js +15 -21
  79. package/dist/negotiation-5NPJL6zp.js +71 -0
  80. package/dist/nodeinfo/client.test.js +29 -111
  81. package/dist/nodeinfo/handler.test.js +26 -26
  82. package/dist/nodeinfo/mod.cjs +10 -0
  83. package/dist/nodeinfo/mod.d.cts +3 -0
  84. package/dist/nodeinfo/mod.d.ts +3 -5
  85. package/dist/nodeinfo/mod.js +6 -7
  86. package/dist/nodeinfo/types.test.js +7 -15
  87. package/dist/nodeinfo-BlLsRSiT.js +4 -0
  88. package/dist/nodeinfo-DuMYTpbZ.cjs +4 -0
  89. package/dist/otel/exporter.test.js +899 -0
  90. package/dist/otel/mod.cjs +262 -0
  91. package/dist/otel/mod.d.cts +230 -0
  92. package/dist/otel/mod.d.ts +232 -0
  93. package/dist/otel/mod.js +261 -0
  94. package/dist/{owner-CQPnQVtf.d.ts → owner-BgI8C-VY.d.ts} +2 -3
  95. package/dist/owner-C-zfmVAD.d.cts +66 -0
  96. package/dist/{owner-DZ5zP8JS.js → owner-CCSlDz_P.js} +45 -8
  97. package/dist/{proof-D8S7qgEZ.js → proof-1s5PweRC.js} +53 -17
  98. package/dist/proof-DCmRymP1.cjs +709 -0
  99. package/dist/{proof-ohtusUSV.js → proof-WPbBCoJ-.js} +4 -3
  100. package/dist/router-D9eI0s4b.js +118 -0
  101. package/dist/{send-BBi1tzS8.js → send-DBgPrFik.js} +9 -4
  102. package/dist/sig/http.test.js +12 -14
  103. package/dist/sig/key.test.js +9 -11
  104. package/dist/sig/ld.test.js +8 -10
  105. package/dist/sig/mod.cjs +26 -0
  106. package/dist/sig/mod.d.cts +4 -0
  107. package/dist/sig/mod.d.ts +3 -7
  108. package/dist/sig/mod.js +6 -10
  109. package/dist/sig/owner.test.js +33 -12
  110. package/dist/sig/proof.test.js +13 -14
  111. package/dist/sig-CwuONEzF.js +4 -0
  112. package/dist/sig-DeXX2xnj.cjs +4 -0
  113. package/dist/testing/mod.d.ts +180 -6946
  114. package/dist/testing/mod.js +4 -4
  115. package/dist/transformers-BjBg6Lag.cjs +116 -0
  116. package/dist/{transformers-Dna8Fg7k.js → transformers-N_ip_y4P.js} +5 -5
  117. package/dist/{types-BIgY6c-l.js → types-BEdCLHqP.js} +1 -3
  118. package/dist/types-Q-qkJXBV.cjs +315 -0
  119. package/dist/{types-CTYFFnQp.js → types-hKTi53FO.js} +8 -169
  120. package/dist/{runtime/authdocloader.test.js → utils/docloader.test.js} +13 -15
  121. package/dist/utils/kv-cache.test.js +211 -0
  122. package/dist/utils/mod.cjs +10 -0
  123. package/dist/utils/mod.d.cts +4 -0
  124. package/dist/utils/mod.d.ts +6 -0
  125. package/dist/utils/mod.js +9 -0
  126. package/dist/utils-Db0ZmjcD.cjs +4 -0
  127. package/dist/utils-Wranxuoe.js +4 -0
  128. package/package.json +69 -55
  129. package/dist/actor-BKxX_F1w.js +0 -37311
  130. package/dist/actor-C22bXuuC.d.ts +0 -130
  131. package/dist/actor-DI_YpFlI.js +0 -146
  132. package/dist/assert_throws-BOO88avQ.js +0 -39
  133. package/dist/authdocloader-UdvnssIx.js +0 -52
  134. package/dist/compat-Bb5myD13.js +0 -4
  135. package/dist/denokv-Bv33Xxea.js +0 -57
  136. package/dist/docloader-4XS4XdXc.js +0 -4615
  137. package/dist/docloader-CxWcuWqQ.d.ts +0 -221
  138. package/dist/fixtures/activitypub.academy/users/brauca_darradiul.json +0 -83
  139. package/dist/fixtures/example.com/announce.json +0 -6
  140. package/dist/fixtures/example.com/collection.json +0 -19
  141. package/dist/fixtures/example.com/create.json +0 -6
  142. package/dist/fixtures/example.com/cross-origin-actor.json +0 -6
  143. package/dist/fixtures/example.com/hong-gildong.json +0 -11
  144. package/dist/fixtures/example.com/invite.json +0 -7
  145. package/dist/fixtures/example.com/key.json +0 -7
  146. package/dist/fixtures/example.com/key2.json +0 -6
  147. package/dist/fixtures/example.com/object.json +0 -6
  148. package/dist/fixtures/example.com/orderedcollectionpage.json +0 -24
  149. package/dist/fixtures/example.com/paged/a.json +0 -13
  150. package/dist/fixtures/example.com/paged/b.json +0 -16
  151. package/dist/fixtures/example.com/paged-collection.json +0 -6
  152. package/dist/fixtures/example.com/person.json +0 -22
  153. package/dist/fixtures/example.com/person2.json +0 -40
  154. package/dist/fixtures/example.com/test.json +0 -5
  155. package/dist/fixtures/example.com/users/handle.json +0 -16
  156. package/dist/fixtures/example.com/wrong-type.json +0 -3
  157. package/dist/fixtures/oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd.json +0 -24
  158. package/dist/fixtures/remote.domain/users/bob.json +0 -20
  159. package/dist/fixtures/server.example/users/alice.json +0 -20
  160. package/dist/fixtures/w3id.org/identity/v1.json +0 -152
  161. package/dist/fixtures/w3id.org/security/data-integrity/v1.json +0 -74
  162. package/dist/fixtures/w3id.org/security/multikey/v1.json +0 -35
  163. package/dist/fixtures/w3id.org/security/v1.json +0 -50
  164. package/dist/fixtures/wizard.casa/users/hongminhee.json +0 -69
  165. package/dist/fixtures/www.w3.org/ns/activitystreams.json +0 -379
  166. package/dist/fixtures/www.w3.org/ns/did/v1.json +0 -58
  167. package/dist/key-C2_QSigr.js +0 -260
  168. package/dist/key-Ck2-lYS5.js +0 -10
  169. package/dist/key-II1NsE_S.js +0 -10
  170. package/dist/lookup-DCIN2EFw.js +0 -322
  171. package/dist/lookup-DVlWgAsd.js +0 -131
  172. package/dist/middleware-CTQfgVW8.js +0 -17
  173. package/dist/middleware-D3rOl6Au.js +0 -26
  174. package/dist/mod-Cxt4Kpf6.d.ts +0 -291
  175. package/dist/mod-DBzN0aCM.d.ts +0 -115
  176. package/dist/mod-TFoH2Ql8.d.ts +0 -104
  177. package/dist/mod-g0xFzAP9.d.ts +0 -2
  178. package/dist/mq-CRGm1e_F.d.ts +0 -143
  179. package/dist/nodeinfo/semver.test.js +0 -143
  180. package/dist/nodeinfo-CyEbLjHs.js +0 -4
  181. package/dist/runtime/docloader.test.js +0 -522
  182. package/dist/runtime/key.test.js +0 -103
  183. package/dist/runtime/langstr.test.js +0 -39
  184. package/dist/runtime/mod.d.ts +0 -8
  185. package/dist/runtime/mod.js +0 -13
  186. package/dist/runtime/multibase/multibase.test.d.ts +0 -3
  187. package/dist/runtime/multibase/multibase.test.js +0 -358
  188. package/dist/runtime/url.test.d.ts +0 -3
  189. package/dist/runtime/url.test.js +0 -45
  190. package/dist/runtime-BSkOVUWM.js +0 -4
  191. package/dist/semver-dArNLkR9.js +0 -149
  192. package/dist/sig-BXJO--F9.js +0 -4
  193. package/dist/src/vocab/accept.yaml +0 -15
  194. package/dist/src/vocab/activity.yaml +0 -98
  195. package/dist/src/vocab/add.yaml +0 -16
  196. package/dist/src/vocab/announce.yaml +0 -30
  197. package/dist/src/vocab/application.yaml +0 -324
  198. package/dist/src/vocab/arrive.yaml +0 -15
  199. package/dist/src/vocab/article.yaml +0 -46
  200. package/dist/src/vocab/audio.yaml +0 -11
  201. package/dist/src/vocab/block.yaml +0 -16
  202. package/dist/src/vocab/chatmessage.yaml +0 -50
  203. package/dist/src/vocab/collection.yaml +0 -154
  204. package/dist/src/vocab/collectionpage.yaml +0 -55
  205. package/dist/src/vocab/create.yaml +0 -28
  206. package/dist/src/vocab/dataintegrityproof.yaml +0 -56
  207. package/dist/src/vocab/delete.yaml +0 -27
  208. package/dist/src/vocab/didservice.yaml +0 -22
  209. package/dist/src/vocab/dislike.yaml +0 -14
  210. package/dist/src/vocab/document.yaml +0 -31
  211. package/dist/src/vocab/emoji.yaml +0 -12
  212. package/dist/src/vocab/emojireact.yaml +0 -17
  213. package/dist/src/vocab/endpoints.yaml +0 -85
  214. package/dist/src/vocab/event.yaml +0 -11
  215. package/dist/src/vocab/export.yaml +0 -9
  216. package/dist/src/vocab/flag.yaml +0 -15
  217. package/dist/src/vocab/follow.yaml +0 -19
  218. package/dist/src/vocab/group.yaml +0 -324
  219. package/dist/src/vocab/hashtag.yaml +0 -14
  220. package/dist/src/vocab/ignore.yaml +0 -14
  221. package/dist/src/vocab/image.yaml +0 -9
  222. package/dist/src/vocab/intransitiveactivity.yaml +0 -15
  223. package/dist/src/vocab/invite.yaml +0 -14
  224. package/dist/src/vocab/join.yaml +0 -14
  225. package/dist/src/vocab/key.yaml +0 -28
  226. package/dist/src/vocab/leave.yaml +0 -14
  227. package/dist/src/vocab/like.yaml +0 -16
  228. package/dist/src/vocab/link.yaml +0 -101
  229. package/dist/src/vocab/listen.yaml +0 -12
  230. package/dist/src/vocab/mention.yaml +0 -9
  231. package/dist/src/vocab/move.yaml +0 -15
  232. package/dist/src/vocab/multikey.yaml +0 -36
  233. package/dist/src/vocab/note.yaml +0 -48
  234. package/dist/src/vocab/object.yaml +0 -404
  235. package/dist/src/vocab/offer.yaml +0 -15
  236. package/dist/src/vocab/orderedcollection.yaml +0 -39
  237. package/dist/src/vocab/orderedcollectionpage.yaml +0 -50
  238. package/dist/src/vocab/organization.yaml +0 -324
  239. package/dist/src/vocab/page.yaml +0 -11
  240. package/dist/src/vocab/person.yaml +0 -324
  241. package/dist/src/vocab/place.yaml +0 -75
  242. package/dist/src/vocab/profile.yaml +0 -26
  243. package/dist/src/vocab/propertyvalue.yaml +0 -32
  244. package/dist/src/vocab/question.yaml +0 -103
  245. package/dist/src/vocab/read.yaml +0 -13
  246. package/dist/src/vocab/reject.yaml +0 -14
  247. package/dist/src/vocab/relationship.yaml +0 -52
  248. package/dist/src/vocab/remove.yaml +0 -14
  249. package/dist/src/vocab/service.yaml +0 -324
  250. package/dist/src/vocab/source.yaml +0 -26
  251. package/dist/src/vocab/tentativeaccept.yaml +0 -14
  252. package/dist/src/vocab/tentativereject.yaml +0 -14
  253. package/dist/src/vocab/tombstone.yaml +0 -24
  254. package/dist/src/vocab/travel.yaml +0 -16
  255. package/dist/src/vocab/undo.yaml +0 -26
  256. package/dist/src/vocab/update.yaml +0 -58
  257. package/dist/src/vocab/video.yaml +0 -11
  258. package/dist/src/vocab/view.yaml +0 -13
  259. package/dist/testing/docloader.test.js +0 -24
  260. package/dist/type-B7_rMIU9.js +0 -42006
  261. package/dist/vocab/actor.test.d.ts +0 -3
  262. package/dist/vocab/actor.test.js +0 -5965
  263. package/dist/vocab/lookup.test.d.ts +0 -3
  264. package/dist/vocab/lookup.test.js +0 -206
  265. package/dist/vocab/mod.d.ts +0 -8
  266. package/dist/vocab/mod.js +0 -10
  267. package/dist/vocab/schema.yaml +0 -247
  268. package/dist/vocab/type.test.d.ts +0 -3
  269. package/dist/vocab/type.test.js +0 -25
  270. package/dist/vocab/vocab.test.d.ts +0 -3
  271. package/dist/vocab/vocab.test.js +0 -3363
  272. package/dist/vocab-3Eie7Ze4.js +0 -246
  273. package/dist/vocab-SOE1ifCr.d.ts +0 -14634
  274. package/dist/webfinger/handler.test.d.ts +0 -3
  275. package/dist/webfinger/lookup.test.d.ts +0 -3
  276. package/dist/webfinger/lookup.test.js +0 -195
  277. package/dist/webfinger/mod.d.ts +0 -6
  278. package/dist/webfinger/mod.js +0 -9
  279. package/dist/webfinger-C3GIyXIg.js +0 -4
  280. package/dist/x/cfworkers.d.ts +0 -61
  281. package/dist/x/cfworkers.js +0 -98
  282. package/dist/x/cfworkers.test.d.ts +0 -3
  283. package/dist/x/cfworkers.test.js +0 -179
  284. package/dist/x/hono.d.ts +0 -56
  285. package/dist/x/hono.js +0 -60
  286. package/dist/x/sveltekit.d.ts +0 -48
  287. package/dist/x/sveltekit.js +0 -68
  288. /package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals-C80BG-_5.js} +0 -0
  289. /package/dist/{collection-CSzG2j1P.js → collection-CcnIw1qY.js} +0 -0
  290. /package/dist/{nodeinfo/semver.test.d.ts → federation/idempotency.test.d.ts} +0 -0
  291. /package/dist/{runtime/authdocloader.test.d.ts → federation/negotiation.test.d.ts} +0 -0
  292. /package/dist/{runtime/docloader.test.d.ts → federation/webfinger.test.d.ts} +0 -0
  293. /package/dist/{mod-1pDWKvUL.d.ts → mod-1E3W847c.d.ts} +0 -0
  294. /package/dist/{runtime/key.test.d.ts → otel/exporter.test.d.ts} +0 -0
  295. /package/dist/{std__assert-X-_kMxKM.js → std__assert-DWivtrGR.js} +0 -0
  296. /package/dist/{testing → utils}/docloader.test.d.ts +0 -0
  297. /package/dist/{runtime/langstr.test.d.ts → utils/kv-cache.test.d.ts} +0 -0
@@ -0,0 +1,232 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { URLPattern } from "urlpattern-polyfill";
3
+ import { KvKey, KvStore } from "../kv-CtOmTRNc.js";
4
+ import { ExportResultCode } from "@opentelemetry/core";
5
+ import { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base";
6
+
7
+ //#region src/otel/exporter.d.ts
8
+ /**
9
+ * The direction of an activity in the trace.
10
+ *
11
+ * @since 1.10.0
12
+ */
13
+ type ActivityDirection = "inbound" | "outbound";
14
+ /**
15
+ * Signature verification details for an inbound activity.
16
+ *
17
+ * @since 1.10.0
18
+ */
19
+ interface SignatureVerificationDetails {
20
+ /**
21
+ * Whether HTTP Signatures were verified.
22
+ */
23
+ httpSignaturesVerified: boolean;
24
+ /**
25
+ * The key ID used for HTTP signature verification, if available.
26
+ */
27
+ httpSignaturesKeyId?: string;
28
+ /**
29
+ * Whether Linked Data Signatures were verified.
30
+ */
31
+ ldSignaturesVerified: boolean;
32
+ }
33
+ /**
34
+ * A record of an activity captured from a trace span.
35
+ * This interface stores the activity data along with trace context
36
+ * for distributed tracing support.
37
+ *
38
+ * @since 1.10.0
39
+ */
40
+ interface TraceActivityRecord {
41
+ /**
42
+ * The trace ID from OpenTelemetry.
43
+ */
44
+ traceId: string;
45
+ /**
46
+ * The span ID from OpenTelemetry.
47
+ */
48
+ spanId: string;
49
+ /**
50
+ * The parent span ID, if any.
51
+ */
52
+ parentSpanId?: string;
53
+ /**
54
+ * Whether this is an inbound or outbound activity.
55
+ */
56
+ direction: ActivityDirection;
57
+ /**
58
+ * The ActivityPub activity type (e.g., "Create", "Follow", "Like").
59
+ */
60
+ activityType: string;
61
+ /**
62
+ * The activity's ID URL, if present.
63
+ */
64
+ activityId?: string;
65
+ /**
66
+ * The actor ID URL (sender of the activity).
67
+ */
68
+ actorId?: string;
69
+ /**
70
+ * The full JSON representation of the activity.
71
+ */
72
+ activityJson: string;
73
+ /**
74
+ * Whether the activity was verified (for inbound activities).
75
+ */
76
+ verified?: boolean;
77
+ /**
78
+ * Detailed signature verification information (for inbound activities).
79
+ */
80
+ signatureDetails?: SignatureVerificationDetails;
81
+ /**
82
+ * The timestamp when this record was created (ISO 8601 format).
83
+ */
84
+ timestamp: string;
85
+ /**
86
+ * The target inbox URL (for outbound activities).
87
+ */
88
+ inboxUrl?: string;
89
+ }
90
+ /**
91
+ * Summary information about a trace.
92
+ *
93
+ * @since 1.10.0
94
+ */
95
+ interface TraceSummary {
96
+ /**
97
+ * The trace ID.
98
+ */
99
+ traceId: string;
100
+ /**
101
+ * The timestamp of the first activity in the trace.
102
+ */
103
+ timestamp: string;
104
+ /**
105
+ * The number of activities in the trace.
106
+ */
107
+ activityCount: number;
108
+ /**
109
+ * Activity types present in this trace.
110
+ */
111
+ activityTypes: string[];
112
+ }
113
+ /**
114
+ * Options for configuring the {@link FedifySpanExporter}.
115
+ *
116
+ * @since 1.10.0
117
+ */
118
+ interface FedifySpanExporterOptions {
119
+ /**
120
+ * The time-to-live for stored trace data.
121
+ * If not specified, data will be stored indefinitely
122
+ * (or until manually deleted).
123
+ */
124
+ ttl?: Temporal.Duration;
125
+ /**
126
+ * The key prefix for storing trace data in the KvStore.
127
+ * Defaults to `["fedify", "traces"]`.
128
+ */
129
+ keyPrefix?: KvKey;
130
+ }
131
+ /**
132
+ * Options for the {@link FedifySpanExporter.getRecentTraces} method.
133
+ *
134
+ * @since 1.10.0
135
+ */
136
+ interface GetRecentTracesOptions {
137
+ /**
138
+ * Maximum number of traces to return.
139
+ * If not specified, returns all available traces.
140
+ */
141
+ limit?: number;
142
+ }
143
+ /**
144
+ * A SpanExporter that persists ActivityPub activity traces to a
145
+ * {@link KvStore}. This enables distributed tracing across multiple
146
+ * nodes in a Fedify deployment.
147
+ *
148
+ * The exporter captures activity data from OpenTelemetry span events
149
+ * (`activitypub.activity.received` and `activitypub.activity.sent`)
150
+ * and stores them in the KvStore with trace context preserved.
151
+ *
152
+ * @example Basic usage with MemoryKvStore
153
+ * ```typescript ignore
154
+ * import { MemoryKvStore } from "@fedify/fedify";
155
+ * import { FedifySpanExporter } from "@fedify/fedify/otel";
156
+ * import {
157
+ * BasicTracerProvider,
158
+ * SimpleSpanProcessor,
159
+ * } from "@opentelemetry/sdk-trace-base";
160
+ *
161
+ * const kv = new MemoryKvStore();
162
+ * const exporter = new FedifySpanExporter(kv, {
163
+ * ttl: Temporal.Duration.from({ hours: 1 }),
164
+ * });
165
+ *
166
+ * const provider = new BasicTracerProvider({
167
+ * spanProcessors: [new SimpleSpanProcessor(exporter)],
168
+ * });
169
+ * ```
170
+ *
171
+ * @example Querying stored traces
172
+ * ```typescript ignore
173
+ * import { MemoryKvStore } from "@fedify/fedify";
174
+ * import { FedifySpanExporter } from "@fedify/fedify/otel";
175
+ *
176
+ * const kv = new MemoryKvStore();
177
+ * const exporter = new FedifySpanExporter(kv);
178
+ * const traceId = "abc123";
179
+ *
180
+ * // Get all activities for a specific trace
181
+ * const activities = await exporter.getActivitiesByTraceId(traceId);
182
+ *
183
+ * // Get recent traces
184
+ * const recentTraces = await exporter.getRecentTraces({ limit: 100 });
185
+ * ```
186
+ *
187
+ * @since 1.10.0
188
+ */
189
+ declare class FedifySpanExporter implements SpanExporter {
190
+ #private;
191
+ /**
192
+ * Creates a new FedifySpanExporter.
193
+ *
194
+ * @param kv The KvStore to persist trace data to.
195
+ * @param options Configuration options.
196
+ */
197
+ constructor(kv: KvStore, options?: FedifySpanExporterOptions);
198
+ /**
199
+ * Exports spans to the KvStore.
200
+ *
201
+ * @param spans The spans to export.
202
+ * @param resultCallback Callback to invoke with the export result.
203
+ */
204
+ export(spans: ReadableSpan[], resultCallback: (result: {
205
+ code: ExportResultCode;
206
+ }) => void): void;
207
+ /**
208
+ * Gets all activity records for a specific trace ID.
209
+ *
210
+ * @param traceId The trace ID to query.
211
+ * @returns An array of activity records belonging to the trace.
212
+ */
213
+ getActivitiesByTraceId(traceId: string): Promise<TraceActivityRecord[]>;
214
+ /**
215
+ * Gets recent traces with summary information.
216
+ *
217
+ * @param options Options for the query.
218
+ * @returns An array of trace summaries.
219
+ */
220
+ getRecentTraces(options?: GetRecentTracesOptions): Promise<TraceSummary[]>;
221
+ /**
222
+ * Forces the exporter to flush any buffered data.
223
+ * This is a no-op because we write directly to the KvStore without buffering.
224
+ */
225
+ forceFlush(): Promise<void>;
226
+ /**
227
+ * Shuts down the exporter.
228
+ */
229
+ shutdown(): Promise<void>;
230
+ }
231
+ //#endregion
232
+ export { ActivityDirection, FedifySpanExporter, FedifySpanExporterOptions, GetRecentTracesOptions, SignatureVerificationDetails, TraceActivityRecord, TraceSummary };
@@ -0,0 +1,261 @@
1
+
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ import { URLPattern } from "urlpattern-polyfill";
4
+
5
+ import { getLogger } from "@logtape/logtape";
6
+ import { ExportResultCode } from "@opentelemetry/core";
7
+
8
+ //#region src/otel/exporter.ts
9
+ /**
10
+ * A SpanExporter that persists ActivityPub activity traces to a
11
+ * {@link KvStore}. This enables distributed tracing across multiple
12
+ * nodes in a Fedify deployment.
13
+ *
14
+ * The exporter captures activity data from OpenTelemetry span events
15
+ * (`activitypub.activity.received` and `activitypub.activity.sent`)
16
+ * and stores them in the KvStore with trace context preserved.
17
+ *
18
+ * @example Basic usage with MemoryKvStore
19
+ * ```typescript ignore
20
+ * import { MemoryKvStore } from "@fedify/fedify";
21
+ * import { FedifySpanExporter } from "@fedify/fedify/otel";
22
+ * import {
23
+ * BasicTracerProvider,
24
+ * SimpleSpanProcessor,
25
+ * } from "@opentelemetry/sdk-trace-base";
26
+ *
27
+ * const kv = new MemoryKvStore();
28
+ * const exporter = new FedifySpanExporter(kv, {
29
+ * ttl: Temporal.Duration.from({ hours: 1 }),
30
+ * });
31
+ *
32
+ * const provider = new BasicTracerProvider({
33
+ * spanProcessors: [new SimpleSpanProcessor(exporter)],
34
+ * });
35
+ * ```
36
+ *
37
+ * @example Querying stored traces
38
+ * ```typescript ignore
39
+ * import { MemoryKvStore } from "@fedify/fedify";
40
+ * import { FedifySpanExporter } from "@fedify/fedify/otel";
41
+ *
42
+ * const kv = new MemoryKvStore();
43
+ * const exporter = new FedifySpanExporter(kv);
44
+ * const traceId = "abc123";
45
+ *
46
+ * // Get all activities for a specific trace
47
+ * const activities = await exporter.getActivitiesByTraceId(traceId);
48
+ *
49
+ * // Get recent traces
50
+ * const recentTraces = await exporter.getRecentTraces({ limit: 100 });
51
+ * ```
52
+ *
53
+ * @since 1.10.0
54
+ */
55
+ var FedifySpanExporter = class {
56
+ #kv;
57
+ #ttl;
58
+ #keyPrefix;
59
+ /**
60
+ * Creates a new FedifySpanExporter.
61
+ *
62
+ * @param kv The KvStore to persist trace data to.
63
+ * @param options Configuration options.
64
+ */
65
+ constructor(kv, options) {
66
+ this.#kv = kv;
67
+ this.#ttl = options?.ttl;
68
+ this.#keyPrefix = options?.keyPrefix ?? ["fedify", "traces"];
69
+ }
70
+ /**
71
+ * Exports spans to the KvStore.
72
+ *
73
+ * @param spans The spans to export.
74
+ * @param resultCallback Callback to invoke with the export result.
75
+ */
76
+ export(spans, resultCallback) {
77
+ this.#exportAsync(spans).then(() => resultCallback({ code: ExportResultCode.SUCCESS })).catch((error) => {
78
+ getLogger([
79
+ "fedify",
80
+ "otel",
81
+ "exporter"
82
+ ]).error("Failed to export spans to KvStore: {error}", { error });
83
+ resultCallback({ code: ExportResultCode.FAILED });
84
+ });
85
+ }
86
+ async #exportAsync(spans) {
87
+ const storeOperations = [];
88
+ for (const span of spans) {
89
+ const records = this.#extractRecords(span);
90
+ for (const record of records) storeOperations.push(this.#storeRecord(record));
91
+ }
92
+ const results = await Promise.allSettled(storeOperations);
93
+ const rejected = results.filter((r) => r.status === "rejected");
94
+ if (rejected.length > 0) throw new AggregateError(rejected.map((r) => r.reason), "Failed to store one or more trace activity records.");
95
+ }
96
+ #extractRecords(span) {
97
+ const records = [];
98
+ const spanContext = span.spanContext();
99
+ const traceId = spanContext.traceId;
100
+ const spanId = spanContext.spanId;
101
+ const parentSpanId = span.parentSpanContext?.spanId;
102
+ for (const event of span.events) if (event.name === "activitypub.activity.received") {
103
+ const record = this.#extractInboundRecord(event, traceId, spanId, parentSpanId);
104
+ if (record != null) records.push(record);
105
+ } else if (event.name === "activitypub.activity.sent") {
106
+ const record = this.#extractOutboundRecord(event, traceId, spanId, parentSpanId);
107
+ if (record != null) records.push(record);
108
+ }
109
+ return records;
110
+ }
111
+ #extractInboundRecord(event, traceId, spanId, parentSpanId) {
112
+ const attrs = event.attributes;
113
+ if (attrs == null) return null;
114
+ const activityJson = attrs["activitypub.activity.json"];
115
+ if (typeof activityJson !== "string") return null;
116
+ let activityType = "Unknown";
117
+ let activityId;
118
+ let actorId;
119
+ try {
120
+ const activity = JSON.parse(activityJson);
121
+ activityType = activity.type ?? "Unknown";
122
+ activityId = activity.id;
123
+ if (typeof activity.actor === "string") actorId = activity.actor;
124
+ else if (activity.actor != null && typeof activity.actor.id === "string") actorId = activity.actor.id;
125
+ } catch {}
126
+ const verified = attrs["activitypub.activity.verified"];
127
+ const httpSigVerified = attrs["http_signatures.verified"];
128
+ const httpSigKeyId = attrs["http_signatures.key_id"];
129
+ const ldSigVerified = attrs["ld_signatures.verified"];
130
+ let signatureDetails;
131
+ if (typeof httpSigVerified === "boolean" || typeof ldSigVerified === "boolean") signatureDetails = {
132
+ httpSignaturesVerified: httpSigVerified === true,
133
+ httpSignaturesKeyId: typeof httpSigKeyId === "string" && httpSigKeyId !== "" ? httpSigKeyId : void 0,
134
+ ldSignaturesVerified: ldSigVerified === true
135
+ };
136
+ return {
137
+ traceId,
138
+ spanId,
139
+ parentSpanId,
140
+ direction: "inbound",
141
+ activityType,
142
+ activityId,
143
+ actorId,
144
+ activityJson,
145
+ verified: typeof verified === "boolean" ? verified : void 0,
146
+ signatureDetails,
147
+ timestamp: (/* @__PURE__ */ new Date(event.time[0] * 1e3 + event.time[1] / 1e6)).toISOString()
148
+ };
149
+ }
150
+ #extractOutboundRecord(event, traceId, spanId, parentSpanId) {
151
+ const attrs = event.attributes;
152
+ if (attrs == null) return null;
153
+ const activityJson = attrs["activitypub.activity.json"];
154
+ if (typeof activityJson !== "string") return null;
155
+ let activityType = "Unknown";
156
+ let activityId;
157
+ let actorId;
158
+ try {
159
+ const activity = JSON.parse(activityJson);
160
+ activityType = activity.type ?? "Unknown";
161
+ activityId = activity.id;
162
+ if (typeof activity.actor === "string") actorId = activity.actor;
163
+ else if (activity.actor != null && typeof activity.actor.id === "string") actorId = activity.actor.id;
164
+ } catch {}
165
+ const inboxUrl = attrs["activitypub.inbox.url"];
166
+ const explicitActivityId = attrs["activitypub.activity.id"];
167
+ return {
168
+ traceId,
169
+ spanId,
170
+ parentSpanId,
171
+ direction: "outbound",
172
+ activityType,
173
+ activityId: activityId ?? (typeof explicitActivityId === "string" && explicitActivityId !== "" ? explicitActivityId : void 0),
174
+ actorId,
175
+ activityJson,
176
+ timestamp: (/* @__PURE__ */ new Date(event.time[0] * 1e3 + event.time[1] / 1e6)).toISOString(),
177
+ inboxUrl: typeof inboxUrl === "string" ? inboxUrl : void 0
178
+ };
179
+ }
180
+ async #storeRecord(record) {
181
+ const options = this.#ttl != null ? { ttl: this.#ttl } : void 0;
182
+ const key = [
183
+ ...this.#keyPrefix,
184
+ record.traceId,
185
+ record.spanId
186
+ ];
187
+ await this.#kv.set(key, record, options);
188
+ await this.#updateTraceSummary(record, options);
189
+ }
190
+ async #setWithCasRetry(key, transform, options) {
191
+ if (this.#kv.cas != null) for (let attempt = 0; attempt < 3; attempt++) {
192
+ const existing$1 = await this.#kv.get(key);
193
+ const newValue$1 = transform(existing$1);
194
+ if (await this.#kv.cas(key, existing$1, newValue$1, options)) return;
195
+ }
196
+ const existing = await this.#kv.get(key);
197
+ const newValue = transform(existing);
198
+ await this.#kv.set(key, newValue, options);
199
+ }
200
+ async #updateTraceSummary(record, options) {
201
+ const summaryKey = [
202
+ ...this.#keyPrefix,
203
+ "_summaries",
204
+ record.traceId
205
+ ];
206
+ await this.#setWithCasRetry(summaryKey, (existing) => {
207
+ const summary = existing != null ? {
208
+ traceId: existing.traceId,
209
+ timestamp: existing.timestamp,
210
+ activityCount: existing.activityCount,
211
+ activityTypes: [...existing.activityTypes]
212
+ } : {
213
+ traceId: record.traceId,
214
+ timestamp: record.timestamp,
215
+ activityCount: 0,
216
+ activityTypes: []
217
+ };
218
+ summary.activityCount += 1;
219
+ if (!summary.activityTypes.includes(record.activityType)) summary.activityTypes.push(record.activityType);
220
+ return summary;
221
+ }, options);
222
+ }
223
+ /**
224
+ * Gets all activity records for a specific trace ID.
225
+ *
226
+ * @param traceId The trace ID to query.
227
+ * @returns An array of activity records belonging to the trace.
228
+ */
229
+ async getActivitiesByTraceId(traceId) {
230
+ const prefix = [...this.#keyPrefix, traceId];
231
+ const records = [];
232
+ for await (const entry of this.#kv.list(prefix)) records.push(entry.value);
233
+ return records;
234
+ }
235
+ /**
236
+ * Gets recent traces with summary information.
237
+ *
238
+ * @param options Options for the query.
239
+ * @returns An array of trace summaries.
240
+ */
241
+ async getRecentTraces(options) {
242
+ const summaryPrefix = [...this.#keyPrefix, "_summaries"];
243
+ const summaries = [];
244
+ for await (const entry of this.#kv.list(summaryPrefix)) summaries.push(entry.value);
245
+ summaries.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
246
+ if (options?.limit != null) return summaries.slice(0, options.limit);
247
+ return summaries;
248
+ }
249
+ /**
250
+ * Forces the exporter to flush any buffered data.
251
+ * This is a no-op because we write directly to the KvStore without buffering.
252
+ */
253
+ async forceFlush() {}
254
+ /**
255
+ * Shuts down the exporter.
256
+ */
257
+ async shutdown() {}
258
+ };
259
+
260
+ //#endregion
261
+ export { FedifySpanExporter };
@@ -1,9 +1,8 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { DocumentLoader } from "./docloader-CxWcuWqQ.js";
4
- import { Activity, CryptographicKey } from "./vocab-SOE1ifCr.js";
5
- import { Actor } from "./actor-C22bXuuC.js";
3
+ import { Activity, Actor, CryptographicKey } from "@fedify/vocab";
6
4
  import { TracerProvider } from "@opentelemetry/api";
5
+ import { DocumentLoader } from "@fedify/vocab-runtime";
7
6
 
8
7
  //#region src/sig/owner.d.ts
9
8
  /**
@@ -0,0 +1,66 @@
1
+ import { Activity, Actor, CryptographicKey } from "@fedify/vocab";
2
+ import { DocumentLoader } from "@fedify/vocab-runtime";
3
+ import { TracerProvider } from "@opentelemetry/api";
4
+
5
+ //#region src/sig/owner.d.ts
6
+ /**
7
+ * Options for {@link doesActorOwnKey}.
8
+ * @since 0.8.0
9
+ */
10
+ interface DoesActorOwnKeyOptions {
11
+ /**
12
+ * The document loader to use for fetching the actor.
13
+ */
14
+ documentLoader?: DocumentLoader;
15
+ /**
16
+ * The context loader to use for JSON-LD context retrieval.
17
+ */
18
+ contextLoader?: DocumentLoader;
19
+ /**
20
+ * The OpenTelemetry tracer provider to use for tracing. If omitted,
21
+ * the global tracer provider is used.
22
+ * @since 1.3.0
23
+ */
24
+ tracerProvider?: TracerProvider;
25
+ }
26
+ /**
27
+ * Checks if the actor of the given activity owns the specified key.
28
+ * @param activity The activity to check.
29
+ * @param key The public key to check.
30
+ * @param options Options for checking the key ownership.
31
+ * @returns Whether the actor is the owner of the key.
32
+ */
33
+ declare function doesActorOwnKey(activity: Activity, key: CryptographicKey, options: DoesActorOwnKeyOptions): Promise<boolean>;
34
+ /**
35
+ * Options for {@link getKeyOwner}.
36
+ * @since 0.8.0
37
+ */
38
+ interface GetKeyOwnerOptions {
39
+ /**
40
+ * The document loader to use for fetching the key and its owner.
41
+ */
42
+ documentLoader?: DocumentLoader;
43
+ /**
44
+ * The context loader to use for JSON-LD context retrieval.
45
+ */
46
+ contextLoader?: DocumentLoader;
47
+ /**
48
+ * The OpenTelemetry tracer provider to use for tracing. If omitted,
49
+ * the global tracer provider is used.
50
+ * @since 1.3.0
51
+ */
52
+ tracerProvider?: TracerProvider;
53
+ }
54
+ /**
55
+ * Gets the actor that owns the specified key. Returns `null` if the key has no
56
+ * known owner.
57
+ *
58
+ * @param keyId The ID of the key to check, or the key itself.
59
+ * @param options Options for getting the key owner.
60
+ * @returns The actor that owns the key, or `null` if the key has no known
61
+ * owner.
62
+ * @since 0.7.0
63
+ */
64
+ declare function getKeyOwner(keyId: URL | CryptographicKey, options: GetKeyOwnerOptions): Promise<Actor | null>;
65
+ //#endregion
66
+ export { DoesActorOwnKeyOptions, GetKeyOwnerOptions, doesActorOwnKey, getKeyOwner };
@@ -3,9 +3,10 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Object as Object$1, getDocumentLoader } from "./type-B7_rMIU9.js";
7
- import { isActor } from "./actor-DI_YpFlI.js";
8
- import { trace } from "@opentelemetry/api";
6
+ import { deno_default } from "./deno-CGe3r5lB.js";
7
+ import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
8
+ import { getDocumentLoader } from "@fedify/vocab-runtime";
9
+ import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
9
10
 
10
11
  //#region src/sig/owner.ts
11
12
  /**
@@ -16,11 +17,47 @@ import { trace } from "@opentelemetry/api";
16
17
  * @returns Whether the actor is the owner of the key.
17
18
  */
18
19
  async function doesActorOwnKey(activity, key, options) {
19
- if (key.ownerId != null) return key.ownerId.href === activity.actorId?.href;
20
- const actor = await activity.getActor(options);
21
- if (actor == null || !isActor(actor)) return false;
22
- for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) return true;
23
- return false;
20
+ const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
21
+ const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
22
+ return await tracer.startActiveSpan("activitypub.verify_key_ownership", {
23
+ kind: SpanKind.INTERNAL,
24
+ attributes: {
25
+ "activitypub.actor.id": activity.actorId?.href ?? "",
26
+ "activitypub.key.id": key.id?.href ?? ""
27
+ }
28
+ }, async (span) => {
29
+ try {
30
+ if (key.ownerId != null) {
31
+ const owns = key.ownerId.href === activity.actorId?.href;
32
+ span.setAttribute("activitypub.key_ownership.verified", owns);
33
+ span.setAttribute("activitypub.key_ownership.method", "owner_id");
34
+ return owns;
35
+ }
36
+ const actor = await activity.getActor(options);
37
+ if (actor == null || !isActor(actor)) {
38
+ span.setAttribute("activitypub.key_ownership.verified", false);
39
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
40
+ return false;
41
+ }
42
+ for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) {
43
+ span.setAttribute("activitypub.key_ownership.verified", true);
44
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
45
+ return true;
46
+ }
47
+ span.setAttribute("activitypub.key_ownership.verified", false);
48
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
49
+ return false;
50
+ } catch (error) {
51
+ span.recordException(error);
52
+ span.setStatus({
53
+ code: SpanStatusCode.ERROR,
54
+ message: String(error)
55
+ });
56
+ throw error;
57
+ } finally {
58
+ span.end();
59
+ }
60
+ });
24
61
  }
25
62
  /**
26
63
  * Gets the actor that owns the specified key. Returns `null` if the key has no