@fedify/fedify 2.1.23 → 2.1.25
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_instance_of-C4Ri6VuN.mjs → assert-BhQd8QHP.mjs} +19 -1
- package/dist/{builder-BlCsjkrX.mjs → builder-DsBAef6b.mjs} +3 -3
- package/dist/{client-CZWLyLmp.mjs → client-DM72NZuk.mjs} +85 -7
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +3 -4
- package/dist/{context-_l9t359k.d.ts → context-BgU5UWTx.d.ts} +4 -3
- package/dist/{context-o22vjzS2.d.cts → context-D4s0Wk3N.d.cts} +4 -3
- package/dist/{deno-B_Gwkjh7.mjs → deno-9AaebKOA.mjs} +1 -1
- package/dist/docloader-DX96uPUj.mjs +78 -0
- package/dist/federation/builder.test.mjs +3 -3
- package/dist/federation/collection.test.mjs +2 -2
- package/dist/federation/handler.test.mjs +128 -10
- package/dist/federation/idempotency.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/keycache.test.mjs +44 -10
- package/dist/federation/kv.test.mjs +2 -2
- package/dist/federation/middleware.test.mjs +227 -12
- 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/mq.test.mjs +99 -44
- package/dist/federation/negotiation.test.mjs +3 -3
- package/dist/federation/retry.test.mjs +1 -1
- package/dist/federation/router.test.mjs +2 -2
- package/dist/federation/send.test.mjs +202 -7
- package/dist/federation/temporal.test.mjs +3 -3
- package/dist/federation/webfinger.test.mjs +3 -3
- package/dist/{http-DIh9_s_-.mjs → http-B5qAeoJd.mjs} +8 -4
- package/dist/{http-Yoq0YGz7.cjs → http-BJEMpnnY.cjs} +171 -7
- package/dist/{http-88deUx3Y.js → http-CdJ6n4rA.js} +160 -8
- package/dist/{http-BDZeS5om.d.ts → http-Dl00HXr4.d.ts} +1 -1
- package/dist/{http-C87EWkO0.d.cts → http-DqZhyEso.d.cts} +1 -1
- package/dist/{inbox-BxCHIWPD.mjs → inbox-BSyjaFbo.mjs} +1 -1
- package/dist/{key-DywPPmb0.mjs → key-x9f-H7eO.mjs} +154 -6
- package/dist/{keycache-CCSwkQcY.mjs → keycache-CaO7wyQA.mjs} +12 -4
- package/dist/{kv-cache-HA011rBG.cjs → kv-cache-BDp2c_QE.cjs} +34 -8
- package/dist/{kv-cache-rHQOc5rE.js → kv-cache-Dx3QwNBI.js} +35 -9
- package/dist/{ld-Ch6FVq7X.mjs → ld-cfUwoi0C.mjs} +3 -3
- package/dist/{middleware-itcr4fAv.cjs → middleware-BXJpAXhO.cjs} +1 -1
- package/dist/{middleware-CYsQG25-.js → middleware-CP35ElZv.js} +99 -14
- package/dist/{middleware-DABFg_Xy.mjs → middleware-DDT9ljTQ.mjs} +1 -1
- package/dist/{middleware-D2O8b03q.mjs → middleware-DHHRwSZH.mjs} +31 -20
- package/dist/{middleware-CUNIlYzF.cjs → middleware-XXuSt_6b.cjs} +99 -14
- package/dist/{mod-CjiK2zrW.d.ts → mod-BLDHhuW0.d.ts} +1 -1
- package/dist/{mod-0dF0OeGw.d.cts → mod-Bx80LUTA.d.cts} +1 -1
- package/dist/{mod-Bv1elC-b.d.ts → mod-DcAiY74j.d.ts} +1 -1
- package/dist/{mod-D5YlzzP3.d.cts → mod-DiuFTYUt.d.cts} +1 -1
- package/dist/{mod-dxOnKp2Y.d.cts → mod-DkE98l_7.d.cts} +3 -1
- package/dist/{mod-BTWFtZwa.d.ts → mod-DqkY4FDr.d.ts} +3 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +77 -2
- package/dist/nodeinfo/handler.test.mjs +3 -3
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/nodeinfo/types.test.mjs +2 -2
- package/dist/otel/exporter.test.mjs +2 -2
- package/dist/{owner-DEvZuyOE.d.cts → owner-B3hNQCG8.d.cts} +11 -0
- package/dist/{owner-CnngXDNJ.d.ts → owner-CiBPcC6F.d.ts} +11 -0
- package/dist/owner-DklgvZXn.mjs +175 -0
- package/dist/{proof-Dt5GV-xi.mjs → proof-CI4rsVLu.mjs} +2 -2
- package/dist/{proof-K3inAqnp.js → proof-Dsa_ZC-M.js} +113 -59
- package/dist/{proof-CEn2R6W9.cjs → proof-DzFzyfIc.cjs} +113 -59
- package/dist/{send-CqaJDT2z.mjs → send-DJmW6Z-I.mjs} +73 -6
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/http.test.mjs +45 -5
- package/dist/sig/key.test.mjs +171 -4
- package/dist/sig/ld.test.mjs +59 -4
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +3 -3
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +106 -7
- package/dist/sig/proof.test.mjs +73 -4
- package/dist/{std__assert-Duiq_YC9.mjs → std__assert-BUOJXi-Z.mjs} +1 -26
- package/dist/{temporal-G_GDghC-.mjs → temporal-BanFifxu.mjs} +1 -1
- package/dist/{types-m8u9L86X.cjs → types-DRPjmHVV.cjs} +101 -5
- package/dist/{types-DTONwNqL.js → types-miAYfiGO.js} +85 -7
- package/dist/utils/docloader.test.mjs +325 -5
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/dist/vocab/cjs.test.mjs +1 -1
- package/package.json +7 -7
- package/dist/assert-ddO5KLpe.mjs +0 -23
- package/dist/docloader-B-IG1dVk.mjs +0 -52
- package/dist/owner-Cygg-fHW.mjs +0 -120
- /package/dist/{accept-Dd__NiUL.mjs → accept-BavzedPB.mjs} +0 -0
- /package/dist/{collection-BD6-SZ6O.mjs → collection-ChgDTHLz.mjs} +0 -0
- /package/dist/{keys-BAK-tUlf.mjs → keys-CtZLJq76.mjs} +0 -0
- /package/dist/{kv-tL2TOE9X.mjs → kv-BrZHNugx.mjs} +0 -0
- /package/dist/{kv-cache-FsT1ljhs.mjs → kv-cache-DqEKe5E0.mjs} +0 -0
- /package/dist/{negotiation-DnsfFF8I.mjs → negotiation-BehA2uul.mjs} +0 -0
- /package/dist/{retry-CJL0poaU.mjs → retry-B_E3V_Dx.mjs} +0 -0
- /package/dist/{types-DCP0WLdt.mjs → types-C37hquWI.mjs} +0 -0
|
@@ -2,8 +2,8 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
|
-
import "../std__assert-
|
|
6
|
-
import { t as MemoryKvStore } from "../kv-
|
|
5
|
+
import "../std__assert-BUOJXi-Z.mjs";
|
|
6
|
+
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
7
7
|
import { test } from "@fedify/fixture";
|
|
8
8
|
//#region src/federation/kv.test.ts
|
|
9
9
|
test("MemoryKvStore", async (t) => {
|
|
@@ -4,24 +4,24 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as esm_default } from "../esm-DVILvP5e.mjs";
|
|
5
5
|
import { n as RouterError } from "../router-CrMLXoOr.mjs";
|
|
6
6
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
7
|
-
import { n as assertStrictEquals } from "../std__assert-
|
|
7
|
+
import { n as assertStrictEquals } from "../std__assert-BUOJXi-Z.mjs";
|
|
8
8
|
import { n as assertFalse, t as assertRejects } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import { n as assertInstanceOf, t as assert } from "../assert-BhQd8QHP.mjs";
|
|
10
10
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
11
11
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { t as
|
|
20
|
-
import { a as createFederation, i as KvSpecDeterminer, n as FederationImpl, r as InboxContextImpl, t as ContextImpl } from "../middleware-D2O8b03q.mjs";
|
|
12
|
+
import { l as verifyRequest, s as signRequest } from "../http-B5qAeoJd.mjs";
|
|
13
|
+
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-CtZLJq76.mjs";
|
|
14
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-DX96uPUj.mjs";
|
|
15
|
+
import { a as compactJsonLd, f as signJsonLd, m as verifyJsonLd, s as detachSignature } from "../ld-cfUwoi0C.mjs";
|
|
16
|
+
import { t as doesActorOwnKey } from "../owner-DklgvZXn.mjs";
|
|
17
|
+
import { n as signObject, r as verifyObject } from "../proof-CI4rsVLu.mjs";
|
|
18
|
+
import { t as MemoryKvStore } from "../kv-BrZHNugx.mjs";
|
|
19
|
+
import { a as createFederation, i as KvSpecDeterminer, n as FederationImpl, r as InboxContextImpl, t as ContextImpl } from "../middleware-DHHRwSZH.mjs";
|
|
21
20
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
22
21
|
import * as vocab from "@fedify/vocab";
|
|
23
22
|
import { Create, Offer, Person, getTypeId, lookupObject } from "@fedify/vocab";
|
|
24
|
-
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
23
|
+
import { FetchError, UrlError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
24
|
+
import dns from "node:dns/promises";
|
|
25
25
|
//#region ../fixture/src/fixtures/example.com/create.json
|
|
26
26
|
var id$2 = "https://example.com/create";
|
|
27
27
|
var create_default = {
|
|
@@ -718,6 +718,31 @@ test({
|
|
|
718
718
|
esm_default.hardReset();
|
|
719
719
|
}
|
|
720
720
|
});
|
|
721
|
+
test("Federation.fetch() [rfc9421] multiple POST signatures", async (t) => {
|
|
722
|
+
for (const validSecond of [true, false]) await t.step(validSecond ? "valid second signature" : "both signatures invalid", async () => {
|
|
723
|
+
const inbox = [];
|
|
724
|
+
const federation = createFederation({
|
|
725
|
+
kv: new MemoryKvStore(),
|
|
726
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
727
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
728
|
+
});
|
|
729
|
+
federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => new vocab.Person({ id: ctx.getActorUri(identifier) }));
|
|
730
|
+
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox").on(vocab.Create, (_ctx, activity) => {
|
|
731
|
+
inbox.push(activity.id.href);
|
|
732
|
+
});
|
|
733
|
+
const signed = await signRequest(new Request("https://example.com/inbox", {
|
|
734
|
+
method: "POST",
|
|
735
|
+
headers: { "Content-Type": "application/activity+json" },
|
|
736
|
+
body: JSON.stringify(create_default)
|
|
737
|
+
}), rsaPrivateKey2, rsaPublicKey2.id, { spec: "rfc9421" });
|
|
738
|
+
const input = signed.headers.get("Signature-Input");
|
|
739
|
+
const signature = signed.headers.get("Signature");
|
|
740
|
+
signed.headers.set("Signature-Input", `${input}, ${input.replace(/^sig1=/, "sig2=")}`);
|
|
741
|
+
signed.headers.set("Signature", `sig1=:AAAAAA==:, ${validSecond ? signature.replace(/^sig1=/, "sig2=") : "sig2=:AAAAAA==:"}`);
|
|
742
|
+
assertEquals((await federation.fetch(signed, { contextData: void 0 })).status, validSecond ? 202 : 401);
|
|
743
|
+
assertEquals(inbox, validSecond ? [id$2] : []);
|
|
744
|
+
});
|
|
745
|
+
});
|
|
721
746
|
test("Federation.fetch()", async (t) => {
|
|
722
747
|
esm_default.spyGlobal();
|
|
723
748
|
esm_default.get("https://example.com/key2", {
|
|
@@ -1427,6 +1452,7 @@ test("FederationImpl.processQueuedTask()", async (t) => {
|
|
|
1427
1452
|
const kv = new MemoryKvStore();
|
|
1428
1453
|
const queuedMessages = [];
|
|
1429
1454
|
const federation = new FederationImpl({
|
|
1455
|
+
allowPrivateAddress: true,
|
|
1430
1456
|
kv,
|
|
1431
1457
|
queue: {
|
|
1432
1458
|
nativeRetrial: true,
|
|
@@ -1489,6 +1515,7 @@ test("FederationImpl.processQueuedTask()", async (t) => {
|
|
|
1489
1515
|
const kv = new MemoryKvStore();
|
|
1490
1516
|
let queuedMessages = [];
|
|
1491
1517
|
const federation = new FederationImpl({
|
|
1518
|
+
allowPrivateAddress: true,
|
|
1492
1519
|
kv,
|
|
1493
1520
|
queue: {
|
|
1494
1521
|
enqueue(message, _options) {
|
|
@@ -2983,6 +3010,105 @@ test("FederationImpl.processQueuedTask()", async (t) => {
|
|
|
2983
3010
|
assertEquals(queuedMessages, []);
|
|
2984
3011
|
});
|
|
2985
3012
|
});
|
|
3013
|
+
test({
|
|
3014
|
+
name: "FederationImpl.processQueuedTask() retries DNS failures",
|
|
3015
|
+
ignore: "Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted",
|
|
3016
|
+
async fn(t) {
|
|
3017
|
+
for (const redirected of [false, true]) await t.step(`redirected: ${redirected}`, async () => {
|
|
3018
|
+
const destination = "https://delivery.invalid/inbox";
|
|
3019
|
+
const publicInbox = "https://8.8.8.8/inbox";
|
|
3020
|
+
const queuedMessages = [];
|
|
3021
|
+
const delays = [];
|
|
3022
|
+
const errors = [];
|
|
3023
|
+
const activities = [];
|
|
3024
|
+
const attempts = [];
|
|
3025
|
+
const delay = Temporal.Duration.from({ seconds: 5 });
|
|
3026
|
+
const federation = new FederationImpl({
|
|
3027
|
+
kv: new MemoryKvStore(),
|
|
3028
|
+
queue: {
|
|
3029
|
+
enqueue(message, options) {
|
|
3030
|
+
queuedMessages.push(message);
|
|
3031
|
+
delays.push(options?.delay);
|
|
3032
|
+
return Promise.resolve();
|
|
3033
|
+
},
|
|
3034
|
+
listen() {
|
|
3035
|
+
return Promise.resolve();
|
|
3036
|
+
}
|
|
3037
|
+
},
|
|
3038
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
3039
|
+
contextLoaderFactory: () => mockDocumentLoader,
|
|
3040
|
+
onOutboxError(error, activity) {
|
|
3041
|
+
errors.push(error);
|
|
3042
|
+
activities.push(activity);
|
|
3043
|
+
},
|
|
3044
|
+
outboxRetryPolicy(options) {
|
|
3045
|
+
attempts.push(options.attempts);
|
|
3046
|
+
return delay;
|
|
3047
|
+
}
|
|
3048
|
+
});
|
|
3049
|
+
const message = {
|
|
3050
|
+
type: "outbox",
|
|
3051
|
+
id: crypto.randomUUID(),
|
|
3052
|
+
baseUrl: "https://example.com",
|
|
3053
|
+
keys: [],
|
|
3054
|
+
activity: {
|
|
3055
|
+
"@context": "https://www.w3.org/ns/activitystreams",
|
|
3056
|
+
type: "Create",
|
|
3057
|
+
id: "https://example.com/activities/dns-failure",
|
|
3058
|
+
actor: "https://example.com/users/alice",
|
|
3059
|
+
object: {
|
|
3060
|
+
type: "Note",
|
|
3061
|
+
content: "test"
|
|
3062
|
+
}
|
|
3063
|
+
},
|
|
3064
|
+
activityType: "https://www.w3.org/ns/activitystreams#Create",
|
|
3065
|
+
inbox: redirected ? publicInbox : destination,
|
|
3066
|
+
sharedInbox: false,
|
|
3067
|
+
started: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3068
|
+
attempt: 0,
|
|
3069
|
+
headers: {},
|
|
3070
|
+
traceContext: {}
|
|
3071
|
+
};
|
|
3072
|
+
const originalLookup = dns.lookup;
|
|
3073
|
+
const resolverError = /* @__PURE__ */ new Error("Resolver unavailable");
|
|
3074
|
+
const lookups = [];
|
|
3075
|
+
dns.lookup = ((hostname) => {
|
|
3076
|
+
lookups.push(hostname);
|
|
3077
|
+
return Promise.reject(resolverError);
|
|
3078
|
+
});
|
|
3079
|
+
try {
|
|
3080
|
+
esm_default.mockGlobal().catch(202);
|
|
3081
|
+
if (redirected) esm_default.route(publicInbox, {
|
|
3082
|
+
status: 307,
|
|
3083
|
+
headers: { Location: destination }
|
|
3084
|
+
});
|
|
3085
|
+
await federation.processQueuedTask(void 0, message);
|
|
3086
|
+
assertEquals(errors.length, 1);
|
|
3087
|
+
const error = errors[0];
|
|
3088
|
+
assertInstanceOf(error, FetchError);
|
|
3089
|
+
assertEquals(error.url.href, destination);
|
|
3090
|
+
assertInstanceOf(error.cause, UrlError);
|
|
3091
|
+
assertEquals(error.cause.reason, "dns");
|
|
3092
|
+
assertStrictEquals(error.cause.cause, resolverError);
|
|
3093
|
+
assertEquals(activities.length, 1);
|
|
3094
|
+
assertInstanceOf(activities[0], Create);
|
|
3095
|
+
assertEquals(activities[0].id?.href, "https://example.com/activities/dns-failure");
|
|
3096
|
+
assertEquals(attempts, [0]);
|
|
3097
|
+
assertEquals(queuedMessages, [{
|
|
3098
|
+
...message,
|
|
3099
|
+
attempt: 1
|
|
3100
|
+
}]);
|
|
3101
|
+
assertEquals(delays, [delay]);
|
|
3102
|
+
assertEquals(lookups, ["delivery.invalid"]);
|
|
3103
|
+
assertEquals(esm_default.callHistory.calls(destination).length, 0);
|
|
3104
|
+
assertEquals(esm_default.callHistory.calls().length, redirected ? 1 : 0);
|
|
3105
|
+
} finally {
|
|
3106
|
+
dns.lookup = originalLookup;
|
|
3107
|
+
esm_default.hardReset();
|
|
3108
|
+
}
|
|
3109
|
+
});
|
|
3110
|
+
}
|
|
3111
|
+
});
|
|
2986
3112
|
test("FederationImpl.processQueuedTask() permanent failure", async (t) => {
|
|
2987
3113
|
esm_default.spyGlobal();
|
|
2988
3114
|
esm_default.post("https://gone.example/inbox", {
|
|
@@ -3016,6 +3142,7 @@ test("FederationImpl.processQueuedTask() permanent failure", async (t) => {
|
|
|
3016
3142
|
return Promise.resolve();
|
|
3017
3143
|
}
|
|
3018
3144
|
},
|
|
3145
|
+
allowPrivateAddress: true,
|
|
3019
3146
|
...options.permanentFailureStatusCodes ? { permanentFailureStatusCodes: options.permanentFailureStatusCodes } : {}
|
|
3020
3147
|
});
|
|
3021
3148
|
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
|
|
@@ -3867,5 +3994,93 @@ test("KvSpecDeterminer", async (t) => {
|
|
|
3867
3994
|
assertEquals(spec, "rfc9421");
|
|
3868
3995
|
});
|
|
3869
3996
|
});
|
|
3997
|
+
test("ContextImpl.sendActivity() honors the private-address policy", async (t) => {
|
|
3998
|
+
for (const allowPrivateAddress of [false, true]) await t.step(`allowPrivateAddress: ${allowPrivateAddress}`, async () => {
|
|
3999
|
+
const inbox = "http://127.0.0.1/inbox";
|
|
4000
|
+
esm_default.mockGlobal().post(inbox, 202);
|
|
4001
|
+
try {
|
|
4002
|
+
const ctx = createFederation({
|
|
4003
|
+
kv: new MemoryKvStore(),
|
|
4004
|
+
allowPrivateAddress
|
|
4005
|
+
}).createContext(new URL("https://example.com/"));
|
|
4006
|
+
const send = () => ctx.sendActivity({
|
|
4007
|
+
privateKey: ed25519PrivateKey,
|
|
4008
|
+
keyId: ed25519Multikey.id
|
|
4009
|
+
}, new Person({
|
|
4010
|
+
id: new URL("https://example.com/recipient"),
|
|
4011
|
+
inbox: new URL(inbox)
|
|
4012
|
+
}), new Create({
|
|
4013
|
+
id: new URL("https://example.com/activity"),
|
|
4014
|
+
actor: new URL("https://example.com/person")
|
|
4015
|
+
}), { immediate: true });
|
|
4016
|
+
if (allowPrivateAddress) {
|
|
4017
|
+
await send();
|
|
4018
|
+
assertEquals(esm_default.callHistory.calls(inbox).length, 1);
|
|
4019
|
+
} else {
|
|
4020
|
+
await assertRejects(send, UrlError);
|
|
4021
|
+
assertEquals(esm_default.callHistory.calls(inbox).length, 0);
|
|
4022
|
+
}
|
|
4023
|
+
} finally {
|
|
4024
|
+
esm_default.hardReset();
|
|
4025
|
+
}
|
|
4026
|
+
});
|
|
4027
|
+
});
|
|
4028
|
+
test("Federation.fetch() bounds inbox bodies before dispatch", async () => {
|
|
4029
|
+
let dispatched = false;
|
|
4030
|
+
const json = JSON.stringify({
|
|
4031
|
+
"@context": "https://www.w3.org/ns/activitystreams",
|
|
4032
|
+
id: "https://example.com/activities/bounded",
|
|
4033
|
+
type: "Create",
|
|
4034
|
+
actor: "https://example.com/actor"
|
|
4035
|
+
});
|
|
4036
|
+
const size = 16 * 1024 * 1024;
|
|
4037
|
+
const federation = createFederation({
|
|
4038
|
+
kv: new MemoryKvStore(),
|
|
4039
|
+
skipSignatureVerification: true,
|
|
4040
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
4041
|
+
});
|
|
4042
|
+
federation.setActorDispatcher("/actors/{identifier}", () => new Person({ id: new URL("https://example.com/actor") }));
|
|
4043
|
+
federation.setInboxListeners("/actors/{identifier}/inbox", "/inbox").on(Create, () => {
|
|
4044
|
+
dispatched = true;
|
|
4045
|
+
});
|
|
4046
|
+
for (const contentLength of [
|
|
4047
|
+
void 0,
|
|
4048
|
+
"1",
|
|
4049
|
+
String(size + 1)
|
|
4050
|
+
]) {
|
|
4051
|
+
assertEquals((await federation.fetch(new Request("https://example.com/inbox", {
|
|
4052
|
+
method: "POST",
|
|
4053
|
+
headers: contentLength == null ? {} : { "Content-Length": contentLength },
|
|
4054
|
+
body: json.padEnd(size + 1)
|
|
4055
|
+
}), { contextData: void 0 })).status, 413);
|
|
4056
|
+
assertFalse(dispatched);
|
|
4057
|
+
}
|
|
4058
|
+
let canceled = false;
|
|
4059
|
+
let pulls = 0;
|
|
4060
|
+
const body = new ReadableStream({
|
|
4061
|
+
pull(controller) {
|
|
4062
|
+
pulls++;
|
|
4063
|
+
controller.enqueue(new Uint8Array(64 * 1024));
|
|
4064
|
+
},
|
|
4065
|
+
cancel() {
|
|
4066
|
+
canceled = true;
|
|
4067
|
+
}
|
|
4068
|
+
}, { highWaterMark: 0 });
|
|
4069
|
+
const request = new Request("https://example.com/inbox", {
|
|
4070
|
+
method: "POST",
|
|
4071
|
+
body,
|
|
4072
|
+
duplex: "half"
|
|
4073
|
+
});
|
|
4074
|
+
assertEquals((await federation.fetch(request, { contextData: void 0 })).status, 413);
|
|
4075
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
4076
|
+
assert(canceled);
|
|
4077
|
+
assert(pulls <= 260);
|
|
4078
|
+
assertFalse(dispatched);
|
|
4079
|
+
assertEquals((await federation.fetch(new Request("https://example.com/inbox", {
|
|
4080
|
+
method: "POST",
|
|
4081
|
+
body: json
|
|
4082
|
+
}), { contextData: void 0 })).status, 202);
|
|
4083
|
+
assert(dispatched);
|
|
4084
|
+
});
|
|
3870
4085
|
//#endregion
|
|
3871
4086
|
export {};
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -2,7 +2,7 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
4
|
require("../chunk-DDcVe30Y.cjs");
|
|
5
|
-
const require_middleware = require("../middleware-
|
|
5
|
+
const require_middleware = require("../middleware-XXuSt_6b.cjs");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
//#region src/federation/kv.ts
|
|
8
8
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as ActorKeyPairsDispatcher, A as createFederation, B as RouterRouteResult, C as InboxChallengePolicy, D as FederationKvPrefixes, E as Rfc6570Expression, F as Message, G as InProcessMessageQueueOptions, H as respondWithObject, I as createFederationBuilder, J as MessageQueueListenOptions, K as MessageQueue, L as Router, M as RetryContext, N as RetryPolicy, O as FederationOrigin, P as createExponentialBackoffPolicy, Q as ActorHandleMapper, R as RouterError, S as IdempotencyStrategy, St as digest, T as ObjectCallbackSetters, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as InProcessMessageQueue, X as ActorAliasMapper, Y as ParallelMessageQueue, Z as ActorDispatcher, _ as FederationBuilder, _t as WebFingerLinksDispatcher, a as InboxContext, at as CustomCollectionCursor, b as FederationStartQueueOptions, bt as PageItems, c as RouteActivityOptions, ct as InboxListener, d as ActorCallbackSetters, dt as ObjectDispatcher, et as AuthorizePredicate, f as CollectionCallbackSetters, ft as OutboxErrorHandler, g as Federation, gt as UnverifiedActivityReason, h as Federatable, ht as UnverifiedActivityHandler, i as GetSignedKeyOptions, it as CustomCollectionCounter, j as CreateExponentialBackoffPolicyOptions, k as FederationQueueOptions, l as SendActivityOptions, lt as NodeInfoDispatcher, m as CustomCollectionCallbackSetters, mt as SharedInboxKeyDispatcher, n as Context, nt as CollectionCursor, o as ParseUriResult, ot as CustomCollectionDispatcher, p as ConstructorWithTypeId, pt as OutboxPermanentFailureHandler, q as MessageQueueEnqueueOptions, r as ForwardActivityOptions, rt as CollectionDispatcher, s as RequestContext, st as InboxErrorHandler, t as ActorKeyPair, tt as CollectionCounter, u as SendActivityOptionsForCollection, ut as ObjectAuthorizePredicate, v as FederationFetchOptions, vt as SendActivityError, w as InboxListenerSetters, x as IdempotencyKeyCallback, xt as buildCollectionSynchronizationHeader, y as FederationOptions, yt as SenderKeyPair, z as RouterOptions } from "../context-
|
|
2
|
+
import { $ as ActorKeyPairsDispatcher, A as createFederation, B as RouterRouteResult, C as InboxChallengePolicy, D as FederationKvPrefixes, E as Rfc6570Expression, F as Message, G as InProcessMessageQueueOptions, H as respondWithObject, I as createFederationBuilder, J as MessageQueueListenOptions, K as MessageQueue, L as Router, M as RetryContext, N as RetryPolicy, O as FederationOrigin, P as createExponentialBackoffPolicy, Q as ActorHandleMapper, R as RouterError, S as IdempotencyStrategy, St as digest, T as ObjectCallbackSetters, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as InProcessMessageQueue, X as ActorAliasMapper, Y as ParallelMessageQueue, Z as ActorDispatcher, _ as FederationBuilder, _t as WebFingerLinksDispatcher, a as InboxContext, at as CustomCollectionCursor, b as FederationStartQueueOptions, bt as PageItems, c as RouteActivityOptions, ct as InboxListener, d as ActorCallbackSetters, dt as ObjectDispatcher, et as AuthorizePredicate, f as CollectionCallbackSetters, ft as OutboxErrorHandler, g as Federation, gt as UnverifiedActivityReason, h as Federatable, ht as UnverifiedActivityHandler, i as GetSignedKeyOptions, it as CustomCollectionCounter, j as CreateExponentialBackoffPolicyOptions, k as FederationQueueOptions, l as SendActivityOptions, lt as NodeInfoDispatcher, m as CustomCollectionCallbackSetters, mt as SharedInboxKeyDispatcher, n as Context, nt as CollectionCursor, o as ParseUriResult, ot as CustomCollectionDispatcher, p as ConstructorWithTypeId, pt as OutboxPermanentFailureHandler, q as MessageQueueEnqueueOptions, r as ForwardActivityOptions, rt as CollectionDispatcher, s as RequestContext, st as InboxErrorHandler, t as ActorKeyPair, tt as CollectionCounter, u as SendActivityOptionsForCollection, ut as ObjectAuthorizePredicate, v as FederationFetchOptions, vt as SendActivityError, w as InboxListenerSetters, x as IdempotencyKeyCallback, xt as buildCollectionSynchronizationHeader, y as FederationOptions, yt as SenderKeyPair, z as RouterOptions } from "../context-D4s0Wk3N.cjs";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-gJ8LYbxX.cjs";
|
|
4
|
-
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-
|
|
4
|
+
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-Bx80LUTA.cjs";
|
|
5
5
|
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MemoryKvStore, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as ActorKeyPairsDispatcher, A as createFederation, B as RouterRouteResult, C as InboxChallengePolicy, D as FederationKvPrefixes, E as Rfc6570Expression, F as Message, G as InProcessMessageQueueOptions, H as respondWithObject, I as createFederationBuilder, J as MessageQueueListenOptions, K as MessageQueue, L as Router, M as RetryContext, N as RetryPolicy, O as FederationOrigin, P as createExponentialBackoffPolicy, Q as ActorHandleMapper, R as RouterError, S as IdempotencyStrategy, St as digest, T as ObjectCallbackSetters, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as InProcessMessageQueue, X as ActorAliasMapper, Y as ParallelMessageQueue, Z as ActorDispatcher, _ as FederationBuilder, _t as WebFingerLinksDispatcher, a as InboxContext, at as CustomCollectionCursor, b as FederationStartQueueOptions, bt as PageItems, c as RouteActivityOptions, ct as InboxListener, d as ActorCallbackSetters, dt as ObjectDispatcher, et as AuthorizePredicate, f as CollectionCallbackSetters, ft as OutboxErrorHandler, g as Federation, gt as UnverifiedActivityReason, h as Federatable, ht as UnverifiedActivityHandler, i as GetSignedKeyOptions, it as CustomCollectionCounter, j as CreateExponentialBackoffPolicyOptions, k as FederationQueueOptions, l as SendActivityOptions, lt as NodeInfoDispatcher, m as CustomCollectionCallbackSetters, mt as SharedInboxKeyDispatcher, n as Context, nt as CollectionCursor, o as ParseUriResult, ot as CustomCollectionDispatcher, p as ConstructorWithTypeId, pt as OutboxPermanentFailureHandler, q as MessageQueueEnqueueOptions, r as ForwardActivityOptions, rt as CollectionDispatcher, s as RequestContext, st as InboxErrorHandler, t as ActorKeyPair, tt as CollectionCounter, u as SendActivityOptionsForCollection, ut as ObjectAuthorizePredicate, v as FederationFetchOptions, vt as SendActivityError, w as InboxListenerSetters, x as IdempotencyKeyCallback, xt as buildCollectionSynchronizationHeader, y as FederationOptions, yt as SenderKeyPair, z as RouterOptions } from "../context-
|
|
2
|
+
import { $ as ActorKeyPairsDispatcher, A as createFederation, B as RouterRouteResult, C as InboxChallengePolicy, D as FederationKvPrefixes, E as Rfc6570Expression, F as Message, G as InProcessMessageQueueOptions, H as respondWithObject, I as createFederationBuilder, J as MessageQueueListenOptions, K as MessageQueue, L as Router, M as RetryContext, N as RetryPolicy, O as FederationOrigin, P as createExponentialBackoffPolicy, Q as ActorHandleMapper, R as RouterError, S as IdempotencyStrategy, St as digest, T as ObjectCallbackSetters, U as respondWithObjectIfAcceptable, V as RespondWithObjectOptions, W as InProcessMessageQueue, X as ActorAliasMapper, Y as ParallelMessageQueue, Z as ActorDispatcher, _ as FederationBuilder, _t as WebFingerLinksDispatcher, a as InboxContext, at as CustomCollectionCursor, b as FederationStartQueueOptions, bt as PageItems, c as RouteActivityOptions, ct as InboxListener, d as ActorCallbackSetters, dt as ObjectDispatcher, et as AuthorizePredicate, f as CollectionCallbackSetters, ft as OutboxErrorHandler, g as Federation, gt as UnverifiedActivityReason, h as Federatable, ht as UnverifiedActivityHandler, i as GetSignedKeyOptions, it as CustomCollectionCounter, j as CreateExponentialBackoffPolicyOptions, k as FederationQueueOptions, l as SendActivityOptions, lt as NodeInfoDispatcher, m as CustomCollectionCallbackSetters, mt as SharedInboxKeyDispatcher, n as Context, nt as CollectionCursor, o as ParseUriResult, ot as CustomCollectionDispatcher, p as ConstructorWithTypeId, pt as OutboxPermanentFailureHandler, q as MessageQueueEnqueueOptions, r as ForwardActivityOptions, rt as CollectionDispatcher, s as RequestContext, st as InboxErrorHandler, t as ActorKeyPair, tt as CollectionCounter, u as SendActivityOptionsForCollection, ut as ObjectAuthorizePredicate, v as FederationFetchOptions, vt as SendActivityError, w as InboxListenerSetters, x as IdempotencyKeyCallback, xt as buildCollectionSynchronizationHeader, y as FederationOptions, yt as SenderKeyPair, z as RouterOptions } from "../context-BgU5UWTx.js";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-D6hNiMTK.js";
|
|
4
|
-
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-
|
|
4
|
+
import { n as handleWebFinger, t as WebFingerHandlerParameters } from "../mod-DcAiY74j.js";
|
|
5
5
|
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MemoryKvStore, Message, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxErrorHandler, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-
|
|
3
|
+
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-CP35ElZv.js";
|
|
4
4
|
import { isEqual } from "es-toolkit";
|
|
5
5
|
//#region src/federation/kv.ts
|
|
6
6
|
/**
|
|
@@ -2,9 +2,9 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { r as assertGreaterOrEqual } from "../std__assert-BUOJXi-Z.mjs";
|
|
6
6
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
7
|
-
import { t as assert } from "../assert-
|
|
7
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
import { delay } from "es-toolkit";
|
|
10
10
|
//#region src/federation/mq.ts
|
|
@@ -248,50 +248,105 @@ test("InProcessMessageQueue", async (t) => {
|
|
|
248
248
|
const listening = mq.listen((message) => {
|
|
249
249
|
messages.push(message);
|
|
250
250
|
}, controller);
|
|
251
|
-
|
|
252
|
-
await
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
251
|
+
try {
|
|
252
|
+
await t.step("enqueue()", async () => {
|
|
253
|
+
await mq.enqueue("Hello, world!");
|
|
254
|
+
});
|
|
255
|
+
await waitFor(() => messages.length > 0, 15e3);
|
|
256
|
+
await t.step("listen()", () => {
|
|
257
|
+
assertEquals(messages, ["Hello, world!"]);
|
|
258
|
+
});
|
|
259
|
+
await t.step("enqueue() with delay", async () => {
|
|
260
|
+
const { timers, enqueued } = captureTimers(() => mq.enqueue("Delayed message", { delay: Temporal.Duration.from({ seconds: 3 }) }));
|
|
261
|
+
await enqueued;
|
|
262
|
+
assertEquals(timers.length, 1);
|
|
263
|
+
assertEquals(timers[0].delay, 3e3);
|
|
264
|
+
await mq.enqueue("Single delay marker");
|
|
265
|
+
await waitFor(() => messages.includes("Single delay marker"), 15e3);
|
|
266
|
+
assertEquals(messages, ["Hello, world!", "Single delay marker"]);
|
|
267
|
+
timers[0].callback();
|
|
268
|
+
});
|
|
269
|
+
await waitFor(() => messages.length >= 3, 15e3);
|
|
270
|
+
await t.step("listen() with delay", () => {
|
|
271
|
+
assertEquals(messages, [
|
|
272
|
+
"Hello, world!",
|
|
273
|
+
"Single delay marker",
|
|
274
|
+
"Delayed message"
|
|
275
|
+
]);
|
|
276
|
+
});
|
|
277
|
+
while (messages.length > 0) messages.pop();
|
|
278
|
+
await t.step("enqueueMany()", async () => {
|
|
279
|
+
const testMessages = Array.from({ length: 5 }, (_, i) => `Batch message ${i}!`);
|
|
280
|
+
await mq.enqueueMany(testMessages);
|
|
281
|
+
});
|
|
282
|
+
await waitFor(() => messages.length >= 5, 15e3);
|
|
283
|
+
await t.step("listen() [multiple]", () => {
|
|
284
|
+
assertEquals(messages.length, 5);
|
|
285
|
+
for (let i = 0; i < 5; i++) assertEquals(messages[i], `Batch message ${i}!`);
|
|
286
|
+
});
|
|
287
|
+
while (messages.length > 0) messages.pop();
|
|
288
|
+
await t.step("enqueueMany() with delay", async () => {
|
|
289
|
+
const testMessages = Array.from({ length: 3 }, (_, i) => `Delayed batch ${i}!`);
|
|
290
|
+
const { timers, enqueued } = captureTimers(() => mq.enqueueMany(testMessages, { delay: Temporal.Duration.from({ seconds: 2 }) }));
|
|
291
|
+
await enqueued;
|
|
292
|
+
assertEquals(timers.length, 1);
|
|
293
|
+
assertEquals(timers[0].delay, 2e3);
|
|
294
|
+
await mq.enqueue("Batch delay marker");
|
|
295
|
+
await waitFor(() => messages.includes("Batch delay marker"), 15e3);
|
|
296
|
+
assertEquals(messages, ["Batch delay marker"]);
|
|
297
|
+
timers[0].callback();
|
|
298
|
+
});
|
|
299
|
+
await waitFor(() => messages.length >= 4, 15e3);
|
|
300
|
+
await t.step("listen() [delayed multiple]", () => {
|
|
301
|
+
assertEquals(messages.length, 4);
|
|
302
|
+
assertEquals(messages[0], "Batch delay marker");
|
|
303
|
+
for (let i = 0; i < 3; i++) assertEquals(messages[i + 1], `Delayed batch ${i}!`);
|
|
304
|
+
});
|
|
305
|
+
} finally {
|
|
306
|
+
controller.abort();
|
|
307
|
+
await listening;
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
function captureTimers(enqueue) {
|
|
311
|
+
const timers = [];
|
|
312
|
+
const original = globalThis.setTimeout;
|
|
313
|
+
globalThis.setTimeout = ((callback, delay) => {
|
|
314
|
+
timers.push({
|
|
315
|
+
callback,
|
|
316
|
+
delay
|
|
317
|
+
});
|
|
318
|
+
return 0;
|
|
286
319
|
});
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
320
|
+
try {
|
|
321
|
+
return {
|
|
322
|
+
timers,
|
|
323
|
+
enqueued: enqueue()
|
|
324
|
+
};
|
|
325
|
+
} finally {
|
|
326
|
+
globalThis.setTimeout = original;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
test("InProcessMessageQueue real delay", async (t) => {
|
|
330
|
+
for (const batch of [false, true]) await t.step(batch ? "enqueueMany()" : "enqueue()", async () => {
|
|
331
|
+
const mq = new InProcessMessageQueue();
|
|
332
|
+
const messages = [];
|
|
333
|
+
const controller = new AbortController();
|
|
334
|
+
const listening = mq.listen((message) => {
|
|
335
|
+
messages.push(message);
|
|
336
|
+
}, controller);
|
|
337
|
+
try {
|
|
338
|
+
const delayed = batch ? ["Delayed 1", "Delayed 2"] : ["Delayed"];
|
|
339
|
+
const options = { delay: Temporal.Duration.from({ milliseconds: 100 }) };
|
|
340
|
+
if (batch) await mq.enqueueMany(delayed, options);
|
|
341
|
+
else await mq.enqueue(delayed[0], options);
|
|
342
|
+
await mq.enqueue("Immediate");
|
|
343
|
+
await waitFor(() => messages.length >= delayed.length + 1, 15e3);
|
|
344
|
+
assertEquals(messages, ["Immediate", ...delayed]);
|
|
345
|
+
} finally {
|
|
346
|
+
controller.abort();
|
|
347
|
+
await listening;
|
|
348
|
+
}
|
|
292
349
|
});
|
|
293
|
-
controller.abort();
|
|
294
|
-
await listening;
|
|
295
350
|
});
|
|
296
351
|
test("InProcessMessageQueue orderingKey", async (t) => {
|
|
297
352
|
const mq = new InProcessMessageQueue();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import "../std__assert-
|
|
4
|
+
import "../std__assert-BUOJXi-Z.mjs";
|
|
5
5
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
6
|
-
import { t as assert } from "../assert-
|
|
7
|
-
import { t as acceptsJsonLd } from "../negotiation-
|
|
6
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
7
|
+
import { t as acceptsJsonLd } from "../negotiation-BehA2uul.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/negotiation.test.ts
|
|
10
10
|
test("acceptsJsonLd()", () => {
|
|
@@ -3,7 +3,7 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { l as AssertionError, t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
5
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
6
|
-
import { t as createExponentialBackoffPolicy } from "../retry-
|
|
6
|
+
import { t as createExponentialBackoffPolicy } from "../retry-B_E3V_Dx.mjs";
|
|
7
7
|
import { test } from "@fedify/fixture";
|
|
8
8
|
//#region src/federation/retry.test.ts
|
|
9
9
|
test("createExponentialBackoffPolicy()", () => {
|
|
@@ -3,10 +3,10 @@ import "urlpattern-polyfill";
|
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { n as RouterError, t as Router } from "../router-CrMLXoOr.mjs";
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
|
-
import "../std__assert-
|
|
6
|
+
import "../std__assert-BUOJXi-Z.mjs";
|
|
7
7
|
import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
|
|
8
|
+
import { t as assert } from "../assert-BhQd8QHP.mjs";
|
|
8
9
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
9
|
-
import { t as assert } from "../assert-ddO5KLpe.mjs";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
//#region src/federation/router.test.ts
|
|
12
12
|
function setUp(options = {}) {
|