@fedify/fedify 2.3.0-dev.994 → 2.3.0-pr.809.36
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 +16 -7
- package/dist/{assert-DikXweDx.mjs → assert-OguE97r2.mjs} +1 -1
- package/dist/{assert_instance_of-C4Ri6VuN.mjs → assert_instance_of-DBC5X09g.mjs} +1 -1
- package/dist/{assert_not_equals--wG9hV7u.mjs → assert_not_equals-DkVK8oqV.mjs} +1 -1
- package/dist/{assert_rejects-B-qJtC9Z.mjs → assert_rejects-DN60FHPX.mjs} +28 -3
- package/dist/{assert_strict_equals-Dmjbg-bA.mjs → assert_strict_equals-XEgZAlrj.mjs} +1 -1
- package/dist/{assert_throws-4NwKEy2q.mjs → assert_throws-BOkhLGYc.mjs} +1 -1
- package/dist/{builder-yAlpiIqP.mjs → builder-DSZ7FZmg.mjs} +96 -42
- package/dist/{chunk-nlSIicah.js → chunk-CRNNMoPX.js} +2 -2
- package/dist/circuit-breaker-CSWsyoef.mjs +337 -0
- package/dist/{client-z-8dc-e1.d.cts → client-CAM_bQXx.d.cts} +1 -0
- package/dist/{client-AtlibPOU.d.ts → client-CSddvgWN.d.ts} +1 -2
- package/dist/compat/mod.d.cts +2 -1
- package/dist/compat/mod.d.ts +2 -3
- package/dist/compat/mod.js +3 -3
- package/dist/compat/outgoing-jsonld.test.mjs +4 -4
- package/dist/compat/public-audience.test.mjs +4 -4
- package/dist/compat/transformers.test.mjs +5 -5
- package/dist/{context-BzH2-ajs.d.ts → context-BBVLF7lx.d.cts} +342 -269
- package/dist/{context-DJGagtNd.d.cts → context-BU6jSQdo.d.ts} +344 -266
- package/dist/{context-Dk_tacqz.mjs → context-DVoTs_wM.mjs} +64 -5
- package/dist/{deno-XBVlKnOX.mjs → deno-DCdM7d93.mjs} +1 -1
- package/dist/{docloader-DPp-X6gk.mjs → docloader-B7mVwA5_.mjs} +4 -4
- package/dist/{esm-DVILvP5e.mjs → esm-vrlUxr60.mjs} +4 -7
- package/dist/federation/builder.test.mjs +163 -11
- package/dist/federation/circuit-breaker.test.d.mts +2 -0
- package/dist/federation/circuit-breaker.test.mjs +446 -0
- package/dist/federation/collection.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +1770 -29
- package/dist/federation/idempotency.test.mjs +5 -5
- package/dist/federation/inbox.test.mjs +4 -4
- package/dist/federation/keycache.test.mjs +5 -5
- package/dist/federation/kv.test.mjs +2 -2
- package/dist/federation/metrics.test.d.mts +2 -0
- package/dist/federation/metrics.test.mjs +634 -0
- package/dist/federation/middleware.test.mjs +4036 -146
- package/dist/federation/mod.cjs +195 -14
- package/dist/federation/mod.d.cts +6 -4
- package/dist/federation/mod.d.ts +6 -6
- package/dist/federation/mod.js +192 -14
- package/dist/federation/mq.test.mjs +176 -15
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/retry.test.mjs +3 -3
- package/dist/federation/router.test.mjs +190 -9
- package/dist/federation/send.test.mjs +153 -15
- package/dist/federation/temporal.test.d.mts +2 -0
- package/dist/federation/temporal.test.mjs +71 -0
- package/dist/federation/webfinger.test.mjs +150 -5
- package/dist/{http-CSlLA54v.mjs → http-BufbkLuW.mjs} +146 -47
- package/dist/{http-B4rrzxtg.js → http-Dh18nwJg.js} +994 -64
- package/dist/{http-aQzN9Ayi.d.ts → http-VyDTd4G3.d.cts} +15 -3
- package/dist/{http-BrGqJDXL.cjs → http-gOiudB3g.cjs} +1099 -61
- package/dist/{http-CrGuipxe.d.cts → http-lf8Hsd91.d.ts} +15 -1
- package/dist/{key-Bzx--sHD.mjs → key-DZdKLJXT.mjs} +43 -18
- package/dist/{kv-CbLNp3zQ.d.cts → kv-D6hNiMTK.d.ts} +1 -0
- package/dist/{kv-cache-DI-Sk7-I.cjs → kv-cache-BuK_nlpY.cjs} +20 -3
- package/dist/{kv-cache-U__xU4qR.mjs → kv-cache-C7SQnkGI.mjs} +21 -3
- package/dist/{kv-cache-EMIqoIuB.js → kv-cache-DNDSb6Po.js} +20 -3
- package/dist/{kv-GFYnFoOl.d.ts → kv-gJ8LYbxX.d.cts} +1 -3
- package/dist/ld-0Lsznacf.mjs +626 -0
- package/dist/metrics-BHeWd24f.mjs +815 -0
- package/dist/{middleware-zjZ6AFCW.mjs → middleware-BNANvDh2.mjs} +1 -1
- package/dist/{middleware-nidH7VZH.js → middleware-BgzRkDcm.js} +2260 -556
- package/dist/{middleware-An4DjES4.cjs → middleware-D-iES1nQ.cjs} +2318 -623
- package/dist/{middleware-K1g6bEkV.mjs → middleware-EV6J_eAc.mjs} +1639 -373
- package/dist/{mod-CR8soWa9.d.ts → mod-B0hW12_O.d.cts} +26 -4
- package/dist/mod-C0F6kvgS.d.cts +182 -0
- package/dist/{mod-Cr3f-ACa.d.cts → mod-COIAjwRS.d.ts} +26 -2
- package/dist/{mod-CMEbIaNh.d.cts → mod-DFvNJcNb.d.ts} +56 -4
- package/dist/mod-vPYVoa5n.d.ts +182 -0
- package/dist/{mod-CLgIXe9w.d.ts → mod-yvIXFAEi.d.cts} +56 -6
- package/dist/mod.cjs +9 -6
- package/dist/mod.d.cts +12 -10
- package/dist/mod.d.ts +12 -12
- package/dist/mod.js +11 -11
- package/dist/mq-D-nlpY04.d.ts +208 -0
- package/dist/mq-D8uSFzxe.d.cts +208 -0
- package/dist/{negotiation-SQvQgUqe.mjs → negotiation-DDstyBvc.mjs} +29 -0
- package/dist/nodeinfo/client.test.mjs +4 -4
- package/dist/nodeinfo/handler.test.mjs +4 -4
- package/dist/nodeinfo/mod.d.cts +2 -1
- package/dist/nodeinfo/mod.d.ts +2 -3
- package/dist/nodeinfo/mod.js +3 -3
- package/dist/nodeinfo/types.test.mjs +3 -3
- package/dist/otel/exporter.test.mjs +28 -25
- package/dist/otel/mod.cjs +6 -5
- package/dist/otel/mod.d.cts +5 -3
- package/dist/otel/mod.d.ts +5 -5
- package/dist/otel/mod.js +8 -7
- package/dist/{outgoing-jsonld-CNmZLixq.mjs → outgoing-jsonld-L_DbOaFe.mjs} +2 -2
- package/dist/{owner-C-tqfvxn.mjs → owner-Cl-1cAR8.mjs} +2 -2
- package/dist/{owner-CptqhsOy.d.cts → owner-CnngXDNJ.d.ts} +2 -1
- package/dist/{owner-74ARJ5TL.d.ts → owner-DEvZuyOE.d.cts} +2 -3
- package/dist/{proof-Bbbwf8_x.js → proof-CyXndf6-.js} +378 -15
- package/dist/{proof-BlmRPzrK.mjs → proof-Dnz8jtiQ.mjs} +26 -8
- package/dist/{proof-BW89QMVB.cjs → proof-tz35unOj.cjs} +432 -15
- package/dist/runtime/mod.d.cts +1 -0
- package/dist/runtime/mod.d.ts +1 -2
- package/dist/runtime/mod.js +3 -3
- package/dist/{send-05pJLcb6.mjs → send-DIbBYN5P.mjs} +72 -26
- package/dist/sig/http.test.mjs +356 -33
- package/dist/sig/key.test.mjs +103 -6
- package/dist/sig/ld.test.mjs +696 -7
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +4 -3
- package/dist/sig/mod.d.ts +4 -5
- package/dist/sig/mod.js +4 -4
- package/dist/sig/owner.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +169 -8
- package/dist/{std__assert-CRDpx_HF.mjs → std__assert-BBjXFNOb.mjs} +5 -30
- package/dist/temporal-BEwob1Vg.mjs +95 -0
- package/dist/testing/mod.d.mts +110 -10
- package/dist/testing/mod.mjs +1 -2
- package/dist/{transformers-ve6e2xcg.js → transformers-BGMIq1cs.js} +2 -2
- package/dist/{types-hvL8ElAs.js → types-CAY3OdLq.js} +2 -2
- package/dist/utils/docloader.test.mjs +6 -6
- package/dist/utils/kv-cache.test.mjs +67 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +2 -1
- package/dist/utils/mod.d.ts +2 -3
- package/dist/utils/mod.js +3 -3
- package/dist/vocab/cjs.test.mjs +1 -1
- package/dist/vocab/mod.d.cts +1 -0
- package/dist/vocab/mod.d.ts +1 -2
- package/dist/vocab/mod.js +2 -2
- package/package.json +16 -16
- package/dist/ld-DR78beiv.mjs +0 -279
- package/dist/middleware-BFBaR0mF.cjs +0 -4
- package/dist/mod-2d12ffz3.d.ts +0 -64
- package/dist/mod-D35TRn09.d.cts +0 -62
- package/dist/router-CrMLXoOr.mjs +0 -114
- package/dist/{activity-listener-ell7W1s9.mjs → activity-listener-tztVvlNb.mjs} +0 -0
- package/dist/{assert_equals-Ew3jOFa3.mjs → assert_equals-C-ZRDbaf.mjs} +0 -0
- package/dist/{client-D_1QpnWt.mjs → client-ByXmQhYD.mjs} +1 -1
- package/dist/{collection-D-HqUuA2.mjs → collection-Cc3DVAhE.mjs} +0 -0
- package/dist/{keycache-EGATflN-.mjs → keycache-BeU0LCII.mjs} +0 -0
- package/dist/{public-audience-DYFHzm_c.mjs → public-audience-Cvbr2Gzt.mjs} +1 -1
- /package/dist/{retry-bMXBL97A.mjs → retry-CXg_MBI-.mjs} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { t as assertEquals } from "../assert_equals-
|
|
5
|
-
import { n as assertGreater
|
|
6
|
-
import { n as assertFalse } from "../assert_rejects-
|
|
7
|
-
import { t as assert } from "../assert-
|
|
4
|
+
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
|
+
import { n as assertGreater } from "../std__assert-BBjXFNOb.mjs";
|
|
6
|
+
import { n as assertGreaterOrEqual, r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
|
|
7
|
+
import { t as assert } from "../assert-OguE97r2.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
import { delay } from "es-toolkit";
|
|
10
10
|
//#region src/federation/mq.ts
|
|
@@ -19,6 +19,7 @@ var InProcessMessageQueue = class {
|
|
|
19
19
|
#messages;
|
|
20
20
|
#monitors;
|
|
21
21
|
#pollIntervalMs;
|
|
22
|
+
#delayedMessages;
|
|
22
23
|
/**
|
|
23
24
|
* Tracks which ordering keys are currently being processed to ensure
|
|
24
25
|
* sequential processing for messages with the same key.
|
|
@@ -37,42 +38,56 @@ var InProcessMessageQueue = class {
|
|
|
37
38
|
this.#messages = [];
|
|
38
39
|
this.#monitors = {};
|
|
39
40
|
this.#pollIntervalMs = Temporal.Duration.from(options.pollInterval ?? { seconds: 5 }).total("millisecond");
|
|
41
|
+
this.#delayedMessages = 0;
|
|
40
42
|
this.#processingKeys = /* @__PURE__ */ new Set();
|
|
41
43
|
}
|
|
42
44
|
enqueue(message, options) {
|
|
43
45
|
const delay = options?.delay == null ? 0 : Math.max(options.delay.total("millisecond"), 0);
|
|
44
46
|
if (delay > 0) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
this.#delayedMessages++;
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
this.#delayedMessages--;
|
|
50
|
+
this.#enqueueReady(message, options);
|
|
51
|
+
}, delay);
|
|
49
52
|
return Promise.resolve();
|
|
50
53
|
}
|
|
54
|
+
this.#enqueueReady(message, options);
|
|
55
|
+
return Promise.resolve();
|
|
56
|
+
}
|
|
57
|
+
#enqueueReady(message, options) {
|
|
51
58
|
const orderingKey = options?.orderingKey ?? null;
|
|
52
59
|
this.#messages.push({
|
|
53
60
|
message,
|
|
54
61
|
orderingKey
|
|
55
62
|
});
|
|
63
|
+
this.#notifyMonitors();
|
|
64
|
+
}
|
|
65
|
+
#notifyMonitors() {
|
|
56
66
|
for (const monitorId in this.#monitors) this.#monitors[monitorId]();
|
|
57
|
-
return Promise.resolve();
|
|
58
67
|
}
|
|
59
68
|
enqueueMany(messages, options) {
|
|
60
69
|
if (messages.length === 0) return Promise.resolve();
|
|
61
70
|
const delay = options?.delay == null ? 0 : Math.max(options.delay.total("millisecond"), 0);
|
|
62
71
|
if (delay > 0) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
const delayedCount = messages.length;
|
|
73
|
+
const deferredMessages = [...messages];
|
|
74
|
+
this.#delayedMessages += delayedCount;
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
this.#delayedMessages -= delayedCount;
|
|
77
|
+
this.#enqueueManyReady(deferredMessages, options);
|
|
78
|
+
}, delay);
|
|
67
79
|
return Promise.resolve();
|
|
68
80
|
}
|
|
81
|
+
this.#enqueueManyReady(messages, options);
|
|
82
|
+
return Promise.resolve();
|
|
83
|
+
}
|
|
84
|
+
#enqueueManyReady(messages, options) {
|
|
69
85
|
const orderingKey = options?.orderingKey ?? null;
|
|
70
86
|
for (const message of messages) this.#messages.push({
|
|
71
87
|
message,
|
|
72
88
|
orderingKey
|
|
73
89
|
});
|
|
74
|
-
|
|
75
|
-
return Promise.resolve();
|
|
90
|
+
this.#notifyMonitors();
|
|
76
91
|
}
|
|
77
92
|
async listen(handler, options = {}) {
|
|
78
93
|
const signal = options.signal;
|
|
@@ -90,6 +105,15 @@ var InProcessMessageQueue = class {
|
|
|
90
105
|
else await this.#wait(10, signal);
|
|
91
106
|
}
|
|
92
107
|
}
|
|
108
|
+
getDepth() {
|
|
109
|
+
const ready = this.#messages.length;
|
|
110
|
+
const delayed = this.#delayedMessages;
|
|
111
|
+
return Promise.resolve({
|
|
112
|
+
queued: ready + delayed,
|
|
113
|
+
ready,
|
|
114
|
+
delayed
|
|
115
|
+
});
|
|
116
|
+
}
|
|
93
117
|
#wait(ms, signal) {
|
|
94
118
|
let timer = null;
|
|
95
119
|
return Promise.any([new Promise((resolve) => {
|
|
@@ -144,6 +168,7 @@ var ParallelMessageQueue = class ParallelMessageQueue {
|
|
|
144
168
|
* @since 1.7.0
|
|
145
169
|
*/
|
|
146
170
|
nativeRetrial;
|
|
171
|
+
getDepth;
|
|
147
172
|
/**
|
|
148
173
|
* Tracks which ordering keys are currently being processed to ensure
|
|
149
174
|
* sequential processing for messages with the same key.
|
|
@@ -167,6 +192,7 @@ var ParallelMessageQueue = class ParallelMessageQueue {
|
|
|
167
192
|
this.queue = queue;
|
|
168
193
|
this.workers = workers;
|
|
169
194
|
this.nativeRetrial = queue.nativeRetrial;
|
|
195
|
+
if (queue.getDepth != null) this.getDepth = () => queue.getDepth();
|
|
170
196
|
}
|
|
171
197
|
enqueue(message, options) {
|
|
172
198
|
return this.queue.enqueue(message, options);
|
|
@@ -256,6 +282,13 @@ test("InProcessMessageQueue", async (t) => {
|
|
|
256
282
|
await t.step("nativeRetrial property", () => {
|
|
257
283
|
assertFalse(mq.nativeRetrial);
|
|
258
284
|
});
|
|
285
|
+
await t.step("getDepth() [empty]", async () => {
|
|
286
|
+
assertEquals(await mq.getDepth(), {
|
|
287
|
+
queued: 0,
|
|
288
|
+
ready: 0,
|
|
289
|
+
delayed: 0
|
|
290
|
+
});
|
|
291
|
+
});
|
|
259
292
|
const messages = [];
|
|
260
293
|
const controller = new AbortController();
|
|
261
294
|
const listening = mq.listen((message) => {
|
|
@@ -306,6 +339,130 @@ test("InProcessMessageQueue", async (t) => {
|
|
|
306
339
|
controller.abort();
|
|
307
340
|
await listening;
|
|
308
341
|
});
|
|
342
|
+
test("InProcessMessageQueue.getDepth()", async () => {
|
|
343
|
+
const mq = new InProcessMessageQueue();
|
|
344
|
+
assertEquals(await mq.getDepth(), {
|
|
345
|
+
queued: 0,
|
|
346
|
+
ready: 0,
|
|
347
|
+
delayed: 0
|
|
348
|
+
});
|
|
349
|
+
await mq.enqueue("Ready message");
|
|
350
|
+
await mq.enqueue("Delayed message", { delay: Temporal.Duration.from({ seconds: 1 }) });
|
|
351
|
+
assertEquals(await mq.getDepth(), {
|
|
352
|
+
queued: 2,
|
|
353
|
+
ready: 1,
|
|
354
|
+
delayed: 1
|
|
355
|
+
});
|
|
356
|
+
const messages = [];
|
|
357
|
+
const controller = new AbortController();
|
|
358
|
+
const listening = mq.listen((message) => {
|
|
359
|
+
messages.push(message);
|
|
360
|
+
if (messages.length >= 2) controller.abort();
|
|
361
|
+
}, { signal: controller.signal });
|
|
362
|
+
await waitFor(() => messages.length >= 2, 15e3);
|
|
363
|
+
await listening;
|
|
364
|
+
assertEquals(await mq.getDepth(), {
|
|
365
|
+
queued: 0,
|
|
366
|
+
ready: 0,
|
|
367
|
+
delayed: 0
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
test("InProcessMessageQueue.getDepth() snapshots delayed batches", async () => {
|
|
371
|
+
const mq = new InProcessMessageQueue();
|
|
372
|
+
const messages = ["first", "second"];
|
|
373
|
+
await mq.enqueueMany(messages, { delay: Temporal.Duration.from({ milliseconds: 250 }) });
|
|
374
|
+
messages.length = 0;
|
|
375
|
+
assertEquals(await mq.getDepth(), {
|
|
376
|
+
queued: 2,
|
|
377
|
+
ready: 0,
|
|
378
|
+
delayed: 2
|
|
379
|
+
});
|
|
380
|
+
const handled = [];
|
|
381
|
+
const controller = new AbortController();
|
|
382
|
+
const listening = mq.listen((message) => {
|
|
383
|
+
handled.push(message);
|
|
384
|
+
if (handled.length >= 2) controller.abort();
|
|
385
|
+
}, { signal: controller.signal });
|
|
386
|
+
await waitFor(() => handled.length >= 2, 15e3);
|
|
387
|
+
await listening;
|
|
388
|
+
assertEquals(handled, ["first", "second"]);
|
|
389
|
+
});
|
|
390
|
+
test("InProcessMessageQueue.getDepth() excludes in-flight messages", async () => {
|
|
391
|
+
const mq = new InProcessMessageQueue();
|
|
392
|
+
let resolveHandler;
|
|
393
|
+
const controller = new AbortController();
|
|
394
|
+
const handled = new Promise((resolve) => {
|
|
395
|
+
resolveHandler = resolve;
|
|
396
|
+
});
|
|
397
|
+
let notifyStarted = () => {};
|
|
398
|
+
const handlerStarted = new Promise((resolve) => {
|
|
399
|
+
notifyStarted = resolve;
|
|
400
|
+
});
|
|
401
|
+
const listening = mq.listen(async () => {
|
|
402
|
+
notifyStarted();
|
|
403
|
+
await handled;
|
|
404
|
+
controller.abort();
|
|
405
|
+
}, { signal: controller.signal });
|
|
406
|
+
try {
|
|
407
|
+
await mq.enqueue("in-flight");
|
|
408
|
+
await handlerStarted;
|
|
409
|
+
assertEquals(await mq.getDepth(), {
|
|
410
|
+
queued: 0,
|
|
411
|
+
ready: 0,
|
|
412
|
+
delayed: 0
|
|
413
|
+
});
|
|
414
|
+
} finally {
|
|
415
|
+
resolveHandler?.();
|
|
416
|
+
controller.abort();
|
|
417
|
+
await listening;
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
test("InProcessMessageQueue delayed enqueue uses the internal ready path", async () => {
|
|
421
|
+
class RejectingReadyQueue extends InProcessMessageQueue {
|
|
422
|
+
enqueue(message, options) {
|
|
423
|
+
if (options?.delay == null) return Promise.reject(/* @__PURE__ */ new Error("ready enqueue should not be called"));
|
|
424
|
+
return super.enqueue(message, options);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
const mq = new RejectingReadyQueue({ pollInterval: { milliseconds: 10 } });
|
|
428
|
+
const messages = [];
|
|
429
|
+
const controller = new AbortController();
|
|
430
|
+
const listening = mq.listen((message) => {
|
|
431
|
+
messages.push(message);
|
|
432
|
+
controller.abort();
|
|
433
|
+
}, { signal: controller.signal });
|
|
434
|
+
try {
|
|
435
|
+
await mq.enqueue("delayed", { delay: Temporal.Duration.from({ milliseconds: 10 }) });
|
|
436
|
+
await waitFor(() => messages.length > 0, 2e3);
|
|
437
|
+
assertEquals(messages, ["delayed"]);
|
|
438
|
+
} finally {
|
|
439
|
+
controller.abort();
|
|
440
|
+
await listening;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
test("InProcessMessageQueue delayed enqueueMany uses the internal ready path", async () => {
|
|
444
|
+
class RejectingReadyQueue extends InProcessMessageQueue {
|
|
445
|
+
enqueueMany(messages, options) {
|
|
446
|
+
if (options?.delay == null) return Promise.reject(/* @__PURE__ */ new Error("ready enqueueMany should not be called"));
|
|
447
|
+
return super.enqueueMany(messages, options);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
const mq = new RejectingReadyQueue({ pollInterval: { milliseconds: 10 } });
|
|
451
|
+
const messages = [];
|
|
452
|
+
const controller = new AbortController();
|
|
453
|
+
const listening = mq.listen((message) => {
|
|
454
|
+
messages.push(message);
|
|
455
|
+
if (messages.length >= 2) controller.abort();
|
|
456
|
+
}, { signal: controller.signal });
|
|
457
|
+
try {
|
|
458
|
+
await mq.enqueueMany(["first", "second"], { delay: Temporal.Duration.from({ milliseconds: 10 }) });
|
|
459
|
+
await waitFor(() => messages.length >= 2, 2e3);
|
|
460
|
+
assertEquals(messages, ["first", "second"]);
|
|
461
|
+
} finally {
|
|
462
|
+
controller.abort();
|
|
463
|
+
await listening;
|
|
464
|
+
}
|
|
465
|
+
});
|
|
309
466
|
test("InProcessMessageQueue orderingKey", async (t) => {
|
|
310
467
|
const mq = new InProcessMessageQueue();
|
|
311
468
|
const orderTracker = {
|
|
@@ -425,6 +582,10 @@ for (const mqName in queues) test({
|
|
|
425
582
|
await t.step("nativeRetrial property inheritance", () => {
|
|
426
583
|
assertEquals(workers.nativeRetrial, mq.nativeRetrial);
|
|
427
584
|
});
|
|
585
|
+
await t.step("getDepth() delegation", async () => {
|
|
586
|
+
if (mq.getDepth == null) assertEquals(workers.getDepth, void 0);
|
|
587
|
+
else assertEquals(await workers.getDepth?.(), await mq.getDepth());
|
|
588
|
+
});
|
|
428
589
|
const messages = [];
|
|
429
590
|
const controller = new AbortController();
|
|
430
591
|
const listening = workers.listen(async (message) => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import "../std__assert-
|
|
5
|
-
import {
|
|
6
|
-
import { t as assert } from "../assert-
|
|
7
|
-
import { t as acceptsJsonLd } from "../negotiation-
|
|
4
|
+
import "../std__assert-BBjXFNOb.mjs";
|
|
5
|
+
import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
|
|
6
|
+
import { t as assert } from "../assert-OguE97r2.mjs";
|
|
7
|
+
import { t as acceptsJsonLd } from "../negotiation-DDstyBvc.mjs";
|
|
8
8
|
import { test } from "@fedify/fixture";
|
|
9
9
|
//#region src/federation/negotiation.test.ts
|
|
10
10
|
test("acceptsJsonLd()", () => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { l as AssertionError, t as assertEquals } from "../assert_equals-
|
|
5
|
-
import { t as assertNotEquals } from "../assert_not_equals
|
|
6
|
-
import { t as createExponentialBackoffPolicy } from "../retry-
|
|
4
|
+
import { l as AssertionError, t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
|
+
import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
|
|
6
|
+
import { t as createExponentialBackoffPolicy } from "../retry-CXg_MBI-.mjs";
|
|
7
7
|
import { test } from "@fedify/fixture";
|
|
8
8
|
//#region src/federation/retry.test.ts
|
|
9
9
|
test("createExponentialBackoffPolicy()", () => {
|
|
@@ -1,16 +1,167 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import "../
|
|
7
|
-
import {
|
|
8
|
-
import { t as
|
|
9
|
-
import {
|
|
4
|
+
import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
|
|
5
|
+
import "../std__assert-BBjXFNOb.mjs";
|
|
6
|
+
import { r as assertFalse } from "../assert_rejects-DN60FHPX.mjs";
|
|
7
|
+
import { t as assertThrows } from "../assert_throws-BOkhLGYc.mjs";
|
|
8
|
+
import { t as assert } from "../assert-OguE97r2.mjs";
|
|
9
|
+
import { getLogger } from "@logtape/logtape";
|
|
10
|
+
import { Router, RouterError, assertPath, isPath } from "@fedify/uri-template";
|
|
10
11
|
import { test } from "@fedify/fixture";
|
|
12
|
+
//#region src/federation/router.ts
|
|
13
|
+
const logger = getLogger([
|
|
14
|
+
"fedify",
|
|
15
|
+
"federation",
|
|
16
|
+
"router",
|
|
17
|
+
"deprecated"
|
|
18
|
+
]);
|
|
19
|
+
let deprecationWarned = false;
|
|
20
|
+
function warnDeprecated() {
|
|
21
|
+
if (deprecationWarned) return;
|
|
22
|
+
deprecationWarned = true;
|
|
23
|
+
logger.warn("The `Router` and `RouterError` classes from `@fedify/fedify` are deprecated. Please use `Router` from `@fedify/uri-template` instead.");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* URL router and constructor based on URI Template
|
|
27
|
+
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)).
|
|
28
|
+
*
|
|
29
|
+
* @deprecated Import `Router` from `@fedify/uri-template` instead. This class
|
|
30
|
+
* remains only for compatibility with older Fedify code. The
|
|
31
|
+
* `@fedify/uri-template` router is the replacement implementation
|
|
32
|
+
* and should be used directly in new code.
|
|
33
|
+
*/
|
|
34
|
+
var Router$1 = class Router$1 {
|
|
35
|
+
#router;
|
|
36
|
+
/**
|
|
37
|
+
* Create a new {@link Router}.
|
|
38
|
+
* @param options Options for the router.
|
|
39
|
+
* @deprecated Use `new Router(options)` from `@fedify/uri-template`
|
|
40
|
+
* instead.
|
|
41
|
+
*/
|
|
42
|
+
constructor(options) {
|
|
43
|
+
this.#router = convertRouterError(() => new Router(options));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether to ignore trailing slashes when matching paths.
|
|
47
|
+
* @deprecated Use `Router` from `@fedify/uri-template` instead. This
|
|
48
|
+
* accessor forwards to the underlying `@fedify/uri-template`
|
|
49
|
+
* router so that post-construction mutation keeps working as
|
|
50
|
+
* in older Fedify code.
|
|
51
|
+
*/
|
|
52
|
+
get trailingSlashInsensitive() {
|
|
53
|
+
return this.#router.trailingSlashInsensitive;
|
|
54
|
+
}
|
|
55
|
+
set trailingSlashInsensitive(value) {
|
|
56
|
+
this.#router.trailingSlashInsensitive = value;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Clones this router.
|
|
60
|
+
* @deprecated Use `Router` from `@fedify/uri-template` instead.
|
|
61
|
+
*/
|
|
62
|
+
clone() {
|
|
63
|
+
return convertRouterError(() => {
|
|
64
|
+
const clone = new Router$1();
|
|
65
|
+
clone.#router = this.#router.clone();
|
|
66
|
+
return clone;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Checks if a path name exists in the router.
|
|
71
|
+
* @param name The name of the path.
|
|
72
|
+
* @returns `true` if the path name exists, otherwise `false`.
|
|
73
|
+
* @deprecated Use `Router` from `@fedify/uri-template` instead.
|
|
74
|
+
*/
|
|
75
|
+
has(name) {
|
|
76
|
+
return convertRouterError(() => this.#router.has(name));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Adds a new path rule to the router.
|
|
80
|
+
* @param template The path pattern.
|
|
81
|
+
* @param name The name of the path.
|
|
82
|
+
* @returns The names of the variables in the path pattern.
|
|
83
|
+
* @deprecated Use `Router` from `@fedify/uri-template` instead. In this
|
|
84
|
+
* compatibility class, `add()` both registers the route and
|
|
85
|
+
* returns the variables in the path pattern. In
|
|
86
|
+
* `@fedify/uri-template`, these two responsibilities are split:
|
|
87
|
+
* `router.add(template, name)` registers the route and returns
|
|
88
|
+
* `void`, while the pure static method
|
|
89
|
+
* `Router.variables(template)` returns the variable names. To
|
|
90
|
+
* migrate, call `Router.variables(template)` when variables are
|
|
91
|
+
* needed, then call `router.add(template, name)` to register the
|
|
92
|
+
* route.
|
|
93
|
+
*/
|
|
94
|
+
add(template, name) {
|
|
95
|
+
return convertRouterError(() => {
|
|
96
|
+
assertPath(template);
|
|
97
|
+
this.#router.add(template, name);
|
|
98
|
+
return Router.variables(template);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Resolves a path name and values from a URL, if any match.
|
|
103
|
+
* @param url The URL to resolve.
|
|
104
|
+
* @returns The name of the path and its values, if any match. Otherwise,
|
|
105
|
+
* `null`.
|
|
106
|
+
* @deprecated Use `Router` from `@fedify/uri-template` instead. Unlike the
|
|
107
|
+
* stricter `@fedify/uri-template` router, this compatibility
|
|
108
|
+
* method keeps the old Fedify 2.x contract of returning `null`
|
|
109
|
+
* (rather than throwing) for inputs that are not router paths.
|
|
110
|
+
*/
|
|
111
|
+
route(url) {
|
|
112
|
+
return convertRouterError(() => {
|
|
113
|
+
if (!isPath(url)) return null;
|
|
114
|
+
return this.#router.route(url);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Constructs a URL/path from a path name and values.
|
|
119
|
+
* @param name The name of the path.
|
|
120
|
+
* @param values The values to expand the path with.
|
|
121
|
+
* @returns The URL/path, if the name exists. Otherwise, `null`.
|
|
122
|
+
* @deprecated Use `Router` from `@fedify/uri-template` instead.
|
|
123
|
+
*/
|
|
124
|
+
build(name, values) {
|
|
125
|
+
return convertRouterError(() => this.#router.build(name, values));
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* An error thrown by the {@link Router}.
|
|
130
|
+
* @deprecated Import `RouterError` from `@fedify/uri-template` instead.
|
|
131
|
+
*/
|
|
132
|
+
var RouterError$1 = class extends RouterError {
|
|
133
|
+
/**
|
|
134
|
+
* Treats every `RouterError` from `@fedify/uri-template` as an instance of
|
|
135
|
+
* this deprecated class.
|
|
136
|
+
*
|
|
137
|
+
* @deprecated Import `RouterError` from `@fedify/uri-template` instead.
|
|
138
|
+
*/
|
|
139
|
+
static [Symbol.hasInstance](instance) {
|
|
140
|
+
return instance instanceof RouterError;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Create a new {@link RouterError}.
|
|
144
|
+
* @param message The error message.
|
|
145
|
+
* @deprecated Import `RouterError` from `@fedify/uri-template` instead.
|
|
146
|
+
*/
|
|
147
|
+
constructor(message) {
|
|
148
|
+
super(message);
|
|
149
|
+
warnDeprecated();
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
function convertRouterError(func) {
|
|
153
|
+
try {
|
|
154
|
+
warnDeprecated();
|
|
155
|
+
return func();
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (error instanceof RouterError) throw new RouterError$1(error.message);
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
11
162
|
//#region src/federation/router.test.ts
|
|
12
163
|
function setUp(options = {}) {
|
|
13
|
-
const router = new Router(options);
|
|
164
|
+
const router = new Router$1(options);
|
|
14
165
|
router.add("/users/{name}", "user");
|
|
15
166
|
router.add("/users/{name}/posts/{postId}" + (options.trailingSlashInsensitive ? "/" : ""), "post");
|
|
16
167
|
return router;
|
|
@@ -29,11 +180,11 @@ test("Router.clone()", () => {
|
|
|
29
180
|
assertEquals(original.route("/users/alice/friends"), null);
|
|
30
181
|
});
|
|
31
182
|
test("Router.add()", () => {
|
|
32
|
-
const router = new Router();
|
|
183
|
+
const router = new Router$1();
|
|
33
184
|
assertEquals(router.add("/users", "users"), /* @__PURE__ */ new Set());
|
|
34
185
|
assertEquals(router.add("/users/{name}", "user"), new Set(["name"]));
|
|
35
186
|
assertEquals(router.add("/users/{name}/posts/{postId}", "post"), new Set(["name", "postId"]));
|
|
36
|
-
assertThrows(() => router.add("foo", "name"), RouterError);
|
|
187
|
+
assertThrows(() => router.add("foo", "name"), RouterError$1);
|
|
37
188
|
});
|
|
38
189
|
test("Router.route()", () => {
|
|
39
190
|
let router = setUp();
|
|
@@ -80,6 +231,21 @@ test("Router.route()", () => {
|
|
|
80
231
|
}
|
|
81
232
|
});
|
|
82
233
|
});
|
|
234
|
+
test("Router.trailingSlashInsensitive (post-construction mutation)", () => {
|
|
235
|
+
const router = setUp();
|
|
236
|
+
assertFalse(router.trailingSlashInsensitive);
|
|
237
|
+
assertEquals(router.route("/users/bob/"), null);
|
|
238
|
+
router.trailingSlashInsensitive = true;
|
|
239
|
+
assert(router.trailingSlashInsensitive);
|
|
240
|
+
assertEquals(router.route("/users/bob/"), {
|
|
241
|
+
name: "user",
|
|
242
|
+
template: "/users/{name}",
|
|
243
|
+
values: { name: "bob" }
|
|
244
|
+
});
|
|
245
|
+
router.trailingSlashInsensitive = false;
|
|
246
|
+
assertFalse(router.trailingSlashInsensitive);
|
|
247
|
+
assertEquals(router.route("/users/bob/"), null);
|
|
248
|
+
});
|
|
83
249
|
test("Router.build()", () => {
|
|
84
250
|
const router = setUp();
|
|
85
251
|
assertEquals(router.build("user", { name: "alice" }), "/users/alice");
|
|
@@ -88,5 +254,20 @@ test("Router.build()", () => {
|
|
|
88
254
|
postId: "123"
|
|
89
255
|
}), "/users/alice/posts/123");
|
|
90
256
|
});
|
|
257
|
+
test("Router.route() returns null for non-path inputs", () => {
|
|
258
|
+
const router = setUp();
|
|
259
|
+
assertEquals(router.route("https://example.com/users/alice"), null);
|
|
260
|
+
assertEquals(router.route("users/alice"), null);
|
|
261
|
+
assertEquals(router.route("not a path"), null);
|
|
262
|
+
assertEquals(router.route("/unknown"), null);
|
|
263
|
+
});
|
|
264
|
+
test("Compatibility between RouterErrors", () => {
|
|
265
|
+
const newError = new RouterError("boom");
|
|
266
|
+
assert(newError instanceof RouterError);
|
|
267
|
+
assert(newError instanceof RouterError$1);
|
|
268
|
+
const previousError = new RouterError$1("boom");
|
|
269
|
+
assert(previousError instanceof RouterError$1);
|
|
270
|
+
assert(previousError instanceof RouterError);
|
|
271
|
+
});
|
|
91
272
|
//#endregion
|
|
92
273
|
export {};
|