@fedify/fedify 2.4.5-dev.2453 → 2.4.5

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 (119) hide show
  1. package/README.md +3 -0
  2. package/dist/{builder-CS2LjGi-.mjs → builder-CUAVOHg6.mjs} +2 -2
  3. package/dist/{client-D-XP_Ccb.d.cts → client-3InDZbba.d.cts} +0 -1
  4. package/dist/{client-D-XP_Ccb.d.ts → client-3InDZbba.d.ts} +0 -1
  5. package/dist/{client-CEnNz8O7.mjs → client-5SIFzW3q.mjs} +113 -64
  6. package/dist/compat/mod.d.cts +1 -1
  7. package/dist/compat/mod.d.ts +1 -1
  8. package/dist/compat/transformers.test.mjs +1 -1
  9. package/dist/{compound-proof-C6_4hMjm.mjs → compound-proof-BNjXclzO.mjs} +2 -2
  10. package/dist/{context-7NyiqIcg.d.ts → context-CVOOd9pD.d.ts} +28 -2
  11. package/dist/{context-tsYPJ2Ew.d.cts → context-D0gFIgev.d.cts} +28 -2
  12. package/dist/{deno-CTWhU1oT.mjs → deno-DcJISdwu.mjs} +1 -1
  13. package/dist/docloader-CP1UxMLL.mjs +136 -0
  14. package/dist/federation/builder.test.mjs +1 -1
  15. package/dist/federation/compound-fanout.test.mjs +6 -3
  16. package/dist/federation/handler-compound-proof.test.mjs +3 -3
  17. package/dist/federation/handler.test.mjs +4 -4
  18. package/dist/federation/hashlink-media.test.mjs +2 -2
  19. package/dist/federation/idempotency.test.mjs +2 -2
  20. package/dist/federation/inbox-report.test.mjs +5 -5
  21. package/dist/federation/inbox.test.mjs +1 -1
  22. package/dist/federation/metrics.test.mjs +1 -1
  23. package/dist/federation/middleware.test.mjs +465 -32
  24. package/dist/federation/mod.cjs +1 -1
  25. package/dist/federation/mod.d.cts +3 -3
  26. package/dist/federation/mod.d.ts +3 -3
  27. package/dist/federation/mod.js +1 -1
  28. package/dist/federation/outgoing-proof.test.mjs +9 -6
  29. package/dist/federation/portable-actor.test.mjs +3 -3
  30. package/dist/federation/portable-chain.test.mjs +3 -3
  31. package/dist/federation/portable-collection.test.mjs +4 -4
  32. package/dist/federation/portable-delivery.test.mjs +2 -2
  33. package/dist/federation/portable-gateway-keys.test.mjs +11 -5
  34. package/dist/federation/portable-inbox.test.mjs +4 -4
  35. package/dist/federation/portable-parse-uri.test.mjs +1 -1
  36. package/dist/federation/portable-route-activity.test.mjs +2 -2
  37. package/dist/federation/portable.test.mjs +3 -3
  38. package/dist/federation/send.test.mjs +498 -88
  39. package/dist/federation/tasks/enqueue.test.mjs +1 -1
  40. package/dist/federation/tasks/tasks.test.mjs +2 -2
  41. package/dist/federation/temporal.test.mjs +1 -1
  42. package/dist/federation/webfinger.test.mjs +1 -1
  43. package/dist/{federation-DWVfQYX_.cjs → federation-Bkfq2YpS.cjs} +240 -102
  44. package/dist/{http-Dx5s5-pP.cjs → http-DHVH0DqC.cjs} +179 -110
  45. package/dist/{http-rgt1uxns.mjs → http-DuGmr8J8.mjs} +204 -106
  46. package/dist/{http-y9FnJFIe.js → http-R0ty0Udi.js} +178 -109
  47. package/dist/{inbox-4AZHfaO8.mjs → inbox-Bl1Y0s_A.mjs} +2 -2
  48. package/dist/{key-DYxuyd-s.d.cts → key-CyCcut3h.d.ts} +1 -2
  49. package/dist/{key-C1nv7_jD.d.ts → key-VEL1QqHF.d.cts} +1 -2
  50. package/dist/{kv-cache-DmxFPJaR.cjs → kv-cache-BtBSBZi9.cjs} +72 -27
  51. package/dist/{kv-cache-C3QkJF-x.mjs → kv-cache-DAV2_U44.mjs} +1 -1
  52. package/dist/{kv-cache-w4yWxqS1.js → kv-cache-FnLtmATH.js} +73 -28
  53. package/dist/{ld-CT-bAqSC.mjs → ld-Cy5GqbvS.mjs} +2 -2
  54. package/dist/{metrics-DsFjgE5X.mjs → metrics-CW8LoN7n.mjs} +1 -1
  55. package/dist/{middleware-DC8Omn-e.mjs → middleware-CdP-lz8Q.mjs} +1 -1
  56. package/dist/{middleware-Ch9WIaoZ.mjs → middleware-D2fk45uN.mjs} +82 -42
  57. package/dist/{middleware-BCHbutlW.js → middleware-D4rQARvq.js} +241 -103
  58. package/dist/{mod-DEZXwV6J.d.ts → mod-B1Qt5cQQ.d.ts} +2 -9
  59. package/dist/{mod-Xj5P4s4d.d.ts → mod-B5COx5Wd.d.ts} +1 -1
  60. package/dist/{mod-CavhAgLw.d.cts → mod-BTxJG7ZH.d.cts} +1 -1
  61. package/dist/{mod-CtpF2BU5.d.ts → mod-CpyjFA9s.d.ts} +1 -1
  62. package/dist/{mod-BojP2Bw3.d.cts → mod-makPMVMg.d.cts} +1 -1
  63. package/dist/{mod-Dw-nPxQh.d.cts → mod-ss0wBUH1.d.cts} +2 -9
  64. package/dist/mod.cjs +5 -5
  65. package/dist/mod.d.cts +6 -6
  66. package/dist/mod.d.ts +6 -6
  67. package/dist/mod.js +5 -5
  68. package/dist/nodeinfo/client.test.mjs +337 -19
  69. package/dist/nodeinfo/handler.test.mjs +1 -1
  70. package/dist/nodeinfo/mod.cjs +1 -1
  71. package/dist/nodeinfo/mod.d.cts +1 -1
  72. package/dist/nodeinfo/mod.d.ts +1 -1
  73. package/dist/nodeinfo/mod.js +1 -1
  74. package/dist/otel/exporter.test.mjs +292 -30
  75. package/dist/otel/mod.cjs +36 -30
  76. package/dist/otel/mod.d.cts +13 -0
  77. package/dist/otel/mod.d.ts +13 -0
  78. package/dist/otel/mod.js +36 -30
  79. package/dist/{owner-BGYYk-xi.mjs → owner-CbQZqFim.mjs} +3 -3
  80. package/dist/{portable-collection-DzEc4cB2.js → portable-collection-B5Aryi8I.js} +1 -1
  81. package/dist/{portable-collection-Cwn7DM0G.cjs → portable-collection-C_Kmvl3q.cjs} +1 -1
  82. package/dist/{portable-collection-DJSwe8QM.mjs → portable-collection-D2JYDadi.mjs} +2 -2
  83. package/dist/{portable-key-Dc6N1SEB.mjs → portable-key-Cc-ctNU2.mjs} +1 -1
  84. package/dist/{proof-DP93iZiH.mjs → proof-UN4CW55z.mjs} +3 -3
  85. package/dist/{send-c6buRbhI.mjs → send-BzbX2e6v.mjs} +174 -76
  86. package/dist/sig/compound-proof-discovery.test.mjs +1 -1
  87. package/dist/sig/compound-proof-producer.test.mjs +1 -1
  88. package/dist/sig/compound-proof-verification.test.mjs +2 -2
  89. package/dist/sig/compound-proof.test.mjs +2 -2
  90. package/dist/sig/http.test.mjs +553 -2
  91. package/dist/sig/key.test.mjs +1 -1
  92. package/dist/sig/ld.test.mjs +1 -1
  93. package/dist/sig/mitra-receive-interop.test.mjs +4 -4
  94. package/dist/sig/mitra-send-interop.test.mjs +3 -3
  95. package/dist/sig/mod.cjs +2 -2
  96. package/dist/sig/mod.d.cts +2 -2
  97. package/dist/sig/mod.d.ts +2 -2
  98. package/dist/sig/mod.js +2 -2
  99. package/dist/sig/owner.test.mjs +1 -1
  100. package/dist/sig/portable-collection.test.mjs +1 -1
  101. package/dist/sig/portable-interop.test.mjs +3 -3
  102. package/dist/sig/portable-key.test.mjs +5 -5
  103. package/dist/sig/proof.test.mjs +4 -4
  104. package/dist/sig/tootik-request-interop.test.mjs +4 -4
  105. package/dist/sig/tootik-send-interop.test.mjs +3 -3
  106. package/dist/sig/verification.test.mjs +3 -3
  107. package/dist/{temporal-DfC1NkLg.mjs → temporal-B7Wvxrjs.mjs} +1 -1
  108. package/dist/testing/kv.test.mjs +1 -1
  109. package/dist/testing/mod.d.mts +26 -0
  110. package/dist/{types-_S2_MeLF.js → types-DUjZb4i6.js} +112 -63
  111. package/dist/{types-poIao40f.cjs → types-hKCCjii0.cjs} +111 -62
  112. package/dist/utils/docloader.test.mjs +344 -36
  113. package/dist/utils/kv-cache.test.mjs +1 -1
  114. package/dist/utils/mod.cjs +1 -1
  115. package/dist/utils/mod.d.cts +1 -1
  116. package/dist/utils/mod.d.ts +1 -1
  117. package/dist/utils/mod.js +1 -1
  118. package/package.json +7 -7
  119. package/dist/docloader-CXFE-n2O.mjs +0 -91
@@ -2,20 +2,21 @@ import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { t as __exportAll } from "./rolldown-runtime-BC-Eo5Mj.js";
4
4
  import { r as getDefaultActivityTransformers } from "./transformers-DAtXl_Kc.js";
5
- import { $ as instrumentDocumentLoader, A as hasSignature, At as isPortableUri, C as InvalidContextReferenceError, Ct as getGatewayKeyBase, Dt as isCompatibleKeyId, E as compactJsonLd, Et as hasPortableActor, F as verifyCompactJsonLd, G as validateCryptoKey, M as isClearlyMalformedContextReference, N as isInvalidUrlTypeError, Nt as name, O as detachSignature, Ot as isPortableId, P as signJsonLd, Pt as version, Q as getRemoteHost, R as wrapContextLoaderForJsonLd, S as normalizeOutgoingActivityJsonLd, St as getCanonicalPortableId, Tt as getRawCanonicalPortableId, W as importJwk, X as getDurationMs, Z as getFederationMetrics, _ as verifyObject, at as recordCollectionTotalItems, b as verifyPortableObjectProofWithRoot, bt as verificationObservation, c as verifyRequestDetailed, ct as recordInboxActivity, d as InvalidPortableObjectIdError, dt as recordWebFingerHandle, et as isAbortError, f as classifyFep2277CoreType, ft as registerQueueDepthGauge, g as verifyMapLocalProof, h as signObject, i as selectRequestSignature, it as recordCollectionRequest, j as hasSignatureLike, jt as isSameObjectId, k as getNormalizationContextLoader, kt as isPortableKeyId, lt as recordOutboxActivity, m as hasProofLike, mt as formatAcceptSignature, n as listRequestSignatures, nt as recordCollectionDispatchDuration, o as validateMaxSignatures, pt as preloadedOnlyDocumentLoader, q as MAX_PORTABLE_KEY_TTL, r as parseRfc9421SignatureInput, rt as recordCollectionPageItems, s as verifyRequest, st as recordFanoutRecipients, t as doubleKnock, tt as recordCircuitBreakerStateChange, ut as recordOutboxEnqueue, v as verifyPortableObjectProof, vt as observeAttempt, w as assertSafeJsonLd, wt as getPortableDid, xt as getAuthenticationOrigin, y as verifyPortableObjectProofPolicy, yt as snapshotKey, z as exportJwk } from "./http-y9FnJFIe.js";
6
- import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-_S2_MeLF.js";
7
- import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "./portable-collection-DzEc4cB2.js";
8
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-w4yWxqS1.js";
5
+ import { $ as instrumentDocumentLoader, A as hasSignature, At as isPortableUri, C as InvalidContextReferenceError, Ct as getGatewayKeyBase, Dt as isCompatibleKeyId, E as compactJsonLd, Et as hasPortableActor, F as verifyCompactJsonLd, G as validateCryptoKey, M as isClearlyMalformedContextReference, N as isInvalidUrlTypeError, Nt as name, O as detachSignature, Ot as isPortableId, P as signJsonLd, Pt as version, Q as getRemoteHost, R as wrapContextLoaderForJsonLd, S as normalizeOutgoingActivityJsonLd, St as getCanonicalPortableId, Tt as getRawCanonicalPortableId, W as importJwk, X as getDurationMs, Z as getFederationMetrics, _ as verifyObject, at as recordCollectionTotalItems, b as verifyPortableObjectProofWithRoot, bt as verificationObservation, c as verifyRequestDetailed, ct as recordInboxActivity, d as InvalidPortableObjectIdError, dt as recordWebFingerHandle, et as isAbortError, f as classifyFep2277CoreType, ft as registerQueueDepthGauge, g as verifyMapLocalProof, h as signObject, i as selectRequestSignature, it as recordCollectionRequest, j as hasSignatureLike, jt as isSameObjectId, k as getNormalizationContextLoader, kt as isPortableKeyId, lt as recordOutboxActivity, m as hasProofLike, mt as formatAcceptSignature, n as listRequestSignatures, nt as recordCollectionDispatchDuration, o as validateMaxSignatures, pt as preloadedOnlyDocumentLoader, q as MAX_PORTABLE_KEY_TTL, r as parseRfc9421SignatureInput, rt as recordCollectionPageItems, s as verifyRequest, st as recordFanoutRecipients, t as doubleKnockScoped, tt as recordCircuitBreakerStateChange, ut as recordOutboxEnqueue, v as verifyPortableObjectProof, vt as observeAttempt, w as assertSafeJsonLd, wt as getPortableDid, xt as getAuthenticationOrigin, y as verifyPortableObjectProofPolicy, yt as snapshotKey, z as exportJwk } from "./http-R0ty0Udi.js";
6
+ import { a as MAX_BODY_SIZE, i as BodyTooLargeError, n as getNodeInfo, o as readBoundedText, t as nodeInfoToJson } from "./types-DUjZb4i6.js";
7
+ import { n as doesActorOwnKey, r as getKeyOwner, t as verifyPortableObject } from "./portable-collection-B5Aryi8I.js";
8
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-FnLtmATH.js";
9
9
  import { getLogger, withContext } from "@logtape/logtape";
10
10
  import { Router, RouterError, assertPath } from "@fedify/uri-template";
11
11
  import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, PUBLIC_COLLECTION, Tombstone, getTypeId, isActor, lookupObject, traverseCollection } from "@fedify/vocab";
12
12
  import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
13
- import { FetchError, UrlError, canonicalizePortableUri, decodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDigestMultibase, parseHashlink, parseIri, preloadedContexts, resolveDocumentLoaderTimeout, toCompatibleEf61Id, validatePublicUrl } from "@fedify/vocab-runtime";
13
+ import { FetchError, UrlError, canonicalizePortableUri, decodeMultibase, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, isGatewayUrl, parseDigestMultibase, parseHashlink, parseIri, preloadedContexts, resolveDocumentLoaderTimeout, toCompatibleEf61Id } from "@fedify/vocab-runtime";
14
14
  import { getPortableGatewayCandidates, isCompatibleEf61Iri } from "@fedify/vocab-runtime/internal/portable-dereference";
15
15
  import { encodeHex } from "byte-encodings/hex";
16
16
  import jsonld from "@fedify/vocab-runtime/jsonld";
17
17
  import { uniq } from "es-toolkit";
18
18
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
19
+ import { openDirectFetch, openPublicFetch } from "@fedify/vocab-runtime/internal";
19
20
  import { lookupWebFinger } from "@fedify/webfinger";
20
21
  import { DataPointType, MeterProvider as MeterProvider$1, MetricReader } from "@opentelemetry/sdk-metrics";
21
22
  import { parse, stringifyAsync } from "devalue";
@@ -3617,9 +3618,10 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
3617
3618
  *
3618
3619
  * @param parameters The parameters for sending the activity.
3619
3620
  * See also {@link SendActivityParameters}.
3621
+ * @param deps The dependencies, for tests.
3620
3622
  * @throws {Error} If the activity fails to send.
3621
3623
  */
3622
- function sendActivity(options) {
3624
+ function sendActivity(options, deps = {}) {
3623
3625
  const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
3624
3626
  return tracerProvider.getTracer(name, version).startActiveSpan("activitypub.send_activity", {
3625
3627
  kind: SpanKind.CLIENT,
@@ -3631,7 +3633,7 @@ function sendActivity(options) {
3631
3633
  await sendActivityInternal({
3632
3634
  ...options,
3633
3635
  tracerProvider
3634
- }, span);
3636
+ }, span, deps);
3635
3637
  } catch (e) {
3636
3638
  span.setStatus({
3637
3639
  code: SpanStatusCode.ERROR,
@@ -3716,13 +3718,14 @@ async function readLimitedResponseBody(response, maxBytes) {
3716
3718
  totalBytes += value.length;
3717
3719
  }
3718
3720
  } finally {
3721
+ if (truncated) reader.cancel().catch(() => {});
3719
3722
  reader.releaseLock();
3720
3723
  }
3721
3724
  let result = chunks.join("");
3722
3725
  if (truncated) result += "… (truncated)";
3723
3726
  return result;
3724
3727
  }
3725
- async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, allowPrivateAddress, headers, specDeterminer, meterProvider, tracerProvider }, span) {
3728
+ async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, allowPrivateAddress, headers, specDeterminer, meterProvider, tracerProvider }, span, deps) {
3726
3729
  const logger = getLogger([
3727
3730
  "fedify",
3728
3731
  "federation",
@@ -3731,9 +3734,11 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
3731
3734
  const federationMetrics = getFederationMetrics(meterProvider);
3732
3735
  const started = performance.now();
3733
3736
  let deliverySuccess = false;
3734
- async function validateUrl(url) {
3735
- if (!allowPrivateAddress) try {
3736
- await validatePublicUrl(url);
3737
+ const openUnvalidatedHop = deps.openHop ?? (allowPrivateAddress ? openDirectFetch : (url) => openPublicFetch(url));
3738
+ async function openHop(url) {
3739
+ let session;
3740
+ try {
3741
+ session = await openUnvalidatedHop(url);
3737
3742
  } catch (error) {
3738
3743
  if (error instanceof UrlError && error.reason === "dns") {
3739
3744
  logger.error("DNS resolution failed for URL: {url}", {
@@ -3750,82 +3755,90 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
3750
3755
  });
3751
3756
  throw error;
3752
3757
  }
3758
+ return session;
3753
3759
  }
3760
+ let initialSession;
3754
3761
  try {
3755
- await validateUrl(inbox.href);
3762
+ initialSession = await openHop(inbox.href);
3756
3763
  } catch (error) {
3757
3764
  if (error instanceof FetchError) federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
3758
3765
  throw error;
3759
3766
  }
3760
- headers = new Headers(headers);
3761
- headers.set("Content-Type", "application/activity+json");
3762
- const request = new Request(inbox, {
3763
- method: "POST",
3764
- headers,
3765
- body: JSON.stringify(activity),
3766
- redirect: "manual"
3767
- });
3768
- let rsaKey = null;
3769
- for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
3770
- rsaKey = key;
3771
- break;
3772
- }
3773
- if (rsaKey == null && keys.length < 1) logger.debug("Sending the activity {activityId} to {inbox} without a signature.", {
3774
- activityId,
3775
- inbox: inbox.href
3776
- });
3777
- else if (rsaKey == null) logger.warn("No supported key found to sign the request to {inbox}. The request will be sent without a signature. In order to sign the request, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
3778
- inbox: inbox.href,
3779
- keys: keys.map((pair) => ({
3780
- keyId: pair.keyId.href,
3781
- privateKey: pair.privateKey
3782
- }))
3783
- });
3784
- let response;
3767
+ let initialPending = true;
3768
+ const openDeliveryHop = (url) => {
3769
+ if (initialPending) {
3770
+ initialPending = false;
3771
+ return Promise.resolve(initialSession);
3772
+ }
3773
+ return openHop(url);
3774
+ };
3785
3775
  try {
3786
- response = rsaKey == null ? await fetchWithValidatedRedirects(request, validateUrl) : await doubleKnock(request, rsaKey, {
3787
- tracerProvider,
3788
- specDeterminer,
3789
- validateRedirect: validateUrl
3776
+ headers = new Headers(headers);
3777
+ headers.set("Content-Type", "application/activity+json");
3778
+ const request = new Request(inbox, {
3779
+ method: "POST",
3780
+ headers,
3781
+ body: JSON.stringify(activity),
3782
+ redirect: "manual"
3790
3783
  });
3791
- } catch (error) {
3792
- const failure = error instanceof FetchError || error instanceof UrlError ? error : createFetchError(inbox.href, error);
3793
- logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
3784
+ let rsaKey = null;
3785
+ for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
3786
+ rsaKey = key;
3787
+ break;
3788
+ }
3789
+ if (rsaKey == null && keys.length < 1) logger.debug("Sending the activity {activityId} to {inbox} without a signature.", {
3794
3790
  activityId,
3791
+ inbox: inbox.href
3792
+ });
3793
+ else if (rsaKey == null) logger.warn("No supported key found to sign the request to {inbox}. The request will be sent without a signature. In order to sign the request, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
3795
3794
  inbox: inbox.href,
3796
- error: failure
3795
+ keys: keys.map((pair) => ({
3796
+ keyId: pair.keyId.href,
3797
+ privateKey: pair.privateKey
3798
+ }))
3797
3799
  });
3798
- federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
3799
- throw failure;
3800
- }
3801
- try {
3802
- if (!response.ok) {
3803
- let error;
3804
- try {
3805
- error = await readLimitedResponseBody(response, MAX_ERROR_RESPONSE_BODY_BYTES);
3806
- } catch (_) {
3807
- error = "";
3808
- }
3809
- logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
3800
+ let outcome;
3801
+ try {
3802
+ outcome = rsaKey == null ? await fetchWithValidatedRedirects(request, openDeliveryHop, (response) => consumeSendActivityResponse(response, inbox)) : await doubleKnockScoped(request, rsaKey, {
3803
+ tracerProvider,
3804
+ specDeterminer
3805
+ }, openDeliveryHop, (response) => consumeSendActivityResponse(response, inbox));
3806
+ } catch (error) {
3807
+ const failure = error instanceof FetchError || error instanceof UrlError ? error : createFetchError(inbox.href, error);
3808
+ logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
3810
3809
  activityId,
3811
3810
  inbox: inbox.href,
3812
- status: response.status,
3813
- statusText: response.statusText,
3814
- error
3811
+ error: failure
3815
3812
  });
3816
- throw new SendActivityError(inbox, response.status, `Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`, error, response.headers);
3813
+ federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
3814
+ throw failure;
3815
+ }
3816
+ try {
3817
+ if (!outcome.ok) {
3818
+ const { status, statusText, error, responseHeaders } = outcome;
3819
+ logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
3820
+ activityId,
3821
+ inbox: inbox.href,
3822
+ status,
3823
+ statusText,
3824
+ error
3825
+ });
3826
+ throw new SendActivityError(inbox, status, `Failed to send activity ${activityId} to ${inbox.href} (${status} ${statusText}):\n${error}`, error, responseHeaders);
3827
+ }
3828
+ deliverySuccess = true;
3829
+ const eventAttributes = {
3830
+ "activitypub.inbox.url": inbox.href,
3831
+ "activitypub.activity.id": activityId ?? ""
3832
+ };
3833
+ if (activityType != null) eventAttributes["activitypub.activity.type"] = activityType;
3834
+ const actorId = getActivityActorId(activity);
3835
+ if (actorId != null) eventAttributes["activitypub.actor.id"] = actorId;
3836
+ span.addEvent("activitypub.activity.sent", eventAttributes);
3837
+ } finally {
3838
+ federationMetrics.recordDelivery(inbox, getDurationMs(started), deliverySuccess, activityType);
3817
3839
  }
3818
- deliverySuccess = true;
3819
- const eventAttributes = {
3820
- "activitypub.inbox.url": inbox.href,
3821
- "activitypub.activity.id": activityId ?? ""
3822
- };
3823
- if (activityType != null) eventAttributes["activitypub.activity.type"] = activityType;
3824
- const actorId = getActivityActorId(activity);
3825
- if (actorId != null) eventAttributes["activitypub.actor.id"] = actorId;
3826
- span.addEvent("activitypub.activity.sent", eventAttributes);
3827
3840
  } finally {
3828
- federationMetrics.recordDelivery(inbox, getDurationMs(started), deliverySuccess, activityType);
3841
+ if (initialPending) await initialSession.close();
3829
3842
  }
3830
3843
  }
3831
3844
  function createFetchError(url, cause) {
@@ -3833,10 +3846,75 @@ function createFetchError(url, cause) {
3833
3846
  error.cause = cause;
3834
3847
  return error;
3835
3848
  }
3836
- async function fetchWithValidatedRedirects(request, validateUrl) {
3849
+ /**
3850
+ * Starts cancelling the body of a response without waiting for it to settle.
3851
+ * The cancellation of a branch of a tee (e.g., a body cloned by a fetch mock)
3852
+ * settles only after the other branch is cancelled too, per the Streams
3853
+ * standard, so awaiting it could block forever. Failures are only logged.
3854
+ */
3855
+ function cancelResponseBody(response, url) {
3856
+ response.body?.cancel().catch((error) => {
3857
+ getLogger([
3858
+ "fedify",
3859
+ "federation",
3860
+ "outbox"
3861
+ ]).debug("Failed to cancel the response body from {url}: {error}", {
3862
+ url,
3863
+ error
3864
+ });
3865
+ });
3866
+ }
3867
+ /**
3868
+ * Reads what is needed from the final response of a delivery while its
3869
+ * session is open: the body of a successful response is cancelled, and at
3870
+ * most 1 KiB of an error response body is read.
3871
+ */
3872
+ async function consumeSendActivityResponse(response, inbox) {
3873
+ if (response.ok) {
3874
+ cancelResponseBody(response, response.url || inbox.href);
3875
+ return { ok: true };
3876
+ }
3877
+ let error;
3878
+ try {
3879
+ error = await readLimitedResponseBody(response, MAX_ERROR_RESPONSE_BODY_BYTES);
3880
+ } catch (_) {
3881
+ error = "";
3882
+ }
3883
+ return {
3884
+ ok: false,
3885
+ status: response.status,
3886
+ statusText: response.statusText,
3887
+ error,
3888
+ responseHeaders: new Headers(response.headers)
3889
+ };
3890
+ }
3891
+ /**
3892
+ * Sends a request without signing it, following redirects manually like the
3893
+ * Fetch standard does. Every hop is opened with `openHop()`, which validates
3894
+ * the destination, after the previous hop is closed. The final response is
3895
+ * passed to `consume()`, and its session is closed after that.
3896
+ * This is exported only for tests; it is not exported from any entry point.
3897
+ * @param request The request to send.
3898
+ * @param openHop The function to open a session for each hop.
3899
+ * @param consume The function to consume the final response.
3900
+ * @returns The value returned by `consume`.
3901
+ */
3902
+ async function fetchWithValidatedRedirects(request, openHop, consume) {
3903
+ const logger = getLogger([
3904
+ "fedify",
3905
+ "federation",
3906
+ "outbox"
3907
+ ]);
3837
3908
  let body = await request.clone().text();
3838
3909
  for (let redirects = 0;; redirects++) {
3839
- const response = await fetch(request, { redirect: "manual" });
3910
+ const session = await openHop(request.url);
3911
+ let response;
3912
+ try {
3913
+ response = await session.fetch(request, { redirect: "manual" });
3914
+ } catch (error) {
3915
+ await closeAfterError(session, logger);
3916
+ throw error;
3917
+ }
3840
3918
  const location = response.headers.get("Location");
3841
3919
  if (![
3842
3920
  301,
@@ -3844,11 +3922,21 @@ async function fetchWithValidatedRedirects(request, validateUrl) {
3844
3922
  303,
3845
3923
  307,
3846
3924
  308
3847
- ].includes(response.status) || location == null) return response;
3848
- await response.body?.cancel();
3925
+ ].includes(response.status) || location == null) try {
3926
+ return await consume(response);
3927
+ } catch (error) {
3928
+ logger.debug("Failed to consume the response from {url}; closing the session: {error}", {
3929
+ url: request.url,
3930
+ error
3931
+ });
3932
+ throw error;
3933
+ } finally {
3934
+ await session.close();
3935
+ }
3936
+ cancelResponseBody(response, request.url);
3937
+ await session.close();
3849
3938
  if (redirects >= 20) throw new TypeError("Too many redirects");
3850
3939
  const url = new URL(location, request.url);
3851
- await validateUrl(url.href);
3852
3940
  const headers = new Headers(request.headers);
3853
3941
  if (url.origin !== new URL(request.url).origin) {
3854
3942
  headers.delete("Authorization");
@@ -3876,6 +3964,16 @@ async function fetchWithValidatedRedirects(request, validateUrl) {
3876
3964
  });
3877
3965
  }
3878
3966
  }
3967
+ async function closeAfterError(session, logger) {
3968
+ try {
3969
+ await session.close();
3970
+ } catch (error) {
3971
+ logger.debug("Failed to close the session for {url}: {error}", {
3972
+ url: session.url.href,
3973
+ error
3974
+ });
3975
+ }
3976
+ }
3879
3977
  /**
3880
3978
  * An error that is thrown when an activity fails to send to a remote inbox.
3881
3979
  * It contains structured information about the failure, including the HTTP
@@ -9823,7 +9921,7 @@ var FederationImpl = class extends FederationBuilderImpl {
9823
9921
  onNotAcceptable ??= notAcceptable;
9824
9922
  onUnauthorized ??= unauthorized;
9825
9923
  const url = new URL(request.url);
9826
- const route = this.router.route(url.pathname);
9924
+ const route = this.router.route(url.pathname, { allowUnencodedColon: true });
9827
9925
  if (route == null) {
9828
9926
  const media = this.hashlinkMediaDispatcher == null ? null : parseHashlinkGatewayRequest(url);
9829
9927
  if (media != null) return await this.#fetchHashlinkMedia(request, media, {
@@ -11556,45 +11654,85 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
11556
11654
  if (object instanceof Tombstone && !(object instanceof cls) && options?.tombstone !== "passthrough") return null;
11557
11655
  return object;
11558
11656
  }
11559
- #signedKey = void 0;
11657
+ #signedKey = null;
11658
+ #signedKeyOwner = null;
11659
+ #signatureChecks = /* @__PURE__ */ new WeakMap();
11660
+ #getSignatureCheck(documentLoader, contextLoader) {
11661
+ let checks = this.#signatureChecks.get(documentLoader);
11662
+ if (checks == null) {
11663
+ checks = /* @__PURE__ */ new WeakMap();
11664
+ this.#signatureChecks.set(documentLoader, checks);
11665
+ }
11666
+ let check = checks.get(contextLoader);
11667
+ if (check == null) {
11668
+ check = {};
11669
+ checks.set(contextLoader, check);
11670
+ }
11671
+ return check;
11672
+ }
11560
11673
  async getSignedKey(options = {}) {
11561
11674
  if (this.#signedKey != null) return this.#signedKey;
11562
- return this.#signedKey = await verifyRequest(this.request, {
11675
+ const documentLoader = options.documentLoader ?? this.documentLoader;
11676
+ const contextLoader = options.contextLoader ?? this.contextLoader;
11677
+ const check = this.#getSignatureCheck(documentLoader, contextLoader);
11678
+ if (check.key != null) return check.key;
11679
+ const promise = verifyRequest(this.request, {
11563
11680
  ...this,
11564
- contextLoader: options.contextLoader ?? this.contextLoader,
11565
- documentLoader: options.documentLoader ?? this.documentLoader,
11681
+ contextLoader,
11682
+ documentLoader,
11566
11683
  timeWindow: this.federation.signatureTimeWindow,
11567
11684
  maxSignatures: this.federation.maxHttpSignatures,
11568
11685
  meterProvider: this.meterProvider,
11569
11686
  tracerProvider: options.tracerProvider ?? this.tracerProvider
11687
+ }).then((key) => {
11688
+ if (key != null) this.#signedKey ??= key;
11689
+ return key;
11690
+ }).catch((error) => {
11691
+ if (check.key === promise) check.key = void 0;
11692
+ throw error;
11570
11693
  });
11694
+ check.key = promise;
11695
+ return await promise;
11571
11696
  }
11572
- #signedKeyOwner = void 0;
11573
11697
  async getSignedKeyOwner(options = {}) {
11574
11698
  if (this.#signedKeyOwner != null) return this.#signedKeyOwner;
11575
- const key = await this.getSignedKey(options);
11576
- if (key == null) return this.#signedKeyOwner = null;
11577
- try {
11578
- return this.#signedKeyOwner = await getKeyOwner(key, {
11579
- contextLoader: options.contextLoader ?? this.contextLoader,
11580
- documentLoader: options.documentLoader ?? this.documentLoader,
11581
- tracerProvider: options.tracerProvider ?? this.tracerProvider
11582
- });
11583
- } catch (error) {
11584
- if (error instanceof FetchError) {
11585
- getLogger([
11586
- "fedify",
11587
- "federation",
11588
- "actor"
11589
- ]).warn("Failed to fetch the key owner {keyOwner} of {keyId} while verifying the request signature; treating the request as unauthenticated: {error}", {
11590
- keyId: key.id?.href,
11591
- keyOwner: error.url.href,
11592
- error
11593
- });
11594
- return this.#signedKeyOwner = null;
11699
+ const normalizedOptions = {
11700
+ documentLoader: options.documentLoader ?? this.documentLoader,
11701
+ contextLoader: options.contextLoader ?? this.contextLoader,
11702
+ tracerProvider: options.tracerProvider ?? this.tracerProvider
11703
+ };
11704
+ const check = this.#getSignatureCheck(normalizedOptions.documentLoader, normalizedOptions.contextLoader);
11705
+ if (check.owner != null) return check.owner;
11706
+ const promise = this.getSignedKey(normalizedOptions).then(async (key) => {
11707
+ if (key == null) {
11708
+ if (check.owner === promise) check.owner = void 0;
11709
+ return null;
11710
+ }
11711
+ try {
11712
+ const owner = await getKeyOwner(key, normalizedOptions);
11713
+ if (owner != null) this.#signedKeyOwner ??= owner;
11714
+ return owner;
11715
+ } catch (error) {
11716
+ if (error instanceof FetchError) {
11717
+ getLogger([
11718
+ "fedify",
11719
+ "federation",
11720
+ "actor"
11721
+ ]).warn("Failed to fetch the key owner {keyOwner} of {keyId} while verifying the request signature; treating the request as unauthenticated: {error}", {
11722
+ keyId: key.id?.href,
11723
+ keyOwner: error.url.href,
11724
+ error
11725
+ });
11726
+ return null;
11727
+ }
11728
+ throw error;
11595
11729
  }
11730
+ }).catch((error) => {
11731
+ if (check.owner === promise) check.owner = void 0;
11596
11732
  throw error;
11597
- }
11733
+ });
11734
+ check.owner = promise;
11735
+ return await promise;
11598
11736
  }
11599
11737
  async isSignedByAudience(object, options = {}) {
11600
11738
  return await isInAudience(object, null) || await isInAudience(object, await this.getSignedKeyOwner(options), options);
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { b as HttpMessageSignaturesSpecDeterminer } from "./key-C1nv7_jD.js";
2
+ import { b as HttpMessageSignaturesSpecDeterminer } from "./key-CyCcut3h.js";
3
3
  import { n as KvStore, t as KvKey } from "./kv-B2mzK5tl.js";
4
4
  import { t as DocumentFetchKind } from "./metrics-DoRtI0qU.js";
5
5
  import { MeterProvider, TracerProvider } from "@opentelemetry/api";
@@ -46,14 +46,7 @@ interface GetAuthenticatedDocumentLoaderOptions extends DocumentLoaderFactoryOpt
46
46
  declare function getAuthenticatedDocumentLoader(identity: {
47
47
  keyId: URL;
48
48
  privateKey: CryptoKey;
49
- }, {
50
- allowPrivateAddress,
51
- maxRedirection,
52
- userAgent,
53
- specDeterminer,
54
- timeout,
55
- tracerProvider
56
- }?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
49
+ }, options?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
57
50
  //#endregion
58
51
  //#region src/utils/kv-cache.d.ts
59
52
  /**
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { Jt as WebFingerLinksDispatcher, St as ActorHandleMapper, bt as ActorAliasMapper, p as RequestContext, xt as ActorDispatcher } from "./context-7NyiqIcg.js";
2
+ import { Jt as WebFingerLinksDispatcher, St as ActorHandleMapper, bt as ActorAliasMapper, p as RequestContext, xt as ActorDispatcher } from "./context-CVOOd9pD.js";
3
3
  import { RouterError, RouterOptions, RouterRouteResult } from "@fedify/uri-template";
4
4
  import { MeterProvider, Span, Tracer } from "@opentelemetry/api";
5
5
 
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { B as VerifyPortableObjectProofOptions, a as KeyCache, v as VerificationObservationOptions, z as VerifyPortableObjectProofFailureReason } from "./key-DYxuyd-s.cjs";
2
+ import { B as VerifyPortableObjectProofOptions, a as KeyCache, v as VerificationObservationOptions, z as VerifyPortableObjectProofFailureReason } from "./key-VEL1QqHF.cjs";
3
3
  import { CryptographicKey, Multikey } from "@fedify/vocab";
4
4
  import { DocumentLoader, PortableObjectVerifierOptions } from "@fedify/vocab-runtime";
5
5
  import { MeterProvider, TracerProvider } from "@opentelemetry/api";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { B as VerifyPortableObjectProofOptions, a as KeyCache, v as VerificationObservationOptions, z as VerifyPortableObjectProofFailureReason } from "./key-C1nv7_jD.js";
2
+ import { B as VerifyPortableObjectProofOptions, a as KeyCache, v as VerificationObservationOptions, z as VerifyPortableObjectProofFailureReason } from "./key-CyCcut3h.js";
3
3
  import { CryptographicKey, Multikey } from "@fedify/vocab";
4
4
  import { MeterProvider, TracerProvider } from "@opentelemetry/api";
5
5
  import { DocumentLoader, PortableObjectVerifierOptions } from "@fedify/vocab-runtime";
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { Jt as WebFingerLinksDispatcher, St as ActorHandleMapper, bt as ActorAliasMapper, p as RequestContext, xt as ActorDispatcher } from "./context-tsYPJ2Ew.cjs";
2
+ import { Jt as WebFingerLinksDispatcher, St as ActorHandleMapper, bt as ActorAliasMapper, p as RequestContext, xt as ActorDispatcher } from "./context-D0gFIgev.cjs";
3
3
  import { MeterProvider, Span, Tracer } from "@opentelemetry/api";
4
4
  import { RouterError, RouterOptions, RouterRouteResult } from "@fedify/uri-template";
5
5
 
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { b as HttpMessageSignaturesSpecDeterminer } from "./key-DYxuyd-s.cjs";
2
+ import { b as HttpMessageSignaturesSpecDeterminer } from "./key-VEL1QqHF.cjs";
3
3
  import { n as KvStore, t as KvKey } from "./kv-B2mzK5tl.cjs";
4
4
  import { t as DocumentFetchKind } from "./metrics-DVKYY6K1.cjs";
5
5
  import { DocumentLoader, DocumentLoaderFactoryOptions } from "@fedify/vocab-runtime";
@@ -46,14 +46,7 @@ interface GetAuthenticatedDocumentLoaderOptions extends DocumentLoaderFactoryOpt
46
46
  declare function getAuthenticatedDocumentLoader(identity: {
47
47
  keyId: URL;
48
48
  privateKey: CryptoKey;
49
- }, {
50
- allowPrivateAddress,
51
- maxRedirection,
52
- userAgent,
53
- specDeterminer,
54
- timeout,
55
- tracerProvider
56
- }?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
49
+ }, options?: GetAuthenticatedDocumentLoaderOptions): DocumentLoader;
57
50
  //#endregion
58
51
  //#region src/utils/kv-cache.d.ts
59
52
  /**
package/dist/mod.cjs CHANGED
@@ -3,11 +3,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  require("./rolldown-runtime-Dmm3t92W.cjs");
4
4
  const require_transformers = require("./transformers-BalCrSsr.cjs");
5
5
  require("./compat/mod.cjs");
6
- const require_http = require("./http-Dx5s5-pP.cjs");
7
- const require_federation = require("./federation-DWVfQYX_.cjs");
8
- const require_types = require("./types-poIao40f.cjs");
9
- const require_portable_collection = require("./portable-collection-Cwn7DM0G.cjs");
10
- const require_kv_cache = require("./kv-cache-DmxFPJaR.cjs");
6
+ const require_http = require("./http-DHVH0DqC.cjs");
7
+ const require_federation = require("./federation-Bkfq2YpS.cjs");
8
+ const require_types = require("./types-hKCCjii0.cjs");
9
+ const require_portable_collection = require("./portable-collection-C_Kmvl3q.cjs");
10
+ const require_kv_cache = require("./kv-cache-BtBSBZi9.cjs");
11
11
  require("./nodeinfo/mod.cjs");
12
12
  require("./runtime/mod.cjs");
13
13
  require("./sig/mod.cjs");
package/dist/mod.d.cts CHANGED
@@ -1,13 +1,13 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { a as InboundService, c as OutboundService, d as Software, f as Usage, i as parseNodeInfo, l as Protocol, n as ParseNodeInfoOptions, o as JsonValue, p as nodeInfoToJson, r as getNodeInfo, s as NodeInfo, t as GetNodeInfoOptions, u as Services } from "./client-D-XP_Ccb.cjs";
3
- import { A as AcceptSignatureParameters, B as VerifyPortableObjectProofOptions, C as VerifyRequestDetailedResult, D as verifyRequest, E as signRequest, F as validateAcceptSignature, G as signObject, H as VerifyProofOptions, I as CreateProofOptions, J as verifyProof, K as verifyObject, L as SignObjectOptions, M as formatAcceptSignature, N as fulfillAcceptSignature, O as verifyRequestDetailed, P as parseAcceptSignature, R as VerifyObjectOptions, S as SignRequestOptions, T as VerifyRequestOptions, U as createProof, V as VerifyPortableObjectProofResult, W as hasProofLike, _ as InboxVerificationKey, a as KeyCache, b as HttpMessageSignaturesSpecDeterminer, c as fetchKeyDetailed, d as InboxProofPolicyFailureReason, f as InboxSignatureCheck, g as InboxVerificationFailureReason, h as InboxVerificationAttempt, i as FetchKeyResult, j as FulfillAcceptSignatureResult, k as AcceptSignatureMember, l as generateCryptoKeyPair, m as InboxSignatureIdentity, n as FetchKeyErrorResult, o as exportJwk, p as InboxSignatureFailureReason, q as verifyPortableObjectProof, r as FetchKeyOptions, s as fetchKey, t as FetchKeyDetailedResult, u as importJwk, w as VerifyRequestFailureReason, x as Rfc9421SignRequestOptions, y as HttpMessageSignaturesSpec, z as VerifyPortableObjectProofFailureReason } from "./key-DYxuyd-s.cjs";
2
+ import { a as InboundService, c as OutboundService, d as Software, f as Usage, i as parseNodeInfo, l as Protocol, n as ParseNodeInfoOptions, o as JsonValue, p as nodeInfoToJson, r as getNodeInfo, s as NodeInfo, t as GetNodeInfoOptions, u as Services } from "./client-3InDZbba.cjs";
3
+ import { A as AcceptSignatureParameters, B as VerifyPortableObjectProofOptions, C as VerifyRequestDetailedResult, D as verifyRequest, E as signRequest, F as validateAcceptSignature, G as signObject, H as VerifyProofOptions, I as CreateProofOptions, J as verifyProof, K as verifyObject, L as SignObjectOptions, M as formatAcceptSignature, N as fulfillAcceptSignature, O as verifyRequestDetailed, P as parseAcceptSignature, R as VerifyObjectOptions, S as SignRequestOptions, T as VerifyRequestOptions, U as createProof, V as VerifyPortableObjectProofResult, W as hasProofLike, _ as InboxVerificationKey, a as KeyCache, b as HttpMessageSignaturesSpecDeterminer, c as fetchKeyDetailed, d as InboxProofPolicyFailureReason, f as InboxSignatureCheck, g as InboxVerificationFailureReason, h as InboxVerificationAttempt, i as FetchKeyResult, j as FulfillAcceptSignatureResult, k as AcceptSignatureMember, l as generateCryptoKeyPair, m as InboxSignatureIdentity, n as FetchKeyErrorResult, o as exportJwk, p as InboxSignatureFailureReason, q as verifyPortableObjectProof, r as FetchKeyOptions, s as fetchKey, t as FetchKeyDetailedResult, u as importJwk, w as VerifyRequestFailureReason, x as Rfc9421SignRequestOptions, y as HttpMessageSignaturesSpec, z as VerifyPortableObjectProofFailureReason } from "./key-VEL1QqHF.cjs";
4
4
  import { i as getKeyOwner, n as GetKeyOwnerOptions, r as doesActorOwnKey, t as DoesActorOwnKeyOptions } from "./owner-BF0L9cMt.cjs";
5
- import { $ as respondWithObject, $t as digest, A as InboxChallengePolicy, At as CustomCollectionDispatcher, B as createFederation, Bt as OutboxListener, C as FederationBenchmarkOptions, Ct as ActorKeyPairsDispatcher, D as FederationStartQueueOptions, Dt as CollectionDispatcher, E as FederationOptions, Et as CollectionCursor, F as PortableInboxForwardingOptions, Ft as MediaUploaderCallback, G as TaskEnqueueOptions, Gt as SharedInboxKeyDispatcher, H as createFederationBuilder, Ht as OutboxPermanentFailureHandler, I as Rfc6570Expression, It as NodeInfoDispatcher, J as CreateExponentialBackoffPolicyOptions, Jt as WebFingerLinksDispatcher, K as TaskHandler, Kt as UnverifiedActivityHandler, L as FederationKvPrefixes, Lt as ObjectAuthorizePredicate, M as MediaUploaderSetters, Mt as HashlinkMediaRequest, N as ObjectCallbackSetters, Nt as InboxErrorHandler, O as IdempotencyKeyCallback, Ot as CustomCollectionCounter, P as OutboxListenerSetters, Pt as InboxListener, Q as RespondWithObjectOptions, Qt as buildCollectionSynchronizationHeader, R as FederationOrigin, Rt as ObjectDispatcher, S as Federation, St as ActorHandleMapper, T as FederationFetchOptions, Tt as CollectionCounter, U as TaskDefinition, Ut as PortableActorIdMapper, V as Message, Vt as OutboxListenerErrorHandler, W as TaskDefinitionOptions, Wt as PortableCollectionOwnerMapper, X as RetryPolicy, Xt as SenderKeyPair, Y as RetryContext, Yt as SendActivityError, Z as createExponentialBackoffPolicy, Zt as PageItems, _ as ActorCallbackSetters, _t as NormalizedCircuitBreakerOptions, a as GetObjectOptions, an as InboxRequestReport, at as MessageQueueEnqueueOptions, b as CustomCollectionCallbackSetters, bt as ActorAliasMapper, c as IsSignedByAudienceOptions, ct as CircuitBreaker, d as ParseUriResult, dt as CircuitBreakerCreateOptions, en as ActivityTransformer, et as respondWithObjectIfAcceptable, f as PortableRequest, ft as CircuitBreakerFailurePolicy, g as SendActivityOptionsForCollection, gt as CircuitBreakerStateChange, h as SendActivityOptions, ht as CircuitBreakerState, i as GetActorOptions, in as InboxRequestOutcome, it as MessageQueueDepth, j as InboxListenerSetters, jt as HashlinkMediaDispatcher, k as IdempotencyStrategy, kt as CustomCollectionCursor, l as OutboxContext, lt as CircuitBreakerActivityDrop, m as RouteActivityOptions, mt as CircuitBreakerOptions, n as Context, nn as InboxJsonValue, nt as InProcessMessageQueueOptions, o as GetSignedKeyOptions, ot as MessageQueueListenOptions, p as RequestContext, pt as CircuitBreakerKvState, q as TaskRegistry, qt as UnverifiedActivityReason, r as ForwardActivityOptions, rn as InboxRequestFinishedHandler, rt as MessageQueue, s as InboxContext, st as ParallelMessageQueue, t as ActorKeyPair, tn as InboxAuthentication, tt as InProcessMessageQueue, u as ParseUriOptions, ut as CircuitBreakerBeforeSendDecision, v as CollectionCallbackSetters, vt as normalizeCircuitBreakerOptions, w as FederationBuilder, wt as AuthorizePredicate, x as Federatable, xt as ActorDispatcher, y as ConstructorWithTypeId, yt as parseCircuitBreakerKvState, z as FederationQueueOptions, zt as OutboxErrorHandler } from "./context-tsYPJ2Ew.cjs";
5
+ import { $ as respondWithObject, $t as digest, A as InboxChallengePolicy, At as CustomCollectionDispatcher, B as createFederation, Bt as OutboxListener, C as FederationBenchmarkOptions, Ct as ActorKeyPairsDispatcher, D as FederationStartQueueOptions, Dt as CollectionDispatcher, E as FederationOptions, Et as CollectionCursor, F as PortableInboxForwardingOptions, Ft as MediaUploaderCallback, G as TaskEnqueueOptions, Gt as SharedInboxKeyDispatcher, H as createFederationBuilder, Ht as OutboxPermanentFailureHandler, I as Rfc6570Expression, It as NodeInfoDispatcher, J as CreateExponentialBackoffPolicyOptions, Jt as WebFingerLinksDispatcher, K as TaskHandler, Kt as UnverifiedActivityHandler, L as FederationKvPrefixes, Lt as ObjectAuthorizePredicate, M as MediaUploaderSetters, Mt as HashlinkMediaRequest, N as ObjectCallbackSetters, Nt as InboxErrorHandler, O as IdempotencyKeyCallback, Ot as CustomCollectionCounter, P as OutboxListenerSetters, Pt as InboxListener, Q as RespondWithObjectOptions, Qt as buildCollectionSynchronizationHeader, R as FederationOrigin, Rt as ObjectDispatcher, S as Federation, St as ActorHandleMapper, T as FederationFetchOptions, Tt as CollectionCounter, U as TaskDefinition, Ut as PortableActorIdMapper, V as Message, Vt as OutboxListenerErrorHandler, W as TaskDefinitionOptions, Wt as PortableCollectionOwnerMapper, X as RetryPolicy, Xt as SenderKeyPair, Y as RetryContext, Yt as SendActivityError, Z as createExponentialBackoffPolicy, Zt as PageItems, _ as ActorCallbackSetters, _t as NormalizedCircuitBreakerOptions, a as GetObjectOptions, an as InboxRequestReport, at as MessageQueueEnqueueOptions, b as CustomCollectionCallbackSetters, bt as ActorAliasMapper, c as IsSignedByAudienceOptions, ct as CircuitBreaker, d as ParseUriResult, dt as CircuitBreakerCreateOptions, en as ActivityTransformer, et as respondWithObjectIfAcceptable, f as PortableRequest, ft as CircuitBreakerFailurePolicy, g as SendActivityOptionsForCollection, gt as CircuitBreakerStateChange, h as SendActivityOptions, ht as CircuitBreakerState, i as GetActorOptions, in as InboxRequestOutcome, it as MessageQueueDepth, j as InboxListenerSetters, jt as HashlinkMediaDispatcher, k as IdempotencyStrategy, kt as CustomCollectionCursor, l as OutboxContext, lt as CircuitBreakerActivityDrop, m as RouteActivityOptions, mt as CircuitBreakerOptions, n as Context, nn as InboxJsonValue, nt as InProcessMessageQueueOptions, o as GetSignedKeyOptions, ot as MessageQueueListenOptions, p as RequestContext, pt as CircuitBreakerKvState, q as TaskRegistry, qt as UnverifiedActivityReason, r as ForwardActivityOptions, rn as InboxRequestFinishedHandler, rt as MessageQueue, s as InboxContext, st as ParallelMessageQueue, t as ActorKeyPair, tn as InboxAuthentication, tt as InProcessMessageQueue, u as ParseUriOptions, ut as CircuitBreakerBeforeSendDecision, v as CollectionCallbackSetters, vt as normalizeCircuitBreakerOptions, w as FederationBuilder, wt as AuthorizePredicate, x as Federatable, xt as ActorDispatcher, y as ConstructorWithTypeId, yt as parseCircuitBreakerKvState, z as FederationQueueOptions, zt as OutboxErrorHandler } from "./context-D0gFIgev.cjs";
6
6
  import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "./kv-B2mzK5tl.cjs";
7
7
  import { actorDehydrator, autoIdAssigner, getDefaultActivityTransformers } from "./compat/mod.cjs";
8
- import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-BojP2Bw3.cjs";
9
- import { a as CreateSignatureOptions, c as VerifySignatureOptions, d as detachSignature, f as hasSignatureLike, h as verifySignature, i as verifyPortableObject, l as attachSignature, m as verifyJsonLd, n as VerifyPortableObjectOptions, o as SignJsonLdOptions, p as signJsonLd, r as VerifyPortableObjectResult, s as VerifyJsonLdOptions, t as VerifyPortableObjectFailureReason, u as createSignature } from "./mod-CavhAgLw.cjs";
10
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-Dw-nPxQh.cjs";
8
+ import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "./mod-makPMVMg.cjs";
9
+ import { a as CreateSignatureOptions, c as VerifySignatureOptions, d as detachSignature, f as hasSignatureLike, h as verifySignature, i as verifyPortableObject, l as attachSignature, m as verifyJsonLd, n as VerifyPortableObjectOptions, o as SignJsonLdOptions, p as signJsonLd, r as VerifyPortableObjectResult, s as VerifyJsonLdOptions, t as VerifyPortableObjectFailureReason, u as createSignature } from "./mod-BTxJG7ZH.cjs";
10
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./mod-ss0wBUH1.cjs";
11
11
  export * from "@fedify/vocab-runtime";
12
12
 
13
13
  //#region src/mod.d.ts