@fedify/fedify 2.3.5-dev.1755 → 2.3.6
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/{builder-De3ym5P9.mjs → builder-CW-9AJCO.mjs} +2 -2
- package/dist/{circuit-breaker-DLS_n1x5.mjs → circuit-breaker-D1fxthDI.mjs} +25 -5
- package/dist/{circuit-breaker-test-utils-BVnv3T76.mjs → circuit-breaker-test-utils-CAdwjgMi.mjs} +1 -1
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +1 -1
- package/dist/compat/public-audience.test.mjs +11 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{context-Bjswu3eC.d.cts → context-BpmLyiPx.d.cts} +3 -2
- package/dist/{context-COxc_O-c.d.ts → context-BxVVO5Ro.d.ts} +3 -2
- package/dist/{deno-Bb3DoPyg.mjs → deno-KC-uf6Un.mjs} +1 -1
- package/dist/{docloader-B9iBabXZ.mjs → docloader-BHS1yt22.mjs} +13 -9
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/circuit-breaker.test.mjs +184 -21
- 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 +10 -9
- 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-DjON0zte.mjs → http-BcbYkefs.mjs} +9 -7
- package/dist/{http-DbMJX--j.cjs → http-DL5ZJBC4.cjs} +8 -6
- package/dist/{http-CNA76HH5.js → http-DzgaVy-x.js} +8 -6
- package/dist/{key-C2zsXBK1.mjs → key-Cbkqgt-G.mjs} +3 -3
- package/dist/{kv-cache-M9GujpTX.js → kv-cache-BWNRhap7.js} +12 -8
- package/dist/{kv-cache-CTOxE4cl.mjs → kv-cache-CT228f7w.mjs} +1 -1
- package/dist/{kv-cache-CZ9RI_NZ.cjs → kv-cache-Dw94l8rT.cjs} +12 -8
- package/dist/{ld-CB6S9oHd.mjs → ld-c-9mCB36.mjs} +3 -3
- package/dist/{metrics-DbryxSc6.mjs → metrics-D8s1eKfJ.mjs} +1 -1
- package/dist/{middleware-HRbD2E7D.mjs → middleware-3L9f9ZTw.mjs} +14 -14
- package/dist/{middleware-aw8NYL2-.cjs → middleware-B29rR42K.cjs} +28 -8
- package/dist/{middleware-BZdewTD9.mjs → middleware-Be2z0t5f.mjs} +1 -1
- package/dist/{middleware-iPQJA9In.js → middleware-D_cNQ7Yq.js} +28 -8
- package/dist/{mod-0bIqGrKQ.d.cts → mod-CjERT09F.d.cts} +1 -1
- package/dist/{mod-3H9Gym5G.d.ts → mod-Rpy4Uwkk.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/{outgoing-jsonld-L_DbOaFe.mjs → outgoing-jsonld-OFoubetZ.mjs} +1 -1
- package/dist/{owner-C5QCaiH6.mjs → owner-CjkdUXE3.mjs} +2 -2
- package/dist/{proof-Bzsr8i8m.js → proof-CrtfGSi7.js} +3 -2
- package/dist/{proof-yq1G2Z6x.cjs → proof-DGlDXtcc.cjs} +3 -2
- package/dist/{proof-CCC9itsd.mjs → proof-D_6qtBdQ.mjs} +5 -5
- package/dist/{public-audience-Cvbr2Gzt.mjs → public-audience-DZJAUUi8.mjs} +2 -1
- package/dist/{send-Zq0hXa8X.mjs → send-i63Det4Y.mjs} +3 -3
- package/dist/sig/http.test.mjs +65 -3
- package/dist/sig/key.test.mjs +46 -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 +2 -2
- package/dist/{temporal-Rytw3yy2.mjs → temporal-CcVjTX30.mjs} +1 -1
- package/dist/utils/docloader.test.mjs +35 -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 +7 -7
|
@@ -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-KC-uf6Un.mjs";
|
|
5
5
|
import { t as ActivityListenerSet } from "./activity-listener-tztVvlNb.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { Router, RouterError, assertPath } from "@fedify/uri-template";
|
|
@@ -80,7 +80,7 @@ var FederationBuilderImpl = class {
|
|
|
80
80
|
* specified.
|
|
81
81
|
*/
|
|
82
82
|
async build(options) {
|
|
83
|
-
const { FederationImpl } = await import("./middleware-
|
|
83
|
+
const { FederationImpl } = await import("./middleware-Be2z0t5f.mjs");
|
|
84
84
|
const f = new FederationImpl(options);
|
|
85
85
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
86
86
|
f.router = this.router.clone();
|
|
@@ -4,10 +4,11 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
//#region src/federation/circuit-breaker.ts
|
|
6
6
|
const MAX_CUSTOM_FAILURE_HISTORY = 100;
|
|
7
|
-
const LEGACY_SWEEP_MARKER = ["__fedify_meta", "
|
|
7
|
+
const LEGACY_SWEEP_MARKER = ["__fedify_meta", "circuit_breaker_state_ttl_sweep_v2"];
|
|
8
8
|
const LEGACY_SWEEP_DELETING_MARKER = { __fedifyDeletingCircuitBreakerLegacyState: true };
|
|
9
9
|
const CIRCUIT_BREAKER_STATE_VERSION = 1;
|
|
10
10
|
const LEGACY_SWEEP_LOCK_TTL = Temporal.Duration.from({ minutes: 5 });
|
|
11
|
+
const LEGACY_SWEEP_RENEW_INTERVAL = Temporal.Duration.from({ minutes: 1 });
|
|
11
12
|
const LEGACY_SWEEP_RETRY_WINDOW = Temporal.Duration.from({ hours: 168 });
|
|
12
13
|
const LEGACY_SWEEP_WAIT_INTERVAL = 10;
|
|
13
14
|
const LEGACY_SWEEP_CAS_ATTEMPTS = 3;
|
|
@@ -222,12 +223,20 @@ var CircuitBreaker = class {
|
|
|
222
223
|
}
|
|
223
224
|
async #sweepLegacyStatesImpl() {
|
|
224
225
|
const markerKey = this.#legacySweepMarkerKey();
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
226
|
+
const acquired = await this.#acquireLegacySweep(markerKey);
|
|
227
|
+
if (acquired === "done") return;
|
|
228
|
+
let marker = acquired;
|
|
229
|
+
let leaseRenewedAt = this.#now();
|
|
227
230
|
try {
|
|
228
231
|
for await (const { key, value } of this.#kv.list(this.#prefix)) {
|
|
229
232
|
if (key.length !== this.#prefix.length + 1) continue;
|
|
230
233
|
await this.#migrateLegacyState(key, value);
|
|
234
|
+
if (Temporal.Instant.compare(this.#now(), leaseRenewedAt.add(LEGACY_SWEEP_RENEW_INTERVAL)) >= 0) {
|
|
235
|
+
const renewed = await this.#renewLegacySweep(markerKey, marker);
|
|
236
|
+
if (renewed == null) return;
|
|
237
|
+
marker = renewed;
|
|
238
|
+
leaseRenewedAt = this.#now();
|
|
239
|
+
}
|
|
231
240
|
}
|
|
232
241
|
} catch (error) {
|
|
233
242
|
await this.#deleteIfUnchanged(markerKey, marker);
|
|
@@ -236,6 +245,14 @@ var CircuitBreaker = class {
|
|
|
236
245
|
const finishedMarker = this.#finishLegacySweepMarker(marker);
|
|
237
246
|
if (await this.#kv.cas(markerKey, marker, finishedMarker)) this.#rememberLegacySweepMarker(finishedMarker);
|
|
238
247
|
}
|
|
248
|
+
async #renewLegacySweep(markerKey, marker) {
|
|
249
|
+
const renewed = {
|
|
250
|
+
state: "sweeping",
|
|
251
|
+
started: this.#now().toString(),
|
|
252
|
+
retryUntil: getLegacySweepRetryUntil(marker) ?? this.#now().add(LEGACY_SWEEP_RETRY_WINDOW).toString()
|
|
253
|
+
};
|
|
254
|
+
if (await this.#kv.cas(markerKey, marker, renewed, { ttl: LEGACY_SWEEP_LOCK_TTL })) return renewed;
|
|
255
|
+
}
|
|
239
256
|
#finishLegacySweepMarker(marker) {
|
|
240
257
|
const retryUntil = getLegacySweepRetryUntil(marker);
|
|
241
258
|
if (retryUntil != null && Temporal.Instant.compare(this.#now(), Temporal.Instant.from(retryUntil)) < 0) return {
|
|
@@ -245,7 +262,10 @@ var CircuitBreaker = class {
|
|
|
245
262
|
return { state: "final" };
|
|
246
263
|
}
|
|
247
264
|
async #migrateLegacyState(key, value) {
|
|
248
|
-
if (isCurrentCircuitBreakerState(value))
|
|
265
|
+
if (isCurrentCircuitBreakerState(value)) {
|
|
266
|
+
await this.#kv.cas(key, value, value, this.#setOptions());
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
249
269
|
const state = parseCircuitBreakerKvState(value);
|
|
250
270
|
if (state != null) {
|
|
251
271
|
await this.#kv.cas(key, value, markCircuitBreakerState(state), this.#setOptions());
|
|
@@ -382,7 +402,7 @@ function normalizeCircuitBreakerOptions(options) {
|
|
|
382
402
|
} else {
|
|
383
403
|
failure = options.failure;
|
|
384
404
|
pruneFailures = (timestamps) => timestamps.slice(-MAX_CUSTOM_FAILURE_HISTORY);
|
|
385
|
-
stateTtl = configuredStateTtl;
|
|
405
|
+
stateTtl = configuredStateTtl ?? recoveryDelay.add(heldActivityTtl);
|
|
386
406
|
}
|
|
387
407
|
return {
|
|
388
408
|
failure,
|
package/dist/compat/mod.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { jt as ActivityTransformer, n as Context } from "../context-
|
|
2
|
+
import { jt as ActivityTransformer, n as Context } from "../context-BpmLyiPx.cjs";
|
|
3
3
|
import { Activity } from "@fedify/vocab";
|
|
4
4
|
|
|
5
5
|
//#region src/compat/transformers.d.ts
|
package/dist/compat/mod.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { jt as ActivityTransformer, n as Context } from "../context-
|
|
2
|
+
import { jt as ActivityTransformer, n as Context } from "../context-BxVVO5Ro.js";
|
|
3
3
|
import { Activity } from "@fedify/vocab";
|
|
4
4
|
|
|
5
5
|
//#region src/compat/transformers.d.ts
|
|
@@ -3,7 +3,7 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
5
|
import { t as assertStrictEquals } from "../assert_strict_equals-XEgZAlrj.mjs";
|
|
6
|
-
import { n as normalizeAttachmentArrays, r as normalizeOutgoingActivityJsonLd, t as isPreloadedContextAttachmentSafe } from "../outgoing-jsonld-
|
|
6
|
+
import { n as normalizeAttachmentArrays, r as normalizeOutgoingActivityJsonLd, t as isPreloadedContextAttachmentSafe } from "../outgoing-jsonld-OFoubetZ.mjs";
|
|
7
7
|
import { Create, Document, Note, PUBLIC_COLLECTION } from "@fedify/vocab";
|
|
8
8
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
9
9
|
//#region src/compat/outgoing-jsonld.test.ts
|
|
@@ -3,8 +3,8 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
5
|
import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
|
|
6
|
-
import { t as normalizePublicAudience } from "../public-audience-
|
|
7
|
-
import { Create, Note, PUBLIC_COLLECTION } from "@fedify/vocab";
|
|
6
|
+
import { t as normalizePublicAudience } from "../public-audience-DZJAUUi8.mjs";
|
|
7
|
+
import { Create, Follow, Note, PUBLIC_COLLECTION } from "@fedify/vocab";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
import { getDocumentLoader, preloadedContexts } from "@fedify/vocab-runtime";
|
|
10
10
|
//#region src/compat/public-audience.test.ts
|
|
@@ -45,6 +45,15 @@ test("normalizePublicAudience() normalises activities serialized by @fedify/voca
|
|
|
45
45
|
const nestedObject = normalized.object;
|
|
46
46
|
assertEquals(nestedObject.to, PUBLIC_URI);
|
|
47
47
|
});
|
|
48
|
+
test("normalizePublicAudience() normalises a public relay Follow object", async () => {
|
|
49
|
+
const compact = await new Follow({
|
|
50
|
+
id: new URL("https://example.com/activities/follow-relay"),
|
|
51
|
+
actor: new URL("https://example.com/alice"),
|
|
52
|
+
object: PUBLIC_COLLECTION
|
|
53
|
+
}).toJsonLd({ format: "compact" });
|
|
54
|
+
assertEquals(compact.object, "as:Public");
|
|
55
|
+
assertEquals((await normalizePublicAudience(compact, getDocumentLoader())).object, PUBLIC_URI);
|
|
56
|
+
});
|
|
48
57
|
test("normalizePublicAudience() is a no-op without the CURIE", async () => {
|
|
49
58
|
const input = {
|
|
50
59
|
"@context": AS_CONTEXT,
|
|
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
|
5
5
|
import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
|
|
6
6
|
import { t as assert } from "../assert-OguE97r2.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
|
|
8
|
-
import { b as autoIdAssigner, n as FederationImpl, y as actorDehydrator } from "../middleware-
|
|
8
|
+
import { b as autoIdAssigner, n as FederationImpl, y as actorDehydrator } from "../middleware-3L9f9ZTw.mjs";
|
|
9
9
|
import { Follow, Person } from "@fedify/vocab";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
//#region src/compat/transformers.test.ts
|
|
@@ -92,8 +92,9 @@ type CircuitBreakerOptions = CircuitBreakerFailurePolicy & {
|
|
|
92
92
|
*
|
|
93
93
|
* When omitted, Fedify derives this from `failureWindow`, `recoveryDelay`, and
|
|
94
94
|
* `heldActivityTtl` for the default numeric failure policy. Custom `failure`
|
|
95
|
-
* callbacks do not have an inspectable time window, so
|
|
96
|
-
*
|
|
95
|
+
* callbacks do not have an inspectable time window, so their state expires
|
|
96
|
+
* after `recoveryDelay` plus `heldActivityTtl` unless this option overrides
|
|
97
|
+
* it.
|
|
97
98
|
*/
|
|
98
99
|
readonly stateTtl?: Temporal.Duration | Temporal.DurationLike;
|
|
99
100
|
/**
|
|
@@ -95,8 +95,9 @@ type CircuitBreakerOptions = CircuitBreakerFailurePolicy & {
|
|
|
95
95
|
*
|
|
96
96
|
* When omitted, Fedify derives this from `failureWindow`, `recoveryDelay`, and
|
|
97
97
|
* `heldActivityTtl` for the default numeric failure policy. Custom `failure`
|
|
98
|
-
* callbacks do not have an inspectable time window, so
|
|
99
|
-
*
|
|
98
|
+
* callbacks do not have an inspectable time window, so their state expires
|
|
99
|
+
* after `recoveryDelay` plus `heldActivityTtl` unless this option overrides
|
|
100
|
+
* it.
|
|
100
101
|
*/
|
|
101
102
|
readonly stateTtl?: Temporal.Duration | Temporal.DurationLike;
|
|
102
103
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { o as validateCryptoKey } from "./key-
|
|
5
|
-
import { n as doubleKnock } from "./http-
|
|
4
|
+
import { o as validateCryptoKey } from "./key-Cbkqgt-G.mjs";
|
|
5
|
+
import { n as doubleKnock } from "./http-BcbYkefs.mjs";
|
|
6
6
|
import { getLogger } from "@logtape/logtape";
|
|
7
7
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
8
8
|
import { curry } from "es-toolkit";
|
|
@@ -26,6 +26,17 @@ const logger = getLogger([
|
|
|
26
26
|
function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedirection, userAgent, specDeterminer, tracerProvider } = {}) {
|
|
27
27
|
validateCryptoKey(identity.privateKey);
|
|
28
28
|
async function load(url, options) {
|
|
29
|
+
await validateUrl(url);
|
|
30
|
+
return getRemoteDocument(url, await doubleKnock(createActivityPubRequest(url, { userAgent }), identity, {
|
|
31
|
+
maxRedirection,
|
|
32
|
+
specDeterminer,
|
|
33
|
+
log: curry(logRequest)(logger),
|
|
34
|
+
tracerProvider,
|
|
35
|
+
signal: options?.signal,
|
|
36
|
+
validateRedirect: validateUrl
|
|
37
|
+
}), load);
|
|
38
|
+
}
|
|
39
|
+
async function validateUrl(url) {
|
|
29
40
|
if (!allowPrivateAddress) try {
|
|
30
41
|
await validatePublicUrl(url);
|
|
31
42
|
} catch (error) {
|
|
@@ -35,13 +46,6 @@ function getAuthenticatedDocumentLoader(identity, { allowPrivateAddress, maxRedi
|
|
|
35
46
|
});
|
|
36
47
|
throw error;
|
|
37
48
|
}
|
|
38
|
-
return getRemoteDocument(url, await doubleKnock(createActivityPubRequest(url, { userAgent }), identity, {
|
|
39
|
-
maxRedirection,
|
|
40
|
-
specDeterminer,
|
|
41
|
-
log: curry(logRequest)(logger),
|
|
42
|
-
tracerProvider,
|
|
43
|
-
signal: options?.signal
|
|
44
|
-
}), load);
|
|
45
49
|
}
|
|
46
50
|
return load;
|
|
47
51
|
}
|
|
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
|
5
5
|
import { r as assertExists } from "../std__assert-BBjXFNOb.mjs";
|
|
6
6
|
import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
|
|
8
|
-
import { r as createFederationBuilder } from "../builder-
|
|
8
|
+
import { r as createFederationBuilder } from "../builder-CW-9AJCO.mjs";
|
|
9
9
|
import { DisallowedOperatorError, DisallowedVarSpecModifierError, DuplicateRouteVariableError, RouteTemplateOptionsNotMatchedError, RouterError } from "@fedify/uri-template";
|
|
10
10
|
import { Activity, Note, Person } from "@fedify/vocab";
|
|
11
11
|
import { test } from "@fedify/fixture";
|
|
@@ -5,8 +5,8 @@ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
|
5
5
|
import "../std__assert-BBjXFNOb.mjs";
|
|
6
6
|
import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
|
|
8
|
-
import { n as normalizeCircuitBreakerOptions, r as parseCircuitBreakerKvState, t as CircuitBreaker } from "../circuit-breaker-
|
|
9
|
-
import { t as markCircuitBreakerLegacySweepDone } from "../circuit-breaker-test-utils-
|
|
8
|
+
import { n as normalizeCircuitBreakerOptions, r as parseCircuitBreakerKvState, t as CircuitBreaker } from "../circuit-breaker-D1fxthDI.mjs";
|
|
9
|
+
import { t as markCircuitBreakerLegacySweepDone } from "../circuit-breaker-test-utils-CAdwjgMi.mjs";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
//#region src/federation/circuit-breaker.test.ts
|
|
12
12
|
var AlwaysConflictingKvStore = class extends MemoryKvStore {
|
|
@@ -51,7 +51,7 @@ var CountingSweepKvStore = class extends MemoryKvStore {
|
|
|
51
51
|
casCalls = [];
|
|
52
52
|
deletedKeys = [];
|
|
53
53
|
get(key) {
|
|
54
|
-
if (key.length === 4 && key[0] === "_fedify" && key[1] === "circuit" && key[2] === "__fedify_meta" && key[3] === "
|
|
54
|
+
if (key.length === 4 && key[0] === "_fedify" && key[1] === "circuit" && key[2] === "__fedify_meta" && key[3] === "circuit_breaker_state_ttl_sweep_v2") this.markerGetCalls++;
|
|
55
55
|
return super.get(key);
|
|
56
56
|
}
|
|
57
57
|
cas(key, expectedValue, newValue, options) {
|
|
@@ -73,7 +73,7 @@ var CountingSweepKvStore = class extends MemoryKvStore {
|
|
|
73
73
|
var ConflictingSweepMarkerKvStore = class extends CountingSweepKvStore {
|
|
74
74
|
attempts = 0;
|
|
75
75
|
cas(key, expectedValue, newValue, options) {
|
|
76
|
-
if (key.length === 4 && key[0] === "_fedify" && key[1] === "circuit" && key[2] === "__fedify_meta" && key[3] === "
|
|
76
|
+
if (key.length === 4 && key[0] === "_fedify" && key[1] === "circuit" && key[2] === "__fedify_meta" && key[3] === "circuit_breaker_state_ttl_sweep_v2") {
|
|
77
77
|
this.attempts++;
|
|
78
78
|
if (this.attempts > 3) throw new Error("legacy sweep did not stop retrying CAS misses");
|
|
79
79
|
return Promise.resolve(false);
|
|
@@ -81,6 +81,23 @@ var ConflictingSweepMarkerKvStore = class extends CountingSweepKvStore {
|
|
|
81
81
|
return super.cas(key, expectedValue, newValue, options);
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
|
+
var ClockAdvancingSweepKvStore = class extends CountingSweepKvStore {
|
|
85
|
+
clock = Temporal.Instant.from("2026-05-25T00:00:00Z");
|
|
86
|
+
cas(key, expectedValue, newValue, options) {
|
|
87
|
+
if (key.length === 3) this.clock = this.clock.add({ seconds: 30 });
|
|
88
|
+
return super.cas(key, expectedValue, newValue, options);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var RenewalLostSweepKvStore = class extends ClockAdvancingSweepKvStore {
|
|
92
|
+
markerCasAttempts = 0;
|
|
93
|
+
cas(key, expectedValue, newValue, options) {
|
|
94
|
+
if (key.length === 4 && key[3] === "circuit_breaker_state_ttl_sweep_v2") {
|
|
95
|
+
this.markerCasAttempts++;
|
|
96
|
+
if (this.markerCasAttempts > 1) return Promise.resolve(false);
|
|
97
|
+
}
|
|
98
|
+
return super.cas(key, expectedValue, newValue, options);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
84
101
|
var MarkerChangedDuringListKvStore = class extends CountingSweepKvStore {
|
|
85
102
|
async *list(prefix) {
|
|
86
103
|
yield* super.list(prefix);
|
|
@@ -88,7 +105,7 @@ var MarkerChangedDuringListKvStore = class extends CountingSweepKvStore {
|
|
|
88
105
|
"_fedify",
|
|
89
106
|
"circuit",
|
|
90
107
|
"__fedify_meta",
|
|
91
|
-
"
|
|
108
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
92
109
|
], { state: "final" });
|
|
93
110
|
}
|
|
94
111
|
};
|
|
@@ -176,6 +193,18 @@ test("normalizeCircuitBreakerOptions() accepts callback failure policy", () => {
|
|
|
176
193
|
assertEquals(options.failure([Temporal.Instant.from("2026-05-25T00:00:00Z")]), false);
|
|
177
194
|
assertEquals(options.failure([Temporal.Instant.from("2026-05-25T00:00:00Z"), Temporal.Instant.from("2026-05-25T00:01:00Z")]), true);
|
|
178
195
|
assertEquals(options.pruneFailures(failures, base.add({ minutes: 105 })).map((t) => t.toString()), failures.slice(-100).map((t) => t.toString()));
|
|
196
|
+
assertEquals(options.stateTtl?.total("millisecond"), Temporal.Duration.from({
|
|
197
|
+
days: 7,
|
|
198
|
+
minutes: 30
|
|
199
|
+
}).total("millisecond"));
|
|
200
|
+
assertEquals(normalizeCircuitBreakerOptions({
|
|
201
|
+
failure: (timestamps) => timestamps.length >= 2,
|
|
202
|
+
recoveryDelay: { hours: 1 },
|
|
203
|
+
heldActivityTtl: { days: 2 }
|
|
204
|
+
}).stateTtl?.total("millisecond"), Temporal.Duration.from({
|
|
205
|
+
days: 2,
|
|
206
|
+
hours: 1
|
|
207
|
+
}).total("millisecond"));
|
|
179
208
|
});
|
|
180
209
|
test("parseCircuitBreakerKvState() validates stored shape", () => {
|
|
181
210
|
assertEquals(parseCircuitBreakerKvState({
|
|
@@ -561,7 +590,7 @@ test("CircuitBreaker writes stored states with a TTL without CAS", async () => {
|
|
|
561
590
|
hours: 1
|
|
562
591
|
}) });
|
|
563
592
|
});
|
|
564
|
-
test("CircuitBreaker
|
|
593
|
+
test("CircuitBreaker writes custom-policy states with a derived TTL", async () => {
|
|
565
594
|
const kv = new CountingCasKvStore();
|
|
566
595
|
await markCircuitBreakerLegacySweepDone(kv);
|
|
567
596
|
await new CircuitBreaker({
|
|
@@ -570,7 +599,10 @@ test("CircuitBreaker preserves custom failure history by default", async () => {
|
|
|
570
599
|
now: () => Temporal.Instant.from("2026-05-25T00:00:00Z"),
|
|
571
600
|
options: { failure: (timestamps) => timestamps.length >= 2 }
|
|
572
601
|
}).recordFailure("remote.example");
|
|
573
|
-
assertEquals(kv.options.at(-1),
|
|
602
|
+
assertEquals(kv.options.at(-1)?.ttl?.total("millisecond"), Temporal.Duration.from({
|
|
603
|
+
days: 7,
|
|
604
|
+
minutes: 30
|
|
605
|
+
}).total("millisecond"));
|
|
574
606
|
});
|
|
575
607
|
test("CircuitBreaker accepts an explicit TTL with custom failure policies", async () => {
|
|
576
608
|
const kv = new CountingCasKvStore();
|
|
@@ -586,7 +618,7 @@ test("CircuitBreaker accepts an explicit TTL with custom failure policies", asyn
|
|
|
586
618
|
}).recordFailure("remote.example");
|
|
587
619
|
assertEquals(kv.options.at(-1), { ttl: Temporal.Duration.from({ days: 14 }) });
|
|
588
620
|
});
|
|
589
|
-
test("CircuitBreaker
|
|
621
|
+
test("CircuitBreaker sweeps legacy states for custom failure policies", async () => {
|
|
590
622
|
const kv = new CountingSweepKvStore();
|
|
591
623
|
await kv.set([
|
|
592
624
|
"_fedify",
|
|
@@ -604,15 +636,146 @@ test("CircuitBreaker skips legacy sweep when custom policies have no TTL", async
|
|
|
604
636
|
});
|
|
605
637
|
await circuit.recordFailure("remote.example");
|
|
606
638
|
await circuit.pendingSweep;
|
|
607
|
-
assertEquals(kv.listCalls,
|
|
639
|
+
assertEquals(kv.listCalls, 1);
|
|
608
640
|
assertEquals(await kv.get([
|
|
609
641
|
"_fedify",
|
|
610
642
|
"circuit",
|
|
611
643
|
"stale.example"
|
|
612
644
|
]), {
|
|
613
645
|
state: "closed",
|
|
614
|
-
failures: ["2026-05-25T00:00:00Z"]
|
|
646
|
+
failures: ["2026-05-25T00:00:00Z"],
|
|
647
|
+
__fedifyCircuitBreakerStateVersion: 1
|
|
648
|
+
});
|
|
649
|
+
assertEquals(kv.casCalls.find(({ key }) => key.at(-1) === "stale.example")?.options?.ttl?.total("millisecond"), Temporal.Duration.from({
|
|
650
|
+
days: 7,
|
|
651
|
+
minutes: 30
|
|
652
|
+
}).total("millisecond"));
|
|
653
|
+
});
|
|
654
|
+
test("CircuitBreaker stamps a TTL on versioned states during sweeps", async () => {
|
|
655
|
+
const kv = new CountingSweepKvStore();
|
|
656
|
+
await kv.set([
|
|
657
|
+
"_fedify",
|
|
658
|
+
"circuit",
|
|
659
|
+
"lingering.example"
|
|
660
|
+
], {
|
|
661
|
+
state: "closed",
|
|
662
|
+
failures: ["2026-05-25T00:00:00Z"],
|
|
663
|
+
__fedifyCircuitBreakerStateVersion: 1
|
|
664
|
+
});
|
|
665
|
+
const circuit = new CircuitBreaker({
|
|
666
|
+
kv,
|
|
667
|
+
prefix: ["_fedify", "circuit"],
|
|
668
|
+
now: () => Temporal.Instant.from("2026-05-25T00:00:00Z"),
|
|
669
|
+
options: { failure: (timestamps) => timestamps.length >= 2 }
|
|
670
|
+
});
|
|
671
|
+
await circuit.recordFailure("remote.example");
|
|
672
|
+
await circuit.pendingSweep;
|
|
673
|
+
assertEquals(await kv.get([
|
|
674
|
+
"_fedify",
|
|
675
|
+
"circuit",
|
|
676
|
+
"lingering.example"
|
|
677
|
+
]), {
|
|
678
|
+
state: "closed",
|
|
679
|
+
failures: ["2026-05-25T00:00:00Z"],
|
|
680
|
+
__fedifyCircuitBreakerStateVersion: 1
|
|
681
|
+
});
|
|
682
|
+
assertEquals(kv.casCalls.find(({ key }) => key.at(-1) === "lingering.example")?.options?.ttl?.total("millisecond"), Temporal.Duration.from({
|
|
683
|
+
days: 7,
|
|
684
|
+
minutes: 30
|
|
685
|
+
}).total("millisecond"));
|
|
686
|
+
});
|
|
687
|
+
test("CircuitBreaker re-sweeps despite a completed v1 sweep marker", async () => {
|
|
688
|
+
const kv = new CountingSweepKvStore();
|
|
689
|
+
await kv.set([
|
|
690
|
+
"_fedify",
|
|
691
|
+
"circuit",
|
|
692
|
+
"__fedify_meta",
|
|
693
|
+
"circuit_breaker_state_ttl_sweep_v1"
|
|
694
|
+
], { state: "final" });
|
|
695
|
+
await kv.set([
|
|
696
|
+
"_fedify",
|
|
697
|
+
"circuit",
|
|
698
|
+
"lingering.example"
|
|
699
|
+
], {
|
|
700
|
+
state: "closed",
|
|
701
|
+
failures: ["2026-05-25T00:00:00Z"],
|
|
702
|
+
__fedifyCircuitBreakerStateVersion: 1
|
|
703
|
+
});
|
|
704
|
+
const circuit = new CircuitBreaker({
|
|
705
|
+
kv,
|
|
706
|
+
prefix: ["_fedify", "circuit"],
|
|
707
|
+
now: () => Temporal.Instant.from("2026-05-25T00:00:00Z"),
|
|
708
|
+
options: { failure: (timestamps) => timestamps.length >= 2 }
|
|
709
|
+
});
|
|
710
|
+
await circuit.recordFailure("remote.example");
|
|
711
|
+
await circuit.pendingSweep;
|
|
712
|
+
assertEquals(kv.listCalls, 1);
|
|
713
|
+
assertEquals(kv.casCalls.find(({ key }) => key.at(-1) === "lingering.example")?.options?.ttl?.total("millisecond"), Temporal.Duration.from({
|
|
714
|
+
days: 7,
|
|
715
|
+
minutes: 30
|
|
716
|
+
}).total("millisecond"));
|
|
717
|
+
});
|
|
718
|
+
test("CircuitBreaker renews the sweep marker lease during long sweeps", async () => {
|
|
719
|
+
const kv = new ClockAdvancingSweepKvStore();
|
|
720
|
+
for (let i = 0; i < 5; i++) await kv.set([
|
|
721
|
+
"_fedify",
|
|
722
|
+
"circuit",
|
|
723
|
+
`host-${i}.example`
|
|
724
|
+
], {
|
|
725
|
+
state: "closed",
|
|
726
|
+
failures: ["2026-05-25T00:00:00Z"],
|
|
727
|
+
__fedifyCircuitBreakerStateVersion: 1
|
|
728
|
+
});
|
|
729
|
+
const circuit = new CircuitBreaker({
|
|
730
|
+
kv,
|
|
731
|
+
prefix: ["_fedify", "circuit"],
|
|
732
|
+
now: () => kv.clock,
|
|
733
|
+
options: { failure: (timestamps) => timestamps.length >= 2 }
|
|
734
|
+
});
|
|
735
|
+
await circuit.getState("remote.example");
|
|
736
|
+
await circuit.pendingSweep;
|
|
737
|
+
assertEquals(kv.casCalls.filter(({ key }) => key.at(-1) === "circuit_breaker_state_ttl_sweep_v2").length, 4);
|
|
738
|
+
assertEquals(await kv.get([
|
|
739
|
+
"_fedify",
|
|
740
|
+
"circuit",
|
|
741
|
+
"__fedify_meta",
|
|
742
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
743
|
+
]), {
|
|
744
|
+
state: "done",
|
|
745
|
+
retryUntil: "2026-06-01T00:00:00Z"
|
|
615
746
|
});
|
|
747
|
+
assertEquals(kv.casCalls.find(({ key }) => key.at(-1) === "host-4.example")?.options?.ttl?.total("millisecond"), Temporal.Duration.from({
|
|
748
|
+
days: 7,
|
|
749
|
+
minutes: 30
|
|
750
|
+
}).total("millisecond"));
|
|
751
|
+
});
|
|
752
|
+
test("CircuitBreaker abandons the sweep when the marker lease is lost", async () => {
|
|
753
|
+
const kv = new RenewalLostSweepKvStore();
|
|
754
|
+
for (let i = 0; i < 5; i++) await kv.set([
|
|
755
|
+
"_fedify",
|
|
756
|
+
"circuit",
|
|
757
|
+
`host-${i}.example`
|
|
758
|
+
], {
|
|
759
|
+
state: "closed",
|
|
760
|
+
failures: ["2026-05-25T00:00:00Z"],
|
|
761
|
+
__fedifyCircuitBreakerStateVersion: 1
|
|
762
|
+
});
|
|
763
|
+
const circuit = new CircuitBreaker({
|
|
764
|
+
kv,
|
|
765
|
+
prefix: ["_fedify", "circuit"],
|
|
766
|
+
now: () => kv.clock,
|
|
767
|
+
options: { failure: (timestamps) => timestamps.length >= 2 }
|
|
768
|
+
});
|
|
769
|
+
await circuit.getState("remote.example");
|
|
770
|
+
await circuit.pendingSweep;
|
|
771
|
+
assertEquals(kv.markerCasAttempts, 2);
|
|
772
|
+
assertEquals(kv.casCalls.filter(({ key }) => key.at(-1) === "host-4.example").length, 0);
|
|
773
|
+
assertEquals((await kv.get([
|
|
774
|
+
"_fedify",
|
|
775
|
+
"circuit",
|
|
776
|
+
"__fedify_meta",
|
|
777
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
778
|
+
]))?.state, "sweeping");
|
|
616
779
|
});
|
|
617
780
|
test("CircuitBreaker migrates legacy states without TTL once", async () => {
|
|
618
781
|
const kv = new CountingSweepKvStore();
|
|
@@ -720,7 +883,7 @@ test("CircuitBreaker migrates legacy states without TTL once", async () => {
|
|
|
720
883
|
"_fedify",
|
|
721
884
|
"circuit",
|
|
722
885
|
"__fedify_meta",
|
|
723
|
-
"
|
|
886
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
724
887
|
]), {
|
|
725
888
|
state: "done",
|
|
726
889
|
retryUntil: "2026-06-01T00:00:00Z"
|
|
@@ -764,7 +927,7 @@ test("CircuitBreaker migrates legacy states without TTL once", async () => {
|
|
|
764
927
|
"_fedify",
|
|
765
928
|
"circuit",
|
|
766
929
|
"__fedify_meta",
|
|
767
|
-
"
|
|
930
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
768
931
|
]), { state: "final" });
|
|
769
932
|
});
|
|
770
933
|
test("CircuitBreaker does not sweep state changed after listing", async () => {
|
|
@@ -800,7 +963,7 @@ test("CircuitBreaker skips legacy sweep already running elsewhere", async () =>
|
|
|
800
963
|
"_fedify",
|
|
801
964
|
"circuit",
|
|
802
965
|
"__fedify_meta",
|
|
803
|
-
"
|
|
966
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
804
967
|
], {
|
|
805
968
|
state: "sweeping",
|
|
806
969
|
started: "2026-05-25T00:00:00Z",
|
|
@@ -841,7 +1004,7 @@ test("CircuitBreaker does not overwrite a changed legacy sweep marker", async ()
|
|
|
841
1004
|
"_fedify",
|
|
842
1005
|
"circuit",
|
|
843
1006
|
"__fedify_meta",
|
|
844
|
-
"
|
|
1007
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
845
1008
|
]), { state: "final" });
|
|
846
1009
|
});
|
|
847
1010
|
test("CircuitBreaker bounds legacy sweep CAS retries", async () => {
|
|
@@ -863,7 +1026,7 @@ test("CircuitBreaker retries expired legacy sweep markers", async () => {
|
|
|
863
1026
|
"_fedify",
|
|
864
1027
|
"circuit",
|
|
865
1028
|
"__fedify_meta",
|
|
866
|
-
"
|
|
1029
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
867
1030
|
], {
|
|
868
1031
|
state: "sweeping",
|
|
869
1032
|
started: "2026-05-25T00:00:00Z",
|
|
@@ -899,7 +1062,7 @@ test("CircuitBreaker retries expired legacy sweep markers", async () => {
|
|
|
899
1062
|
"_fedify",
|
|
900
1063
|
"circuit",
|
|
901
1064
|
"__fedify_meta",
|
|
902
|
-
"
|
|
1065
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
903
1066
|
]), {
|
|
904
1067
|
state: "done",
|
|
905
1068
|
retryUntil: "2026-06-01T00:00:00Z"
|
|
@@ -911,7 +1074,7 @@ test("CircuitBreaker caches completed legacy sweep markers", async () => {
|
|
|
911
1074
|
"_fedify",
|
|
912
1075
|
"circuit",
|
|
913
1076
|
"__fedify_meta",
|
|
914
|
-
"
|
|
1077
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
915
1078
|
], {
|
|
916
1079
|
state: "done",
|
|
917
1080
|
retryUntil: "2026-06-01T00:00:00Z"
|
|
@@ -952,7 +1115,7 @@ test("CircuitBreaker retries malformed legacy sweep markers", async () => {
|
|
|
952
1115
|
"_fedify",
|
|
953
1116
|
"circuit",
|
|
954
1117
|
"__fedify_meta",
|
|
955
|
-
"
|
|
1118
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
956
1119
|
], {
|
|
957
1120
|
state: "done",
|
|
958
1121
|
retryUntil: "not an instant"
|
|
@@ -991,7 +1154,7 @@ test("CircuitBreaker retries malformed legacy sweep markers", async () => {
|
|
|
991
1154
|
"_fedify",
|
|
992
1155
|
"circuit",
|
|
993
1156
|
"__fedify_meta",
|
|
994
|
-
"
|
|
1157
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
995
1158
|
]), {
|
|
996
1159
|
state: "done",
|
|
997
1160
|
retryUntil: "2026-06-01T00:00:00Z"
|
|
@@ -1011,13 +1174,13 @@ test("CircuitBreaker retries legacy sweep after transient failures", async () =>
|
|
|
1011
1174
|
"_fedify",
|
|
1012
1175
|
"circuit",
|
|
1013
1176
|
"__fedify_meta",
|
|
1014
|
-
"
|
|
1177
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
1015
1178
|
]), void 0);
|
|
1016
1179
|
assertEquals(kv.deletedKeys, [[
|
|
1017
1180
|
"_fedify",
|
|
1018
1181
|
"circuit",
|
|
1019
1182
|
"__fedify_meta",
|
|
1020
|
-
"
|
|
1183
|
+
"circuit_breaker_state_ttl_sweep_v2"
|
|
1021
1184
|
]]);
|
|
1022
1185
|
assertEquals(await circuit.getState("remote.example"), {
|
|
1023
1186
|
state: "closed",
|
|
@@ -8,11 +8,11 @@ import { n as assertGreaterOrEqual, t as assertRejects } from "../assert_rejects
|
|
|
8
8
|
import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
|
|
9
9
|
import { t as assert } from "../assert-OguE97r2.mjs";
|
|
10
10
|
import { r as parseAcceptSignature } from "../accept-CPkZzmGN.mjs";
|
|
11
|
-
import { s as signRequest } from "../http-
|
|
11
|
+
import { s as signRequest } from "../http-BcbYkefs.mjs";
|
|
12
12
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-DGu1NFwu.mjs";
|
|
13
|
-
import { a as compactJsonLd, p as signJsonLd } from "../ld-
|
|
13
|
+
import { a as compactJsonLd, p as signJsonLd } from "../ld-c-9mCB36.mjs";
|
|
14
14
|
import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
|
|
15
|
-
import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-
|
|
15
|
+
import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-3L9f9ZTw.mjs";
|
|
16
16
|
import { t as ActivityListenerSet } from "../activity-listener-tztVvlNb.mjs";
|
|
17
17
|
import { Activity, Create, Note, Person, Tombstone } from "@fedify/vocab";
|
|
18
18
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
5
|
import "../std__assert-BBjXFNOb.mjs";
|
|
6
6
|
import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-DGu1NFwu.mjs";
|
|
7
|
-
import { r as signObject } from "../proof-
|
|
7
|
+
import { r as signObject } from "../proof-D_6qtBdQ.mjs";
|
|
8
8
|
import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-3L9f9ZTw.mjs";
|
|
10
10
|
import { Create, Follow, Person } from "@fedify/vocab";
|
|
11
11
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
12
|
//#region src/federation/idempotency.test.ts
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
5
|
import "../std__assert-BBjXFNOb.mjs";
|
|
6
6
|
import { t as assertRejects } from "../assert_rejects-DN60FHPX.mjs";
|
|
7
|
-
import { _ as recordKeyLookup, 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, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-
|
|
7
|
+
import { _ as recordKeyLookup, 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, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-D8s1eKfJ.mjs";
|
|
8
8
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
9
9
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
10
10
|
import { DataPointType, MeterProvider, MetricReader } from "@opentelemetry/sdk-metrics";
|