@fedify/fedify 2.0.0-dev.1961 → 2.0.0-dev.211

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 (266) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +66 -36
  3. package/dist/{builder-BrqBKkVi.js → builder-CBUaUcr5.js} +5 -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-Bns6uTJq.js +109 -0
  13. package/dist/{context-V-XS2_6O.d.ts → context-C7vzWilY.d.ts} +63 -65
  14. package/dist/{context-PxGADCsD.d.cts → context-CrB9RFy5.d.cts} +63 -65
  15. package/dist/deno-Ldk6cZ5y.js +117 -0
  16. package/dist/{testing-DpRy1YTU.js → dist-B5f6a8Tt.js} +90 -110
  17. package/dist/{docloader-HB61Uc88.js → docloader-CX_8i5G9.js} +3 -3
  18. package/dist/{esm-DaZiDvFW.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 +110 -22
  22. package/dist/federation/idempotency.test.js +23 -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 +95 -93
  27. package/dist/federation/mod.cjs +8 -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 +5 -6
  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 +51 -9
  36. package/dist/{webfinger/handler.test.js → federation/webfinger.test.js} +24 -22
  37. package/dist/{federation-CRpdnOMS.cjs → federation-B431K2gm.cjs} +22 -0
  38. package/dist/{federation-jcR8-ZxP.js → federation-BbZwNNWj.js} +28 -6
  39. package/dist/{http-M8k5mKc0.d.cts → http-ClB3pLcL.d.cts} +1 -1
  40. package/dist/{http-CUsGQiwU.js → http-CnZ1IHUS.js} +119 -9
  41. package/dist/{http-BbO0ejuk.d.ts → http-DLBDPal9.d.ts} +1 -1
  42. package/dist/{http-B2bao4EB.js → http-DNpKjQw7.js} +3 -2
  43. package/dist/{http-BxgYWxTY.cjs → http-dzRhLC1t.cjs} +132 -16
  44. package/dist/{inbox-CAojlSWc.js → inbox-DR-Gk02p.js} +2 -1
  45. package/dist/{key-Dz-KWCap.js → key-C1rxalIW.js} +3 -3
  46. package/dist/{keycache-Czcf33al.js → keycache-DRxpZ5r9.js} +1 -1
  47. package/dist/{keys-BN4nelft.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-DN9pfMBe.js → kv-cache-BEeqyGER.js} +14 -1
  52. package/dist/{kv-cache-5j5Pb-V6.cjs → kv-cache-BlS1sett.cjs} +2 -2
  53. package/dist/{kv-cache-Bq6kUUoG.js → kv-cache-DpIq7Isv.js} +2 -2
  54. package/dist/{ld-CEJHYq8u.js → ld-Cm6SNnYj.js} +4 -3
  55. package/dist/middleware-BJ396MAL.cjs +12 -0
  56. package/dist/{middleware-DW3rJHWy.cjs → middleware-CBBhOrXl.cjs} +210 -194
  57. package/dist/middleware-CRk4rARo.js +12 -0
  58. package/dist/middleware-DaemJ_4r.js +26 -0
  59. package/dist/{middleware-DgrceAHB.js → middleware-DmcjHVg8.js} +162 -165
  60. package/dist/{middleware-Df9OWALM.js → middleware-JPuzpoIQ.js} +164 -154
  61. package/dist/{mod-DMpuiKXi.d.cts → mod-0p9zUdzg.d.cts} +6 -6
  62. package/dist/mod-0qnPv4EC.d.cts +62 -0
  63. package/dist/{mod-DgxG-byT.d.cts → mod-BrS8tiad.d.cts} +2 -2
  64. package/dist/mod-C3SOvTD1.d.ts +64 -0
  65. package/dist/{mod-BoRKfJPE.d.cts → mod-D6pS5_xJ.d.cts} +4 -4
  66. package/dist/{mod-D5Z2tISD.d.ts → mod-jOa7W503.d.ts} +2 -2
  67. package/dist/{mod-Cdo6SYlJ.d.ts → mod-waqu-BL_.d.ts} +4 -4
  68. package/dist/{mod-aAE2wOWV.d.ts → mod-xc20HhMD.d.ts} +6 -6
  69. package/dist/mod.cjs +11 -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-JwI-WzF-.js → owner-D-ZwLwaI.js} +44 -8
  88. package/dist/{proof-Dhqndmfg.js → proof-B-5l6HNZ.js} +3 -2
  89. package/dist/{proof-CObJuclI.cjs → proof-C2oMTHcU.cjs} +63 -28
  90. package/dist/{proof-xH0V1mdD.js → proof-lN5nVUla.js} +46 -11
  91. package/dist/router-D9eI0s4b.js +118 -0
  92. package/dist/{send-1o7D-GGL.js → send-D0AlkVEU.js} +9 -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 +29 -6
  101. package/dist/sig/proof.test.js +6 -6
  102. package/dist/testing/mod.d.ts +70 -6999
  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/package.json +24 -35
  116. package/dist/actor-DhgrrgXz.cjs +0 -42079
  117. package/dist/actor-DiKHxw_H.js +0 -41647
  118. package/dist/actor-DqFajh9s.d.ts +0 -130
  119. package/dist/actor-Kqyoic-M.js +0 -146
  120. package/dist/actor-f2NtjyCg.d.cts +0 -128
  121. package/dist/fixtures/activitypub.academy/users/brauca_darradiul.json +0 -83
  122. package/dist/fixtures/example.com/announce.json +0 -6
  123. package/dist/fixtures/example.com/collection.json +0 -19
  124. package/dist/fixtures/example.com/create.json +0 -6
  125. package/dist/fixtures/example.com/cross-origin-actor.json +0 -6
  126. package/dist/fixtures/example.com/hong-gildong.json +0 -11
  127. package/dist/fixtures/example.com/invite.json +0 -7
  128. package/dist/fixtures/example.com/key.json +0 -7
  129. package/dist/fixtures/example.com/key2.json +0 -6
  130. package/dist/fixtures/example.com/object.json +0 -6
  131. package/dist/fixtures/example.com/orderedcollectionpage.json +0 -24
  132. package/dist/fixtures/example.com/paged/a.json +0 -13
  133. package/dist/fixtures/example.com/paged/b.json +0 -16
  134. package/dist/fixtures/example.com/paged-collection.json +0 -6
  135. package/dist/fixtures/example.com/person.json +0 -22
  136. package/dist/fixtures/example.com/person2.json +0 -40
  137. package/dist/fixtures/example.com/test.json +0 -5
  138. package/dist/fixtures/example.com/users/handle.json +0 -16
  139. package/dist/fixtures/example.com/wrong-type.json +0 -3
  140. package/dist/fixtures/media.example.com/avatars/test-avatar.jpg.json +0 -6
  141. package/dist/fixtures/oeee.cafe/ap/users/3609fd4e-d51d-4db8-9f04-4189815864dd.json +0 -24
  142. package/dist/fixtures/remote.domain/users/bob.json +0 -20
  143. package/dist/fixtures/server.example/users/alice.json +0 -20
  144. package/dist/fixtures/w3id.org/identity/v1.json +0 -152
  145. package/dist/fixtures/w3id.org/security/data-integrity/v1.json +0 -74
  146. package/dist/fixtures/w3id.org/security/multikey/v1.json +0 -35
  147. package/dist/fixtures/w3id.org/security/v1.json +0 -50
  148. package/dist/fixtures/wizard.casa/users/hongminhee.json +0 -69
  149. package/dist/fixtures/www.w3.org/ns/activitystreams.json +0 -379
  150. package/dist/fixtures/www.w3.org/ns/did/v1.json +0 -58
  151. package/dist/lookup-D8hvtZHY.js +0 -42178
  152. package/dist/lookup-_Hap2IXS.cjs +0 -265
  153. package/dist/lookup-gMu_9ZKY.js +0 -253
  154. package/dist/middleware-19QFZj7b.js +0 -26
  155. package/dist/middleware-BbbcXY4w.cjs +0 -15
  156. package/dist/middleware-CSTK543z.js +0 -15
  157. package/dist/mod-BlVovdcy.d.ts +0 -309
  158. package/dist/mod-BxRCHTz-.d.cts +0 -307
  159. package/dist/mod-C58MZ7Wx.d.cts +0 -113
  160. package/dist/mod-CcDPcLJW.d.cts +0 -1
  161. package/dist/mod-Ds0mpFZU.d.ts +0 -115
  162. package/dist/mod-bjzj5QIb.d.ts +0 -2
  163. package/dist/src/vocab/accept.yaml +0 -15
  164. package/dist/src/vocab/activity.yaml +0 -98
  165. package/dist/src/vocab/add.yaml +0 -16
  166. package/dist/src/vocab/announce.yaml +0 -30
  167. package/dist/src/vocab/application.yaml +0 -324
  168. package/dist/src/vocab/arrive.yaml +0 -15
  169. package/dist/src/vocab/article.yaml +0 -46
  170. package/dist/src/vocab/audio.yaml +0 -11
  171. package/dist/src/vocab/block.yaml +0 -16
  172. package/dist/src/vocab/chatmessage.yaml +0 -50
  173. package/dist/src/vocab/collection.yaml +0 -154
  174. package/dist/src/vocab/collectionpage.yaml +0 -55
  175. package/dist/src/vocab/create.yaml +0 -28
  176. package/dist/src/vocab/dataintegrityproof.yaml +0 -56
  177. package/dist/src/vocab/delete.yaml +0 -27
  178. package/dist/src/vocab/didservice.yaml +0 -22
  179. package/dist/src/vocab/dislike.yaml +0 -14
  180. package/dist/src/vocab/document.yaml +0 -31
  181. package/dist/src/vocab/emoji.yaml +0 -12
  182. package/dist/src/vocab/emojireact.yaml +0 -17
  183. package/dist/src/vocab/endpoints.yaml +0 -85
  184. package/dist/src/vocab/event.yaml +0 -11
  185. package/dist/src/vocab/export.yaml +0 -9
  186. package/dist/src/vocab/flag.yaml +0 -15
  187. package/dist/src/vocab/follow.yaml +0 -19
  188. package/dist/src/vocab/group.yaml +0 -324
  189. package/dist/src/vocab/hashtag.yaml +0 -14
  190. package/dist/src/vocab/ignore.yaml +0 -14
  191. package/dist/src/vocab/image.yaml +0 -9
  192. package/dist/src/vocab/intransitiveactivity.yaml +0 -15
  193. package/dist/src/vocab/invite.yaml +0 -14
  194. package/dist/src/vocab/join.yaml +0 -14
  195. package/dist/src/vocab/key.yaml +0 -28
  196. package/dist/src/vocab/leave.yaml +0 -14
  197. package/dist/src/vocab/like.yaml +0 -16
  198. package/dist/src/vocab/link.yaml +0 -101
  199. package/dist/src/vocab/listen.yaml +0 -12
  200. package/dist/src/vocab/mention.yaml +0 -9
  201. package/dist/src/vocab/move.yaml +0 -15
  202. package/dist/src/vocab/multikey.yaml +0 -36
  203. package/dist/src/vocab/note.yaml +0 -48
  204. package/dist/src/vocab/object.yaml +0 -404
  205. package/dist/src/vocab/offer.yaml +0 -15
  206. package/dist/src/vocab/orderedcollection.yaml +0 -39
  207. package/dist/src/vocab/orderedcollectionpage.yaml +0 -50
  208. package/dist/src/vocab/organization.yaml +0 -324
  209. package/dist/src/vocab/page.yaml +0 -11
  210. package/dist/src/vocab/person.yaml +0 -324
  211. package/dist/src/vocab/place.yaml +0 -75
  212. package/dist/src/vocab/profile.yaml +0 -26
  213. package/dist/src/vocab/propertyvalue.yaml +0 -32
  214. package/dist/src/vocab/question.yaml +0 -103
  215. package/dist/src/vocab/read.yaml +0 -13
  216. package/dist/src/vocab/reject.yaml +0 -14
  217. package/dist/src/vocab/relationship.yaml +0 -52
  218. package/dist/src/vocab/remove.yaml +0 -14
  219. package/dist/src/vocab/service.yaml +0 -324
  220. package/dist/src/vocab/source.yaml +0 -26
  221. package/dist/src/vocab/tentativeaccept.yaml +0 -14
  222. package/dist/src/vocab/tentativereject.yaml +0 -14
  223. package/dist/src/vocab/tombstone.yaml +0 -24
  224. package/dist/src/vocab/travel.yaml +0 -16
  225. package/dist/src/vocab/undo.yaml +0 -26
  226. package/dist/src/vocab/update.yaml +0 -58
  227. package/dist/src/vocab/video.yaml +0 -11
  228. package/dist/src/vocab/view.yaml +0 -13
  229. package/dist/testing/docloader.test.js +0 -22
  230. package/dist/vocab/actor.test.js +0 -5963
  231. package/dist/vocab/lookup.test.d.ts +0 -3
  232. package/dist/vocab/lookup.test.js +0 -454
  233. package/dist/vocab/mod.cjs +0 -86
  234. package/dist/vocab/mod.d.cts +0 -4
  235. package/dist/vocab/mod.d.ts +0 -6
  236. package/dist/vocab/mod.js +0 -9
  237. package/dist/vocab/type.test.d.ts +0 -3
  238. package/dist/vocab/type.test.js +0 -24
  239. package/dist/vocab/vocab.test.d.ts +0 -3
  240. package/dist/vocab/vocab.test.js +0 -9397
  241. package/dist/vocab-BCWe1Ih5.d.ts +0 -14905
  242. package/dist/vocab-CAwj263k.js +0 -255
  243. package/dist/vocab-CeDBzu-f.d.cts +0 -14903
  244. package/dist/vocab-DgHGCFcw.cjs +0 -291
  245. package/dist/webfinger/handler.test.d.ts +0 -3
  246. package/dist/webfinger/lookup.test.d.ts +0 -3
  247. package/dist/webfinger/lookup.test.js +0 -193
  248. package/dist/webfinger/mod.cjs +0 -8
  249. package/dist/webfinger/mod.d.cts +0 -2
  250. package/dist/webfinger/mod.d.ts +0 -4
  251. package/dist/webfinger/mod.js +0 -8
  252. package/dist/webfinger-C72Y8lrh.js +0 -4
  253. package/dist/webfinger-vAtLmxOF.cjs +0 -4
  254. /package/dist/{collection-BzWsN9pB.js → collection-CcnIw1qY.js} +0 -0
  255. /package/dist/{testing/docloader.test.d.ts → federation/webfinger.test.d.ts} +0 -0
  256. /package/dist/{mod-CVgZgliM.d.ts → mod-1E3W847c.d.ts} +0 -0
  257. /package/dist/{mod-B-hUPT2N.d.cts → mod-C81L6_lQ.d.cts} +0 -0
  258. /package/dist/{negotiation-C4nFufNk.js → negotiation-5NPJL6zp.js} +0 -0
  259. /package/dist/{nodeinfo-BnthBobC.js → nodeinfo-BlLsRSiT.js} +0 -0
  260. /package/dist/{nodeinfo-CdN0rEnZ.cjs → nodeinfo-DuMYTpbZ.cjs} +0 -0
  261. /package/dist/{vocab/actor.test.d.ts → otel/exporter.test.d.ts} +0 -0
  262. /package/dist/{retry-CfF8Gn4d.js → retry-D4GJ670a.js} +0 -0
  263. /package/dist/{sig-C34-oHBl.js → sig-CwuONEzF.js} +0 -0
  264. /package/dist/{sig-YYj5tCnr.cjs → sig-DeXX2xnj.cjs} +0 -0
  265. /package/dist/{utils-DyRU1gdZ.cjs → utils-Db0ZmjcD.cjs} +0 -0
  266. /package/dist/{utils-D-Va7aXC.js → utils-Wranxuoe.js} +0 -0
@@ -0,0 +1,255 @@
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 activityCount = existing != null ? existing.activityCount + 1 : 1;
208
+ const activityTypes = existing != null ? existing.activityTypes.includes(record.activityType) ? existing.activityTypes : [...existing.activityTypes, record.activityType] : [record.activityType];
209
+ return {
210
+ traceId: existing?.traceId ?? record.traceId,
211
+ timestamp: existing?.timestamp ?? record.timestamp,
212
+ activityCount,
213
+ activityTypes
214
+ };
215
+ }, options);
216
+ }
217
+ /**
218
+ * Gets all activity records for a specific trace ID.
219
+ *
220
+ * @param traceId The trace ID to query.
221
+ * @returns An array of activity records belonging to the trace.
222
+ */
223
+ async getActivitiesByTraceId(traceId) {
224
+ const prefix = [...this.#keyPrefix, traceId];
225
+ const records = [];
226
+ for await (const entry of this.#kv.list(prefix)) records.push(entry.value);
227
+ return records;
228
+ }
229
+ /**
230
+ * Gets recent traces with summary information.
231
+ *
232
+ * @param options Options for the query.
233
+ * @returns An array of trace summaries.
234
+ */
235
+ async getRecentTraces(options) {
236
+ const summaryPrefix = [...this.#keyPrefix, "_summaries"];
237
+ const summaries = [];
238
+ for await (const entry of this.#kv.list(summaryPrefix)) summaries.push(entry.value);
239
+ summaries.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
240
+ if (options?.limit != null) return summaries.slice(0, options.limit);
241
+ return summaries;
242
+ }
243
+ /**
244
+ * Forces the exporter to flush any buffered data.
245
+ * This is a no-op because we write directly to the KvStore without buffering.
246
+ */
247
+ async forceFlush() {}
248
+ /**
249
+ * Shuts down the exporter.
250
+ */
251
+ async shutdown() {}
252
+ };
253
+
254
+ //#endregion
255
+ export { FedifySpanExporter };
@@ -1,7 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { Activity, CryptographicKey } from "./vocab-BCWe1Ih5.js";
4
- import { Actor } from "./actor-DqFajh9s.js";
3
+ import { Activity, Actor, CryptographicKey } from "@fedify/vocab";
5
4
  import { TracerProvider } from "@opentelemetry/api";
6
5
  import { DocumentLoader } from "@fedify/vocab-runtime";
7
6
 
@@ -1,5 +1,4 @@
1
- import { Activity, CryptographicKey } from "./vocab-CeDBzu-f.cjs";
2
- import { Actor } from "./actor-f2NtjyCg.cjs";
1
+ import { Activity, Actor, CryptographicKey } from "@fedify/vocab";
3
2
  import { DocumentLoader } from "@fedify/vocab-runtime";
4
3
  import { TracerProvider } from "@opentelemetry/api";
5
4
 
@@ -3,10 +3,10 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { CryptographicKey, Object as Object$1 } from "./lookup-D8hvtZHY.js";
7
- import { isActor } from "./actor-Kqyoic-M.js";
6
+ import { deno_default } from "./deno-Ldk6cZ5y.js";
7
+ import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
8
8
  import { getDocumentLoader } from "@fedify/vocab-runtime";
9
- import { trace } from "@opentelemetry/api";
9
+ import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
10
10
 
11
11
  //#region src/sig/owner.ts
12
12
  /**
@@ -17,11 +17,47 @@ import { trace } from "@opentelemetry/api";
17
17
  * @returns Whether the actor is the owner of the key.
18
18
  */
19
19
  async function doesActorOwnKey(activity, key, options) {
20
- if (key.ownerId != null) return key.ownerId.href === activity.actorId?.href;
21
- const actor = await activity.getActor(options);
22
- if (actor == null || !isActor(actor)) return false;
23
- for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) return true;
24
- 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
+ });
25
61
  }
26
62
  /**
27
63
  * Gets the actor that owns the specified key. Returns `null` if the key has no
@@ -3,9 +3,10 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { Activity, DataIntegrityProof, Multikey, deno_default, getTypeId } from "./lookup-D8hvtZHY.js";
7
- import { fetchKey, validateCryptoKey } from "./key-Dz-KWCap.js";
6
+ import { deno_default } from "./deno-Ldk6cZ5y.js";
7
+ import { fetchKey, validateCryptoKey } from "./key-C1rxalIW.js";
8
8
  import { getLogger } from "@logtape/logtape";
9
+ import { Activity, DataIntegrityProof, Multikey, getTypeId } from "@fedify/vocab";
9
10
  import { SpanStatusCode, trace } from "@opentelemetry/api";
10
11
  import { encodeHex } from "byte-encodings/hex";
11
12
  import serialize from "json-canon";
@@ -3,15 +3,14 @@
3
3
  const { URLPattern } = require("urlpattern-polyfill");
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
- const require_lookup = require('./lookup-_Hap2IXS.cjs');
7
- const require_actor = require('./actor-DhgrrgXz.cjs');
8
- const require_http = require('./http-BxgYWxTY.cjs');
6
+ const require_http = require('./http-dzRhLC1t.cjs');
9
7
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
8
+ const __fedify_vocab = require_chunk.__toESM(require("@fedify/vocab"));
10
9
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
11
- const jsonld = require_chunk.__toESM(require("jsonld"));
12
- const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
13
10
  const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
14
11
  const byte_encodings_base64 = require_chunk.__toESM(require("byte-encodings/base64"));
12
+ const __fedify_vocab_runtime = require_chunk.__toESM(require("@fedify/vocab-runtime"));
13
+ const jsonld = require_chunk.__toESM(require("jsonld"));
15
14
  const json_canon = require_chunk.__toESM(require("json-canon"));
16
15
 
17
16
  //#region src/sig/ld.ts
@@ -82,7 +81,7 @@ async function createSignature(jsonLd, privateKey, keyId, { contextLoader, creat
82
81
  */
83
82
  async function signJsonLd(jsonLd, privateKey, keyId, options) {
84
83
  const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
85
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
84
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
86
85
  return await tracer.startActiveSpan("ld_signatures.sign", { attributes: { "ld_signatures.key_id": keyId.href } }, async (span) => {
87
86
  try {
88
87
  const signature = await createSignature(jsonLd, privateKey, keyId, options);
@@ -151,7 +150,7 @@ async function verifySignature(jsonLd, options = {}) {
151
150
  });
152
151
  return null;
153
152
  }
154
- const { key, cached } = await require_http.fetchKey(new URL(sig.creator), require_actor.CryptographicKey, options);
153
+ const { key, cached } = await require_http.fetchKey(new URL(sig.creator), __fedify_vocab.CryptographicKey, options);
155
154
  if (key == null) return null;
156
155
  const sigOpts = {
157
156
  ...sig,
@@ -192,7 +191,7 @@ async function verifySignature(jsonLd, options = {}) {
192
191
  keyId: sig.creator,
193
192
  ...sig
194
193
  });
195
- const { key: key$1 } = await require_http.fetchKey(new URL(sig.creator), require_actor.CryptographicKey, {
194
+ const { key: key$1 } = await require_http.fetchKey(new URL(sig.creator), __fedify_vocab.CryptographicKey, {
196
195
  ...options,
197
196
  keyCache: {
198
197
  get: () => Promise.resolve(void 0),
@@ -221,19 +220,19 @@ async function verifySignature(jsonLd, options = {}) {
221
220
  */
222
221
  async function verifyJsonLd(jsonLd, options = {}) {
223
222
  const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
224
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
223
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
225
224
  return await tracer.startActiveSpan("ld_signatures.verify", async (span) => {
226
225
  try {
227
- const object = await require_actor.Object.fromJsonLd(jsonLd, options);
226
+ const object = await __fedify_vocab.Object.fromJsonLd(jsonLd, options);
228
227
  if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
229
- span.setAttribute("activitypub.object.type", require_actor.getTypeId(object).href);
228
+ span.setAttribute("activitypub.object.type", (0, __fedify_vocab.getTypeId)(object).href);
230
229
  if (typeof jsonLd === "object" && jsonLd != null && "signature" in jsonLd && typeof jsonLd.signature === "object" && jsonLd.signature != null) {
231
230
  if ("creator" in jsonLd.signature && typeof jsonLd.signature.creator === "string") span.setAttribute("ld_signatures.key_id", jsonLd.signature.creator);
232
231
  if ("signatureValue" in jsonLd.signature && typeof jsonLd.signature.signatureValue === "string") span.setAttribute("ld_signatures.signature", jsonLd.signature.signatureValue);
233
232
  if ("type" in jsonLd.signature && typeof jsonLd.signature.type === "string") span.setAttribute("ld_signatures.type", jsonLd.signature.type);
234
233
  }
235
234
  const attributions = new Set(object.attributionIds.map((uri) => uri.href));
236
- if (object instanceof require_actor.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
235
+ if (object instanceof __fedify_vocab.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
237
236
  const key = await verifySignature(jsonLd, options);
238
237
  if (key == null) return false;
239
238
  if (key.ownerId == null) {
@@ -277,11 +276,47 @@ async function hashJsonLd(jsonLd, contextLoader) {
277
276
  * @returns Whether the actor is the owner of the key.
278
277
  */
279
278
  async function doesActorOwnKey(activity, key, options) {
280
- if (key.ownerId != null) return key.ownerId.href === activity.actorId?.href;
281
- const actor = await activity.getActor(options);
282
- if (actor == null || !require_actor.isActor(actor)) return false;
283
- for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) return true;
284
- return false;
279
+ const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
280
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
281
+ return await tracer.startActiveSpan("activitypub.verify_key_ownership", {
282
+ kind: __opentelemetry_api.SpanKind.INTERNAL,
283
+ attributes: {
284
+ "activitypub.actor.id": activity.actorId?.href ?? "",
285
+ "activitypub.key.id": key.id?.href ?? ""
286
+ }
287
+ }, async (span) => {
288
+ try {
289
+ if (key.ownerId != null) {
290
+ const owns = key.ownerId.href === activity.actorId?.href;
291
+ span.setAttribute("activitypub.key_ownership.verified", owns);
292
+ span.setAttribute("activitypub.key_ownership.method", "owner_id");
293
+ return owns;
294
+ }
295
+ const actor = await activity.getActor(options);
296
+ if (actor == null || !(0, __fedify_vocab.isActor)(actor)) {
297
+ span.setAttribute("activitypub.key_ownership.verified", false);
298
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
299
+ return false;
300
+ }
301
+ for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) {
302
+ span.setAttribute("activitypub.key_ownership.verified", true);
303
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
304
+ return true;
305
+ }
306
+ span.setAttribute("activitypub.key_ownership.verified", false);
307
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
308
+ return false;
309
+ } catch (error) {
310
+ span.recordException(error);
311
+ span.setStatus({
312
+ code: __opentelemetry_api.SpanStatusCode.ERROR,
313
+ message: String(error)
314
+ });
315
+ throw error;
316
+ } finally {
317
+ span.end();
318
+ }
319
+ });
285
320
  }
286
321
  /**
287
322
  * Gets the actor that owns the specified key. Returns `null` if the key has no
@@ -298,7 +333,7 @@ async function getKeyOwner(keyId, options) {
298
333
  const documentLoader = options.documentLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)();
299
334
  const contextLoader = options.contextLoader ?? (0, __fedify_vocab_runtime.getDocumentLoader)();
300
335
  let object;
301
- if (keyId instanceof require_actor.CryptographicKey) {
336
+ if (keyId instanceof __fedify_vocab.CryptographicKey) {
302
337
  object = keyId;
303
338
  if (object.id == null) return null;
304
339
  keyId = object.id;
@@ -311,7 +346,7 @@ async function getKeyOwner(keyId, options) {
311
346
  return null;
312
347
  }
313
348
  try {
314
- object = await require_actor.Object.fromJsonLd(keyDoc, {
349
+ object = await __fedify_vocab.Object.fromJsonLd(keyDoc, {
315
350
  documentLoader,
316
351
  contextLoader,
317
352
  tracerProvider
@@ -319,7 +354,7 @@ async function getKeyOwner(keyId, options) {
319
354
  } catch (e) {
320
355
  if (!(e instanceof TypeError)) throw e;
321
356
  try {
322
- object = await require_actor.CryptographicKey.fromJsonLd(keyDoc, {
357
+ object = await __fedify_vocab.CryptographicKey.fromJsonLd(keyDoc, {
323
358
  documentLoader,
324
359
  contextLoader,
325
360
  tracerProvider
@@ -331,14 +366,14 @@ async function getKeyOwner(keyId, options) {
331
366
  }
332
367
  }
333
368
  let owner = null;
334
- if (object instanceof require_actor.CryptographicKey) {
369
+ if (object instanceof __fedify_vocab.CryptographicKey) {
335
370
  if (object.ownerId == null) return null;
336
371
  owner = await object.getOwner({
337
372
  documentLoader,
338
373
  contextLoader,
339
374
  tracerProvider
340
375
  });
341
- } else if (require_actor.isActor(object)) owner = object;
376
+ } else if ((0, __fedify_vocab.isActor)(object)) owner = object;
342
377
  else return null;
343
378
  if (owner == null) return null;
344
379
  for (const kid of owner.publicKeyIds) if (kid.href === keyId.href) return owner;
@@ -391,7 +426,7 @@ async function createProof(object, privateKey, keyId, { contextLoader, context,
391
426
  digest.set(new Uint8Array(proofDigest), 0);
392
427
  digest.set(new Uint8Array(msgDigest), proofDigest.byteLength);
393
428
  const sig = await crypto.subtle.sign("Ed25519", privateKey, digest);
394
- return new require_actor.DataIntegrityProof({
429
+ return new __fedify_vocab.DataIntegrityProof({
395
430
  cryptosuite: "eddsa-jcs-2022",
396
431
  verificationMethod: keyId,
397
432
  proofPurpose: "assertionMethod",
@@ -411,8 +446,8 @@ async function createProof(object, privateKey, keyId, { contextLoader, context,
411
446
  */
412
447
  async function signObject(object, privateKey, keyId, options = {}) {
413
448
  const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
414
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
415
- return await tracer.startActiveSpan("object_integrity_proofs.sign", { attributes: { "activitypub.object.type": require_actor.getTypeId(object).href } }, async (span) => {
449
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
450
+ return await tracer.startActiveSpan("object_integrity_proofs.sign", { attributes: { "activitypub.object.type": (0, __fedify_vocab.getTypeId)(object).href } }, async (span) => {
416
451
  try {
417
452
  if (object.id != null) span.setAttribute("activitypub.object.id", object.id.href);
418
453
  const existingProofs = [];
@@ -447,7 +482,7 @@ async function signObject(object, privateKey, keyId, options = {}) {
447
482
  */
448
483
  async function verifyProof(jsonLd, proof, options = {}) {
449
484
  const tracerProvider = options.tracerProvider ?? __opentelemetry_api.trace.getTracerProvider();
450
- const tracer = tracerProvider.getTracer(require_lookup.deno_default.name, require_lookup.deno_default.version);
485
+ const tracer = tracerProvider.getTracer(require_http.deno_default.name, require_http.deno_default.version);
451
486
  return await tracer.startActiveSpan("object_integrity_proofs.verify", async (span) => {
452
487
  if (span.isRecording()) {
453
488
  if (proof.cryptosuite != null) span.setAttribute("object_integrity_proofs.cryptosuite", proof.cryptosuite);
@@ -471,7 +506,7 @@ async function verifyProof(jsonLd, proof, options = {}) {
471
506
  }
472
507
  async function verifyProofInternal(jsonLd, proof, options) {
473
508
  if (typeof jsonLd !== "object" || proof.cryptosuite !== "eddsa-jcs-2022" || proof.verificationMethodId == null || proof.proofPurpose !== "assertionMethod" || proof.proofValue == null || proof.created == null) return null;
474
- const publicKeyPromise = require_http.fetchKey(proof.verificationMethodId, require_actor.Multikey, options);
509
+ const publicKeyPromise = require_http.fetchKey(proof.verificationMethodId, __fedify_vocab.Multikey, options);
475
510
  const proofConfig = {
476
511
  "@context": jsonLd["@context"],
477
512
  type: "DataIntegrityProof",
@@ -576,7 +611,7 @@ async function verifyObject(cls, jsonLd, options = {}) {
576
611
  ]);
577
612
  const object = await cls.fromJsonLd(jsonLd, options);
578
613
  const attributions = new Set(object.attributionIds.map((uri) => uri.href));
579
- if (object instanceof require_actor.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
614
+ if (object instanceof __fedify_vocab.Activity) for (const uri of object.actorIds) attributions.add(uri.href);
580
615
  for await (const proof of object.getProofs(options)) {
581
616
  const key = await verifyProof(jsonLd, proof, options);
582
617
  if (key === null) return null;
@@ -2,15 +2,14 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
- import { deno_default } from "./lookup-gMu_9ZKY.js";
6
- import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, getTypeId, isActor } from "./actor-DiKHxw_H.js";
7
- import { fetchKey, validateCryptoKey } from "./http-CUsGQiwU.js";
5
+ import { deno_default, fetchKey, validateCryptoKey } from "./http-CnZ1IHUS.js";
8
6
  import { getLogger } from "@logtape/logtape";
9
- import { SpanStatusCode, trace } from "@opentelemetry/api";
10
- import jsonld from "jsonld";
11
- import { getDocumentLoader } from "@fedify/vocab-runtime";
7
+ import { Activity, CryptographicKey, DataIntegrityProof, Multikey, Object as Object$1, getTypeId, isActor } from "@fedify/vocab";
8
+ import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
12
9
  import { encodeHex } from "byte-encodings/hex";
13
10
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
11
+ import { getDocumentLoader } from "@fedify/vocab-runtime";
12
+ import jsonld from "jsonld";
14
13
  import serialize from "json-canon";
15
14
 
16
15
  //#region src/sig/ld.ts
@@ -276,11 +275,47 @@ async function hashJsonLd(jsonLd, contextLoader) {
276
275
  * @returns Whether the actor is the owner of the key.
277
276
  */
278
277
  async function doesActorOwnKey(activity, key, options) {
279
- if (key.ownerId != null) return key.ownerId.href === activity.actorId?.href;
280
- const actor = await activity.getActor(options);
281
- if (actor == null || !isActor(actor)) return false;
282
- for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) return true;
283
- return false;
278
+ const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
279
+ const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
280
+ return await tracer.startActiveSpan("activitypub.verify_key_ownership", {
281
+ kind: SpanKind.INTERNAL,
282
+ attributes: {
283
+ "activitypub.actor.id": activity.actorId?.href ?? "",
284
+ "activitypub.key.id": key.id?.href ?? ""
285
+ }
286
+ }, async (span) => {
287
+ try {
288
+ if (key.ownerId != null) {
289
+ const owns = key.ownerId.href === activity.actorId?.href;
290
+ span.setAttribute("activitypub.key_ownership.verified", owns);
291
+ span.setAttribute("activitypub.key_ownership.method", "owner_id");
292
+ return owns;
293
+ }
294
+ const actor = await activity.getActor(options);
295
+ if (actor == null || !isActor(actor)) {
296
+ span.setAttribute("activitypub.key_ownership.verified", false);
297
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
298
+ return false;
299
+ }
300
+ for (const publicKeyId of actor.publicKeyIds) if (key.id != null && publicKeyId.href === key.id.href) {
301
+ span.setAttribute("activitypub.key_ownership.verified", true);
302
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
303
+ return true;
304
+ }
305
+ span.setAttribute("activitypub.key_ownership.verified", false);
306
+ span.setAttribute("activitypub.key_ownership.method", "actor_fetch");
307
+ return false;
308
+ } catch (error) {
309
+ span.recordException(error);
310
+ span.setStatus({
311
+ code: SpanStatusCode.ERROR,
312
+ message: String(error)
313
+ });
314
+ throw error;
315
+ } finally {
316
+ span.end();
317
+ }
318
+ });
284
319
  }
285
320
  /**
286
321
  * Gets the actor that owns the specified key. Returns `null` if the key has no