@fedify/fedify 2.3.0-dev.1358 → 2.3.0-dev.1361
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.
- package/dist/{assert-OguE97r2.mjs → assert-DikXweDx.mjs} +1 -1
- package/dist/{assert_instance_of-DBC5X09g.mjs → assert_instance_of-C4Ri6VuN.mjs} +1 -1
- package/dist/{assert_not_equals-DkVK8oqV.mjs → assert_not_equals--wG9hV7u.mjs} +1 -1
- package/dist/{assert_rejects-DN60FHPX.mjs → assert_rejects-DQP-q39h.mjs} +2 -2
- package/dist/{assert_strict_equals-XEgZAlrj.mjs → assert_strict_equals-Dmjbg-bA.mjs} +1 -1
- package/dist/{assert_throws-BOkhLGYc.mjs → assert_throws-4NwKEy2q.mjs} +1 -1
- package/dist/{builder-DzVFe97C.mjs → builder-Ec1dUgEm.mjs} +23 -3
- package/dist/codec-Bf-rTqks.mjs +94 -0
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +3 -3
- package/dist/compat/public-audience.test.mjs +3 -3
- package/dist/compat/transformers.test.mjs +5 -5
- package/dist/{context-DVoTs_wM.mjs → context-BrIOaBSs.mjs} +7 -1
- package/dist/{context-BBVLF7lx.d.cts → context-BuGH_Vft.d.cts} +286 -70
- package/dist/{context-BU6jSQdo.d.ts → context-CLtZxCu6.d.ts} +285 -70
- package/dist/{deno-DvIcq4tK.mjs → deno-C1j4CMgo.mjs} +1 -1
- package/dist/{docloader-CX_OFc81.mjs → docloader-DLb-Mj7i.mjs} +2 -2
- package/dist/federation/builder.test.mjs +5 -5
- package/dist/federation/circuit-breaker.test.mjs +5 -5
- package/dist/federation/collection.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +13 -13
- package/dist/federation/idempotency.test.mjs +6 -6
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/keycache.test.mjs +5 -5
- package/dist/federation/kv.test.mjs +3 -3
- package/dist/federation/metrics.test.mjs +4 -4
- package/dist/federation/middleware.test.mjs +200 -19
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +5 -260
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/retry.test.mjs +3 -3
- package/dist/federation/router.test.mjs +5 -5
- package/dist/federation/send.test.mjs +10 -10
- package/dist/federation/tasks/codec.test.d.mts +2 -0
- package/dist/federation/tasks/codec.test.mjs +292 -0
- package/dist/federation/tasks/tasks.test.d.mts +2 -0
- package/dist/federation/tasks/tasks.test.mjs +651 -0
- package/dist/federation/temporal.test.mjs +4 -4
- package/dist/federation/webfinger.test.mjs +6 -6
- package/dist/{http-CM2Ip5Ht.js → http-1oEzWsNL.js} +1 -1
- package/dist/{http-BHA9pOpl.cjs → http-DwM39C9Q.cjs} +1 -1
- package/dist/{http-CltP0Rqv.mjs → http-pFZqYnR0.mjs} +4 -4
- package/dist/{key-DErraSAS.mjs → key-E-05ikaC.mjs} +2 -2
- package/dist/{kv-cache-B7FwKJOW.js → kv-cache-CgchQxpw.js} +1 -1
- package/dist/{kv-cache--1ru-DvM.mjs → kv-cache-D-OZCnQz.mjs} +1 -1
- package/dist/{kv-cache-C5u4leI_.cjs → kv-cache-enboxEhN.cjs} +1 -1
- package/dist/{ld-Bw3crZBI.mjs → ld-Bi8DPgxi.mjs} +3 -3
- package/dist/{metrics-CVUGVaXk.mjs → metrics-BC8TM85p.mjs} +1 -1
- package/dist/{middleware-B6YinpAg.mjs → middleware-6R3zHHW0.mjs} +182 -23
- package/dist/{middleware-Cfd9ewnF.mjs → middleware-B81UTyWc.mjs} +1 -1
- package/dist/{middleware-Blo20EWW.cjs → middleware-TZyBWL4B.cjs} +277 -10
- package/dist/{middleware-L0L66VwD.js → middleware-bEYsEa2y.js} +277 -10
- package/dist/{mod-C0F6kvgS.d.cts → mod-DRokcHeU.d.cts} +1 -1
- package/dist/{mod-vPYVoa5n.d.ts → mod-r-1xOW_C.d.ts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +4 -4
- package/dist/mod.d.ts +4 -4
- package/dist/mod.js +4 -4
- package/dist/mq-CvJAzRz5.mjs +260 -0
- package/dist/nodeinfo/client.test.mjs +3 -3
- package/dist/nodeinfo/handler.test.mjs +5 -5
- package/dist/nodeinfo/types.test.mjs +4 -4
- package/dist/otel/exporter.test.mjs +3 -3
- package/dist/{outgoing-jsonld-L_DbOaFe.mjs → outgoing-jsonld-BgFLCJQ_.mjs} +1 -1
- package/dist/{owner-DPUA0BdS.mjs → owner-9bbtWYCS.mjs} +2 -2
- package/dist/{proof-Bp9AZ0zD.cjs → proof-B45zHTY3.cjs} +1 -1
- package/dist/{proof-wPNfEcFb.js → proof-CA5R6h5L.js} +1 -1
- package/dist/{proof-sIdKSfJc.mjs → proof-DS0QOtP2.mjs} +5 -5
- package/dist/{send-b2odHY4e.mjs → send-CyGRAWkX.mjs} +3 -3
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/http.test.mjs +8 -8
- package/dist/sig/key.test.mjs +6 -6
- package/dist/sig/ld.test.mjs +7 -7
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +8 -8
- package/dist/{std__assert-BBjXFNOb.mjs → std__assert-BTEgfoJo.mjs} +4 -4
- package/dist/{temporal-I7QQSZR_.mjs → temporal-B82PdoA8.mjs} +1 -1
- package/dist/testing/mod.d.mts +378 -7
- package/dist/testing/mod.mjs +3 -2
- package/dist/testing-CjYPStvE.mjs +55 -0
- package/dist/utils/docloader.test.mjs +6 -6
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +9 -7
- /package/dist/{accept-CPkZzmGN.mjs → accept-CceiKpCy.mjs} +0 -0
- /package/dist/{activity-listener-tztVvlNb.mjs → activity-listener-BeTGV3wc.mjs} +0 -0
- /package/dist/{assert_equals-C-ZRDbaf.mjs → assert_equals-Ew3jOFa3.mjs} +0 -0
- /package/dist/{circuit-breaker-CSWsyoef.mjs → circuit-breaker-hJBB6jwA.mjs} +0 -0
- /package/dist/{client-ByXmQhYD.mjs → client-B_A6mfn3.mjs} +0 -0
- /package/dist/{collection-Cc3DVAhE.mjs → collection-Dp5ky45w.mjs} +0 -0
- /package/dist/{keycache-BeU0LCII.mjs → keycache-CaOR6NYg.mjs} +0 -0
- /package/dist/{keys-DGu1NFwu.mjs → keys-C3kae-6B.mjs} +0 -0
- /package/dist/{kv-rV3vodCc.mjs → kv-x2IvBUyq.mjs} +0 -0
- /package/dist/{negotiation-DDstyBvc.mjs → negotiation-m_L2nyS3.mjs} +0 -0
- /package/dist/{public-audience-Cvbr2Gzt.mjs → public-audience-N3pyOx2p.mjs} +0 -0
- /package/dist/{retry-CXg_MBI-.mjs → retry-DI4O-zYl.mjs} +0 -0
- /package/dist/{types-J53Kw7so.mjs → types-BFowWFTT.mjs} +0 -0
|
@@ -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-
|
|
5
|
-
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-
|
|
7
|
-
import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-C1j4CMgo.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BC8TM85p.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-E-05ikaC.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-
|
|
5
|
-
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-
|
|
4
|
+
import { n as version, t as name } from "./deno-C1j4CMgo.mjs";
|
|
5
|
+
import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-BC8TM85p.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,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-
|
|
3
|
+
import { C as recordDocumentCache, d as validateCryptoKey, t as doubleKnock } from "./http-1oEzWsNL.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-
|
|
4
|
+
import { p as recordDocumentCache } from "./metrics-BC8TM85p.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,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-
|
|
4
|
+
const require_http = require("./http-DwM39C9Q.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,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-
|
|
5
|
-
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-
|
|
6
|
-
import { n as fetchKey, o as validateCryptoKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-C1j4CMgo.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BC8TM85p.mjs";
|
|
6
|
+
import { n as fetchKey, o as validateCryptoKey } from "./key-E-05ikaC.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-
|
|
4
|
+
import { n as version, t as name } from "./deno-C1j4CMgo.mjs";
|
|
5
5
|
import { metrics } from "@opentelemetry/api";
|
|
6
6
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
7
7
|
//#region src/federation/metrics.ts
|
|
@@ -1,27 +1,28 @@
|
|
|
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-
|
|
5
|
-
import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-
|
|
6
|
-
import { t as formatAcceptSignature } from "./accept-
|
|
7
|
-
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-
|
|
8
|
-
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-
|
|
9
|
-
import { t as getAuthenticatedDocumentLoader } from "./docloader-
|
|
10
|
-
import { n as kvCache } from "./kv-cache
|
|
11
|
-
import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-
|
|
12
|
-
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-
|
|
13
|
-
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-
|
|
14
|
-
import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-
|
|
15
|
-
import { t as getNodeInfo } from "./client-
|
|
16
|
-
import { t as nodeInfoToJson } from "./types-
|
|
17
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-
|
|
18
|
-
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-
|
|
19
|
-
import { t as CircuitBreaker } from "./circuit-breaker-
|
|
20
|
-
import { t as buildCollectionSynchronizationHeader } from "./collection-
|
|
21
|
-
import { t as KvKeyCache } from "./keycache-
|
|
22
|
-
import { t as acceptsJsonLd } from "./negotiation-
|
|
23
|
-
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-
|
|
24
|
-
import { t as createExponentialBackoffPolicy } from "./retry-
|
|
4
|
+
import { n as version, t as name } from "./deno-C1j4CMgo.mjs";
|
|
5
|
+
import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-BC8TM85p.mjs";
|
|
6
|
+
import { t as formatAcceptSignature } from "./accept-CceiKpCy.mjs";
|
|
7
|
+
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-E-05ikaC.mjs";
|
|
8
|
+
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-pFZqYnR0.mjs";
|
|
9
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-DLb-Mj7i.mjs";
|
|
10
|
+
import { n as kvCache } from "./kv-cache-D-OZCnQz.mjs";
|
|
11
|
+
import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-Bi8DPgxi.mjs";
|
|
12
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-9bbtWYCS.mjs";
|
|
13
|
+
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-BgFLCJQ_.mjs";
|
|
14
|
+
import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-DS0QOtP2.mjs";
|
|
15
|
+
import { t as getNodeInfo } from "./client-B_A6mfn3.mjs";
|
|
16
|
+
import { t as nodeInfoToJson } from "./types-BFowWFTT.mjs";
|
|
17
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-CyGRAWkX.mjs";
|
|
18
|
+
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-Ec1dUgEm.mjs";
|
|
19
|
+
import { t as CircuitBreaker } from "./circuit-breaker-hJBB6jwA.mjs";
|
|
20
|
+
import { t as buildCollectionSynchronizationHeader } from "./collection-Dp5ky45w.mjs";
|
|
21
|
+
import { t as KvKeyCache } from "./keycache-CaOR6NYg.mjs";
|
|
22
|
+
import { t as acceptsJsonLd } from "./negotiation-m_L2nyS3.mjs";
|
|
23
|
+
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-B82PdoA8.mjs";
|
|
24
|
+
import { t as createExponentialBackoffPolicy } from "./retry-DI4O-zYl.mjs";
|
|
25
|
+
import { t as TaskCodec } from "./codec-Bf-rTqks.mjs";
|
|
25
26
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
26
27
|
import { RouterError } from "@fedify/uri-template";
|
|
27
28
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
@@ -2409,9 +2410,12 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2409
2410
|
inboxQueue;
|
|
2410
2411
|
outboxQueue;
|
|
2411
2412
|
fanoutQueue;
|
|
2413
|
+
taskQueue;
|
|
2412
2414
|
inboxQueueStarted;
|
|
2413
2415
|
outboxQueueStarted;
|
|
2414
2416
|
fanoutQueueStarted;
|
|
2417
|
+
taskQueueStarted;
|
|
2418
|
+
startedTaskQueues;
|
|
2415
2419
|
manuallyStartQueue;
|
|
2416
2420
|
origin;
|
|
2417
2421
|
documentLoaderFactory;
|
|
@@ -2425,6 +2429,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2425
2429
|
skipSignatureVerification;
|
|
2426
2430
|
outboxRetryPolicy;
|
|
2427
2431
|
inboxRetryPolicy;
|
|
2432
|
+
taskRetryPolicy;
|
|
2433
|
+
taskQueueResolution;
|
|
2428
2434
|
circuitBreaker;
|
|
2429
2435
|
activityTransformers;
|
|
2430
2436
|
_tracerProvider;
|
|
@@ -2470,14 +2476,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2470
2476
|
this.inboxQueue = void 0;
|
|
2471
2477
|
this.outboxQueue = void 0;
|
|
2472
2478
|
this.fanoutQueue = void 0;
|
|
2479
|
+
this.taskQueue = void 0;
|
|
2473
2480
|
} else if ("enqueue" in options.queue && "listen" in options.queue) {
|
|
2474
2481
|
this.inboxQueue = options.queue;
|
|
2475
2482
|
this.outboxQueue = options.queue;
|
|
2476
2483
|
this.fanoutQueue = options.queue;
|
|
2484
|
+
this.taskQueue = void 0;
|
|
2477
2485
|
} else {
|
|
2478
2486
|
this.inboxQueue = options.queue.inbox;
|
|
2479
2487
|
this.outboxQueue = options.queue.outbox;
|
|
2480
2488
|
this.fanoutQueue = options.queue.fanout;
|
|
2489
|
+
this.taskQueue = options.queue.task;
|
|
2481
2490
|
}
|
|
2482
2491
|
if (options.circuitBreaker !== false && this.outboxQueue != null) {
|
|
2483
2492
|
this.circuitBreaker = new CircuitBreaker({
|
|
@@ -2501,6 +2510,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2501
2510
|
this.inboxQueueStarted = false;
|
|
2502
2511
|
this.outboxQueueStarted = false;
|
|
2503
2512
|
this.fanoutQueueStarted = false;
|
|
2513
|
+
this.taskQueueStarted = false;
|
|
2514
|
+
this.startedTaskQueues = /* @__PURE__ */ new Set();
|
|
2504
2515
|
this.manuallyStartQueue = options.manuallyStartQueue ?? false;
|
|
2505
2516
|
if (options.origin != null) if (typeof options.origin === "string") {
|
|
2506
2517
|
if (!URL.canParse(options.origin) || !options.origin.match(/^https?:\/\//)) throw new TypeError(`Invalid origin: ${JSON.stringify(options.origin)}`);
|
|
@@ -2582,6 +2593,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2582
2593
|
this.inboxChallengePolicy = options.inboxChallengePolicy;
|
|
2583
2594
|
this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy();
|
|
2584
2595
|
this.inboxRetryPolicy = options.inboxRetryPolicy ?? createExponentialBackoffPolicy();
|
|
2596
|
+
this.taskRetryPolicy = options.taskRetryPolicy ?? createExponentialBackoffPolicy();
|
|
2597
|
+
this.taskQueueResolution = options.taskQueueResolution ?? "fallback";
|
|
2585
2598
|
this.activityTransformers = options.activityTransformers ?? getDefaultActivityTransformers();
|
|
2586
2599
|
this._tracerProvider = options.tracerProvider;
|
|
2587
2600
|
if (benchmarkMode) {
|
|
@@ -2630,8 +2643,14 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2630
2643
|
_getTracer() {
|
|
2631
2644
|
return this.tracerProvider.getTracer(name, version);
|
|
2632
2645
|
}
|
|
2646
|
+
resolveTaskQueue(taskName) {
|
|
2647
|
+
const resolved = this.taskDefinitions.get(taskName)?.queue ?? this.taskQueue;
|
|
2648
|
+
if (resolved != null) return resolved;
|
|
2649
|
+
return this.taskQueueResolution === "strict" ? void 0 : this.outboxQueue;
|
|
2650
|
+
}
|
|
2633
2651
|
async _startQueueInternal(ctxData, signal, queue) {
|
|
2634
|
-
|
|
2652
|
+
const hasDedicatedTaskQueue = [...this.taskDefinitions.values()].some((def) => def.queue != null);
|
|
2653
|
+
if (this.inboxQueue == null && this.outboxQueue == null && this.fanoutQueue == null && this.taskQueue == null && !hasDedicatedTaskQueue) return;
|
|
2635
2654
|
const logger = getLogger([
|
|
2636
2655
|
"fedify",
|
|
2637
2656
|
"federation",
|
|
@@ -2653,6 +2672,26 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2653
2672
|
this.fanoutQueueStarted = true;
|
|
2654
2673
|
promises.push(this.fanoutQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2655
2674
|
}
|
|
2675
|
+
if (this.taskQueue != null && this.taskQueue !== this.inboxQueue && this.taskQueue !== this.outboxQueue && this.taskQueue !== this.fanoutQueue && (queue == null || queue === "task") && !this.taskQueueStarted) {
|
|
2676
|
+
logger.debug("Starting a task worker.");
|
|
2677
|
+
this.taskQueueStarted = true;
|
|
2678
|
+
promises.push(this.taskQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2679
|
+
}
|
|
2680
|
+
if (queue == null || queue === "task") {
|
|
2681
|
+
const standardQueues = new Set([
|
|
2682
|
+
this.inboxQueue,
|
|
2683
|
+
this.outboxQueue,
|
|
2684
|
+
this.fanoutQueue,
|
|
2685
|
+
this.taskQueue
|
|
2686
|
+
].filter((q) => q != null));
|
|
2687
|
+
for (const def of this.taskDefinitions.values()) {
|
|
2688
|
+
const taskQueue = def.queue;
|
|
2689
|
+
if (taskQueue == null || standardQueues.has(taskQueue) || this.startedTaskQueues.has(taskQueue)) continue;
|
|
2690
|
+
logger.debug("Starting a worker for a dedicated per-task queue.");
|
|
2691
|
+
this.startedTaskQueues.add(taskQueue);
|
|
2692
|
+
promises.push(taskQueue.listen((msg) => this.processQueuedTask(ctxData, msg), { signal }));
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2656
2695
|
await Promise.all(promises);
|
|
2657
2696
|
}
|
|
2658
2697
|
processQueuedTask(contextData, message) {
|
|
@@ -2774,7 +2813,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
2774
2813
|
}
|
|
2775
2814
|
});
|
|
2776
2815
|
});
|
|
2777
|
-
}
|
|
2816
|
+
} else if (message.type === "task") await this.#listenTaskMessage(contextData, message);
|
|
2778
2817
|
});
|
|
2779
2818
|
}
|
|
2780
2819
|
async #listenFanoutMessage(data, message) {
|
|
@@ -3338,6 +3377,77 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3338
3377
|
listenerSpan.end();
|
|
3339
3378
|
});
|
|
3340
3379
|
}
|
|
3380
|
+
async #listenTaskMessage(contextData, message) {
|
|
3381
|
+
const logger = getLogger([
|
|
3382
|
+
"fedify",
|
|
3383
|
+
"federation",
|
|
3384
|
+
"task"
|
|
3385
|
+
]);
|
|
3386
|
+
const def = this.taskDefinitions.get(message.taskName);
|
|
3387
|
+
if (def == null) {
|
|
3388
|
+
logger.warn("Received a custom task {taskName} with no registered handler; dropping.", { taskName: message.taskName });
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3391
|
+
const context = this.#createContext(new URL(message.baseUrl), contextData);
|
|
3392
|
+
let data;
|
|
3393
|
+
try {
|
|
3394
|
+
data = await context.codec.decode(def.schema, message.data);
|
|
3395
|
+
} catch (error) {
|
|
3396
|
+
logger.error("Custom task {taskName} payload could not be decoded or validated; dropping:\n{error}", {
|
|
3397
|
+
taskName: message.taskName,
|
|
3398
|
+
error
|
|
3399
|
+
});
|
|
3400
|
+
return;
|
|
3401
|
+
}
|
|
3402
|
+
try {
|
|
3403
|
+
await def.handler(context, data);
|
|
3404
|
+
} catch (error) {
|
|
3405
|
+
if (def.onError != null) try {
|
|
3406
|
+
await def.onError(context, error, data);
|
|
3407
|
+
} catch (onErrorError) {
|
|
3408
|
+
logger.error("onError for custom task {taskName} threw:\n{error}", {
|
|
3409
|
+
taskName: message.taskName,
|
|
3410
|
+
error: onErrorError
|
|
3411
|
+
});
|
|
3412
|
+
}
|
|
3413
|
+
const queue = this.resolveTaskQueue(def.name);
|
|
3414
|
+
if (queue?.nativeRetrial) throw error;
|
|
3415
|
+
const retryPolicy = def.retryPolicy ?? this.taskRetryPolicy;
|
|
3416
|
+
let elapsedTime = Temporal.Duration.from({ seconds: 0 });
|
|
3417
|
+
try {
|
|
3418
|
+
elapsedTime = Temporal.Instant.from(message.started).until(Temporal.Now.instant());
|
|
3419
|
+
} catch (parseError) {
|
|
3420
|
+
logger.error("Custom task {taskName} has an unparsable started time {started}; treating elapsedTime as zero:\n{error}", {
|
|
3421
|
+
taskName: message.taskName,
|
|
3422
|
+
started: message.started,
|
|
3423
|
+
error: parseError
|
|
3424
|
+
});
|
|
3425
|
+
}
|
|
3426
|
+
const delay = retryPolicy({
|
|
3427
|
+
elapsedTime,
|
|
3428
|
+
attempts: message.attempt
|
|
3429
|
+
});
|
|
3430
|
+
if (delay != null && queue != null) {
|
|
3431
|
+
logger.error("Custom task {taskName} failed (attempt #{attempt}); retry...:\n{error}", {
|
|
3432
|
+
taskName: message.taskName,
|
|
3433
|
+
attempt: message.attempt,
|
|
3434
|
+
error
|
|
3435
|
+
});
|
|
3436
|
+
const retryMessage = {
|
|
3437
|
+
...message,
|
|
3438
|
+
attempt: message.attempt + 1
|
|
3439
|
+
};
|
|
3440
|
+
await queue.enqueue(retryMessage, {
|
|
3441
|
+
delay: clampNegativeDelay(delay),
|
|
3442
|
+
orderingKey: message.orderingKey
|
|
3443
|
+
});
|
|
3444
|
+
} else logger.error("Custom task {taskName} failed after {attempt} attempts; giving up:\n{error}", {
|
|
3445
|
+
taskName: message.taskName,
|
|
3446
|
+
attempt: message.attempt,
|
|
3447
|
+
error
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3341
3451
|
startQueue(contextData, options = {}) {
|
|
3342
3452
|
return this._startQueueInternal(contextData, options.signal, options.queue);
|
|
3343
3453
|
}
|
|
@@ -3914,6 +4024,7 @@ var ContextImpl = class ContextImpl {
|
|
|
3914
4024
|
documentLoader;
|
|
3915
4025
|
contextLoader;
|
|
3916
4026
|
invokedFromActorKeyPairsDispatcher;
|
|
4027
|
+
#codec;
|
|
3917
4028
|
constructor({ url, federation, data, documentLoader, contextLoader, invokedFromActorKeyPairsDispatcher }) {
|
|
3918
4029
|
this.url = url;
|
|
3919
4030
|
this.federation = federation;
|
|
@@ -3922,6 +4033,15 @@ var ContextImpl = class ContextImpl {
|
|
|
3922
4033
|
this.contextLoader = contextLoader;
|
|
3923
4034
|
this.invokedFromActorKeyPairsDispatcher = invokedFromActorKeyPairsDispatcher;
|
|
3924
4035
|
}
|
|
4036
|
+
/**
|
|
4037
|
+
* A {@link TaskCodec} bound to this context's loaders, used to encode
|
|
4038
|
+
* and decode custom task payloads. Lazily created and cached so a context
|
|
4039
|
+
* that never enqueues or dispatches a task pays nothing.
|
|
4040
|
+
* @internal
|
|
4041
|
+
*/
|
|
4042
|
+
get codec() {
|
|
4043
|
+
return this.#codec ??= new TaskCodec(this);
|
|
4044
|
+
}
|
|
3925
4045
|
clone(data) {
|
|
3926
4046
|
return new ContextImpl({
|
|
3927
4047
|
url: this.url,
|
|
@@ -4240,6 +4360,45 @@ var ContextImpl = class ContextImpl {
|
|
|
4240
4360
|
allowPrivateAddress: this.federation.allowPrivateAddress
|
|
4241
4361
|
});
|
|
4242
4362
|
}
|
|
4363
|
+
async enqueueTask(task, data, options = {}) {
|
|
4364
|
+
await this.#enqueueTasks(task, [data], options);
|
|
4365
|
+
}
|
|
4366
|
+
async enqueueTaskMany(task, payloads, options = {}) {
|
|
4367
|
+
await this.#enqueueTasks(task, payloads, options);
|
|
4368
|
+
}
|
|
4369
|
+
async #enqueueTasks(task, items, options) {
|
|
4370
|
+
const def = this.federation.taskDefinitions.get(task.name);
|
|
4371
|
+
if (def == null || def.handle !== task) throw new TypeError(`Task ${JSON.stringify(task.name)} is not defined on this federation; pass a handle returned by its defineTask().`);
|
|
4372
|
+
const queue = this.federation.resolveTaskQueue(task.name);
|
|
4373
|
+
if (queue == null) throw new TypeError("No message queue is configured for tasks; pass `queue` to createFederation() or to defineTask().");
|
|
4374
|
+
if (items.length < 1) return;
|
|
4375
|
+
const delay = options.delay == null ? void 0 : Temporal.Duration.from(options.delay);
|
|
4376
|
+
const messages = await Promise.all(items.map(this.#encodeTaskMessage(task, options)));
|
|
4377
|
+
if (!this.federation.manuallyStartQueue) this.federation._startQueueInternal(this.data);
|
|
4378
|
+
const enqueueOptions = {
|
|
4379
|
+
delay,
|
|
4380
|
+
orderingKey: options.orderingKey
|
|
4381
|
+
};
|
|
4382
|
+
if (messages.length === 1) await queue.enqueue(messages[0], enqueueOptions);
|
|
4383
|
+
else if (queue.enqueueMany != null) await queue.enqueueMany(messages, enqueueOptions);
|
|
4384
|
+
else await Promise.all(messages.map((m) => queue.enqueue(m, enqueueOptions)));
|
|
4385
|
+
}
|
|
4386
|
+
#encodeTaskMessage = (task, options) => async (data) => {
|
|
4387
|
+
const encoded = await this.codec.encode(task.schema, data);
|
|
4388
|
+
const carrier = {};
|
|
4389
|
+
propagation.inject(context.active(), carrier);
|
|
4390
|
+
return {
|
|
4391
|
+
type: "task",
|
|
4392
|
+
id: crypto.randomUUID(),
|
|
4393
|
+
baseUrl: this.origin,
|
|
4394
|
+
taskName: task.name,
|
|
4395
|
+
data: encoded,
|
|
4396
|
+
started: Temporal.Now.instant().toString(),
|
|
4397
|
+
attempt: 0,
|
|
4398
|
+
orderingKey: options.orderingKey,
|
|
4399
|
+
traceContext: carrier
|
|
4400
|
+
};
|
|
4401
|
+
};
|
|
4243
4402
|
sendActivity(sender, recipients, activity, options = {}) {
|
|
4244
4403
|
return this.tracerProvider.getTracer(name, version).startActiveSpan(this.federation.outboxQueue == null || options.immediate ? "activitypub.outbox" : "activitypub.fanout", {
|
|
4245
4404
|
kind: this.federation.outboxQueue == null || options.immediate ? SpanKind.CLIENT : SpanKind.PRODUCER,
|