@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.
Files changed (138) hide show
  1. package/README.md +16 -7
  2. package/dist/{assert-DikXweDx.mjs → assert-OguE97r2.mjs} +1 -1
  3. package/dist/{assert_instance_of-C4Ri6VuN.mjs → assert_instance_of-DBC5X09g.mjs} +1 -1
  4. package/dist/{assert_not_equals--wG9hV7u.mjs → assert_not_equals-DkVK8oqV.mjs} +1 -1
  5. package/dist/{assert_rejects-B-qJtC9Z.mjs → assert_rejects-DN60FHPX.mjs} +28 -3
  6. package/dist/{assert_strict_equals-Dmjbg-bA.mjs → assert_strict_equals-XEgZAlrj.mjs} +1 -1
  7. package/dist/{assert_throws-4NwKEy2q.mjs → assert_throws-BOkhLGYc.mjs} +1 -1
  8. package/dist/{builder-yAlpiIqP.mjs → builder-DSZ7FZmg.mjs} +96 -42
  9. package/dist/{chunk-nlSIicah.js → chunk-CRNNMoPX.js} +2 -2
  10. package/dist/circuit-breaker-CSWsyoef.mjs +337 -0
  11. package/dist/{client-z-8dc-e1.d.cts → client-CAM_bQXx.d.cts} +1 -0
  12. package/dist/{client-AtlibPOU.d.ts → client-CSddvgWN.d.ts} +1 -2
  13. package/dist/compat/mod.d.cts +2 -1
  14. package/dist/compat/mod.d.ts +2 -3
  15. package/dist/compat/mod.js +3 -3
  16. package/dist/compat/outgoing-jsonld.test.mjs +4 -4
  17. package/dist/compat/public-audience.test.mjs +4 -4
  18. package/dist/compat/transformers.test.mjs +5 -5
  19. package/dist/{context-BzH2-ajs.d.ts → context-BBVLF7lx.d.cts} +342 -269
  20. package/dist/{context-DJGagtNd.d.cts → context-BU6jSQdo.d.ts} +344 -266
  21. package/dist/{context-Dk_tacqz.mjs → context-DVoTs_wM.mjs} +64 -5
  22. package/dist/{deno-XBVlKnOX.mjs → deno-DCdM7d93.mjs} +1 -1
  23. package/dist/{docloader-DPp-X6gk.mjs → docloader-B7mVwA5_.mjs} +4 -4
  24. package/dist/{esm-DVILvP5e.mjs → esm-vrlUxr60.mjs} +4 -7
  25. package/dist/federation/builder.test.mjs +163 -11
  26. package/dist/federation/circuit-breaker.test.d.mts +2 -0
  27. package/dist/federation/circuit-breaker.test.mjs +446 -0
  28. package/dist/federation/collection.test.mjs +3 -3
  29. package/dist/federation/handler.test.mjs +1770 -29
  30. package/dist/federation/idempotency.test.mjs +5 -5
  31. package/dist/federation/inbox.test.mjs +4 -4
  32. package/dist/federation/keycache.test.mjs +5 -5
  33. package/dist/federation/kv.test.mjs +2 -2
  34. package/dist/federation/metrics.test.d.mts +2 -0
  35. package/dist/federation/metrics.test.mjs +634 -0
  36. package/dist/federation/middleware.test.mjs +4036 -146
  37. package/dist/federation/mod.cjs +195 -14
  38. package/dist/federation/mod.d.cts +6 -4
  39. package/dist/federation/mod.d.ts +6 -6
  40. package/dist/federation/mod.js +192 -14
  41. package/dist/federation/mq.test.mjs +176 -15
  42. package/dist/federation/negotiation.test.mjs +4 -4
  43. package/dist/federation/retry.test.mjs +3 -3
  44. package/dist/federation/router.test.mjs +190 -9
  45. package/dist/federation/send.test.mjs +153 -15
  46. package/dist/federation/temporal.test.d.mts +2 -0
  47. package/dist/federation/temporal.test.mjs +71 -0
  48. package/dist/federation/webfinger.test.mjs +150 -5
  49. package/dist/{http-CSlLA54v.mjs → http-BufbkLuW.mjs} +146 -47
  50. package/dist/{http-B4rrzxtg.js → http-Dh18nwJg.js} +994 -64
  51. package/dist/{http-aQzN9Ayi.d.ts → http-VyDTd4G3.d.cts} +15 -3
  52. package/dist/{http-BrGqJDXL.cjs → http-gOiudB3g.cjs} +1099 -61
  53. package/dist/{http-CrGuipxe.d.cts → http-lf8Hsd91.d.ts} +15 -1
  54. package/dist/{key-Bzx--sHD.mjs → key-DZdKLJXT.mjs} +43 -18
  55. package/dist/{kv-CbLNp3zQ.d.cts → kv-D6hNiMTK.d.ts} +1 -0
  56. package/dist/{kv-cache-DI-Sk7-I.cjs → kv-cache-BuK_nlpY.cjs} +20 -3
  57. package/dist/{kv-cache-U__xU4qR.mjs → kv-cache-C7SQnkGI.mjs} +21 -3
  58. package/dist/{kv-cache-EMIqoIuB.js → kv-cache-DNDSb6Po.js} +20 -3
  59. package/dist/{kv-GFYnFoOl.d.ts → kv-gJ8LYbxX.d.cts} +1 -3
  60. package/dist/ld-0Lsznacf.mjs +626 -0
  61. package/dist/metrics-BHeWd24f.mjs +815 -0
  62. package/dist/{middleware-zjZ6AFCW.mjs → middleware-BNANvDh2.mjs} +1 -1
  63. package/dist/{middleware-nidH7VZH.js → middleware-BgzRkDcm.js} +2260 -556
  64. package/dist/{middleware-An4DjES4.cjs → middleware-D-iES1nQ.cjs} +2318 -623
  65. package/dist/{middleware-K1g6bEkV.mjs → middleware-EV6J_eAc.mjs} +1639 -373
  66. package/dist/{mod-CR8soWa9.d.ts → mod-B0hW12_O.d.cts} +26 -4
  67. package/dist/mod-C0F6kvgS.d.cts +182 -0
  68. package/dist/{mod-Cr3f-ACa.d.cts → mod-COIAjwRS.d.ts} +26 -2
  69. package/dist/{mod-CMEbIaNh.d.cts → mod-DFvNJcNb.d.ts} +56 -4
  70. package/dist/mod-vPYVoa5n.d.ts +182 -0
  71. package/dist/{mod-CLgIXe9w.d.ts → mod-yvIXFAEi.d.cts} +56 -6
  72. package/dist/mod.cjs +9 -6
  73. package/dist/mod.d.cts +12 -10
  74. package/dist/mod.d.ts +12 -12
  75. package/dist/mod.js +11 -11
  76. package/dist/mq-D-nlpY04.d.ts +208 -0
  77. package/dist/mq-D8uSFzxe.d.cts +208 -0
  78. package/dist/{negotiation-SQvQgUqe.mjs → negotiation-DDstyBvc.mjs} +29 -0
  79. package/dist/nodeinfo/client.test.mjs +4 -4
  80. package/dist/nodeinfo/handler.test.mjs +4 -4
  81. package/dist/nodeinfo/mod.d.cts +2 -1
  82. package/dist/nodeinfo/mod.d.ts +2 -3
  83. package/dist/nodeinfo/mod.js +3 -3
  84. package/dist/nodeinfo/types.test.mjs +3 -3
  85. package/dist/otel/exporter.test.mjs +28 -25
  86. package/dist/otel/mod.cjs +6 -5
  87. package/dist/otel/mod.d.cts +5 -3
  88. package/dist/otel/mod.d.ts +5 -5
  89. package/dist/otel/mod.js +8 -7
  90. package/dist/{outgoing-jsonld-CNmZLixq.mjs → outgoing-jsonld-L_DbOaFe.mjs} +2 -2
  91. package/dist/{owner-C-tqfvxn.mjs → owner-Cl-1cAR8.mjs} +2 -2
  92. package/dist/{owner-CptqhsOy.d.cts → owner-CnngXDNJ.d.ts} +2 -1
  93. package/dist/{owner-74ARJ5TL.d.ts → owner-DEvZuyOE.d.cts} +2 -3
  94. package/dist/{proof-Bbbwf8_x.js → proof-CyXndf6-.js} +378 -15
  95. package/dist/{proof-BlmRPzrK.mjs → proof-Dnz8jtiQ.mjs} +26 -8
  96. package/dist/{proof-BW89QMVB.cjs → proof-tz35unOj.cjs} +432 -15
  97. package/dist/runtime/mod.d.cts +1 -0
  98. package/dist/runtime/mod.d.ts +1 -2
  99. package/dist/runtime/mod.js +3 -3
  100. package/dist/{send-05pJLcb6.mjs → send-DIbBYN5P.mjs} +72 -26
  101. package/dist/sig/http.test.mjs +356 -33
  102. package/dist/sig/key.test.mjs +103 -6
  103. package/dist/sig/ld.test.mjs +696 -7
  104. package/dist/sig/mod.cjs +2 -2
  105. package/dist/sig/mod.d.cts +4 -3
  106. package/dist/sig/mod.d.ts +4 -5
  107. package/dist/sig/mod.js +4 -4
  108. package/dist/sig/owner.test.mjs +6 -6
  109. package/dist/sig/proof.test.mjs +169 -8
  110. package/dist/{std__assert-CRDpx_HF.mjs → std__assert-BBjXFNOb.mjs} +5 -30
  111. package/dist/temporal-BEwob1Vg.mjs +95 -0
  112. package/dist/testing/mod.d.mts +110 -10
  113. package/dist/testing/mod.mjs +1 -2
  114. package/dist/{transformers-ve6e2xcg.js → transformers-BGMIq1cs.js} +2 -2
  115. package/dist/{types-hvL8ElAs.js → types-CAY3OdLq.js} +2 -2
  116. package/dist/utils/docloader.test.mjs +6 -6
  117. package/dist/utils/kv-cache.test.mjs +67 -2
  118. package/dist/utils/mod.cjs +1 -1
  119. package/dist/utils/mod.d.cts +2 -1
  120. package/dist/utils/mod.d.ts +2 -3
  121. package/dist/utils/mod.js +3 -3
  122. package/dist/vocab/cjs.test.mjs +1 -1
  123. package/dist/vocab/mod.d.cts +1 -0
  124. package/dist/vocab/mod.d.ts +1 -2
  125. package/dist/vocab/mod.js +2 -2
  126. package/package.json +16 -16
  127. package/dist/ld-DR78beiv.mjs +0 -279
  128. package/dist/middleware-BFBaR0mF.cjs +0 -4
  129. package/dist/mod-2d12ffz3.d.ts +0 -64
  130. package/dist/mod-D35TRn09.d.cts +0 -62
  131. package/dist/router-CrMLXoOr.mjs +0 -114
  132. package/dist/{activity-listener-ell7W1s9.mjs → activity-listener-tztVvlNb.mjs} +0 -0
  133. package/dist/{assert_equals-Ew3jOFa3.mjs → assert_equals-C-ZRDbaf.mjs} +0 -0
  134. package/dist/{client-D_1QpnWt.mjs → client-ByXmQhYD.mjs} +1 -1
  135. package/dist/{collection-D-HqUuA2.mjs → collection-Cc3DVAhE.mjs} +0 -0
  136. package/dist/{keycache-EGATflN-.mjs → keycache-BeU0LCII.mjs} +0 -0
  137. package/dist/{public-audience-DYFHzm_c.mjs → public-audience-Cvbr2Gzt.mjs} +1 -1
  138. /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-Ew3jOFa3.mjs";
5
- import { n as assertGreater, r as assertGreaterOrEqual } from "../std__assert-CRDpx_HF.mjs";
6
- import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
7
- import { t as assert } from "../assert-DikXweDx.mjs";
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
- setTimeout(() => this.enqueue(message, {
46
- ...options,
47
- delay: void 0
48
- }), delay);
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
- setTimeout(() => this.enqueueMany(messages, {
64
- ...options,
65
- delay: void 0
66
- }), delay);
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
- for (const monitorId in this.#monitors) this.#monitors[monitorId]();
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-CRDpx_HF.mjs";
5
- import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
6
- import { t as assert } from "../assert-DikXweDx.mjs";
7
- import { t as acceptsJsonLd } from "../negotiation-SQvQgUqe.mjs";
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-Ew3jOFa3.mjs";
5
- import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
6
- import { t as createExponentialBackoffPolicy } from "../retry-bMXBL97A.mjs";
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 { n as RouterError, t as Router } from "../router-CrMLXoOr.mjs";
5
- import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
6
- import "../std__assert-CRDpx_HF.mjs";
7
- import { n as assertFalse } from "../assert_rejects-B-qJtC9Z.mjs";
8
- import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
9
- import { t as assert } from "../assert-DikXweDx.mjs";
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 {};