@fedify/fedify 2.3.0-dev.1212 → 2.3.0-dev.1213

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 (83) hide show
  1. package/dist/{builder-DdbtvTFp.mjs → builder-Bj-7Sl7u.mjs} +9 -2
  2. package/dist/compat/mod.d.cts +1 -1
  3. package/dist/compat/mod.d.ts +1 -1
  4. package/dist/compat/outgoing-jsonld.test.mjs +1 -1
  5. package/dist/compat/public-audience.test.mjs +1 -1
  6. package/dist/compat/transformers.test.mjs +2 -2
  7. package/dist/{context-DMHK7jqX.d.cts → context-BBVLF7lx.d.cts} +41 -2
  8. package/dist/{context-K9cg8oGx.d.ts → context-BU6jSQdo.d.ts} +42 -2
  9. package/dist/{deno-DTaoLXHr.mjs → deno-BUzynMVz.mjs} +1 -1
  10. package/dist/{docloader-CdNiXmNg.mjs → docloader-jQPthO4U.mjs} +2 -2
  11. package/dist/{esm-BQRw925N.mjs → esm-vrlUxr60.mjs} +23 -1
  12. package/dist/federation/builder.test.mjs +21 -2
  13. package/dist/federation/circuit-breaker.test.mjs +1 -1
  14. package/dist/federation/handler.test.mjs +6 -6
  15. package/dist/federation/idempotency.test.mjs +4 -4
  16. package/dist/federation/keycache.test.mjs +1 -1
  17. package/dist/federation/kv.test.mjs +1 -1
  18. package/dist/federation/metrics.test.mjs +147 -1
  19. package/dist/federation/middleware.test.mjs +446 -18
  20. package/dist/federation/mod.cjs +1 -1
  21. package/dist/federation/mod.d.cts +3 -3
  22. package/dist/federation/mod.d.ts +3 -3
  23. package/dist/federation/mod.js +1 -1
  24. package/dist/federation/send.test.mjs +8 -4426
  25. package/dist/federation/temporal.test.mjs +1 -1
  26. package/dist/federation/webfinger.test.mjs +2 -2
  27. package/dist/{http-Czeyq7if.cjs → http-B1zlPuh3.cjs} +79 -2
  28. package/dist/{http-BEG9kx13.js → http-B_WbYMnB.js} +74 -3
  29. package/dist/{http-ByCfCX5K.mjs → http-CDaMGwCP.mjs} +4 -4
  30. package/dist/{key-Bhsx9PrC.mjs → key-DdP4HxTK.mjs} +2 -2
  31. package/dist/{kv-cache-qRBN2G2Z.cjs → kv-cache-CPIfTWt5.cjs} +1 -1
  32. package/dist/{kv-cache-D9U1AnXH.js → kv-cache-CXo8QM4m.js} +1 -1
  33. package/dist/{kv-cache-D4jzgeYW.mjs → kv-cache-DSjv5Aeh.mjs} +1 -1
  34. package/dist/{ld-CHtLb_Uh.mjs → ld-CuOEh5aB.mjs} +3 -3
  35. package/dist/{metrics-uwSF8DLC.mjs → metrics-B5vvJYMV.mjs} +74 -3
  36. package/dist/{middleware-BmSzD5U9.mjs → middleware-Cq9S8A5O.mjs} +328 -24
  37. package/dist/{middleware-CyiBzIwY.mjs → middleware-DPE-IRlD.mjs} +1 -1
  38. package/dist/{middleware-DrKDd2JT.js → middleware-Dft_sYeS.js} +352 -41
  39. package/dist/{middleware-CRORNnSU.cjs → middleware-DlqW4IRW.cjs} +351 -40
  40. package/dist/{mod-YLnSsEHY.d.cts → mod-C0F6kvgS.d.cts} +1 -1
  41. package/dist/{mod-CfOFqS0w.d.ts → mod-vPYVoa5n.d.ts} +1 -1
  42. package/dist/mod.cjs +4 -4
  43. package/dist/mod.d.cts +4 -4
  44. package/dist/mod.d.ts +4 -4
  45. package/dist/mod.js +4 -4
  46. package/dist/nodeinfo/client.test.mjs +2 -2
  47. package/dist/nodeinfo/handler.test.mjs +2 -2
  48. package/dist/nodeinfo/types.test.mjs +1 -1
  49. package/dist/otel/exporter.test.mjs +1 -1
  50. package/dist/{outgoing-jsonld-BgFLCJQ_.mjs → outgoing-jsonld-L_DbOaFe.mjs} +1 -1
  51. package/dist/{owner-B0Zrhs0w.mjs → owner--n8rmG51.mjs} +2 -2
  52. package/dist/{proof-frzCtYji.cjs → proof-BKpJ_p_d.cjs} +1 -1
  53. package/dist/{proof-CZhAX94C.js → proof-BsvB1vGI.js} +1 -1
  54. package/dist/{proof-DbJFxpzD.mjs → proof-dhtwaP4z.mjs} +5 -5
  55. package/dist/{send-kst2L0Df.mjs → send-CTQ30Wbe.mjs} +3 -3
  56. package/dist/sig/accept.test.mjs +1 -1
  57. package/dist/sig/http.test.mjs +4 -4
  58. package/dist/sig/key.test.mjs +2 -2
  59. package/dist/sig/ld.test.mjs +3 -3
  60. package/dist/sig/mod.cjs +2 -2
  61. package/dist/sig/mod.js +2 -2
  62. package/dist/sig/owner.test.mjs +2 -2
  63. package/dist/sig/proof.test.mjs +3 -3
  64. package/dist/{temporal-CcGypkzd.mjs → temporal-gfUaZjGU.mjs} +1 -1
  65. package/dist/testing/mod.d.mts +1 -0
  66. package/dist/utils/docloader.test.mjs +4 -4
  67. package/dist/utils/kv-cache.test.mjs +1 -1
  68. package/dist/utils/mod.cjs +1 -1
  69. package/dist/utils/mod.js +1 -1
  70. package/package.json +7 -7
  71. package/dist/chunk-DNRtMIoB.mjs +0 -29
  72. package/dist/execAsync-Dmet7-28.mjs +0 -13
  73. package/dist/getMachineId-bsd-Bn0le7-J.mjs +0 -29
  74. package/dist/getMachineId-darwin-CVjKuDgj.mjs +0 -26
  75. package/dist/getMachineId-linux-DbG4BXa-.mjs +0 -22
  76. package/dist/getMachineId-unsupported-lC8T9hPE.mjs +0 -17
  77. package/dist/getMachineId-win-c5zxTSS1.mjs +0 -28
  78. /package/dist/{accept-CceiKpCy.mjs → accept-CPkZzmGN.mjs} +0 -0
  79. /package/dist/{client-B_A6mfn3.mjs → client-ByXmQhYD.mjs} +0 -0
  80. /package/dist/{keys-C3kae-6B.mjs → keys-DGu1NFwu.mjs} +0 -0
  81. /package/dist/{kv-x2IvBUyq.mjs → kv-rV3vodCc.mjs} +0 -0
  82. /package/dist/{public-audience-N3pyOx2p.mjs → public-audience-Cvbr2Gzt.mjs} +0 -0
  83. /package/dist/{types-BFowWFTT.mjs → types-J53Kw7so.mjs} +0 -0
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
4
4
  import "../std__assert-BBjXFNOb.mjs";
5
5
  import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
6
6
  import { t as assert } from "../assert-OguE97r2.mjs";
7
- import { t as hasMalformedKnownTemporalLiteral } from "../temporal-CcGypkzd.mjs";
7
+ import { t as hasMalformedKnownTemporalLiteral } from "../temporal-gfUaZjGU.mjs";
8
8
  import { test } from "@fedify/fixture";
9
9
  //#region src/federation/temporal.test.ts
10
10
  test("hasMalformedKnownTemporalLiteral() detects expanded proof timestamps", async () => {
@@ -5,8 +5,8 @@ import { r as createRequestContext } from "../context-DVoTs_wM.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
6
  import "../std__assert-BBjXFNOb.mjs";
7
7
  import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
8
- import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
9
- import { o as createFederation, s as handleWebFinger } from "../middleware-BmSzD5U9.mjs";
8
+ import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
9
+ import { o as createFederation, s as handleWebFinger } from "../middleware-Cq9S8A5O.mjs";
10
10
  import { Image, Link, Person, Tombstone } from "@fedify/vocab";
11
11
  import { createTestMeterProvider, test } from "@fedify/fixture";
12
12
  //#region src/federation/webfinger.test.ts
@@ -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.1212+3737de7f";
14
+ var version = "2.3.0-dev.1213+8ffffeb8";
15
15
  //#endregion
16
16
  //#region src/sig/accept.ts
17
17
  /**
@@ -169,6 +169,7 @@ var FederationMetrics = class {
169
169
  queueTaskFailed;
170
170
  queueTaskDuration;
171
171
  queueTaskInFlight;
172
+ queueDepth;
172
173
  fanoutRecipients;
173
174
  inboxActivity;
174
175
  outboxActivity;
@@ -200,7 +201,22 @@ var FederationMetrics = class {
200
201
  });
201
202
  this.signatureVerificationDuration = meter.createHistogram("activitypub.signature.verification.duration", {
202
203
  description: "Duration of ActivityPub signature verification, including local key lookup and remote key fetches.",
203
- unit: "ms"
204
+ unit: "ms",
205
+ advice: { explicitBucketBoundaries: [
206
+ .1,
207
+ .25,
208
+ .5,
209
+ 1,
210
+ 2.5,
211
+ 5,
212
+ 10,
213
+ 25,
214
+ 50,
215
+ 100,
216
+ 250,
217
+ 500,
218
+ 1e3
219
+ ] }
204
220
  });
205
221
  this.signatureKeyFetchDuration = meter.createHistogram("activitypub.signature.key_fetch.duration", {
206
222
  description: "Duration of public key lookup performed during ActivityPub signature verification.",
@@ -278,6 +294,10 @@ var FederationMetrics = class {
278
294
  description: "Queue tasks currently being processed in this Fedify process.",
279
295
  unit: "{task}"
280
296
  });
297
+ this.queueDepth = meter.createObservableGauge("fedify.queue.depth", {
298
+ description: "Messages waiting in configured Fedify queues, as reported by the queue backend.",
299
+ unit: "{message}"
300
+ });
281
301
  this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
282
302
  description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
283
303
  unit: "{recipient}"
@@ -585,6 +605,57 @@ function getQueueBackend(queue) {
585
605
  return name;
586
606
  }
587
607
  /**
608
+ * Registers a callback for observing queue backend depth.
609
+ * @since 2.3.0
610
+ */
611
+ function registerQueueDepthGauge(meterProvider, entries, options = {}) {
612
+ const uniqueQueues = /* @__PURE__ */ new Map();
613
+ for (const { role, queue } of entries) {
614
+ if (queue?.getDepth == null) continue;
615
+ const roles = uniqueQueues.get(queue);
616
+ if (roles == null) uniqueQueues.set(queue, [role]);
617
+ else if (!roles.includes(role)) roles.push(role);
618
+ }
619
+ if (uniqueQueues.size < 1) return;
620
+ const queueEntries = Array.from(uniqueQueues.entries());
621
+ getFederationMetrics(meterProvider).queueDepth.addCallback(async (observableResult) => {
622
+ await Promise.all(queueEntries.map(async ([queue, roles]) => {
623
+ let depth;
624
+ try {
625
+ depth = await queue.getDepth();
626
+ } catch {
627
+ return;
628
+ }
629
+ if (depth == null) return;
630
+ const attributes = buildQueueDepthAttributes(queue, roles, options);
631
+ observableResult.observe(depth.queued, {
632
+ ...attributes,
633
+ "fedify.queue.depth.state": "queued"
634
+ });
635
+ if (depth.ready != null) observableResult.observe(depth.ready, {
636
+ ...attributes,
637
+ "fedify.queue.depth.state": "ready"
638
+ });
639
+ if (depth.delayed != null) observableResult.observe(depth.delayed, {
640
+ ...attributes,
641
+ "fedify.queue.depth.state": "delayed"
642
+ });
643
+ }));
644
+ });
645
+ }
646
+ function buildQueueDepthAttributes(queue, roles, options) {
647
+ const sortedRoles = roles.toSorted();
648
+ const role = sortedRoles.length === 1 ? sortedRoles[0] : "shared";
649
+ const attributes = { "fedify.queue.role": role };
650
+ if (options.sourceId != null) attributes["fedify.federation.instance_id"] = options.sourceId;
651
+ if (role === "shared") attributes["fedify.queue.roles"] = sortedRoles.join(",");
652
+ const backend = getQueueBackend(queue);
653
+ if (backend != null) attributes["fedify.queue.backend"] = backend;
654
+ const nativeRetrial = queue.nativeRetrial;
655
+ if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
656
+ return attributes;
657
+ }
658
+ /**
588
659
  * Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
589
660
  * for the initial attempt, also records
590
661
  * `activitypub.outbox.activity{queued}`.
@@ -2500,6 +2571,12 @@ Object.defineProperty(exports, "recordWebFingerHandle", {
2500
2571
  return recordWebFingerHandle;
2501
2572
  }
2502
2573
  });
2574
+ Object.defineProperty(exports, "registerQueueDepthGauge", {
2575
+ enumerable: true,
2576
+ get: function() {
2577
+ return registerQueueDepthGauge;
2578
+ }
2579
+ });
2503
2580
  Object.defineProperty(exports, "signRequest", {
2504
2581
  enumerable: true,
2505
2582
  get: function() {
@@ -10,7 +10,7 @@ import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } fro
10
10
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
11
11
  //#region deno.json
12
12
  var name = "@fedify/fedify";
13
- var version = "2.3.0-dev.1212+3737de7f";
13
+ var version = "2.3.0-dev.1213+8ffffeb8";
14
14
  //#endregion
15
15
  //#region src/sig/accept.ts
16
16
  /**
@@ -168,6 +168,7 @@ var FederationMetrics = class {
168
168
  queueTaskFailed;
169
169
  queueTaskDuration;
170
170
  queueTaskInFlight;
171
+ queueDepth;
171
172
  fanoutRecipients;
172
173
  inboxActivity;
173
174
  outboxActivity;
@@ -199,7 +200,22 @@ var FederationMetrics = class {
199
200
  });
200
201
  this.signatureVerificationDuration = meter.createHistogram("activitypub.signature.verification.duration", {
201
202
  description: "Duration of ActivityPub signature verification, including local key lookup and remote key fetches.",
202
- unit: "ms"
203
+ unit: "ms",
204
+ advice: { explicitBucketBoundaries: [
205
+ .1,
206
+ .25,
207
+ .5,
208
+ 1,
209
+ 2.5,
210
+ 5,
211
+ 10,
212
+ 25,
213
+ 50,
214
+ 100,
215
+ 250,
216
+ 500,
217
+ 1e3
218
+ ] }
203
219
  });
204
220
  this.signatureKeyFetchDuration = meter.createHistogram("activitypub.signature.key_fetch.duration", {
205
221
  description: "Duration of public key lookup performed during ActivityPub signature verification.",
@@ -277,6 +293,10 @@ var FederationMetrics = class {
277
293
  description: "Queue tasks currently being processed in this Fedify process.",
278
294
  unit: "{task}"
279
295
  });
296
+ this.queueDepth = meter.createObservableGauge("fedify.queue.depth", {
297
+ description: "Messages waiting in configured Fedify queues, as reported by the queue backend.",
298
+ unit: "{message}"
299
+ });
280
300
  this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
281
301
  description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
282
302
  unit: "{recipient}"
@@ -584,6 +604,57 @@ function getQueueBackend(queue) {
584
604
  return name;
585
605
  }
586
606
  /**
607
+ * Registers a callback for observing queue backend depth.
608
+ * @since 2.3.0
609
+ */
610
+ function registerQueueDepthGauge(meterProvider, entries, options = {}) {
611
+ const uniqueQueues = /* @__PURE__ */ new Map();
612
+ for (const { role, queue } of entries) {
613
+ if (queue?.getDepth == null) continue;
614
+ const roles = uniqueQueues.get(queue);
615
+ if (roles == null) uniqueQueues.set(queue, [role]);
616
+ else if (!roles.includes(role)) roles.push(role);
617
+ }
618
+ if (uniqueQueues.size < 1) return;
619
+ const queueEntries = Array.from(uniqueQueues.entries());
620
+ getFederationMetrics(meterProvider).queueDepth.addCallback(async (observableResult) => {
621
+ await Promise.all(queueEntries.map(async ([queue, roles]) => {
622
+ let depth;
623
+ try {
624
+ depth = await queue.getDepth();
625
+ } catch {
626
+ return;
627
+ }
628
+ if (depth == null) return;
629
+ const attributes = buildQueueDepthAttributes(queue, roles, options);
630
+ observableResult.observe(depth.queued, {
631
+ ...attributes,
632
+ "fedify.queue.depth.state": "queued"
633
+ });
634
+ if (depth.ready != null) observableResult.observe(depth.ready, {
635
+ ...attributes,
636
+ "fedify.queue.depth.state": "ready"
637
+ });
638
+ if (depth.delayed != null) observableResult.observe(depth.delayed, {
639
+ ...attributes,
640
+ "fedify.queue.depth.state": "delayed"
641
+ });
642
+ }));
643
+ });
644
+ }
645
+ function buildQueueDepthAttributes(queue, roles, options) {
646
+ const sortedRoles = roles.toSorted();
647
+ const role = sortedRoles.length === 1 ? sortedRoles[0] : "shared";
648
+ const attributes = { "fedify.queue.role": role };
649
+ if (options.sourceId != null) attributes["fedify.federation.instance_id"] = options.sourceId;
650
+ if (role === "shared") attributes["fedify.queue.roles"] = sortedRoles.join(",");
651
+ const backend = getQueueBackend(queue);
652
+ if (backend != null) attributes["fedify.queue.backend"] = backend;
653
+ const nativeRetrial = queue.nativeRetrial;
654
+ if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
655
+ return attributes;
656
+ }
657
+ /**
587
658
  * Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
588
659
  * for the initial attempt, also records
589
660
  * `activitypub.outbox.activity{queued}`.
@@ -2331,4 +2402,4 @@ function timingSafeEqual(a, b) {
2331
2402
  return result === 0;
2332
2403
  }
2333
2404
  //#endregion
2334
- export { fulfillAcceptSignature as A, recordDocumentCache as C, recordOutboxEnqueue as D, recordOutboxActivity as E, validateAcceptSignature as M, name as N, recordWebFingerHandle as O, version as P, recordCollectionTotalItems as S, recordInboxActivity as T, measureSignatureKeyFetch as _, verifyRequestDetailed as a, recordCollectionPageItems as b, fetchKeyDetailed as c, validateCryptoKey as d, getDurationMs as f, isAbortError$1 as g, instrumentDocumentLoader as h, verifyRequest as i, parseAcceptSignature as j, formatAcceptSignature as k, generateCryptoKeyPair as l, getRemoteHost as m, parseRfc9421SignatureInput as n, exportJwk as o, getFederationMetrics as p, signRequest as r, fetchKey as s, doubleKnock as t, importJwk as u, recordCircuitBreakerStateChange as v, recordFanoutRecipients as w, recordCollectionRequest as x, recordCollectionDispatchDuration as y };
2405
+ export { formatAcceptSignature as A, recordDocumentCache as C, recordOutboxEnqueue as D, recordOutboxActivity as E, version as F, parseAcceptSignature as M, validateAcceptSignature as N, recordWebFingerHandle as O, name as P, recordCollectionTotalItems as S, recordInboxActivity as T, measureSignatureKeyFetch as _, verifyRequestDetailed as a, recordCollectionPageItems as b, fetchKeyDetailed as c, validateCryptoKey as d, getDurationMs as f, isAbortError$1 as g, instrumentDocumentLoader as h, verifyRequest as i, fulfillAcceptSignature as j, registerQueueDepthGauge as k, generateCryptoKeyPair as l, getRemoteHost as m, parseRfc9421SignatureInput as n, exportJwk as o, getFederationMetrics as p, signRequest as r, fetchKey as s, doubleKnock as t, importJwk as u, recordCircuitBreakerStateChange as v, recordFanoutRecipients as w, recordCollectionRequest as x, recordCollectionDispatchDuration as y };
@@ -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-DTaoLXHr.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-uwSF8DLC.mjs";
6
- import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CceiKpCy.mjs";
7
- import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-Bhsx9PrC.mjs";
4
+ import { n as version, t as name } from "./deno-BUzynMVz.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-B5vvJYMV.mjs";
6
+ import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPkZzmGN.mjs";
7
+ import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-DdP4HxTK.mjs";
8
8
  import { getLogger } from "@logtape/logtape";
9
9
  import { CryptographicKey } from "@fedify/vocab";
10
10
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,8 +1,8 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-DTaoLXHr.mjs";
5
- import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-uwSF8DLC.mjs";
4
+ import { n as version, t as name } from "./deno-BUzynMVz.mjs";
5
+ import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-B5vvJYMV.mjs";
6
6
  import { getLogger } from "@logtape/logtape";
7
7
  import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
8
8
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,7 +1,7 @@
1
1
  const { Temporal } = require("@js-temporal/polyfill");
2
2
  const { URLPattern } = require("urlpattern-polyfill");
3
3
  require("./chunk-DDcVe30Y.cjs");
4
- const require_http = require("./http-Czeyq7if.cjs");
4
+ const require_http = require("./http-B1zlPuh3.cjs");
5
5
  let _logtape_logtape = require("@logtape/logtape");
6
6
  let es_toolkit = require("es-toolkit");
7
7
  let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-BEG9kx13.js";
3
+ import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-B_WbYMnB.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { curry } from "es-toolkit";
6
6
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { p as recordDocumentCache } from "./metrics-uwSF8DLC.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-B5vvJYMV.mjs";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { preloadedContexts } from "@fedify/vocab-runtime";
7
7
  //#region src/utils/kv-cache.ts
@@ -1,9 +1,9 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-DTaoLXHr.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-uwSF8DLC.mjs";
6
- import { n as fetchKey, o as validateCryptoKey } from "./key-Bhsx9PrC.mjs";
4
+ import { n as version, t as name } from "./deno-BUzynMVz.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-B5vvJYMV.mjs";
6
+ import { n as fetchKey, o as validateCryptoKey } from "./key-DdP4HxTK.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-DTaoLXHr.mjs";
4
+ import { n as version, t as name } from "./deno-BUzynMVz.mjs";
5
5
  import { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -21,6 +21,7 @@ var FederationMetrics = class {
21
21
  queueTaskFailed;
22
22
  queueTaskDuration;
23
23
  queueTaskInFlight;
24
+ queueDepth;
24
25
  fanoutRecipients;
25
26
  inboxActivity;
26
27
  outboxActivity;
@@ -52,7 +53,22 @@ var FederationMetrics = class {
52
53
  });
53
54
  this.signatureVerificationDuration = meter.createHistogram("activitypub.signature.verification.duration", {
54
55
  description: "Duration of ActivityPub signature verification, including local key lookup and remote key fetches.",
55
- unit: "ms"
56
+ unit: "ms",
57
+ advice: { explicitBucketBoundaries: [
58
+ .1,
59
+ .25,
60
+ .5,
61
+ 1,
62
+ 2.5,
63
+ 5,
64
+ 10,
65
+ 25,
66
+ 50,
67
+ 100,
68
+ 250,
69
+ 500,
70
+ 1e3
71
+ ] }
56
72
  });
57
73
  this.signatureKeyFetchDuration = meter.createHistogram("activitypub.signature.key_fetch.duration", {
58
74
  description: "Duration of public key lookup performed during ActivityPub signature verification.",
@@ -130,6 +146,10 @@ var FederationMetrics = class {
130
146
  description: "Queue tasks currently being processed in this Fedify process.",
131
147
  unit: "{task}"
132
148
  });
149
+ this.queueDepth = meter.createObservableGauge("fedify.queue.depth", {
150
+ description: "Messages waiting in configured Fedify queues, as reported by the queue backend.",
151
+ unit: "{message}"
152
+ });
133
153
  this.fanoutRecipients = meter.createHistogram("activitypub.fanout.recipients", {
134
154
  description: "Number of recipient inboxes produced by an ActivityPub fanout task.",
135
155
  unit: "{recipient}"
@@ -437,6 +457,57 @@ function getQueueBackend(queue) {
437
457
  return name;
438
458
  }
439
459
  /**
460
+ * Registers a callback for observing queue backend depth.
461
+ * @since 2.3.0
462
+ */
463
+ function registerQueueDepthGauge(meterProvider, entries, options = {}) {
464
+ const uniqueQueues = /* @__PURE__ */ new Map();
465
+ for (const { role, queue } of entries) {
466
+ if (queue?.getDepth == null) continue;
467
+ const roles = uniqueQueues.get(queue);
468
+ if (roles == null) uniqueQueues.set(queue, [role]);
469
+ else if (!roles.includes(role)) roles.push(role);
470
+ }
471
+ if (uniqueQueues.size < 1) return;
472
+ const queueEntries = Array.from(uniqueQueues.entries());
473
+ getFederationMetrics(meterProvider).queueDepth.addCallback(async (observableResult) => {
474
+ await Promise.all(queueEntries.map(async ([queue, roles]) => {
475
+ let depth;
476
+ try {
477
+ depth = await queue.getDepth();
478
+ } catch {
479
+ return;
480
+ }
481
+ if (depth == null) return;
482
+ const attributes = buildQueueDepthAttributes(queue, roles, options);
483
+ observableResult.observe(depth.queued, {
484
+ ...attributes,
485
+ "fedify.queue.depth.state": "queued"
486
+ });
487
+ if (depth.ready != null) observableResult.observe(depth.ready, {
488
+ ...attributes,
489
+ "fedify.queue.depth.state": "ready"
490
+ });
491
+ if (depth.delayed != null) observableResult.observe(depth.delayed, {
492
+ ...attributes,
493
+ "fedify.queue.depth.state": "delayed"
494
+ });
495
+ }));
496
+ });
497
+ }
498
+ function buildQueueDepthAttributes(queue, roles, options) {
499
+ const sortedRoles = roles.toSorted();
500
+ const role = sortedRoles.length === 1 ? sortedRoles[0] : "shared";
501
+ const attributes = { "fedify.queue.role": role };
502
+ if (options.sourceId != null) attributes["fedify.federation.instance_id"] = options.sourceId;
503
+ if (role === "shared") attributes["fedify.queue.roles"] = sortedRoles.join(",");
504
+ const backend = getQueueBackend(queue);
505
+ if (backend != null) attributes["fedify.queue.backend"] = backend;
506
+ const nativeRetrial = queue.nativeRetrial;
507
+ if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
508
+ return attributes;
509
+ }
510
+ /**
440
511
  * Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue and,
441
512
  * for the initial attempt, also records
442
513
  * `activitypub.outbox.activity{queued}`.
@@ -741,4 +812,4 @@ function getDurationMs(start) {
741
812
  return Math.max(0, performance.now() - start);
742
813
  }
743
814
  //#endregion
744
- export { recordKeyLookup as _, instrumentDocumentLoader as a, recordWebFingerHandle as b, recordCircuitBreakerStateChange as c, recordCollectionRequest as d, recordCollectionTotalItems as f, recordInboxActivity as g, recordFanoutRecipients as h, getRemoteHost as i, recordCollectionDispatchDuration as l, recordDocumentFetch as m, getDurationMs as n, isAbortError as o, recordDocumentCache as p, getFederationMetrics as r, measureSignatureKeyFetch as s, classifyFetchError as t, recordCollectionPageItems as u, recordOutboxActivity as v, recordOutboxEnqueue as y };
815
+ export { recordKeyLookup as _, instrumentDocumentLoader as a, recordWebFingerHandle as b, recordCircuitBreakerStateChange as c, recordCollectionRequest as d, recordCollectionTotalItems as f, recordInboxActivity as g, recordFanoutRecipients as h, getRemoteHost as i, recordCollectionDispatchDuration as l, recordDocumentFetch as m, getDurationMs as n, isAbortError as o, recordDocumentCache as p, getFederationMetrics as r, measureSignatureKeyFetch as s, classifyFetchError as t, recordCollectionPageItems as u, recordOutboxActivity as v, registerQueueDepthGauge as x, recordOutboxEnqueue as y };