@fedify/fedify 2.3.1 → 2.3.2-dev.1556
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/README.md +10 -7
- package/dist/{builder-hivpmhlD.mjs → builder-DosLp_w5.mjs} +2 -2
- package/dist/{circuit-breaker-CSWsyoef.mjs → circuit-breaker-DLS_n1x5.mjs} +190 -7
- package/dist/circuit-breaker-test-utils-BVnv3T76.mjs +14 -0
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{context-BBVLF7lx.d.cts → context-Bjswu3eC.d.cts} +18 -1
- package/dist/{context-BU6jSQdo.d.ts → context-COxc_O-c.d.ts} +18 -1
- package/dist/{deno-C8RG0HM3.mjs → deno-Bg8I1L40.mjs} +1 -1
- package/dist/{docloader-YZA0m_3O.mjs → docloader-Dxsk3R8v.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/circuit-breaker.test.mjs +622 -3
- package/dist/federation/handler.test.mjs +3 -3
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +16 -8
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-PCt0862M.mjs → http-BaUm6xbz.mjs} +3 -3
- package/dist/{http-DPOMa1DD.js → http-Bw8wN_Uk.js} +1 -1
- package/dist/{http-BajqV0pH.cjs → http-y8Cigpuq.cjs} +1 -1
- package/dist/{key-BKYwmbur.mjs → key-DOnwUeY9.mjs} +2 -2
- package/dist/{kv-cache-CVG3m2_-.cjs → kv-cache-B9AAXEOS.cjs} +1 -1
- package/dist/{kv-cache-Ceg0c1wh.mjs → kv-cache-CE_QUNa6.mjs} +1 -1
- package/dist/{kv-cache-IjRceERu.js → kv-cache-DilyIIfz.js} +1 -1
- package/dist/{ld-Dcw2skfn.mjs → ld-CiONXo2U.mjs} +3 -3
- package/dist/{metrics-Pue1x4ta.mjs → metrics-CmX7KEfY.mjs} +1 -1
- package/dist/{middleware-By8lqc18.js → middleware-BEhF8uxY.js} +193 -10
- package/dist/{middleware-CyxqoeW9.mjs → middleware-CRMohX8-.mjs} +1 -1
- package/dist/{middleware-WU_5fbGS.mjs → middleware-Cf0dFqr9.mjs} +13 -13
- package/dist/{middleware-BiXEAbn2.cjs → middleware-DZf3vcun.cjs} +193 -10
- package/dist/{mod-C0F6kvgS.d.cts → mod-0bIqGrKQ.d.cts} +1 -1
- package/dist/{mod-vPYVoa5n.d.ts → mod-3H9Gym5G.d.ts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +2 -2
- package/dist/mod.d.ts +2 -2
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-pVJ0Twi7.mjs → owner-C7h5_D1P.mjs} +2 -2
- package/dist/{proof-HzavUYxN.cjs → proof-BKOUYRRh.cjs} +1 -1
- package/dist/{proof-pXYODmNV.mjs → proof-BVuILGqP.mjs} +3 -3
- package/dist/{proof-DA8Kbchf.js → proof-DNlVt3rz.js} +1 -1
- package/dist/{send-BfAp60BJ.mjs → send-7kSXrsl4.mjs} +3 -3
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +1 -1
- package/dist/{temporal-HZHBbbk4.mjs → temporal-D3Bspq6d.mjs} +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- 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 +6 -6
|
@@ -2,10 +2,10 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./chunk-CRNNMoPX.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-BGMIq1cs.js";
|
|
5
|
-
import { A as formatAcceptSignature, D as recordOutboxEnqueue, E as recordOutboxActivity, F as version, O as recordWebFingerHandle, P as name, S as recordCollectionTotalItems, T as recordInboxActivity, a as verifyRequestDetailed, b as recordCollectionPageItems, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, k as registerQueueDepthGauge, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, v as recordCircuitBreakerStateChange, w as recordFanoutRecipients, x as recordCollectionRequest, y as recordCollectionDispatchDuration } from "./http-
|
|
6
|
-
import { _ as hasSignatureLike, b as signJsonLd, c as getKeyOwner, f as compactJsonLd, g as hasSignature, h as getNormalizationContextLoader, i as verifyObject, l as InvalidContextReferenceError, m as detachSignature, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, r as signObject, s as doesActorOwnKey, u as assertSafeJsonLd, v as isClearlyMalformedContextReference, w as wrapContextLoaderForJsonLd, x as verifyCompactJsonLd, y as isInvalidUrlTypeError } from "./proof-
|
|
5
|
+
import { A as formatAcceptSignature, D as recordOutboxEnqueue, E as recordOutboxActivity, F as version, O as recordWebFingerHandle, P as name, S as recordCollectionTotalItems, T as recordInboxActivity, a as verifyRequestDetailed, b as recordCollectionPageItems, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, k as registerQueueDepthGauge, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, v as recordCircuitBreakerStateChange, w as recordFanoutRecipients, x as recordCollectionRequest, y as recordCollectionDispatchDuration } from "./http-Bw8wN_Uk.js";
|
|
6
|
+
import { _ as hasSignatureLike, b as signJsonLd, c as getKeyOwner, f as compactJsonLd, g as hasSignature, h as getNormalizationContextLoader, i as verifyObject, l as InvalidContextReferenceError, m as detachSignature, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, r as signObject, s as doesActorOwnKey, u as assertSafeJsonLd, v as isClearlyMalformedContextReference, w as wrapContextLoaderForJsonLd, x as verifyCompactJsonLd, y as isInvalidUrlTypeError } from "./proof-DNlVt3rz.js";
|
|
7
7
|
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-CAY3OdLq.js";
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-DilyIIfz.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, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
@@ -680,6 +680,13 @@ function createFederationBuilder() {
|
|
|
680
680
|
//#endregion
|
|
681
681
|
//#region src/federation/circuit-breaker.ts
|
|
682
682
|
const MAX_CUSTOM_FAILURE_HISTORY = 100;
|
|
683
|
+
const LEGACY_SWEEP_MARKER = ["__fedify_meta", "circuit_breaker_state_ttl_sweep_v1"];
|
|
684
|
+
const LEGACY_SWEEP_DELETING_MARKER = { __fedifyDeletingCircuitBreakerLegacyState: true };
|
|
685
|
+
const CIRCUIT_BREAKER_STATE_VERSION = 1;
|
|
686
|
+
const LEGACY_SWEEP_LOCK_TTL = Temporal.Duration.from({ minutes: 5 });
|
|
687
|
+
const LEGACY_SWEEP_RETRY_WINDOW = Temporal.Duration.from({ hours: 168 });
|
|
688
|
+
const LEGACY_SWEEP_WAIT_INTERVAL = 10;
|
|
689
|
+
const LEGACY_SWEEP_CAS_ATTEMPTS = 3;
|
|
683
690
|
/**
|
|
684
691
|
* Tracks reachability state for remote outbox delivery hosts.
|
|
685
692
|
* @since 2.3.0
|
|
@@ -689,6 +696,8 @@ var CircuitBreaker = class {
|
|
|
689
696
|
#prefix;
|
|
690
697
|
#options;
|
|
691
698
|
#now;
|
|
699
|
+
#legacySweep;
|
|
700
|
+
#legacySweepDone;
|
|
692
701
|
#stateChangeObserver;
|
|
693
702
|
constructor(options) {
|
|
694
703
|
this.#kv = options.kv;
|
|
@@ -705,6 +714,7 @@ var CircuitBreaker = class {
|
|
|
705
714
|
return now.until(this.#capHeldRetryAt(now, heldSince, now.add(delay)));
|
|
706
715
|
}
|
|
707
716
|
async beforeSend(remoteHost, message) {
|
|
717
|
+
this.#sweepLegacyStates();
|
|
708
718
|
const heldSince = parseHeldSince(message.circuitHeldSince);
|
|
709
719
|
const now = this.#now();
|
|
710
720
|
if (heldSince != null && Temporal.Instant.compare(heldSince.add(this.#options.heldActivityTtl), now) <= 0) return {
|
|
@@ -786,6 +796,7 @@ var CircuitBreaker = class {
|
|
|
786
796
|
throw new Error(`Failed to update circuit breaker state for ${remoteHost}`);
|
|
787
797
|
}
|
|
788
798
|
async recordSuccess(remoteHost) {
|
|
799
|
+
this.#sweepLegacyStates();
|
|
789
800
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
790
801
|
const oldState = await this.#get(remoteHost);
|
|
791
802
|
if (oldState == null) return void 0;
|
|
@@ -806,6 +817,7 @@ var CircuitBreaker = class {
|
|
|
806
817
|
return await this.recordSuccess(remoteHost);
|
|
807
818
|
}
|
|
808
819
|
async recordFailure(remoteHost) {
|
|
820
|
+
this.#sweepLegacyStates();
|
|
809
821
|
const now = this.#now();
|
|
810
822
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
811
823
|
const oldState = await this.#get(remoteHost);
|
|
@@ -853,26 +865,122 @@ var CircuitBreaker = class {
|
|
|
853
865
|
}
|
|
854
866
|
}
|
|
855
867
|
async getState(remoteHost) {
|
|
856
|
-
|
|
868
|
+
this.#sweepLegacyStates();
|
|
869
|
+
return stripStoredCircuitBreakerState(await this.#get(remoteHost));
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* The currently running background legacy sweep, if any.
|
|
873
|
+
* @internal
|
|
874
|
+
*/
|
|
875
|
+
get pendingSweep() {
|
|
876
|
+
return this.#legacySweep;
|
|
857
877
|
}
|
|
858
878
|
#key(remoteHost) {
|
|
859
879
|
return [...this.#prefix, remoteHost];
|
|
860
880
|
}
|
|
881
|
+
#legacySweepMarkerKey() {
|
|
882
|
+
return [...this.#prefix, ...LEGACY_SWEEP_MARKER];
|
|
883
|
+
}
|
|
884
|
+
#sweepLegacyStates() {
|
|
885
|
+
if (this.#kv.cas == null) return;
|
|
886
|
+
if (this.#options.stateTtl == null) return;
|
|
887
|
+
if (this.#legacySweep != null) return;
|
|
888
|
+
if (this.#isLegacySweepDone()) return;
|
|
889
|
+
this.#legacySweep = this.#sweepLegacyStatesImpl().catch((error) => {
|
|
890
|
+
getLogger([
|
|
891
|
+
"fedify",
|
|
892
|
+
"federation",
|
|
893
|
+
"circuit"
|
|
894
|
+
]).warn("Failed to sweep legacy circuit breaker state:\n{error}", { error });
|
|
895
|
+
}).finally(() => {
|
|
896
|
+
this.#legacySweep = void 0;
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
async #sweepLegacyStatesImpl() {
|
|
900
|
+
const markerKey = this.#legacySweepMarkerKey();
|
|
901
|
+
const marker = await this.#acquireLegacySweep(markerKey);
|
|
902
|
+
if (marker === "done") return;
|
|
903
|
+
try {
|
|
904
|
+
for await (const { key, value } of this.#kv.list(this.#prefix)) {
|
|
905
|
+
if (key.length !== this.#prefix.length + 1) continue;
|
|
906
|
+
await this.#migrateLegacyState(key, value);
|
|
907
|
+
}
|
|
908
|
+
} catch (error) {
|
|
909
|
+
await this.#deleteIfUnchanged(markerKey, marker);
|
|
910
|
+
throw error;
|
|
911
|
+
}
|
|
912
|
+
const finishedMarker = this.#finishLegacySweepMarker(marker);
|
|
913
|
+
if (await this.#kv.cas(markerKey, marker, finishedMarker)) this.#rememberLegacySweepMarker(finishedMarker);
|
|
914
|
+
}
|
|
915
|
+
#finishLegacySweepMarker(marker) {
|
|
916
|
+
const retryUntil = getLegacySweepRetryUntil(marker);
|
|
917
|
+
if (retryUntil != null && Temporal.Instant.compare(this.#now(), Temporal.Instant.from(retryUntil)) < 0) return {
|
|
918
|
+
state: "done",
|
|
919
|
+
retryUntil
|
|
920
|
+
};
|
|
921
|
+
return { state: "final" };
|
|
922
|
+
}
|
|
923
|
+
async #migrateLegacyState(key, value) {
|
|
924
|
+
if (isCurrentCircuitBreakerState(value)) return;
|
|
925
|
+
const state = parseCircuitBreakerKvState(value);
|
|
926
|
+
if (state != null) {
|
|
927
|
+
await this.#kv.cas(key, value, markCircuitBreakerState(state), this.#setOptions());
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
await this.#deleteIfUnchanged(key, value);
|
|
931
|
+
}
|
|
932
|
+
async #deleteIfUnchanged(key, value) {
|
|
933
|
+
if (await this.#kv.cas(key, value, LEGACY_SWEEP_DELETING_MARKER, { ttl: LEGACY_SWEEP_LOCK_TTL })) await this.#kv.delete(key);
|
|
934
|
+
}
|
|
935
|
+
async #acquireLegacySweep(markerKey) {
|
|
936
|
+
for (let attempt = 0; attempt < LEGACY_SWEEP_CAS_ATTEMPTS; attempt++) {
|
|
937
|
+
const marker = await this.#kv.get(markerKey);
|
|
938
|
+
const now = this.#now();
|
|
939
|
+
if (isLegacySweepActive(marker, now)) {
|
|
940
|
+
this.#rememberLegacySweepMarker(marker);
|
|
941
|
+
return "done";
|
|
942
|
+
}
|
|
943
|
+
const retryUntil = isLegacySweepRetryDue(marker, now) ? marker.retryUntil : getLegacySweepRetryUntil(marker) ?? now.add(LEGACY_SWEEP_RETRY_WINDOW).toString();
|
|
944
|
+
const sweeping = {
|
|
945
|
+
state: "sweeping",
|
|
946
|
+
started: now.toString(),
|
|
947
|
+
retryUntil
|
|
948
|
+
};
|
|
949
|
+
if (await this.#kv.cas(markerKey, marker ?? void 0, sweeping, { ttl: LEGACY_SWEEP_LOCK_TTL })) return sweeping;
|
|
950
|
+
await delay(LEGACY_SWEEP_WAIT_INTERVAL);
|
|
951
|
+
}
|
|
952
|
+
return "done";
|
|
953
|
+
}
|
|
954
|
+
#isLegacySweepDone() {
|
|
955
|
+
if (this.#legacySweepDone === "final") return true;
|
|
956
|
+
if (this.#legacySweepDone == null) return false;
|
|
957
|
+
if (Temporal.Instant.compare(this.#now(), this.#legacySweepDone) < 0) return true;
|
|
958
|
+
this.#legacySweepDone = void 0;
|
|
959
|
+
return false;
|
|
960
|
+
}
|
|
961
|
+
#rememberLegacySweepMarker(marker) {
|
|
962
|
+
const doneUntil = getLegacySweepDoneUntil(marker, this.#now());
|
|
963
|
+
if (doneUntil != null) this.#legacySweepDone = doneUntil;
|
|
964
|
+
}
|
|
861
965
|
#capHeldRetryAt(now, heldSince, retryAt) {
|
|
862
966
|
const expiresAt = (heldSince ?? now).add(this.#options.heldActivityTtl);
|
|
863
967
|
return Temporal.Instant.compare(expiresAt, retryAt) < 0 ? expiresAt : retryAt;
|
|
864
968
|
}
|
|
865
969
|
async #get(remoteHost) {
|
|
866
|
-
return
|
|
970
|
+
return parseStoredCircuitBreakerKvState(await this.#kv.get(this.#key(remoteHost)));
|
|
867
971
|
}
|
|
868
972
|
async #replace(remoteHost, oldState, newState) {
|
|
869
973
|
const key = this.#key(remoteHost);
|
|
974
|
+
const storedState = newState == null ? void 0 : markCircuitBreakerState(newState);
|
|
870
975
|
if (this.#kv.cas == null) {
|
|
871
|
-
if (
|
|
872
|
-
else await this.#kv.set(key,
|
|
976
|
+
if (storedState == null) await this.#kv.delete(key);
|
|
977
|
+
else await this.#kv.set(key, storedState, this.#setOptions());
|
|
873
978
|
return true;
|
|
874
979
|
}
|
|
875
|
-
return await this.#kv.cas(key, oldState,
|
|
980
|
+
return await this.#kv.cas(key, oldState, storedState, storedState == null ? void 0 : this.#setOptions());
|
|
981
|
+
}
|
|
982
|
+
#setOptions() {
|
|
983
|
+
return this.#options.stateTtl == null ? void 0 : { ttl: this.#options.stateTtl };
|
|
876
984
|
}
|
|
877
985
|
async #notifyStateChange(remoteHost, previousState, newState) {
|
|
878
986
|
try {
|
|
@@ -912,18 +1020,25 @@ var CircuitBreaker = class {
|
|
|
912
1020
|
* @param options The public circuit breaker options supplied to Fedify.
|
|
913
1021
|
* @returns The normalized failure predicate, failure pruning function,
|
|
914
1022
|
* duration values, and optional callbacks with defaults applied.
|
|
915
|
-
* @throws {RangeError} If any configured duration is not positive
|
|
1023
|
+
* @throws {RangeError} If any configured duration is not positive, or if
|
|
1024
|
+
* `stateTtl` is shorter than `recoveryDelay`.
|
|
916
1025
|
* @throws {TypeError} If `failureThreshold` is not a positive integer.
|
|
917
1026
|
*/
|
|
918
1027
|
function normalizeCircuitBreakerOptions(options) {
|
|
919
1028
|
const recoveryDelay = toInstantDuration(options.recoveryDelay ?? { minutes: 30 });
|
|
920
1029
|
const heldActivityTtl = toInstantDuration(options.heldActivityTtl ?? { hours: 168 });
|
|
921
1030
|
const releaseInterval = toInstantDuration(options.releaseInterval ?? { seconds: 1 });
|
|
1031
|
+
const configuredStateTtl = options.stateTtl == null ? void 0 : toInstantDuration(options.stateTtl);
|
|
922
1032
|
assertPositiveDuration(recoveryDelay, "recoveryDelay");
|
|
923
1033
|
assertPositiveDuration(heldActivityTtl, "heldActivityTtl");
|
|
924
1034
|
assertPositiveDuration(releaseInterval, "releaseInterval");
|
|
1035
|
+
if (configuredStateTtl != null) {
|
|
1036
|
+
assertPositiveDuration(configuredStateTtl, "stateTtl");
|
|
1037
|
+
if (Temporal.Duration.compare(configuredStateTtl, recoveryDelay) < 0) throw new RangeError("stateTtl must be at least recoveryDelay.");
|
|
1038
|
+
}
|
|
925
1039
|
let failure;
|
|
926
1040
|
let pruneFailures;
|
|
1041
|
+
let stateTtl;
|
|
927
1042
|
if (options.failure == null) {
|
|
928
1043
|
const failureThreshold = options.failureThreshold ?? 5;
|
|
929
1044
|
if (!Number.isInteger(failureThreshold) || failureThreshold <= 0) throw new TypeError("failureThreshold must be a positive integer.");
|
|
@@ -939,9 +1054,11 @@ function normalizeCircuitBreakerOptions(options) {
|
|
|
939
1054
|
const last = timestamps[timestamps.length - 1];
|
|
940
1055
|
return Temporal.Duration.compare(first.until(last), failureWindow) <= 0;
|
|
941
1056
|
};
|
|
1057
|
+
stateTtl = configuredStateTtl ?? maxDuration(recoveryDelay.add(failureWindow), recoveryDelay.add(heldActivityTtl));
|
|
942
1058
|
} else {
|
|
943
1059
|
failure = options.failure;
|
|
944
1060
|
pruneFailures = (timestamps) => timestamps.slice(-MAX_CUSTOM_FAILURE_HISTORY);
|
|
1061
|
+
stateTtl = configuredStateTtl;
|
|
945
1062
|
}
|
|
946
1063
|
return {
|
|
947
1064
|
failure,
|
|
@@ -949,10 +1066,72 @@ function normalizeCircuitBreakerOptions(options) {
|
|
|
949
1066
|
recoveryDelay,
|
|
950
1067
|
heldActivityTtl,
|
|
951
1068
|
releaseInterval,
|
|
1069
|
+
stateTtl,
|
|
952
1070
|
onStateChange: options.onStateChange,
|
|
953
1071
|
onActivityDrop: options.onActivityDrop
|
|
954
1072
|
};
|
|
955
1073
|
}
|
|
1074
|
+
function maxDuration(duration, ...durations) {
|
|
1075
|
+
return durations.reduce((max, candidate) => Temporal.Duration.compare(candidate, max) > 0 ? candidate : max, duration);
|
|
1076
|
+
}
|
|
1077
|
+
function isLegacySweepDone(value, now) {
|
|
1078
|
+
return getLegacySweepDoneUntil(value, now) != null;
|
|
1079
|
+
}
|
|
1080
|
+
function getLegacySweepDoneUntil(value, now) {
|
|
1081
|
+
if (typeof value !== "object" || value == null || !("state" in value)) return;
|
|
1082
|
+
if (value.state === "final") return "final";
|
|
1083
|
+
if (value.state === "done" && "retryUntil" in value && typeof value.retryUntil === "string") try {
|
|
1084
|
+
const retryUntil = Temporal.Instant.from(value.retryUntil);
|
|
1085
|
+
return Temporal.Instant.compare(now, retryUntil) < 0 ? retryUntil : void 0;
|
|
1086
|
+
} catch {
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
function isLegacySweepRetryDue(value, now) {
|
|
1091
|
+
if (typeof value !== "object" || value == null || !("state" in value) || value.state !== "done" || !("retryUntil" in value) || typeof value.retryUntil !== "string") return false;
|
|
1092
|
+
try {
|
|
1093
|
+
return Temporal.Instant.compare(now, Temporal.Instant.from(value.retryUntil)) >= 0;
|
|
1094
|
+
} catch {
|
|
1095
|
+
return false;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
function isLegacySweepActive(value, now) {
|
|
1099
|
+
return isLegacySweepDone(value, now) || isLegacySweepInProgress(value, now);
|
|
1100
|
+
}
|
|
1101
|
+
function isLegacySweepInProgress(value, now) {
|
|
1102
|
+
if (typeof value !== "object" || value == null || !("state" in value) || value.state !== "sweeping" || !("started" in value) || typeof value.started !== "string") return false;
|
|
1103
|
+
try {
|
|
1104
|
+
return Temporal.Instant.compare(now, Temporal.Instant.from(value.started).add(LEGACY_SWEEP_LOCK_TTL)) < 0;
|
|
1105
|
+
} catch {
|
|
1106
|
+
return false;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
function getLegacySweepRetryUntil(value) {
|
|
1110
|
+
if (typeof value !== "object" || value == null || !("retryUntil" in value) || typeof value.retryUntil !== "string") return;
|
|
1111
|
+
try {
|
|
1112
|
+
Temporal.Instant.from(value.retryUntil);
|
|
1113
|
+
return value.retryUntil;
|
|
1114
|
+
} catch {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
function isCurrentCircuitBreakerState(value) {
|
|
1119
|
+
return typeof value === "object" && value != null && "__fedifyCircuitBreakerStateVersion" in value && value.__fedifyCircuitBreakerStateVersion === CIRCUIT_BREAKER_STATE_VERSION;
|
|
1120
|
+
}
|
|
1121
|
+
function markCircuitBreakerState(state) {
|
|
1122
|
+
return {
|
|
1123
|
+
...state,
|
|
1124
|
+
__fedifyCircuitBreakerStateVersion: CIRCUIT_BREAKER_STATE_VERSION
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
function stripStoredCircuitBreakerState(state) {
|
|
1128
|
+
if (state == null) return void 0;
|
|
1129
|
+
const { __fedifyCircuitBreakerStateVersion: _, ...publicState } = state;
|
|
1130
|
+
return publicState;
|
|
1131
|
+
}
|
|
1132
|
+
function delay(milliseconds) {
|
|
1133
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
1134
|
+
}
|
|
956
1135
|
function toInstantDuration(duration) {
|
|
957
1136
|
const parsed = Temporal.Duration.from(duration);
|
|
958
1137
|
return Temporal.Duration.from({ milliseconds: Math.trunc(parsed.total({
|
|
@@ -987,6 +1166,9 @@ function parseHeldSince(value) {
|
|
|
987
1166
|
* valid instant strings, or `undefined` when the stored value is malformed.
|
|
988
1167
|
*/
|
|
989
1168
|
function parseCircuitBreakerKvState(value) {
|
|
1169
|
+
return stripStoredCircuitBreakerState(parseStoredCircuitBreakerKvState(value));
|
|
1170
|
+
}
|
|
1171
|
+
function parseStoredCircuitBreakerKvState(value) {
|
|
990
1172
|
const isInstantString = (v) => {
|
|
991
1173
|
if (typeof v !== "string") return false;
|
|
992
1174
|
try {
|
|
@@ -1006,7 +1188,8 @@ function parseCircuitBreakerKvState(value) {
|
|
|
1006
1188
|
state: record.state,
|
|
1007
1189
|
failures: record.failures,
|
|
1008
1190
|
...record.opened == null ? {} : { opened: record.opened },
|
|
1009
|
-
...record.halfOpened == null ? {} : { halfOpened: record.halfOpened }
|
|
1191
|
+
...record.halfOpened == null ? {} : { halfOpened: record.halfOpened },
|
|
1192
|
+
...record.__fedifyCircuitBreakerStateVersion === CIRCUIT_BREAKER_STATE_VERSION ? { __fedifyCircuitBreakerStateVersion: CIRCUIT_BREAKER_STATE_VERSION } : {}
|
|
1010
1193
|
};
|
|
1011
1194
|
}
|
|
1012
1195
|
//#endregion
|
|
@@ -1,26 +1,26 @@
|
|
|
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-
|
|
4
|
+
import { n as version, t as name } from "./deno-Bg8I1L40.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-CmX7KEfY.mjs";
|
|
6
6
|
import { t as formatAcceptSignature } from "./accept-CPkZzmGN.mjs";
|
|
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-
|
|
7
|
+
import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-DOnwUeY9.mjs";
|
|
8
|
+
import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-BaUm6xbz.mjs";
|
|
9
|
+
import { t as getAuthenticatedDocumentLoader } from "./docloader-Dxsk3R8v.mjs";
|
|
10
|
+
import { n as kvCache } from "./kv-cache-CE_QUNa6.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-CiONXo2U.mjs";
|
|
12
|
+
import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-C7h5_D1P.mjs";
|
|
13
13
|
import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-L_DbOaFe.mjs";
|
|
14
|
-
import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-
|
|
14
|
+
import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-BVuILGqP.mjs";
|
|
15
15
|
import { t as getNodeInfo } from "./client-ByXmQhYD.mjs";
|
|
16
16
|
import { t as nodeInfoToJson } from "./types-J53Kw7so.mjs";
|
|
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-
|
|
17
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-7kSXrsl4.mjs";
|
|
18
|
+
import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-DosLp_w5.mjs";
|
|
19
|
+
import { t as CircuitBreaker } from "./circuit-breaker-DLS_n1x5.mjs";
|
|
20
20
|
import { t as buildCollectionSynchronizationHeader } from "./collection-Cc3DVAhE.mjs";
|
|
21
21
|
import { t as KvKeyCache } from "./keycache-BeU0LCII.mjs";
|
|
22
22
|
import { t as acceptsJsonLd } from "./negotiation-DDstyBvc.mjs";
|
|
23
|
-
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-
|
|
23
|
+
import { t as hasMalformedKnownTemporalLiteral } from "./temporal-D3Bspq6d.mjs";
|
|
24
24
|
import { t as createExponentialBackoffPolicy } from "./retry-CXg_MBI-.mjs";
|
|
25
25
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
26
26
|
import { RouterError } from "@fedify/uri-template";
|