@fedify/fedify 2.4.0-dev.1564 → 2.4.0-dev.1570

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 (113) hide show
  1. package/README.md +4 -0
  2. package/dist/{assert-OguE97r2.mjs → assert-DvVHoIZ0.mjs} +1 -1
  3. package/dist/{assert_instance_of-DBC5X09g.mjs → assert_instance_of-CxoC8bVq.mjs} +1 -1
  4. package/dist/{assert_not_equals-DkVK8oqV.mjs → assert_not_equals-C8vcTTA3.mjs} +1 -1
  5. package/dist/{assert_rejects-DN60FHPX.mjs → assert_rejects-DAdaaIWM.mjs} +2 -2
  6. package/dist/{assert_strict_equals-XEgZAlrj.mjs → assert_strict_equals-BzqyKuYL.mjs} +1 -1
  7. package/dist/{assert_throws-BOkhLGYc.mjs → assert_throws-zN79lgIC.mjs} +1 -1
  8. package/dist/{builder-DQrTY2uR.mjs → builder-CJnWbgbj.mjs} +23 -3
  9. package/dist/codec-nfBU4Up4.mjs +124 -0
  10. package/dist/compat/mod.d.cts +1 -1
  11. package/dist/compat/mod.d.ts +1 -1
  12. package/dist/compat/outgoing-jsonld.test.mjs +3 -3
  13. package/dist/compat/public-audience.test.mjs +3 -3
  14. package/dist/compat/transformers.test.mjs +5 -5
  15. package/dist/{context-DVoTs_wM.mjs → context-BBRTgkrs.mjs} +8 -2
  16. package/dist/{context-BBVLF7lx.d.cts → context-BLe0NPtZ.d.cts} +530 -259
  17. package/dist/{context-BU6jSQdo.d.ts → context-GfQA-CqB.d.ts} +529 -259
  18. package/dist/{deno-0Q35TVjL.mjs → deno-klNxGW7W.mjs} +1 -1
  19. package/dist/{docloader-DnNi7FT5.mjs → docloader-CuFH35j1.mjs} +3 -3
  20. package/dist/federation/builder.test.mjs +5 -5
  21. package/dist/federation/circuit-breaker.test.mjs +5 -5
  22. package/dist/federation/collection.test.mjs +3 -3
  23. package/dist/federation/handler.test.mjs +13 -23
  24. package/dist/federation/idempotency.test.mjs +6 -6
  25. package/dist/federation/inbox.test.mjs +3 -3
  26. package/dist/federation/keycache.test.mjs +5 -5
  27. package/dist/federation/kv.test.mjs +3 -3
  28. package/dist/federation/metrics.test.mjs +4 -4
  29. package/dist/federation/middleware.test.mjs +204 -19
  30. package/dist/federation/mod.cjs +3 -259
  31. package/dist/federation/mod.d.cts +4 -4
  32. package/dist/federation/mod.d.ts +4 -4
  33. package/dist/federation/mod.js +1 -257
  34. package/dist/federation/mq.test.mjs +103 -261
  35. package/dist/federation/negotiation.test.mjs +4 -4
  36. package/dist/federation/retry.test.mjs +3 -3
  37. package/dist/federation/router.test.mjs +5 -5
  38. package/dist/federation/send.test.mjs +10 -10
  39. package/dist/federation/tasks/codec.test.d.mts +2 -0
  40. package/dist/federation/tasks/codec.test.mjs +302 -0
  41. package/dist/federation/tasks/enqueue.test.d.mts +2 -0
  42. package/dist/federation/tasks/enqueue.test.mjs +1057 -0
  43. package/dist/federation/tasks/tasks.test.d.mts +2 -0
  44. package/dist/federation/tasks/tasks.test.mjs +1228 -0
  45. package/dist/federation/temporal.test.mjs +4 -4
  46. package/dist/federation/webfinger.test.mjs +6 -6
  47. package/dist/{http-BjTMQwgu.js → http-D0jH0kco.js} +6 -4
  48. package/dist/{http-Blx3a-we.cjs → http-DeuPW1Oh.cjs} +6 -4
  49. package/dist/{http-ZYObKFyR.mjs → http-JdRPUYku.mjs} +4 -4
  50. package/dist/{key-By86iSF1.mjs → key-o0_ipvUR.mjs} +2 -2
  51. package/dist/{kv-cache-BB6kQbPO.cjs → kv-cache-C3rqzQvu.cjs} +1 -1
  52. package/dist/{kv-cache-W72QYEvy.mjs → kv-cache-CM7w20U5.mjs} +1 -1
  53. package/dist/{kv-cache-3GvEiOJJ.js → kv-cache-DSWq2JHU.js} +1 -1
  54. package/dist/{ld-uNPJsHf9.mjs → ld-C__CEgQH.mjs} +3 -3
  55. package/dist/{metrics-D7atQvAx.mjs → metrics-CLSPm4dZ.mjs} +6 -4
  56. package/dist/{mq-D-nlpY04.d.ts → metrics-CoUJLQhZ.d.cts} +69 -1
  57. package/dist/{mq-D8uSFzxe.d.cts → metrics-Dc4jR-IC.d.ts} +69 -1
  58. package/dist/{middleware-DM5XOWG5.cjs → middleware-B502nwxx.cjs} +874 -134
  59. package/dist/{middleware-DYaez_JC.mjs → middleware-CdMiavoh.mjs} +1 -1
  60. package/dist/{middleware-B3XvOhoB.mjs → middleware-CjHqy-1i.mjs} +469 -150
  61. package/dist/{middleware-ICGLZUHG.js → middleware-zuLSkPIk.js} +863 -135
  62. package/dist/{mod-C0F6kvgS.d.cts → mod-B8Efb9qp.d.cts} +1 -1
  63. package/dist/{mod-yvIXFAEi.d.cts → mod-BtEaIEcD.d.cts} +1 -31
  64. package/dist/{mod-vPYVoa5n.d.ts → mod-Cmr39iWq.d.ts} +1 -1
  65. package/dist/{mod-DFvNJcNb.d.ts → mod-UMmveiO0.d.ts} +1 -31
  66. package/dist/mod.cjs +6 -6
  67. package/dist/mod.d.cts +6 -6
  68. package/dist/mod.d.ts +6 -6
  69. package/dist/mod.js +5 -5
  70. package/dist/mq-03vS-C9P.mjs +276 -0
  71. package/dist/nodeinfo/client.test.mjs +3 -3
  72. package/dist/nodeinfo/handler.test.mjs +5 -5
  73. package/dist/nodeinfo/types.test.mjs +4 -4
  74. package/dist/otel/exporter.test.mjs +3 -3
  75. package/dist/{outgoing-jsonld-L_DbOaFe.mjs → outgoing-jsonld-BNL8AC14.mjs} +1 -1
  76. package/dist/{owner-C1IdnJbE.mjs → owner-gz4TUfKG.mjs} +2 -2
  77. package/dist/{proof-B0wYpR4P.cjs → proof-CiDzRtr0.cjs} +1 -1
  78. package/dist/{proof-3th48TRO.mjs → proof-CuQpZ_AT.mjs} +5 -5
  79. package/dist/{proof-hzw73GGW.js → proof-DQWTf6oB.js} +1 -1
  80. package/dist/{send-BqPEr21p.mjs → send-B60teucv.mjs} +3 -3
  81. package/dist/sig/accept.test.mjs +1 -1
  82. package/dist/sig/http.test.mjs +8 -8
  83. package/dist/sig/key.test.mjs +6 -6
  84. package/dist/sig/ld.test.mjs +7 -7
  85. package/dist/sig/mod.cjs +2 -2
  86. package/dist/sig/mod.js +2 -2
  87. package/dist/sig/owner.test.mjs +6 -6
  88. package/dist/sig/proof.test.mjs +8 -8
  89. package/dist/{std__assert-BBjXFNOb.mjs → std__assert-Dh6uLf_q.mjs} +4 -4
  90. package/dist/{temporal-C7NUQ3nU.mjs → temporal-CvVMrvJJ.mjs} +1 -1
  91. package/dist/testing/mod.d.mts +1037 -8
  92. package/dist/testing/mod.mjs +3 -2
  93. package/dist/testing-Dy-WhqpN.mjs +77 -0
  94. package/dist/utils/docloader.test.mjs +6 -6
  95. package/dist/utils/kv-cache.test.mjs +1 -1
  96. package/dist/utils/mod.cjs +1 -1
  97. package/dist/utils/mod.d.cts +1 -1
  98. package/dist/utils/mod.d.ts +1 -1
  99. package/dist/utils/mod.js +1 -1
  100. package/package.json +8 -6
  101. /package/dist/{accept-CPkZzmGN.mjs → accept-CgDcxvjV.mjs} +0 -0
  102. /package/dist/{activity-listener-tztVvlNb.mjs → activity-listener-BeTGV3wc.mjs} +0 -0
  103. /package/dist/{assert_equals-C-ZRDbaf.mjs → assert_equals-PBVKNMJd.mjs} +0 -0
  104. /package/dist/{circuit-breaker-CSWsyoef.mjs → circuit-breaker-hJBB6jwA.mjs} +0 -0
  105. /package/dist/{client-ByXmQhYD.mjs → client-B_A6mfn3.mjs} +0 -0
  106. /package/dist/{collection-Cc3DVAhE.mjs → collection-Dp5ky45w.mjs} +0 -0
  107. /package/dist/{keycache-BeU0LCII.mjs → keycache-CaOR6NYg.mjs} +0 -0
  108. /package/dist/{keys-DGu1NFwu.mjs → keys-CSYsOMFG.mjs} +0 -0
  109. /package/dist/{kv-rV3vodCc.mjs → kv-CIvR3Non.mjs} +0 -0
  110. /package/dist/{negotiation-DDstyBvc.mjs → negotiation-m_L2nyS3.mjs} +0 -0
  111. /package/dist/{public-audience-Cvbr2Gzt.mjs → public-audience-c9zmYKgA.mjs} +0 -0
  112. /package/dist/{retry-CXg_MBI-.mjs → retry-DI4O-zYl.mjs} +0 -0
  113. /package/dist/{types-J53Kw7so.mjs → types-BFowWFTT.mjs} +0 -0
@@ -1,10 +1,10 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import "../std__assert-BBjXFNOb.mjs";
5
- import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
6
- import { t as assert } from "../assert-OguE97r2.mjs";
7
- import { t as hasMalformedKnownTemporalLiteral } from "../temporal-C7NUQ3nU.mjs";
4
+ import "../std__assert-Dh6uLf_q.mjs";
5
+ import { r as assertFalse } from "../assert_rejects-DAdaaIWM.mjs";
6
+ import { t as assert } from "../assert-DvVHoIZ0.mjs";
7
+ import { t as hasMalformedKnownTemporalLiteral } from "../temporal-CvVMrvJJ.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 () => {
@@ -1,12 +1,12 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { r as createRequestContext } from "../context-DVoTs_wM.mjs";
5
- import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
6
- import "../std__assert-BBjXFNOb.mjs";
7
- import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
8
- import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
9
- import { o as createFederation, s as handleWebFinger } from "../middleware-B3XvOhoB.mjs";
4
+ import { r as createRequestContext } from "../context-BBRTgkrs.mjs";
5
+ import { t as MemoryKvStore } from "../kv-CIvR3Non.mjs";
6
+ import { t as assertEquals } from "../assert_equals-PBVKNMJd.mjs";
7
+ import "../std__assert-Dh6uLf_q.mjs";
8
+ import { t as assertNotEquals } from "../assert_not_equals-C8vcTTA3.mjs";
9
+ import { o as createFederation, s as handleWebFinger } from "../middleware-CjHqy-1i.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
@@ -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.4.0-dev.1564+5a2c6c2c";
13
+ var version = "2.4.0-dev.1570+f1b6aaa3";
14
14
  //#endregion
15
15
  //#region src/sig/accept.ts
16
16
  /**
@@ -472,10 +472,10 @@ var FederationMetrics = class {
472
472
  this.httpServerRequestCount.add(1, attributes);
473
473
  this.httpServerRequestDuration.record(durationMs, attributes);
474
474
  }
475
- recordQueueTaskEnqueued(common, attempt) {
475
+ recordQueueTaskEnqueued(common, attempt, count = 1) {
476
476
  const attributes = buildQueueTaskAttributes(common);
477
477
  attributes["fedify.queue.task.attempt"] = attempt;
478
- this.queueTaskEnqueued.add(1, attributes);
478
+ this.queueTaskEnqueued.add(count, attributes);
479
479
  }
480
480
  recordQueueTaskStarted(common) {
481
481
  this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
@@ -486,9 +486,10 @@ var FederationMetrics = class {
486
486
  decrementQueueTaskInFlight(common) {
487
487
  this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
488
488
  }
489
- recordQueueTaskOutcome(common, result, durationMs) {
489
+ recordQueueTaskOutcome(common, result, durationMs, failureReason) {
490
490
  const attributes = buildQueueTaskAttributes(common);
491
491
  attributes["fedify.queue.task.result"] = result;
492
+ if (failureReason != null && result === "failed") attributes["fedify.task.failure_reason"] = failureReason;
492
493
  if (result === "completed") this.queueTaskCompleted.add(1, attributes);
493
494
  else if (result === "failed") this.queueTaskFailed.add(1, attributes);
494
495
  this.queueTaskDuration.record(durationMs, attributes);
@@ -582,6 +583,7 @@ function buildQueueTaskAttributes(common) {
582
583
  const nativeRetrial = common.queue?.nativeRetrial;
583
584
  if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
584
585
  if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
586
+ if (common.taskName != null) attributes["fedify.task.name"] = common.taskName;
585
587
  return attributes;
586
588
  }
587
589
  function buildQueueTaskInFlightAttributes(common) {
@@ -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.4.0-dev.1564+5a2c6c2c";
14
+ var version = "2.4.0-dev.1570+f1b6aaa3";
15
15
  //#endregion
16
16
  //#region src/sig/accept.ts
17
17
  /**
@@ -473,10 +473,10 @@ var FederationMetrics = class {
473
473
  this.httpServerRequestCount.add(1, attributes);
474
474
  this.httpServerRequestDuration.record(durationMs, attributes);
475
475
  }
476
- recordQueueTaskEnqueued(common, attempt) {
476
+ recordQueueTaskEnqueued(common, attempt, count = 1) {
477
477
  const attributes = buildQueueTaskAttributes(common);
478
478
  attributes["fedify.queue.task.attempt"] = attempt;
479
- this.queueTaskEnqueued.add(1, attributes);
479
+ this.queueTaskEnqueued.add(count, attributes);
480
480
  }
481
481
  recordQueueTaskStarted(common) {
482
482
  this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
@@ -487,9 +487,10 @@ var FederationMetrics = class {
487
487
  decrementQueueTaskInFlight(common) {
488
488
  this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
489
489
  }
490
- recordQueueTaskOutcome(common, result, durationMs) {
490
+ recordQueueTaskOutcome(common, result, durationMs, failureReason) {
491
491
  const attributes = buildQueueTaskAttributes(common);
492
492
  attributes["fedify.queue.task.result"] = result;
493
+ if (failureReason != null && result === "failed") attributes["fedify.task.failure_reason"] = failureReason;
493
494
  if (result === "completed") this.queueTaskCompleted.add(1, attributes);
494
495
  else if (result === "failed") this.queueTaskFailed.add(1, attributes);
495
496
  this.queueTaskDuration.record(durationMs, attributes);
@@ -583,6 +584,7 @@ function buildQueueTaskAttributes(common) {
583
584
  const nativeRetrial = common.queue?.nativeRetrial;
584
585
  if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
585
586
  if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
587
+ if (common.taskName != null) attributes["fedify.task.name"] = common.taskName;
586
588
  return attributes;
587
589
  }
588
590
  function buildQueueTaskInFlightAttributes(common) {
@@ -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-0Q35TVjL.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-D7atQvAx.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-By86iSF1.mjs";
4
+ import { n as version, t as name } from "./deno-klNxGW7W.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CLSPm4dZ.mjs";
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-o0_ipvUR.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-0Q35TVjL.mjs";
5
- import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-D7atQvAx.mjs";
4
+ import { n as version, t as name } from "./deno-klNxGW7W.mjs";
5
+ import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-CLSPm4dZ.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-Blx3a-we.cjs");
4
+ const require_http = require("./http-DeuPW1Oh.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,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-D7atQvAx.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-CLSPm4dZ.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,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-BjTMQwgu.js";
3
+ import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-D0jH0kco.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,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-0Q35TVjL.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-D7atQvAx.mjs";
6
- import { n as fetchKey, o as validateCryptoKey } from "./key-By86iSF1.mjs";
4
+ import { n as version, t as name } from "./deno-klNxGW7W.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CLSPm4dZ.mjs";
6
+ import { n as fetchKey, o as validateCryptoKey } from "./key-o0_ipvUR.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-0Q35TVjL.mjs";
4
+ import { n as version, t as name } from "./deno-klNxGW7W.mjs";
5
5
  import { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -325,10 +325,10 @@ var FederationMetrics = class {
325
325
  this.httpServerRequestCount.add(1, attributes);
326
326
  this.httpServerRequestDuration.record(durationMs, attributes);
327
327
  }
328
- recordQueueTaskEnqueued(common, attempt) {
328
+ recordQueueTaskEnqueued(common, attempt, count = 1) {
329
329
  const attributes = buildQueueTaskAttributes(common);
330
330
  attributes["fedify.queue.task.attempt"] = attempt;
331
- this.queueTaskEnqueued.add(1, attributes);
331
+ this.queueTaskEnqueued.add(count, attributes);
332
332
  }
333
333
  recordQueueTaskStarted(common) {
334
334
  this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
@@ -339,9 +339,10 @@ var FederationMetrics = class {
339
339
  decrementQueueTaskInFlight(common) {
340
340
  this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
341
341
  }
342
- recordQueueTaskOutcome(common, result, durationMs) {
342
+ recordQueueTaskOutcome(common, result, durationMs, failureReason) {
343
343
  const attributes = buildQueueTaskAttributes(common);
344
344
  attributes["fedify.queue.task.result"] = result;
345
+ if (failureReason != null && result === "failed") attributes["fedify.task.failure_reason"] = failureReason;
345
346
  if (result === "completed") this.queueTaskCompleted.add(1, attributes);
346
347
  else if (result === "failed") this.queueTaskFailed.add(1, attributes);
347
348
  this.queueTaskDuration.record(durationMs, attributes);
@@ -435,6 +436,7 @@ function buildQueueTaskAttributes(common) {
435
436
  const nativeRetrial = common.queue?.nativeRetrial;
436
437
  if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
437
438
  if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
439
+ if (common.taskName != null) attributes["fedify.task.name"] = common.taskName;
438
440
  return attributes;
439
441
  }
440
442
  function buildQueueTaskInFlightAttributes(common) {
@@ -1,4 +1,7 @@
1
1
  /// <reference lib="esnext.temporal" />
2
+ import { DocumentLoader } from "@fedify/vocab-runtime";
3
+ import { MeterProvider } from "@opentelemetry/api";
4
+
2
5
  //#region src/federation/mq.d.ts
3
6
  /**
4
7
  * Additional options for enqueuing a message in a queue.
@@ -24,6 +27,19 @@ interface MessageQueueEnqueueOptions {
24
27
  * @since 2.0.0
25
28
  */
26
29
  readonly orderingKey?: string;
30
+ /**
31
+ * An optional key requesting at-most-once enqueue semantics for messages
32
+ * that share it. A backend that declares
33
+ * {@link MessageQueue.nativeDeduplication} `true` owns the check: a message
34
+ * whose `deduplicationKey` was already seen within the backend's
35
+ * deduplication window is dropped instead of enqueued. Backends without
36
+ * native deduplication ignore this field; Fedify performs its own
37
+ * best-effort deduplication before reaching them on the paths that support
38
+ * it.
39
+ *
40
+ * @since 2.4.0
41
+ */
42
+ readonly deduplicationKey?: string;
27
43
  }
28
44
  /**
29
45
  * Additional options for listening to a message queue.
@@ -81,6 +97,17 @@ interface MessageQueue {
81
97
  */
82
98
  readonly nativeRetrial?: boolean;
83
99
  /**
100
+ * Whether the message queue backend deduplicates messages that share a
101
+ * {@link MessageQueueEnqueueOptions.deduplicationKey} natively. When `true`,
102
+ * Fedify forwards the `deduplicationKey` and relies on the backend to drop
103
+ * duplicates; when `false` or omitted, Fedify applies its own best-effort
104
+ * key–value deduplication on the paths that request it.
105
+ *
106
+ * @default `false`
107
+ * @since 2.4.0
108
+ */
109
+ readonly nativeDeduplication?: boolean;
110
+ /**
84
111
  * Enqueues a message in the queue.
85
112
  * @param message The message to enqueue.
86
113
  * @param options Additional options for enqueuing the message.
@@ -141,6 +168,11 @@ declare class InProcessMessageQueue implements MessageQueue {
141
168
  */
142
169
  readonly nativeRetrial = false;
143
170
  /**
171
+ * In-process message queue does not deduplicate messages natively.
172
+ * @since 2.4.0
173
+ */
174
+ readonly nativeDeduplication = false;
175
+ /**
144
176
  * Constructs a new {@link InProcessMessageQueue} with the given options.
145
177
  * @param options Additional options for the in-process message queue.
146
178
  */
@@ -189,6 +221,11 @@ declare class ParallelMessageQueue implements MessageQueue {
189
221
  * @since 1.7.0
190
222
  */
191
223
  readonly nativeRetrial?: boolean;
224
+ /**
225
+ * Inherits the native deduplication capability from the wrapped queue.
226
+ * @since 2.4.0
227
+ */
228
+ readonly nativeDeduplication?: boolean;
192
229
  readonly getDepth?: () => Promise<MessageQueueDepth>;
193
230
  /**
194
231
  * Constructs a new {@link ParallelMessageQueue} with the given queue and
@@ -205,4 +242,35 @@ declare class ParallelMessageQueue implements MessageQueue {
205
242
  listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
206
243
  }
207
244
  //#endregion
208
- export { MessageQueueEnqueueOptions as a, MessageQueueDepth as i, InProcessMessageQueueOptions as n, MessageQueueListenOptions as o, MessageQueue as r, ParallelMessageQueue as s, InProcessMessageQueue as t };
245
+ //#region src/federation/metrics.d.ts
246
+ /**
247
+ * The kind of remote ActivityPub lookup, recorded as
248
+ * `activitypub.lookup.kind` on the public-key lookup and remote document
249
+ * fetch metric families.
250
+ *
251
+ * - `public_key`: a public key lookup performed by `fetchKey` /
252
+ * `fetchKeyDetailed` (always recorded on `activitypub.key.lookup*`).
253
+ * - `actor`: a document fetch whose resolved value is an Actor. The
254
+ * bucket exists in the taxonomy for future actor-aware call sites;
255
+ * today, actor documents fetched through Fedify's generic document
256
+ * loader are still classified as `object` because the kind is decided
257
+ * at the loader boundary, before the response is parsed.
258
+ * - `object`: a generic ActivityPub object fetch through Fedify's
259
+ * document loader. This is the default classification for
260
+ * `documentLoader` invocations that do not match a more specific
261
+ * bucket.
262
+ * - `context`: a JSON-LD `@context` document fetch through Fedify's
263
+ * context loader.
264
+ * - `other`: a fetch that does not fit any of the above classifications.
265
+ * @since 2.3.0
266
+ */
267
+ type LookupKind = "public_key" | "actor" | "object" | "context" | "other";
268
+ /**
269
+ * The {@link LookupKind} values that can appear on remote document fetch
270
+ * metrics. `public_key` lookups are reported on the
271
+ * `activitypub.key.lookup` metric family instead, so it is excluded here.
272
+ * @since 2.3.0
273
+ */
274
+ type DocumentFetchKind = Exclude<LookupKind, "public_key">;
275
+ //#endregion
276
+ export { MessageQueueDepth as a, ParallelMessageQueue as c, MessageQueue as i, InProcessMessageQueue as n, MessageQueueEnqueueOptions as o, InProcessMessageQueueOptions as r, MessageQueueListenOptions as s, DocumentFetchKind as t };
@@ -1,4 +1,7 @@
1
1
  /// <reference lib="esnext.temporal" />
2
+ import { MeterProvider } from "@opentelemetry/api";
3
+ import { DocumentLoader } from "@fedify/vocab-runtime";
4
+
2
5
  //#region src/federation/mq.d.ts
3
6
  /**
4
7
  * Additional options for enqueuing a message in a queue.
@@ -24,6 +27,19 @@ interface MessageQueueEnqueueOptions {
24
27
  * @since 2.0.0
25
28
  */
26
29
  readonly orderingKey?: string;
30
+ /**
31
+ * An optional key requesting at-most-once enqueue semantics for messages
32
+ * that share it. A backend that declares
33
+ * {@link MessageQueue.nativeDeduplication} `true` owns the check: a message
34
+ * whose `deduplicationKey` was already seen within the backend's
35
+ * deduplication window is dropped instead of enqueued. Backends without
36
+ * native deduplication ignore this field; Fedify performs its own
37
+ * best-effort deduplication before reaching them on the paths that support
38
+ * it.
39
+ *
40
+ * @since 2.4.0
41
+ */
42
+ readonly deduplicationKey?: string;
27
43
  }
28
44
  /**
29
45
  * Additional options for listening to a message queue.
@@ -81,6 +97,17 @@ interface MessageQueue {
81
97
  */
82
98
  readonly nativeRetrial?: boolean;
83
99
  /**
100
+ * Whether the message queue backend deduplicates messages that share a
101
+ * {@link MessageQueueEnqueueOptions.deduplicationKey} natively. When `true`,
102
+ * Fedify forwards the `deduplicationKey` and relies on the backend to drop
103
+ * duplicates; when `false` or omitted, Fedify applies its own best-effort
104
+ * key–value deduplication on the paths that request it.
105
+ *
106
+ * @default `false`
107
+ * @since 2.4.0
108
+ */
109
+ readonly nativeDeduplication?: boolean;
110
+ /**
84
111
  * Enqueues a message in the queue.
85
112
  * @param message The message to enqueue.
86
113
  * @param options Additional options for enqueuing the message.
@@ -141,6 +168,11 @@ declare class InProcessMessageQueue implements MessageQueue {
141
168
  */
142
169
  readonly nativeRetrial = false;
143
170
  /**
171
+ * In-process message queue does not deduplicate messages natively.
172
+ * @since 2.4.0
173
+ */
174
+ readonly nativeDeduplication = false;
175
+ /**
144
176
  * Constructs a new {@link InProcessMessageQueue} with the given options.
145
177
  * @param options Additional options for the in-process message queue.
146
178
  */
@@ -189,6 +221,11 @@ declare class ParallelMessageQueue implements MessageQueue {
189
221
  * @since 1.7.0
190
222
  */
191
223
  readonly nativeRetrial?: boolean;
224
+ /**
225
+ * Inherits the native deduplication capability from the wrapped queue.
226
+ * @since 2.4.0
227
+ */
228
+ readonly nativeDeduplication?: boolean;
192
229
  readonly getDepth?: () => Promise<MessageQueueDepth>;
193
230
  /**
194
231
  * Constructs a new {@link ParallelMessageQueue} with the given queue and
@@ -205,4 +242,35 @@ declare class ParallelMessageQueue implements MessageQueue {
205
242
  listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
206
243
  }
207
244
  //#endregion
208
- export { MessageQueueEnqueueOptions as a, MessageQueueDepth as i, InProcessMessageQueueOptions as n, MessageQueueListenOptions as o, MessageQueue as r, ParallelMessageQueue as s, InProcessMessageQueue as t };
245
+ //#region src/federation/metrics.d.ts
246
+ /**
247
+ * The kind of remote ActivityPub lookup, recorded as
248
+ * `activitypub.lookup.kind` on the public-key lookup and remote document
249
+ * fetch metric families.
250
+ *
251
+ * - `public_key`: a public key lookup performed by `fetchKey` /
252
+ * `fetchKeyDetailed` (always recorded on `activitypub.key.lookup*`).
253
+ * - `actor`: a document fetch whose resolved value is an Actor. The
254
+ * bucket exists in the taxonomy for future actor-aware call sites;
255
+ * today, actor documents fetched through Fedify's generic document
256
+ * loader are still classified as `object` because the kind is decided
257
+ * at the loader boundary, before the response is parsed.
258
+ * - `object`: a generic ActivityPub object fetch through Fedify's
259
+ * document loader. This is the default classification for
260
+ * `documentLoader` invocations that do not match a more specific
261
+ * bucket.
262
+ * - `context`: a JSON-LD `@context` document fetch through Fedify's
263
+ * context loader.
264
+ * - `other`: a fetch that does not fit any of the above classifications.
265
+ * @since 2.3.0
266
+ */
267
+ type LookupKind = "public_key" | "actor" | "object" | "context" | "other";
268
+ /**
269
+ * The {@link LookupKind} values that can appear on remote document fetch
270
+ * metrics. `public_key` lookups are reported on the
271
+ * `activitypub.key.lookup` metric family instead, so it is excluded here.
272
+ * @since 2.3.0
273
+ */
274
+ type DocumentFetchKind = Exclude<LookupKind, "public_key">;
275
+ //#endregion
276
+ export { MessageQueueDepth as a, ParallelMessageQueue as c, MessageQueue as i, InProcessMessageQueue as n, MessageQueueEnqueueOptions as o, InProcessMessageQueueOptions as r, MessageQueueListenOptions as s, DocumentFetchKind as t };