@fedify/fedify 2.3.0-dev.1114 → 2.3.0-dev.1131

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 (69) hide show
  1. package/dist/{builder-YlEusQth.mjs → builder-DckAhD27.mjs} +2 -2
  2. package/dist/compat/mod.d.cts +1 -1
  3. package/dist/compat/mod.d.ts +1 -1
  4. package/dist/compat/transformers.test.mjs +1 -1
  5. package/dist/{context-cSUMk2da.d.ts → context-Cq18Gplu.d.ts} +3 -208
  6. package/dist/{context-Ch-ZLyTQ.d.cts → context-tc6VOOOL.d.cts} +3 -208
  7. package/dist/{deno-CF3jMgip.mjs → deno--CS-SBS9.mjs} +1 -1
  8. package/dist/{docloader-BENj6vQ4.mjs → docloader-k6huZLQL.mjs} +2 -2
  9. package/dist/federation/builder.test.mjs +1 -1
  10. package/dist/federation/handler.test.mjs +2 -2
  11. package/dist/federation/idempotency.test.mjs +2 -2
  12. package/dist/federation/metrics.test.d.mts +2 -0
  13. package/dist/federation/metrics.test.mjs +335 -0
  14. package/dist/federation/middleware.test.mjs +444 -6
  15. package/dist/federation/mod.cjs +1 -1
  16. package/dist/federation/mod.d.cts +3 -2
  17. package/dist/federation/mod.d.ts +3 -2
  18. package/dist/federation/mod.js +1 -1
  19. package/dist/federation/send.test.mjs +3 -3
  20. package/dist/federation/webfinger.test.mjs +1 -1
  21. package/dist/{http-CKCgOPkX.cjs → http-CJfvRL7D.cjs} +352 -22
  22. package/dist/{http-BmOZYc-8.mjs → http-IywnQdiX.mjs} +7 -5
  23. package/dist/{http-D6LP89UO.d.ts → http-VyDTd4G3.d.cts} +8 -1
  24. package/dist/{http-CpzZ9zsb.js → http-cqujdCRz.js} +323 -23
  25. package/dist/{http-D6aw3j2U.d.cts → http-lf8Hsd91.d.ts} +8 -1
  26. package/dist/{key-B4I8H5Lc.mjs → key-Df3tMleh.mjs} +42 -17
  27. package/dist/{kv-cache-DY-XWOqM.cjs → kv-cache-L0SMQkcd.cjs} +19 -2
  28. package/dist/{kv-cache-Wc5ezcVW.js → kv-cache-pEejzYq4.js} +19 -2
  29. package/dist/{kv-cache-DihufyAQ.mjs → kv-cache-q9Ec2ryS.mjs} +19 -1
  30. package/dist/{ld-B5D5THhl.mjs → ld-BGwiJpl3.mjs} +3 -3
  31. package/dist/{metrics-ek3ilf6c.mjs → metrics-BTOMkW8C.mjs} +280 -5
  32. package/dist/{middleware-EqTYPG4F.cjs → middleware-B2rtdpFV.cjs} +75 -28
  33. package/dist/{middleware-DlcecZMq.mjs → middleware-BB0IbDow.mjs} +84 -37
  34. package/dist/{middleware-EI7OU6BR.mjs → middleware-Dnql59Y8.mjs} +1 -1
  35. package/dist/{middleware-CuZbBw-N.js → middleware-DtOddSVg.js} +75 -28
  36. package/dist/{mod-BDhgfjP7.d.cts → mod-B0hW12_O.d.cts} +1 -1
  37. package/dist/{mod-B-Lin9Sy.d.ts → mod-COIAjwRS.d.ts} +1 -1
  38. package/dist/{mod-C6E8rkcz.d.ts → mod-CajNYYkt.d.ts} +1 -1
  39. package/dist/{mod-DLrRb0dx.d.ts → mod-DFvNJcNb.d.ts} +54 -3
  40. package/dist/{mod-P9tE2WmM.d.cts → mod-DnzgcPcy.d.cts} +1 -1
  41. package/dist/{mod-BR_BB0bh.d.cts → mod-yvIXFAEi.d.cts} +54 -3
  42. package/dist/mod.cjs +4 -4
  43. package/dist/mod.d.cts +6 -5
  44. package/dist/mod.d.ts +6 -5
  45. package/dist/mod.js +4 -4
  46. package/dist/mq-D-nlpY04.d.ts +208 -0
  47. package/dist/mq-D8uSFzxe.d.cts +208 -0
  48. package/dist/nodeinfo/handler.test.mjs +1 -1
  49. package/dist/{owner-DO810N24.mjs → owner-CIt4hvmM.mjs} +2 -2
  50. package/dist/{proof-DIoqrKnX.cjs → proof-B1_u25UV.cjs} +1 -1
  51. package/dist/{proof-BgfyWv7b.mjs → proof-BYlrRSmZ.mjs} +3 -3
  52. package/dist/{proof-Vd8-1EWh.js → proof-DMGIjHYH.js} +1 -1
  53. package/dist/{send-CAYXdUTk.mjs → send-DJFpze7B.mjs} +3 -3
  54. package/dist/sig/http.test.mjs +6 -2
  55. package/dist/sig/key.test.mjs +99 -2
  56. package/dist/sig/ld.test.mjs +2 -2
  57. package/dist/sig/mod.cjs +2 -2
  58. package/dist/sig/mod.d.cts +2 -2
  59. package/dist/sig/mod.d.ts +2 -2
  60. package/dist/sig/mod.js +2 -2
  61. package/dist/sig/owner.test.mjs +1 -1
  62. package/dist/sig/proof.test.mjs +1 -1
  63. package/dist/utils/docloader.test.mjs +2 -2
  64. package/dist/utils/kv-cache.test.mjs +67 -2
  65. package/dist/utils/mod.cjs +1 -1
  66. package/dist/utils/mod.d.cts +1 -1
  67. package/dist/utils/mod.d.ts +1 -1
  68. package/dist/utils/mod.js +1 -1
  69. package/package.json +6 -6
@@ -11,7 +11,7 @@ let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conve
11
11
  let byte_encodings_base64 = require("byte-encodings/base64");
12
12
  //#region deno.json
13
13
  var name = "@fedify/fedify";
14
- var version = "2.3.0-dev.1114+15a3316d";
14
+ var version = "2.3.0-dev.1131+553b59b8";
15
15
  //#endregion
16
16
  //#region src/sig/accept.ts
17
17
  /**
@@ -169,6 +169,14 @@ var FederationMetrics = class {
169
169
  queueTaskFailed;
170
170
  queueTaskDuration;
171
171
  queueTaskInFlight;
172
+ fanoutRecipients;
173
+ inboxActivity;
174
+ outboxActivity;
175
+ keyLookup;
176
+ keyLookupDuration;
177
+ documentFetch;
178
+ documentFetchDuration;
179
+ documentCache;
172
180
  constructor(meterProvider) {
173
181
  const meter = meterProvider.getMeter(name, version);
174
182
  this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
@@ -263,6 +271,70 @@ var FederationMetrics = class {
263
271
  description: "Queue tasks currently being processed in this Fedify process.",
264
272
  unit: "{task}"
265
273
  });
274
+ this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
275
+ description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
276
+ unit: "{recipient}"
277
+ });
278
+ this.inboxActivity = meter.createCounter("activitypub.inbox.activity", {
279
+ description: "ActivityPub activities observed at the inbox lifecycle level: queued, processed, retried, rejected, or abandoned.",
280
+ unit: "{activity}"
281
+ });
282
+ this.outboxActivity = meter.createCounter("activitypub.outbox.activity", {
283
+ description: "ActivityPub activities observed at the outbox lifecycle level: queued, retried, or abandoned. Per-recipient delivery counters live on `activitypub.delivery.*`.",
284
+ unit: "{activity}"
285
+ });
286
+ this.keyLookup = meter.createCounter("activitypub.key.lookup", {
287
+ description: "Public-key lookup attempts performed by Fedify, including both cache hits and remote fetches.",
288
+ unit: "{lookup}"
289
+ });
290
+ this.keyLookupDuration = meter.createHistogram("activitypub.key.lookup.duration", {
291
+ description: "Duration of public-key lookups performed by Fedify, including any remote fetch.",
292
+ unit: "ms",
293
+ advice: { explicitBucketBoundaries: [
294
+ 5,
295
+ 10,
296
+ 25,
297
+ 50,
298
+ 75,
299
+ 100,
300
+ 250,
301
+ 500,
302
+ 750,
303
+ 1e3,
304
+ 2500,
305
+ 5e3,
306
+ 7500,
307
+ 1e4
308
+ ] }
309
+ });
310
+ this.documentFetch = meter.createCounter("activitypub.document.fetch", {
311
+ description: "Remote JSON-LD document loader invocations made by Fedify-wrapped loaders.",
312
+ unit: "{fetch}"
313
+ });
314
+ this.documentFetchDuration = meter.createHistogram("activitypub.document.fetch.duration", {
315
+ description: "Duration of remote JSON-LD document loader invocations made by Fedify-wrapped loaders.",
316
+ unit: "ms",
317
+ advice: { explicitBucketBoundaries: [
318
+ 5,
319
+ 10,
320
+ 25,
321
+ 50,
322
+ 75,
323
+ 100,
324
+ 250,
325
+ 500,
326
+ 750,
327
+ 1e3,
328
+ 2500,
329
+ 5e3,
330
+ 7500,
331
+ 1e4
332
+ ] }
333
+ });
334
+ this.documentCache = meter.createCounter("activitypub.document.cache", {
335
+ description: "KV-backed document loader cache lookups, with `hit` or `miss` classification.",
336
+ unit: "{lookup}"
337
+ });
266
338
  }
267
339
  recordDelivery(inbox, durationMs, success, activityType) {
268
340
  const deliveryAttributes = {
@@ -335,7 +407,53 @@ var FederationMetrics = class {
335
407
  else if (result === "failed") this.queueTaskFailed.add(1, attributes);
336
408
  this.queueTaskDuration.record(durationMs, attributes);
337
409
  }
410
+ recordFanoutRecipients(recipientCount, activityType) {
411
+ const attributes = {};
412
+ if (activityType != null) attributes["activitypub.activity.type"] = activityType;
413
+ this.fanoutRecipients.record(recipientCount, attributes);
414
+ }
415
+ recordInboxActivity(result, activityType) {
416
+ this.inboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
417
+ }
418
+ recordOutboxActivity(result, activityType) {
419
+ this.outboxActivity.add(1, buildActivityLifecycleAttributes(result, activityType));
420
+ }
421
+ recordKeyLookup(attrs) {
422
+ const attributes = {
423
+ "activitypub.lookup.kind": "public_key",
424
+ "activitypub.lookup.result": attrs.result,
425
+ "activitypub.cache.enabled": attrs.cacheEnabled
426
+ };
427
+ if (attrs.remoteUrl != null) attributes["activitypub.remote.host"] = getRemoteHost(attrs.remoteUrl);
428
+ if (attrs.statusCode != null) attributes["http.response.status_code"] = attrs.statusCode;
429
+ this.keyLookup.add(1, attributes);
430
+ this.keyLookupDuration.record(attrs.durationMs, attributes);
431
+ }
432
+ recordDocumentFetch(attrs) {
433
+ const attributes = {
434
+ "activitypub.lookup.kind": attrs.kind,
435
+ "activitypub.lookup.result": attrs.result
436
+ };
437
+ if (attrs.remoteUrl != null) attributes["activitypub.remote.host"] = getRemoteHost(attrs.remoteUrl);
438
+ if (attrs.cacheEnabled != null) attributes["activitypub.cache.enabled"] = attrs.cacheEnabled;
439
+ if (attrs.statusCode != null) attributes["http.response.status_code"] = attrs.statusCode;
440
+ this.documentFetch.add(1, attributes);
441
+ this.documentFetchDuration.record(attrs.durationMs, attributes);
442
+ }
443
+ recordDocumentCache(attrs) {
444
+ const attributes = {
445
+ "activitypub.lookup.kind": attrs.kind,
446
+ "activitypub.lookup.result": attrs.result
447
+ };
448
+ if (attrs.remoteUrl != null) attributes["activitypub.remote.host"] = getRemoteHost(attrs.remoteUrl);
449
+ this.documentCache.add(1, attributes);
450
+ }
338
451
  };
452
+ function buildActivityLifecycleAttributes(result, activityType) {
453
+ const attributes = { "activitypub.processing.result": result };
454
+ if (activityType != null) attributes["activitypub.activity.type"] = activityType;
455
+ return attributes;
456
+ }
339
457
  function buildQueueTaskAttributes(common) {
340
458
  const attributes = { "fedify.queue.role": common.role };
341
459
  const backend = getQueueBackend(common.queue);
@@ -365,20 +483,176 @@ function getQueueBackend(queue) {
365
483
  return name;
366
484
  }
367
485
  /**
368
- * Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue.
486
+ * Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
487
+ * for the initial attempt, also records
488
+ * `activitypub.outbox.activity{queued}`.
369
489
  *
370
490
  * Both `Context.sendActivity()` and `OutboxContext.forwardActivity()` enqueue
371
491
  * outbox messages with the same metric attributes (role, queue, activity
372
492
  * type, attempt), so they share this helper rather than each defining a local
373
- * closure.
493
+ * closure. Retry enqueues (attempt > 0) intentionally do not record a
494
+ * second `activitypub.outbox.activity{queued}`; retries are reported as
495
+ * `result=retried` from the retry-scheduling site, which has the failure
496
+ * context.
374
497
  * @since 2.3.0
375
498
  */
376
499
  function recordOutboxEnqueue(meterProvider, outboxQueue, message) {
377
- getFederationMetrics(meterProvider).recordQueueTaskEnqueued({
500
+ const metrics = getFederationMetrics(meterProvider);
501
+ metrics.recordQueueTaskEnqueued({
378
502
  role: "outbox",
379
503
  queue: outboxQueue,
380
504
  activityType: message.activityType
381
505
  }, message.attempt);
506
+ if (message.attempt === 0) metrics.recordOutboxActivity("queued", message.activityType);
507
+ }
508
+ /**
509
+ * Records `activitypub.fanout.recipients` with the number of recipient
510
+ * inboxes a single fanout produced. The histogram is unitless count
511
+ * (one measurement per fanout enqueue). Recipient URLs are deliberately
512
+ * not recorded; only the activity type, when known.
513
+ * @since 2.3.0
514
+ */
515
+ function recordFanoutRecipients(meterProvider, recipientCount, activityType) {
516
+ getFederationMetrics(meterProvider).recordFanoutRecipients(recipientCount, activityType);
517
+ }
518
+ /**
519
+ * Records one `activitypub.inbox.activity` measurement. The
520
+ * `activitypub.processing.result` attribute is always present;
521
+ * `activitypub.activity.type` is recorded only when Fedify already knows
522
+ * the activity type.
523
+ * @since 2.3.0
524
+ */
525
+ function recordInboxActivity(meterProvider, result, activityType) {
526
+ getFederationMetrics(meterProvider).recordInboxActivity(result, activityType);
527
+ }
528
+ /**
529
+ * Records one `activitypub.outbox.activity` measurement. The
530
+ * `activitypub.processing.result` attribute is always present;
531
+ * `activitypub.activity.type` is recorded only when Fedify already knows
532
+ * the activity type (it is always known for outbox lifecycle events).
533
+ * @since 2.3.0
534
+ */
535
+ function recordOutboxActivity(meterProvider, result, activityType) {
536
+ getFederationMetrics(meterProvider).recordOutboxActivity(result, activityType);
537
+ }
538
+ /**
539
+ * Records one measurement on `activitypub.key.lookup` (counter) and
540
+ * `activitypub.key.lookup.duration` (histogram) for a public-key lookup.
541
+ *
542
+ * `activitypub.lookup.kind` is always recorded as `public_key`; the result
543
+ * classification, remote host, HTTP status code (when an HTTP response was
544
+ * received), and `activitypub.cache.enabled` are recorded as attributes on
545
+ * both measurements. Full key URLs and key IDs are deliberately omitted to
546
+ * keep cardinality bounded.
547
+ * @since 2.3.0
548
+ */
549
+ function recordKeyLookup(meterProvider, attrs) {
550
+ getFederationMetrics(meterProvider).recordKeyLookup(attrs);
551
+ }
552
+ /**
553
+ * Records one measurement each on `activitypub.document.fetch` (counter)
554
+ * and `activitypub.document.fetch.duration` (histogram) for one remote
555
+ * JSON-LD document loader invocation, with bounded
556
+ * `activitypub.lookup.kind` and `activitypub.lookup.result` attributes
557
+ * plus the optional remote-host, cache-enabled, and HTTP status-code
558
+ * attributes. Counter and histogram are always recorded together so
559
+ * aggregate rate and latency views stay in sync.
560
+ * @since 2.3.0
561
+ */
562
+ function recordDocumentFetch(meterProvider, attrs) {
563
+ getFederationMetrics(meterProvider).recordDocumentFetch(attrs);
564
+ }
565
+ /**
566
+ * Records one `activitypub.document.cache` measurement, classifying the
567
+ * lookup as `hit` (the cache returned an entry) or `miss` (the cache was
568
+ * consulted and returned nothing, prompting a delegate fetch).
569
+ * @since 2.3.0
570
+ */
571
+ function recordDocumentCache(meterProvider, attrs) {
572
+ getFederationMetrics(meterProvider).recordDocumentCache(attrs);
573
+ }
574
+ /**
575
+ * Classifies a thrown value from a key or document fetch into the bounded
576
+ * {@link LookupResult} taxonomy and, when an HTTP response was received,
577
+ * surfaces its status code.
578
+ *
579
+ * - `FetchError` with a `Response` whose status is `404` or `410`:
580
+ * `result=not_found` and the response status code.
581
+ * - `FetchError` with any other `Response`: `result=error` and the
582
+ * response status code.
583
+ * - `FetchError` without a `Response`: `result=network_error`.
584
+ * - An `AbortError` (typically from a cancelled fetch): `result=network_error`.
585
+ * - A bare `TypeError` (the shape native `fetch()` raises on DNS, connect,
586
+ * and TLS failures before any response is observed):
587
+ * `result=network_error`.
588
+ * - Any other value: `result=error`.
589
+ * @since 2.3.0
590
+ */
591
+ function classifyFetchError(error) {
592
+ if (error instanceof _fedify_vocab_runtime.FetchError) {
593
+ if (error.response != null) {
594
+ const status = error.response.status;
595
+ return {
596
+ result: status === 404 || status === 410 ? "not_found" : "error",
597
+ statusCode: status
598
+ };
599
+ }
600
+ return { result: "network_error" };
601
+ }
602
+ if (isAbortError$1(error)) return { result: "network_error" };
603
+ if (error instanceof TypeError) return { result: "network_error" };
604
+ return { result: "error" };
605
+ }
606
+ /**
607
+ * Wraps a {@link DocumentLoader} so each invocation records one
608
+ * measurement on `activitypub.document.fetch` (counter) and one on
609
+ * `activitypub.document.fetch.duration` (histogram), classifying the
610
+ * outcome via {@link classifyFetchError} when the wrapped loader throws
611
+ * and as `fetched` on success. The wrapper rethrows whatever the
612
+ * wrapped loader throws so caller behavior is unchanged.
613
+ *
614
+ * The wrapper records the hostname of the requested URL on
615
+ * `activitypub.remote.host` when the URL parses; full URLs, paths, and
616
+ * query strings are deliberately excluded to keep cardinality bounded.
617
+ * HTTP status codes are recorded only when the failure carries a
618
+ * `Response` (currently, when the wrapped loader throws a
619
+ * {@link FetchError} with a non-`null` `response`).
620
+ * @since 2.3.0
621
+ */
622
+ function instrumentDocumentLoader(loader, options) {
623
+ const meterProvider = options.meterProvider;
624
+ if (meterProvider == null) return loader;
625
+ return async (url, opts) => {
626
+ const start = performance.now();
627
+ let remoteUrl;
628
+ try {
629
+ remoteUrl = new URL(url);
630
+ } catch {
631
+ remoteUrl = void 0;
632
+ }
633
+ try {
634
+ const result = await loader(url, opts);
635
+ recordDocumentFetch(meterProvider, {
636
+ durationMs: getDurationMs(start),
637
+ kind: options.kind,
638
+ result: "fetched",
639
+ remoteUrl,
640
+ cacheEnabled: options.cacheEnabled
641
+ });
642
+ return result;
643
+ } catch (error) {
644
+ const classified = classifyFetchError(error);
645
+ recordDocumentFetch(meterProvider, {
646
+ durationMs: getDurationMs(start),
647
+ kind: options.kind,
648
+ result: classified.result,
649
+ remoteUrl,
650
+ cacheEnabled: options.cacheEnabled,
651
+ statusCode: classified.statusCode
652
+ });
653
+ throw error;
654
+ }
655
+ };
382
656
  }
383
657
  /**
384
658
  * Times an awaited public key fetch and records exactly one
@@ -760,24 +1034,48 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
760
1034
  };
761
1035
  }
762
1036
  async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, onFetchError) {
763
- const logger = (0, _logtape_logtape.getLogger)([
764
- "fedify",
765
- "sig",
766
- "key"
767
- ]);
768
- const keyId = cacheKey.href;
769
- const keyCache = options.keyCache;
770
- const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
771
- if (cached?.key === null && cached.cached) return await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
772
- if (cached != null) return cached;
773
- logger.debug("Fetching key {keyId} to verify signature...", { keyId });
774
- let document;
1037
+ const start = performance.now();
1038
+ let outcome = { result: "error" };
775
1039
  try {
776
- document = (await (options.documentLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)())(keyId)).document;
777
- } catch (error) {
778
- return await onFetchError(error, cacheKey, keyId, keyCache, logger);
1040
+ const logger = (0, _logtape_logtape.getLogger)([
1041
+ "fedify",
1042
+ "sig",
1043
+ "key"
1044
+ ]);
1045
+ const keyId = cacheKey.href;
1046
+ const keyCache = options.keyCache;
1047
+ const cached = await getCachedFetchKey(cacheKey, keyId, cls, keyCache, logger);
1048
+ if (cached?.key === null && cached.cached) {
1049
+ const cachedUnavailable = await onCachedUnavailable(cacheKey, keyId, keyCache, logger);
1050
+ outcome = { result: "hit" };
1051
+ return cachedUnavailable;
1052
+ }
1053
+ if (cached != null) {
1054
+ outcome = { result: "hit" };
1055
+ return cached;
1056
+ }
1057
+ logger.debug("Fetching key {keyId} to verify signature...", { keyId });
1058
+ let document;
1059
+ try {
1060
+ document = (await (options.documentLoader ?? (0, _fedify_vocab_runtime.getDocumentLoader)())(keyId)).document;
1061
+ } catch (error) {
1062
+ const classified = classifyFetchError(error);
1063
+ const errored = await onFetchError(error, cacheKey, keyId, keyCache, logger);
1064
+ outcome = classified;
1065
+ return errored;
1066
+ }
1067
+ const resolved = await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
1068
+ outcome = { result: resolved.key != null ? "fetched" : "invalid" };
1069
+ return resolved;
1070
+ } finally {
1071
+ recordKeyLookup(options.meterProvider, {
1072
+ durationMs: getDurationMs(start),
1073
+ result: outcome.result,
1074
+ remoteUrl: cacheKey,
1075
+ cacheEnabled: options.keyCache != null,
1076
+ statusCode: outcome.statusCode
1077
+ });
779
1078
  }
780
- return await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
781
1079
  }
782
1080
  async function fetchKeyInternal(keyId, cls, options = {}) {
783
1081
  return await fetchKeyWithResult(typeof keyId === "string" ? new URL(keyId) : keyId, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
@@ -1359,7 +1657,8 @@ async function verifyRequestDraft(request, span, metricsContext, { documentLoade
1359
1657
  documentLoader,
1360
1658
  contextLoader,
1361
1659
  keyCache,
1362
- tracerProvider
1660
+ tracerProvider,
1661
+ meterProvider
1363
1662
  }));
1364
1663
  if (fetchError != null) return keyFetchErrorResult(keyIdUrl, fetchError);
1365
1664
  if (key == null) return invalidSignatureResult(keyIdUrl);
@@ -1574,7 +1873,8 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
1574
1873
  documentLoader,
1575
1874
  contextLoader,
1576
1875
  keyCache,
1577
- tracerProvider
1876
+ tracerProvider,
1877
+ meterProvider
1578
1878
  }));
1579
1879
  if (fetchError != null) {
1580
1880
  setFailure(keyFetchErrorResult(keyId, fetchError));
@@ -1943,6 +2243,12 @@ Object.defineProperty(exports, "importJwk", {
1943
2243
  return importJwk;
1944
2244
  }
1945
2245
  });
2246
+ Object.defineProperty(exports, "instrumentDocumentLoader", {
2247
+ enumerable: true,
2248
+ get: function() {
2249
+ return instrumentDocumentLoader;
2250
+ }
2251
+ });
1946
2252
  Object.defineProperty(exports, "isAbortError", {
1947
2253
  enumerable: true,
1948
2254
  get: function() {
@@ -1973,6 +2279,30 @@ Object.defineProperty(exports, "parseRfc9421SignatureInput", {
1973
2279
  return parseRfc9421SignatureInput;
1974
2280
  }
1975
2281
  });
2282
+ Object.defineProperty(exports, "recordDocumentCache", {
2283
+ enumerable: true,
2284
+ get: function() {
2285
+ return recordDocumentCache;
2286
+ }
2287
+ });
2288
+ Object.defineProperty(exports, "recordFanoutRecipients", {
2289
+ enumerable: true,
2290
+ get: function() {
2291
+ return recordFanoutRecipients;
2292
+ }
2293
+ });
2294
+ Object.defineProperty(exports, "recordInboxActivity", {
2295
+ enumerable: true,
2296
+ get: function() {
2297
+ return recordInboxActivity;
2298
+ }
2299
+ });
2300
+ Object.defineProperty(exports, "recordOutboxActivity", {
2301
+ enumerable: true,
2302
+ get: function() {
2303
+ return recordOutboxActivity;
2304
+ }
2305
+ });
1976
2306
  Object.defineProperty(exports, "recordOutboxEnqueue", {
1977
2307
  enumerable: true,
1978
2308
  get: function() {
@@ -1,10 +1,10 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-CF3jMgip.mjs";
5
- import { a as measureSignatureKeyFetch, n as getFederationMetrics, t as getDurationMs } from "./metrics-ek3ilf6c.mjs";
4
+ import { n as version, t as name } from "./deno--CS-SBS9.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BTOMkW8C.mjs";
6
6
  import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CgDcxvjV.mjs";
7
- import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-B4I8H5Lc.mjs";
7
+ import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-Df3tMleh.mjs";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { CryptographicKey } from "@fedify/vocab";
10
10
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -569,7 +569,8 @@ async function verifyRequestDraft(request, span, metricsContext, { documentLoade
569
569
  documentLoader,
570
570
  contextLoader,
571
571
  keyCache,
572
- tracerProvider
572
+ tracerProvider,
573
+ meterProvider
573
574
  }));
574
575
  if (fetchError != null) return keyFetchErrorResult(keyIdUrl, fetchError);
575
576
  if (key == null) return invalidSignatureResult(keyIdUrl);
@@ -784,7 +785,8 @@ async function verifyRequestRfc9421(request, span, metricsContext, { documentLoa
784
785
  documentLoader,
785
786
  contextLoader,
786
787
  keyCache,
787
- tracerProvider
788
+ tracerProvider,
789
+ meterProvider
788
790
  }));
789
791
  if (fetchError != null) {
790
792
  setFailure(keyFetchErrorResult(keyId, fetchError));
@@ -1,7 +1,7 @@
1
1
  /// <reference lib="esnext.temporal" />
2
2
  import { CryptographicKey, Multikey } from "@fedify/vocab";
3
- import { MeterProvider, TracerProvider } from "@opentelemetry/api";
4
3
  import { DocumentLoader } from "@fedify/vocab-runtime";
4
+ import { MeterProvider, TracerProvider } from "@opentelemetry/api";
5
5
 
6
6
  //#region src/sig/key.d.ts
7
7
  /**
@@ -52,6 +52,13 @@ interface FetchKeyOptions {
52
52
  * @since 1.3.0
53
53
  */
54
54
  tracerProvider?: TracerProvider;
55
+ /**
56
+ * The OpenTelemetry meter provider to use for recording
57
+ * `activitypub.key.lookup` and `activitypub.key.lookup.duration`. If
58
+ * omitted, the global meter provider is used.
59
+ * @since 2.3.0
60
+ */
61
+ meterProvider?: MeterProvider;
55
62
  }
56
63
  /**
57
64
  * The result of {@link fetchKey}.