@fedify/fedify 2.4.0-dev.1490 → 2.4.0-dev.1504
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 +3 -4
- package/dist/{assert-OguE97r2.mjs → assert-DvVHoIZ0.mjs} +1 -1
- package/dist/{assert_instance_of-DBC5X09g.mjs → assert_instance_of-CxoC8bVq.mjs} +1 -1
- package/dist/{assert_not_equals-DkVK8oqV.mjs → assert_not_equals-C8vcTTA3.mjs} +1 -1
- package/dist/{assert_rejects-DN60FHPX.mjs → assert_rejects-DAdaaIWM.mjs} +2 -2
- package/dist/{assert_strict_equals-XEgZAlrj.mjs → assert_strict_equals-BzqyKuYL.mjs} +1 -1
- package/dist/{assert_throws-BOkhLGYc.mjs → assert_throws-zN79lgIC.mjs} +1 -1
- package/dist/{builder-CwwQRArg.mjs → builder-Ck0Fl_a5.mjs} +23 -3
- package/dist/codec-CmlPqjNX.mjs +103 -0
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/outgoing-jsonld.test.mjs +3 -3
- package/dist/compat/public-audience.test.mjs +3 -3
- package/dist/compat/transformers.test.mjs +5 -5
- package/dist/{context-DVoTs_wM.mjs → context-BBRTgkrs.mjs} +8 -2
- package/dist/{context-BU6jSQdo.d.ts → context-BF5B4ZDk.d.ts} +529 -259
- package/dist/{context-BBVLF7lx.d.cts → context-CYF8X0ft.d.cts} +530 -259
- package/dist/{deno-Yohf1ISx.mjs → deno-D3gb4X9v.mjs} +1 -1
- package/dist/{docloader-B6DFWEOx.mjs → docloader-DUKu0GzG.mjs} +3 -3
- package/dist/federation/builder.test.mjs +5 -5
- package/dist/federation/circuit-breaker.test.mjs +5 -5
- package/dist/federation/collection.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +13 -13
- package/dist/federation/idempotency.test.mjs +6 -6
- package/dist/federation/inbox.test.mjs +3 -3
- package/dist/federation/keycache.test.mjs +5 -5
- package/dist/federation/kv.test.mjs +3 -3
- package/dist/federation/metrics.test.mjs +4 -4
- package/dist/federation/middleware.test.mjs +200 -19
- package/dist/federation/mod.cjs +3 -259
- package/dist/federation/mod.d.cts +4 -4
- package/dist/federation/mod.d.ts +4 -4
- package/dist/federation/mod.js +1 -257
- package/dist/federation/mq.test.mjs +103 -261
- package/dist/federation/negotiation.test.mjs +4 -4
- package/dist/federation/retry.test.mjs +3 -3
- package/dist/federation/router.test.mjs +5 -5
- package/dist/federation/send.test.mjs +10 -10
- package/dist/federation/tasks/codec.test.d.mts +2 -0
- package/dist/federation/tasks/codec.test.mjs +292 -0
- package/dist/federation/tasks/enqueue.test.d.mts +2 -0
- package/dist/federation/tasks/enqueue.test.mjs +992 -0
- package/dist/federation/tasks/tasks.test.d.mts +2 -0
- package/dist/federation/tasks/tasks.test.mjs +555 -0
- package/dist/federation/temporal.test.mjs +4 -4
- package/dist/federation/webfinger.test.mjs +6 -6
- package/dist/{http-BeDlAH97.mjs → http-BNFQkiEZ.mjs} +4 -4
- package/dist/{http-BqSm-f2G.js → http-CrZzUAtV.js} +7 -17
- package/dist/{http-C3eJp_Ha.cjs → http-D9p2_d2X.cjs} +7 -17
- package/dist/{key-DNBTcjuV.mjs → key-BM_SRwBV.mjs} +8 -18
- package/dist/{kv-cache-b2HaCLC-.mjs → kv-cache-BE1QIPdL.mjs} +1 -1
- package/dist/{kv-cache-Crq8nvSV.js → kv-cache-Ch_Zv5Yq.js} +1 -1
- package/dist/{kv-cache-CGJMNSs-.cjs → kv-cache-Cna211RR.cjs} +1 -1
- package/dist/{ld-CQlFhsU6.mjs → ld-ubkf03eb.mjs} +3 -3
- package/dist/{metrics-B6RKtTLt.mjs → metrics-BXR36qzu.mjs} +1 -1
- package/dist/{middleware-CBM9vGYg.cjs → middleware-DUNeIkXN.cjs} +694 -51
- package/dist/{middleware-CsxoclmN.mjs → middleware-iP9VRMus.mjs} +310 -67
- package/dist/{middleware-B3vFLcCh.js → middleware-lB4vtShP.js} +683 -52
- package/dist/{middleware-CQygcRYE.mjs → middleware-pzCP79He.mjs} +1 -1
- package/dist/{mod-vPYVoa5n.d.ts → mod-4WGAuR6X.d.ts} +1 -1
- package/dist/{mod-C0F6kvgS.d.cts → mod-BHEB3xhE.d.cts} +1 -1
- package/dist/mod.cjs +6 -6
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +5 -5
- package/dist/mq-03vS-C9P.mjs +276 -0
- package/dist/{mq-D8uSFzxe.d.cts → mq-B5_hohs7.d.ts} +34 -0
- package/dist/{mq-D-nlpY04.d.ts → mq-DXMt_qCY.d.cts} +34 -0
- package/dist/nodeinfo/client.test.mjs +3 -3
- package/dist/nodeinfo/handler.test.mjs +5 -5
- package/dist/nodeinfo/types.test.mjs +4 -4
- package/dist/otel/exporter.test.mjs +3 -3
- package/dist/{outgoing-jsonld-L_DbOaFe.mjs → outgoing-jsonld-BNL8AC14.mjs} +1 -1
- package/dist/{owner-B1FnbZ1w.mjs → owner-Bf1KkncT.mjs} +2 -2
- package/dist/{proof-BhNTn0HE.js → proof-BMcsi8q_.js} +1 -1
- package/dist/{proof-BUuvq0ia.mjs → proof-Q781Ks5q.mjs} +5 -5
- package/dist/{proof-ChmZL5rY.cjs → proof-yeAU1MyT.cjs} +1 -1
- package/dist/{send-Dq-Ofquk.mjs → send-DFV0S_n9.mjs} +3 -3
- package/dist/sig/accept.test.mjs +1 -1
- package/dist/sig/http.test.mjs +8 -8
- package/dist/sig/key.test.mjs +6 -56
- package/dist/sig/ld.test.mjs +7 -7
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +6 -6
- package/dist/sig/proof.test.mjs +8 -8
- package/dist/{std__assert-BBjXFNOb.mjs → std__assert-Dh6uLf_q.mjs} +4 -4
- package/dist/{temporal-C-vrfOld.mjs → temporal-CyOjsqPj.mjs} +1 -1
- package/dist/testing/mod.d.mts +1037 -8
- package/dist/testing/mod.mjs +3 -2
- package/dist/testing-Dy-WhqpN.mjs +77 -0
- package/dist/utils/docloader.test.mjs +6 -6
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +12 -7
- /package/dist/{accept-CPkZzmGN.mjs → accept-CgDcxvjV.mjs} +0 -0
- /package/dist/{activity-listener-tztVvlNb.mjs → activity-listener-BeTGV3wc.mjs} +0 -0
- /package/dist/{assert_equals-C-ZRDbaf.mjs → assert_equals-PBVKNMJd.mjs} +0 -0
- /package/dist/{circuit-breaker-CSWsyoef.mjs → circuit-breaker-hJBB6jwA.mjs} +0 -0
- /package/dist/{client-ByXmQhYD.mjs → client-B_A6mfn3.mjs} +0 -0
- /package/dist/{collection-Cc3DVAhE.mjs → collection-Dp5ky45w.mjs} +0 -0
- /package/dist/{keycache-BeU0LCII.mjs → keycache-CaOR6NYg.mjs} +0 -0
- /package/dist/{keys-DGu1NFwu.mjs → keys-CSYsOMFG.mjs} +0 -0
- /package/dist/{kv-rV3vodCc.mjs → kv-CIvR3Non.mjs} +0 -0
- /package/dist/{negotiation-DDstyBvc.mjs → negotiation-m_L2nyS3.mjs} +0 -0
- /package/dist/{public-audience-Cvbr2Gzt.mjs → public-audience-c9zmYKgA.mjs} +0 -0
- /package/dist/{retry-CXg_MBI-.mjs → retry-DI4O-zYl.mjs} +0 -0
- /package/dist/{types-J53Kw7so.mjs → types-BFowWFTT.mjs} +0 -0
package/dist/testing/mod.d.mts
CHANGED
|
@@ -2,11 +2,12 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
3
|
import { ExportResultCode } from "@opentelemetry/core";
|
|
4
4
|
import { Router } from "@fedify/uri-template";
|
|
5
|
-
import { Activity, Actor, Collection, CryptographicKey, Hashtag, Link, LookupObjectOptions, Multikey, Object as Object$1, Recipient, Tombstone, TraverseCollectionOptions } from "@fedify/vocab";
|
|
5
|
+
import { Activity, Actor, Collection, CryptographicKey, Hashtag, Link, LookupObjectOptions, Multikey, Note, Object as Object$1, Recipient, Tombstone, TraverseCollectionOptions } from "@fedify/vocab";
|
|
6
6
|
import { Link as Link$1, LookupWebFingerOptions, ResourceDescriptor } from "@fedify/webfinger";
|
|
7
7
|
import { MeterProvider, TracerProvider } from "@opentelemetry/api";
|
|
8
|
-
import { DocumentLoader, GetUserAgentOptions } from "@fedify/vocab-runtime";
|
|
8
|
+
import { AuthenticatedDocumentLoaderFactory, DocumentLoader, DocumentLoaderFactory, GetUserAgentOptions } from "@fedify/vocab-runtime";
|
|
9
9
|
import { MeterProvider as MeterProvider$1, MetricReader } from "@opentelemetry/sdk-metrics";
|
|
10
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
10
11
|
|
|
11
12
|
//#region src/nodeinfo/types.d.ts
|
|
12
13
|
/**
|
|
@@ -202,7 +203,29 @@ interface GetKeyOwnerOptions {
|
|
|
202
203
|
tracerProvider?: TracerProvider;
|
|
203
204
|
}
|
|
204
205
|
//#endregion
|
|
206
|
+
//#region src/compat/types.d.ts
|
|
207
|
+
/**
|
|
208
|
+
* A function that transforms an activity object.
|
|
209
|
+
* @since 1.4.0
|
|
210
|
+
*/
|
|
211
|
+
type ActivityTransformer<TContextData> = (activity: Activity, context: Context<TContextData>) => Activity;
|
|
212
|
+
//#endregion
|
|
205
213
|
//#region src/sig/http.d.ts
|
|
214
|
+
/**
|
|
215
|
+
* The standard to use for signing and verifying HTTP signatures.
|
|
216
|
+
* @since 1.6.0
|
|
217
|
+
*/
|
|
218
|
+
type HttpMessageSignaturesSpec =
|
|
219
|
+
/**
|
|
220
|
+
* The Signing HTTP Messages (draft-cavage-http-signatures-12) specification,
|
|
221
|
+
* which is widely adopted and used in the fediverse (as of May 2025).
|
|
222
|
+
*/
|
|
223
|
+
"draft-cavage-http-signatures-12"
|
|
224
|
+
/**
|
|
225
|
+
* The HTTP Message Signatures (RFC 9421) specification, which is the
|
|
226
|
+
* finalized standard but not widely adopted yet (as of May 2025).
|
|
227
|
+
*/
|
|
228
|
+
| "rfc9421";
|
|
206
229
|
/**
|
|
207
230
|
* The reason why {@link verifyRequestDetailed} could not verify a request.
|
|
208
231
|
* @since 2.1.0
|
|
@@ -471,6 +494,15 @@ type SharedInboxKeyDispatcher<TContextData> = (context: Context<TContextData>) =
|
|
|
471
494
|
} | {
|
|
472
495
|
username: string;
|
|
473
496
|
} | null>;
|
|
497
|
+
/**
|
|
498
|
+
* A callback that handles errors during outbox processing.
|
|
499
|
+
*
|
|
500
|
+
* @param error The error that occurred.
|
|
501
|
+
* @param activity The activity that caused the error. If it is `null`, the
|
|
502
|
+
* error occurred during deserializing the activity.
|
|
503
|
+
* @since 0.6.0
|
|
504
|
+
*/
|
|
505
|
+
type OutboxErrorHandler = (error: Error, activity: Activity | null) => void | Promise<void>;
|
|
474
506
|
/**
|
|
475
507
|
* A callback that handles permanent delivery failures when sending activities
|
|
476
508
|
* to remote inboxes.
|
|
@@ -580,6 +612,472 @@ type CustomCollectionCounter<TParam extends string, TContextData> = (context: Re
|
|
|
580
612
|
*/
|
|
581
613
|
type CustomCollectionCursor<TParam extends string, TContext extends Context<TContextData>, TContextData> = (context: TContext, values: Record<TParam, string>) => string | null | Promise<string | null>;
|
|
582
614
|
//#endregion
|
|
615
|
+
//#region src/federation/kv.d.ts
|
|
616
|
+
/**
|
|
617
|
+
* A key for a key–value store. An array of one or more strings.
|
|
618
|
+
*
|
|
619
|
+
* @since 0.5.0
|
|
620
|
+
*/
|
|
621
|
+
type KvKey = readonly [string] | readonly [string, ...string[]];
|
|
622
|
+
/**
|
|
623
|
+
* Additional options for setting a value in a key–value store.
|
|
624
|
+
*
|
|
625
|
+
* @since 0.5.0
|
|
626
|
+
*/
|
|
627
|
+
interface KvStoreSetOptions {
|
|
628
|
+
/**
|
|
629
|
+
* The time-to-live (TTL) for the value.
|
|
630
|
+
*/
|
|
631
|
+
ttl?: Temporal.Duration;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* An entry returned by the {@link KvStore.list} method.
|
|
635
|
+
*
|
|
636
|
+
* @since 1.10.0
|
|
637
|
+
*/
|
|
638
|
+
interface KvStoreListEntry {
|
|
639
|
+
/**
|
|
640
|
+
* The key of the entry.
|
|
641
|
+
*/
|
|
642
|
+
readonly key: KvKey;
|
|
643
|
+
/**
|
|
644
|
+
* The value of the entry.
|
|
645
|
+
*/
|
|
646
|
+
readonly value: unknown;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* An abstract interface for a key–value store.
|
|
650
|
+
*
|
|
651
|
+
* @since 0.5.0
|
|
652
|
+
*/
|
|
653
|
+
interface KvStore {
|
|
654
|
+
/**
|
|
655
|
+
* Gets the value for the given key.
|
|
656
|
+
* @param key The key to get the value for.
|
|
657
|
+
* @returns The value for the key, or `undefined` if the key does not exist.
|
|
658
|
+
* @template T The type of the value to get.
|
|
659
|
+
*/
|
|
660
|
+
get<T = unknown>(key: KvKey): Promise<T | undefined>;
|
|
661
|
+
/**
|
|
662
|
+
* Sets the value for the given key.
|
|
663
|
+
* @param key The key to set the value for.
|
|
664
|
+
* @param value The value to set.
|
|
665
|
+
* @param options Additional options for setting the value.
|
|
666
|
+
*/
|
|
667
|
+
set(key: KvKey, value: unknown, options?: KvStoreSetOptions): Promise<void>;
|
|
668
|
+
/**
|
|
669
|
+
* Deletes the value for the given key.
|
|
670
|
+
* @param key The key to delete.
|
|
671
|
+
*/
|
|
672
|
+
delete(key: KvKey): Promise<void>;
|
|
673
|
+
/**
|
|
674
|
+
* Compare-and-swap (CAS) operation for the key–value store.
|
|
675
|
+
* @param key The key to perform the CAS operation on.
|
|
676
|
+
* @param expectedValue The expected value for the key.
|
|
677
|
+
* @param newValue The new value to set if the expected value matches.
|
|
678
|
+
* @param options Additional options for setting the value.
|
|
679
|
+
* @return `true` if the CAS operation was successful, `false` otherwise.
|
|
680
|
+
* @since 1.8.0
|
|
681
|
+
*/
|
|
682
|
+
cas?: (key: KvKey, expectedValue: unknown, newValue: unknown, options?: KvStoreSetOptions) => Promise<boolean>;
|
|
683
|
+
/**
|
|
684
|
+
* Lists all entries in the store that match the given prefix.
|
|
685
|
+
* If no prefix is given, all entries are returned.
|
|
686
|
+
* @param prefix The prefix to filter keys by. If not specified, all entries
|
|
687
|
+
* are returned.
|
|
688
|
+
* @returns An async iterable of entries matching the prefix.
|
|
689
|
+
* @since 1.10.0
|
|
690
|
+
* @since 2.0.0 This method is now required instead of optional.
|
|
691
|
+
*/
|
|
692
|
+
list(prefix?: KvKey): AsyncIterable<KvStoreListEntry>;
|
|
693
|
+
}
|
|
694
|
+
//#endregion
|
|
695
|
+
//#region src/federation/circuit-breaker.d.ts
|
|
696
|
+
/**
|
|
697
|
+
* The state of a remote host circuit breaker.
|
|
698
|
+
* @since 2.3.0
|
|
699
|
+
*/
|
|
700
|
+
type CircuitBreakerState = "closed" | "open" | "half-open";
|
|
701
|
+
/**
|
|
702
|
+
* Details passed to {@link CircuitBreakerOptions.onActivityDrop} when a held
|
|
703
|
+
* activity expires before the remote host recovers.
|
|
704
|
+
* @since 2.3.0
|
|
705
|
+
*/
|
|
706
|
+
interface CircuitBreakerActivityDrop {
|
|
707
|
+
/** The inbox URL that would have received the activity. */
|
|
708
|
+
readonly inbox: URL;
|
|
709
|
+
/** The activity that was dropped. */
|
|
710
|
+
readonly activity: Activity;
|
|
711
|
+
/** The activity ID, when known. */
|
|
712
|
+
readonly activityId?: string;
|
|
713
|
+
/** The activity type. */
|
|
714
|
+
readonly activityType: string;
|
|
715
|
+
/** The actor IDs represented by this inbox. */
|
|
716
|
+
readonly actorIds: readonly URL[];
|
|
717
|
+
/** The time when Fedify first held this activity. */
|
|
718
|
+
readonly heldSince: Temporal.Instant;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Configures how a remote host circuit opens after repeated delivery
|
|
722
|
+
* failures.
|
|
723
|
+
* @since 2.3.0
|
|
724
|
+
*/
|
|
725
|
+
type CircuitBreakerFailurePolicy = {
|
|
726
|
+
failure(timestamps: readonly Temporal.Instant[]): boolean;
|
|
727
|
+
readonly failureThreshold?: never;
|
|
728
|
+
readonly failureWindow?: never;
|
|
729
|
+
} | {
|
|
730
|
+
readonly failure?: never;
|
|
731
|
+
readonly failureThreshold?: number;
|
|
732
|
+
readonly failureWindow?: Temporal.Duration | Temporal.DurationLike;
|
|
733
|
+
};
|
|
734
|
+
/**
|
|
735
|
+
* Options for Fedify's outbound activity circuit breaker.
|
|
736
|
+
* @since 2.3.0
|
|
737
|
+
*/
|
|
738
|
+
type CircuitBreakerOptions = CircuitBreakerFailurePolicy & {
|
|
739
|
+
/**
|
|
740
|
+
* How long an open circuit waits before allowing a half-open recovery probe.
|
|
741
|
+
* @default `{ minutes: 30 }`
|
|
742
|
+
*/
|
|
743
|
+
readonly recoveryDelay?: Temporal.Duration | Temporal.DurationLike;
|
|
744
|
+
/**
|
|
745
|
+
* How long Fedify keeps requeueing activities held by an open circuit before
|
|
746
|
+
* dropping them.
|
|
747
|
+
* @default `{ days: 7 }`
|
|
748
|
+
*/
|
|
749
|
+
readonly heldActivityTtl?: Temporal.Duration | Temporal.DurationLike;
|
|
750
|
+
/**
|
|
751
|
+
* How often other held activities retry while a half-open probe is in
|
|
752
|
+
* flight. The probe is treated as stale after the recovery delay.
|
|
753
|
+
* @default `{ seconds: 1 }`
|
|
754
|
+
*/
|
|
755
|
+
readonly releaseInterval?: Temporal.Duration | Temporal.DurationLike;
|
|
756
|
+
/**
|
|
757
|
+
* Called whenever the circuit state changes.
|
|
758
|
+
*/
|
|
759
|
+
readonly onStateChange?: (remoteHost: string, previousState: CircuitBreakerState, newState: CircuitBreakerState) => void | Promise<void>;
|
|
760
|
+
/**
|
|
761
|
+
* Called when an activity held by the circuit breaker expires.
|
|
762
|
+
*/
|
|
763
|
+
readonly onActivityDrop?: (remoteHost: string, details: CircuitBreakerActivityDrop) => void | Promise<void>;
|
|
764
|
+
};
|
|
765
|
+
//#endregion
|
|
766
|
+
//#region src/federation/mq.d.ts
|
|
767
|
+
/**
|
|
768
|
+
* Additional options for enqueuing a message in a queue.
|
|
769
|
+
*
|
|
770
|
+
* @since 0.5.0
|
|
771
|
+
*/
|
|
772
|
+
interface MessageQueueEnqueueOptions {
|
|
773
|
+
/**
|
|
774
|
+
* The delay before the message is enqueued. No delay by default.
|
|
775
|
+
*
|
|
776
|
+
* It must not be negative.
|
|
777
|
+
*/
|
|
778
|
+
readonly delay?: Temporal.Duration;
|
|
779
|
+
/**
|
|
780
|
+
* An optional key that ensures messages with the same ordering key are
|
|
781
|
+
* processed sequentially (one at a time). Messages with different ordering
|
|
782
|
+
* keys (or no ordering key) may be processed in parallel.
|
|
783
|
+
*
|
|
784
|
+
* This is useful for ensuring that related messages are processed in order,
|
|
785
|
+
* such as ensuring that a `Delete` activity is processed after a `Create`
|
|
786
|
+
* activity for the same object.
|
|
787
|
+
*
|
|
788
|
+
* @since 2.0.0
|
|
789
|
+
*/
|
|
790
|
+
readonly orderingKey?: string;
|
|
791
|
+
/**
|
|
792
|
+
* An optional key requesting at-most-once enqueue semantics for messages
|
|
793
|
+
* that share it. A backend that declares
|
|
794
|
+
* {@link MessageQueue.nativeDeduplication} `true` owns the check: a message
|
|
795
|
+
* whose `deduplicationKey` was already seen within the backend's
|
|
796
|
+
* deduplication window is dropped instead of enqueued. Backends without
|
|
797
|
+
* native deduplication ignore this field; Fedify performs its own
|
|
798
|
+
* best-effort deduplication before reaching them on the paths that support
|
|
799
|
+
* it.
|
|
800
|
+
*
|
|
801
|
+
* @since 2.4.0
|
|
802
|
+
*/
|
|
803
|
+
readonly deduplicationKey?: string;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Additional options for listening to a message queue.
|
|
807
|
+
*
|
|
808
|
+
* @since 1.0.0
|
|
809
|
+
*/
|
|
810
|
+
interface MessageQueueListenOptions {
|
|
811
|
+
/**
|
|
812
|
+
* The signal to abort listening to the message queue.
|
|
813
|
+
*/
|
|
814
|
+
signal?: AbortSignal;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* The number of messages waiting in a message queue.
|
|
818
|
+
*
|
|
819
|
+
* @since 2.3.0
|
|
820
|
+
*/
|
|
821
|
+
interface MessageQueueDepth {
|
|
822
|
+
/**
|
|
823
|
+
* The total number of messages still waiting in the backend queue.
|
|
824
|
+
*
|
|
825
|
+
* This does not include messages that have already been handed to a worker
|
|
826
|
+
* for processing.
|
|
827
|
+
*/
|
|
828
|
+
readonly queued: number;
|
|
829
|
+
/**
|
|
830
|
+
* The number of queued messages eligible for immediate processing.
|
|
831
|
+
*
|
|
832
|
+
* Queue backends that cannot cheaply distinguish ready and delayed messages
|
|
833
|
+
* may omit this field.
|
|
834
|
+
*/
|
|
835
|
+
readonly ready?: number;
|
|
836
|
+
/**
|
|
837
|
+
* The number of queued messages scheduled for later delivery.
|
|
838
|
+
*
|
|
839
|
+
* Queue backends that cannot cheaply distinguish ready and delayed messages
|
|
840
|
+
* may omit this field.
|
|
841
|
+
*/
|
|
842
|
+
readonly delayed?: number;
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* An abstract interface for a message queue.
|
|
846
|
+
*
|
|
847
|
+
* @since 0.5.0
|
|
848
|
+
*/
|
|
849
|
+
interface MessageQueue {
|
|
850
|
+
/**
|
|
851
|
+
* Whether the message queue backend provides native retry mechanisms.
|
|
852
|
+
* When `true`, Fedify will skip its own retry logic and rely on the backend
|
|
853
|
+
* to handle retries. When `false` or omitted, Fedify will handle retries
|
|
854
|
+
* using its own retry policies.
|
|
855
|
+
*
|
|
856
|
+
* @default `false`
|
|
857
|
+
* @since 1.7.0
|
|
858
|
+
*/
|
|
859
|
+
readonly nativeRetrial?: boolean;
|
|
860
|
+
/**
|
|
861
|
+
* Whether the message queue backend deduplicates messages that share a
|
|
862
|
+
* {@link MessageQueueEnqueueOptions.deduplicationKey} natively. When `true`,
|
|
863
|
+
* Fedify forwards the `deduplicationKey` and relies on the backend to drop
|
|
864
|
+
* duplicates; when `false` or omitted, Fedify applies its own best-effort
|
|
865
|
+
* key–value deduplication on the paths that request it.
|
|
866
|
+
*
|
|
867
|
+
* @default `false`
|
|
868
|
+
* @since 2.4.0
|
|
869
|
+
*/
|
|
870
|
+
readonly nativeDeduplication?: boolean;
|
|
871
|
+
/**
|
|
872
|
+
* Enqueues a message in the queue.
|
|
873
|
+
* @param message The message to enqueue.
|
|
874
|
+
* @param options Additional options for enqueuing the message.
|
|
875
|
+
*/
|
|
876
|
+
enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
877
|
+
/**
|
|
878
|
+
* Enqueues multiple messages in the queue. This operation is optional,
|
|
879
|
+
* and may not be supported by all implementations. If not supported,
|
|
880
|
+
* Fedify will invoke {@link enqueue} for each message.
|
|
881
|
+
*
|
|
882
|
+
* @param messages The messages to enqueue.
|
|
883
|
+
* @param options Additional options for enqueuing the messages.
|
|
884
|
+
*/
|
|
885
|
+
enqueueMany?: (messages: readonly any[], options?: MessageQueueEnqueueOptions) => Promise<void>;
|
|
886
|
+
/**
|
|
887
|
+
* Listens for messages in the queue.
|
|
888
|
+
* @param handler The handler for messages in the queue.
|
|
889
|
+
* @param options Additional options for listening to the message queue.
|
|
890
|
+
* @returns A promise that resolves when the listening is done. It never
|
|
891
|
+
* rejects, and is resolved when the signal is aborted. If no
|
|
892
|
+
* signal is provided, it never resolves.
|
|
893
|
+
*/
|
|
894
|
+
listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
|
|
895
|
+
/**
|
|
896
|
+
* Gets the number of messages waiting in the queue.
|
|
897
|
+
*
|
|
898
|
+
* This operation is optional, and may not be supported by all
|
|
899
|
+
* implementations. The returned counts exclude messages currently being
|
|
900
|
+
* handled by a worker.
|
|
901
|
+
*
|
|
902
|
+
* @since 2.3.0
|
|
903
|
+
*/
|
|
904
|
+
getDepth?(): Promise<MessageQueueDepth>;
|
|
905
|
+
}
|
|
906
|
+
//#endregion
|
|
907
|
+
//#region src/federation/retry.d.ts
|
|
908
|
+
/**
|
|
909
|
+
* The context passed to a {@link RetryPolicy} callback.
|
|
910
|
+
* @since 0.12.0
|
|
911
|
+
*/
|
|
912
|
+
interface RetryContext {
|
|
913
|
+
/**
|
|
914
|
+
* The elapsed time since the first attempt.
|
|
915
|
+
*/
|
|
916
|
+
readonly elapsedTime: Temporal.Duration;
|
|
917
|
+
/**
|
|
918
|
+
* The number of attempts so far.
|
|
919
|
+
*/
|
|
920
|
+
readonly attempts: number;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* A policy that determines the delay before the next retry.
|
|
924
|
+
* @param context The retry context.
|
|
925
|
+
* @returns The delay before the next retry, or `null` to stop retrying.
|
|
926
|
+
* It must not negative.
|
|
927
|
+
* @since 0.12.0
|
|
928
|
+
*/
|
|
929
|
+
type RetryPolicy = (context: RetryContext) => Temporal.Duration | null;
|
|
930
|
+
//#endregion
|
|
931
|
+
//#region src/federation/tasks/task.d.ts
|
|
932
|
+
/**
|
|
933
|
+
* A callback that processes a custom background task.
|
|
934
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
935
|
+
* @template TData The type of the task payload, inferred from the task's
|
|
936
|
+
* schema.
|
|
937
|
+
* @param ctx The context for the worker processing the task.
|
|
938
|
+
* @param data The decoded and validated task payload.
|
|
939
|
+
* @since 2.4.0
|
|
940
|
+
*/
|
|
941
|
+
type TaskHandler<TContextData, TData> = (ctx: Context<TContextData>, data: TData) => Promise<void> | void;
|
|
942
|
+
/**
|
|
943
|
+
* Options for {@link TaskRegistry.defineTask}.
|
|
944
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
945
|
+
* @template TSchema The [Standard Schema](https://standardschema.dev/) that
|
|
946
|
+
* validates the task payload.
|
|
947
|
+
* @since 2.4.0
|
|
948
|
+
*/
|
|
949
|
+
interface TaskDefinitionOptions<TContextData, TSchema extends StandardSchemaV1> {
|
|
950
|
+
/**
|
|
951
|
+
* The [Standard Schema](https://standardschema.dev/) that validates the
|
|
952
|
+
* task payload. The payload type is inferred from this schema.
|
|
953
|
+
*
|
|
954
|
+
* The payload is validated twice: once at enqueue time (fail fast) and
|
|
955
|
+
* once at dequeue time (drift protection against payloads enqueued by an
|
|
956
|
+
* older deployment). Because the same schema runs on both sides, its
|
|
957
|
+
* validation must be idempotent: the validated output must itself be
|
|
958
|
+
* a valid input. Transforming schemas (e.g., Zod's `.transform()`) whose
|
|
959
|
+
* output differs in shape from their input are not supported.
|
|
960
|
+
*/
|
|
961
|
+
readonly schema: TSchema;
|
|
962
|
+
/**
|
|
963
|
+
* The callback that processes the task on a background worker.
|
|
964
|
+
*/
|
|
965
|
+
readonly handler: TaskHandler<TContextData, StandardSchemaV1.InferOutput<TSchema>>;
|
|
966
|
+
/**
|
|
967
|
+
* The retry policy for this task. If omitted, the federation-wide
|
|
968
|
+
* task retry policy is used, which defaults to an exponential backoff
|
|
969
|
+
* policy.
|
|
970
|
+
*/
|
|
971
|
+
readonly retryPolicy?: RetryPolicy;
|
|
972
|
+
/**
|
|
973
|
+
* A callback invoked when the {@link handler} throws an error, before
|
|
974
|
+
* a retry is scheduled.
|
|
975
|
+
* @param ctx The context for the worker processing the task.
|
|
976
|
+
* @param error The error thrown by the handler.
|
|
977
|
+
* @param data The decoded and validated task payload.
|
|
978
|
+
*/
|
|
979
|
+
readonly onError?: (ctx: Context<TContextData>, error: unknown, data: StandardSchemaV1.InferOutput<TSchema>) => Promise<void> | void;
|
|
980
|
+
/**
|
|
981
|
+
* The message queue dedicated to this task. If omitted, the task is
|
|
982
|
+
* routed to the federation-wide task queue, falling back to the outbox
|
|
983
|
+
* queue (unless `taskQueueResolution: "strict"` is configured).
|
|
984
|
+
*/
|
|
985
|
+
readonly queue?: MessageQueue;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Phantom key binding a {@link TaskDefinition} to its federation's context
|
|
989
|
+
* data type. Declared only—no value exists at runtime, and the symbol is
|
|
990
|
+
* not exported, so the marker stays out of user-facing completions.
|
|
991
|
+
*/
|
|
992
|
+
declare const contextDataBrand: unique symbol;
|
|
993
|
+
/**
|
|
994
|
+
* The handle returned by {@link TaskRegistry.defineTask}. It carries the
|
|
995
|
+
* task name and schema so that {@link Context.enqueueTask} can validate the
|
|
996
|
+
* payload and infer its type at every call site.
|
|
997
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
998
|
+
* @template TData The type of the task payload, inferred from the task's
|
|
999
|
+
* schema.
|
|
1000
|
+
* @since 2.4.0
|
|
1001
|
+
*/
|
|
1002
|
+
interface TaskDefinition<TContextData, TData> {
|
|
1003
|
+
/**
|
|
1004
|
+
* The unique name of the task.
|
|
1005
|
+
*/
|
|
1006
|
+
readonly name: string;
|
|
1007
|
+
/**
|
|
1008
|
+
* The [Standard Schema](https://standardschema.dev/) that validates the
|
|
1009
|
+
* task payload.
|
|
1010
|
+
*/
|
|
1011
|
+
readonly schema: StandardSchemaV1<unknown, TData>;
|
|
1012
|
+
/**
|
|
1013
|
+
* @internal Phantom marker binding the handle to its federation.
|
|
1014
|
+
*/
|
|
1015
|
+
readonly [contextDataBrand]?: TContextData;
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Registration of custom background tasks. Both {@link Federation} and
|
|
1019
|
+
* {@link FederationBuilder} implement this interface.
|
|
1020
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
1021
|
+
* @since 2.4.0
|
|
1022
|
+
*/
|
|
1023
|
+
interface TaskRegistry<TContextData> {
|
|
1024
|
+
/**
|
|
1025
|
+
* Defines a custom background task. The returned handle is passed to
|
|
1026
|
+
* {@link Context.enqueueTask} to enqueue the task.
|
|
1027
|
+
*
|
|
1028
|
+
* @example
|
|
1029
|
+
* ``` typescript
|
|
1030
|
+
* const sendDigest = federation.defineTask("sendDigest", {
|
|
1031
|
+
* schema: digestSchema,
|
|
1032
|
+
* handler: async (ctx, data) => {
|
|
1033
|
+
* // …process the payload on a background worker…
|
|
1034
|
+
* },
|
|
1035
|
+
* });
|
|
1036
|
+
* ```
|
|
1037
|
+
*
|
|
1038
|
+
* @param name The unique name of the task.
|
|
1039
|
+
* @param options The task definition options. The payload type is
|
|
1040
|
+
* inferred from `options.schema`.
|
|
1041
|
+
* @returns The handle to pass to {@link Context.enqueueTask}.
|
|
1042
|
+
* @throws {TypeError} If a task with the same name is already defined.
|
|
1043
|
+
*/
|
|
1044
|
+
defineTask<TSchema extends StandardSchemaV1>(name: string, options: TaskDefinitionOptions<TContextData, TSchema>): TaskDefinition<TContextData, StandardSchemaV1.InferOutput<TSchema>>;
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Options for {@link Context.enqueueTask} and {@link Context.enqueueTaskMany}.
|
|
1048
|
+
* @since 2.4.0
|
|
1049
|
+
*/
|
|
1050
|
+
interface TaskEnqueueOptions {
|
|
1051
|
+
/**
|
|
1052
|
+
* The delay before the task is processed. No delay by default.
|
|
1053
|
+
*/
|
|
1054
|
+
readonly delay?: Temporal.DurationLike;
|
|
1055
|
+
/**
|
|
1056
|
+
* An optional key that ensures tasks with the same ordering key are
|
|
1057
|
+
* processed sequentially (one at a time).
|
|
1058
|
+
*/
|
|
1059
|
+
readonly orderingKey?: string;
|
|
1060
|
+
/**
|
|
1061
|
+
* An optional key requesting at-most-once enqueue for tasks that share it.
|
|
1062
|
+
*
|
|
1063
|
+
* A queue with {@link MessageQueue.nativeDeduplication} `true` enforces it
|
|
1064
|
+
* strictly; otherwise deduplication is best-effort via {@link KvStore.cas},
|
|
1065
|
+
* and {@link FederationOptions.taskDeduplicationFallback} decides whether a
|
|
1066
|
+
* missing `cas` proceeds without deduplication or throws.
|
|
1067
|
+
*
|
|
1068
|
+
* For {@link Context.enqueueTaskMany}, one key governs the whole batch. When
|
|
1069
|
+
* deduplication is actually applied—a native queue, or the key–value
|
|
1070
|
+
* fallback through {@link KvStore.cas}—a multi-item batch with a
|
|
1071
|
+
* `deduplicationKey` requires the queue to implement
|
|
1072
|
+
* {@link MessageQueue.enqueueMany} so it enqueues atomically, or the call
|
|
1073
|
+
* throws a `TypeError`. Under the `"open"` fallback with no `cas`, no marker
|
|
1074
|
+
* is taken, so such a batch instead fans out without deduplication.
|
|
1075
|
+
*
|
|
1076
|
+
* @since 2.4.0
|
|
1077
|
+
*/
|
|
1078
|
+
readonly deduplicationKey?: string;
|
|
1079
|
+
}
|
|
1080
|
+
//#endregion
|
|
583
1081
|
//#region src/federation/queue.d.ts
|
|
584
1082
|
interface SenderKeyJwkPair {
|
|
585
1083
|
readonly keyId: string;
|
|
@@ -594,7 +1092,7 @@ interface SenderKeyJwkPair {
|
|
|
594
1092
|
* type.
|
|
595
1093
|
* @since 1.6.0
|
|
596
1094
|
*/
|
|
597
|
-
type Message = FanoutMessage | OutboxMessage | InboxMessage;
|
|
1095
|
+
type Message = FanoutMessage | OutboxMessage | InboxMessage | TaskMessage;
|
|
598
1096
|
interface FanoutMessage {
|
|
599
1097
|
readonly type: "fanout";
|
|
600
1098
|
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
@@ -648,6 +1146,24 @@ interface OutboxMessage {
|
|
|
648
1146
|
readonly circuitHeldSince?: string;
|
|
649
1147
|
readonly traceContext: Readonly<Record<string, string>>;
|
|
650
1148
|
}
|
|
1149
|
+
/**
|
|
1150
|
+
* A message that carries a custom background task. Every field is
|
|
1151
|
+
* a string, number, or plain record so that the message survives both
|
|
1152
|
+
* JSON serialization and structured clone on every queue backend.
|
|
1153
|
+
* @since 2.4.0
|
|
1154
|
+
*/
|
|
1155
|
+
interface TaskMessage {
|
|
1156
|
+
readonly type: "task";
|
|
1157
|
+
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1158
|
+
readonly baseUrl: string;
|
|
1159
|
+
readonly taskName: string;
|
|
1160
|
+
/** devalue-encoded task data; vocab objects bridged to expanded JSON-LD. */
|
|
1161
|
+
readonly data: string;
|
|
1162
|
+
readonly started: string;
|
|
1163
|
+
readonly attempt: number;
|
|
1164
|
+
readonly orderingKey?: string;
|
|
1165
|
+
readonly traceContext: Readonly<Record<string, string>>;
|
|
1166
|
+
}
|
|
651
1167
|
interface InboxMessage {
|
|
652
1168
|
readonly type: "inbox";
|
|
653
1169
|
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
@@ -695,6 +1211,107 @@ interface InboxMessage {
|
|
|
695
1211
|
readonly traceContext: Readonly<Record<string, string>>;
|
|
696
1212
|
}
|
|
697
1213
|
//#endregion
|
|
1214
|
+
//#region src/federation/middleware.d.ts
|
|
1215
|
+
/**
|
|
1216
|
+
* Configures the task queues for sending and receiving activities.
|
|
1217
|
+
* @since 1.3.0
|
|
1218
|
+
*/
|
|
1219
|
+
interface FederationQueueOptions {
|
|
1220
|
+
/**
|
|
1221
|
+
* The message queue for incoming activities. If not provided, incoming
|
|
1222
|
+
* activities will not be queued and will be processed immediately.
|
|
1223
|
+
*/
|
|
1224
|
+
readonly inbox?: MessageQueue;
|
|
1225
|
+
/**
|
|
1226
|
+
* The message queue for outgoing activities. If not provided, outgoing
|
|
1227
|
+
* activities will not be queued and will be sent immediately.
|
|
1228
|
+
*/
|
|
1229
|
+
readonly outbox?: MessageQueue;
|
|
1230
|
+
/**
|
|
1231
|
+
* The message queue for fanning out outgoing activities. If not provided,
|
|
1232
|
+
* outgoing activities will not be fanned out in the background, but will be
|
|
1233
|
+
* fanned out immediately, which causes slow response times on
|
|
1234
|
+
* {@link Context.sendActivity} calls.
|
|
1235
|
+
*/
|
|
1236
|
+
readonly fanout?: MessageQueue;
|
|
1237
|
+
/**
|
|
1238
|
+
* The message queue for custom background tasks. If not provided,
|
|
1239
|
+
* tasks are routed to the outbox queue (unless
|
|
1240
|
+
* {@link FederationOptions.taskQueueResolution} is `"strict"`).
|
|
1241
|
+
* @since 2.4.0
|
|
1242
|
+
*/
|
|
1243
|
+
readonly task?: MessageQueue;
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Prefixes for namespacing keys in the Deno KV store.
|
|
1247
|
+
*/
|
|
1248
|
+
interface FederationKvPrefixes {
|
|
1249
|
+
/**
|
|
1250
|
+
* The key prefix used for storing whether activities have already been
|
|
1251
|
+
* processed or not.
|
|
1252
|
+
* @default `["_fedify", "activityIdempotence"]`
|
|
1253
|
+
*/
|
|
1254
|
+
readonly activityIdempotence: KvKey;
|
|
1255
|
+
/**
|
|
1256
|
+
* The key prefix used for storing remote JSON-LD documents.
|
|
1257
|
+
* @default `["_fedify", "remoteDocument"]`
|
|
1258
|
+
*/
|
|
1259
|
+
readonly remoteDocument: KvKey;
|
|
1260
|
+
/**
|
|
1261
|
+
* The key prefix used for caching public keys.
|
|
1262
|
+
* @default `["_fedify", "publicKey"]`
|
|
1263
|
+
* @since 0.12.0
|
|
1264
|
+
*/
|
|
1265
|
+
readonly publicKey: KvKey;
|
|
1266
|
+
/**
|
|
1267
|
+
* The key prefix used for caching HTTP Message Signatures specs.
|
|
1268
|
+
* The cached spec is used to reduce the number of requests to make signed
|
|
1269
|
+
* requests ("double-knocking" technique).
|
|
1270
|
+
* @default `["_fedify", "httpMessageSignaturesSpec"]`
|
|
1271
|
+
* @since 1.6.0
|
|
1272
|
+
*/
|
|
1273
|
+
readonly httpMessageSignaturesSpec: KvKey;
|
|
1274
|
+
/**
|
|
1275
|
+
* The key prefix used for storing `Accept-Signature` challenge nonces.
|
|
1276
|
+
* Only used when {@link InboxChallengePolicy.requestNonce} is `true`.
|
|
1277
|
+
* @default `["_fedify", "acceptSignatureNonce"]`
|
|
1278
|
+
* @since 2.1.0
|
|
1279
|
+
*/
|
|
1280
|
+
readonly acceptSignatureNonce: KvKey;
|
|
1281
|
+
/**
|
|
1282
|
+
* The key prefix used for storing outbound delivery circuit breaker state.
|
|
1283
|
+
* @default `["_fedify", "circuit"]`
|
|
1284
|
+
* @since 2.3.0
|
|
1285
|
+
*/
|
|
1286
|
+
readonly circuitBreaker: KvKey;
|
|
1287
|
+
/**
|
|
1288
|
+
* The key prefix used for storing custom background task deduplication
|
|
1289
|
+
* markers. Kept separate from {@link activityIdempotence} so the two key
|
|
1290
|
+
* spaces never collide.
|
|
1291
|
+
* @default `["_fedify", "taskDeduplication"]`
|
|
1292
|
+
* @since 2.4.0
|
|
1293
|
+
*/
|
|
1294
|
+
readonly taskDeduplication: KvKey;
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Options for {@link FederationOptions.origin} when it is not a string.
|
|
1298
|
+
* @since 1.5.0
|
|
1299
|
+
*/
|
|
1300
|
+
interface FederationOrigin {
|
|
1301
|
+
/**
|
|
1302
|
+
* The canonical hostname for fediverse handles (which are looked up through
|
|
1303
|
+
* WebFinger). This is used for WebFinger lookups. It has to be a valid
|
|
1304
|
+
* hostname, e.g., `"example.com"`.
|
|
1305
|
+
*/
|
|
1306
|
+
handleHost: string;
|
|
1307
|
+
/**
|
|
1308
|
+
* The canonical origin for web URLs. This is used for constructing absolute
|
|
1309
|
+
* URLs. It has to start with either `"http://"` or `"https://"`, and must
|
|
1310
|
+
* not contain a path or query string, e.g., `"https://example.com"`.
|
|
1311
|
+
*/
|
|
1312
|
+
webOrigin: string;
|
|
1313
|
+
}
|
|
1314
|
+
//#endregion
|
|
698
1315
|
//#region src/federation/federation.d.ts
|
|
699
1316
|
/**
|
|
700
1317
|
* Options for {@link Federation.startQueue} method.
|
|
@@ -707,18 +1324,18 @@ interface FederationStartQueueOptions {
|
|
|
707
1324
|
signal?: AbortSignal;
|
|
708
1325
|
/**
|
|
709
1326
|
* Starts the task worker only for the specified queue. If unspecified,
|
|
710
|
-
* which is the default, the task worker starts for all
|
|
711
|
-
* inbox, outbox, and
|
|
1327
|
+
* which is the default, the task worker starts for all four queues:
|
|
1328
|
+
* inbox, outbox, fanout, and task.
|
|
712
1329
|
* @since 1.3.0
|
|
713
1330
|
*/
|
|
714
|
-
queue?: "inbox" | "outbox" | "fanout";
|
|
1331
|
+
queue?: "inbox" | "outbox" | "fanout" | "task";
|
|
715
1332
|
}
|
|
716
1333
|
/**
|
|
717
1334
|
* A common interface between {@link Federation} and {@link FederationBuilder}.
|
|
718
1335
|
* @template TContextData The context data to pass to the {@link Context}.
|
|
719
1336
|
* @since 1.6.0
|
|
720
1337
|
*/
|
|
721
|
-
interface Federatable<TContextData> {
|
|
1338
|
+
interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
722
1339
|
/**
|
|
723
1340
|
* Registers a NodeInfo dispatcher.
|
|
724
1341
|
* @param path The URI path pattern for the NodeInfo dispatcher. The syntax
|
|
@@ -1164,6 +1781,321 @@ interface Federation<TContextData> extends Federatable<TContextData> {
|
|
|
1164
1781
|
*/
|
|
1165
1782
|
fetch(request: Request, options: FederationFetchOptions<TContextData>): Promise<Response>;
|
|
1166
1783
|
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Policy for emitting `Accept-Signature` challenges on inbox `401`
|
|
1786
|
+
* responses, as defined in
|
|
1787
|
+
* [RFC 9421 §5](https://www.rfc-editor.org/rfc/rfc9421#section-5).
|
|
1788
|
+
* @since 2.1.0
|
|
1789
|
+
*/
|
|
1790
|
+
interface InboxChallengePolicy {
|
|
1791
|
+
/**
|
|
1792
|
+
* Whether to emit `Accept-Signature` headers on `401` responses
|
|
1793
|
+
* caused by HTTP Signature verification failures.
|
|
1794
|
+
*/
|
|
1795
|
+
enabled: boolean;
|
|
1796
|
+
/**
|
|
1797
|
+
* The covered component identifiers to request. Only request-applicable
|
|
1798
|
+
* identifiers should be used (`@status` is automatically excluded).
|
|
1799
|
+
* @default `["@method", "@target-uri", "@authority", "content-digest"]`
|
|
1800
|
+
*/
|
|
1801
|
+
components?: string[];
|
|
1802
|
+
/**
|
|
1803
|
+
* Whether to generate and require a one-time nonce for replay protection.
|
|
1804
|
+
* When enabled, a cryptographically random nonce is included in each
|
|
1805
|
+
* challenge and verified on subsequent requests. Requires a
|
|
1806
|
+
* {@link KvStore}.
|
|
1807
|
+
* @default `false`
|
|
1808
|
+
*/
|
|
1809
|
+
requestNonce?: boolean;
|
|
1810
|
+
/**
|
|
1811
|
+
* The time-to-live (in seconds) for stored nonces. After this period,
|
|
1812
|
+
* nonces expire and are no longer accepted.
|
|
1813
|
+
* @default `300` (5 minutes)
|
|
1814
|
+
*/
|
|
1815
|
+
nonceTtlSeconds?: number;
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* Options for cooperative benchmark mode.
|
|
1819
|
+
* @since 2.3.0
|
|
1820
|
+
*/
|
|
1821
|
+
interface FederationBenchmarkOptions {
|
|
1822
|
+
/**
|
|
1823
|
+
* Server-controlled inbox URLs that the benchmark trigger endpoint may
|
|
1824
|
+
* deliver to.
|
|
1825
|
+
*/
|
|
1826
|
+
triggerSinks?: readonly (string | URL)[];
|
|
1827
|
+
/**
|
|
1828
|
+
* Whether the benchmark trigger endpoint may deliver to recipients outside
|
|
1829
|
+
* {@link FederationBenchmarkOptions.triggerSinks}.
|
|
1830
|
+
*
|
|
1831
|
+
* Do not enable this option unless the benchmark endpoint is only reachable
|
|
1832
|
+
* by a trusted benchmark controller.
|
|
1833
|
+
*/
|
|
1834
|
+
allowUnsafeTriggerRecipients?: boolean;
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Options for creating a {@link Federation} object.
|
|
1838
|
+
* @template TContextData The context data to pass to the {@link Context}.
|
|
1839
|
+
* @since 1.6.0
|
|
1840
|
+
*/
|
|
1841
|
+
interface FederationOptions<TContextData> {
|
|
1842
|
+
/**
|
|
1843
|
+
* The key–value store used for caching, outbox queues, and inbox idempotence.
|
|
1844
|
+
*/
|
|
1845
|
+
kv: KvStore;
|
|
1846
|
+
/**
|
|
1847
|
+
* Prefixes for namespacing keys in the Deno KV store. By default, all keys
|
|
1848
|
+
* are prefixed with `["_fedify"]`.
|
|
1849
|
+
*/
|
|
1850
|
+
kvPrefixes?: Partial<FederationKvPrefixes>;
|
|
1851
|
+
/**
|
|
1852
|
+
* The message queue for sending and receiving activities. If not provided,
|
|
1853
|
+
* activities will not be queued and will be processed immediately.
|
|
1854
|
+
*
|
|
1855
|
+
* If a `MessageQueue` is provided, both the `inbox` and `outbox` queues
|
|
1856
|
+
* will be set to the same queue.
|
|
1857
|
+
*
|
|
1858
|
+
* If a `FederationQueueOptions` object is provided, you can set the queues
|
|
1859
|
+
* separately (since Fedify 1.3.0).
|
|
1860
|
+
*/
|
|
1861
|
+
queue?: FederationQueueOptions | MessageQueue;
|
|
1862
|
+
/**
|
|
1863
|
+
* Whether to start the task queue manually or automatically.
|
|
1864
|
+
*
|
|
1865
|
+
* If `true`, the task queue will not start automatically and you need to
|
|
1866
|
+
* manually start it by calling the {@link Federation.startQueue} method.
|
|
1867
|
+
*
|
|
1868
|
+
* If `false`, the task queue will start automatically as soon as
|
|
1869
|
+
* the first task is enqueued.
|
|
1870
|
+
*
|
|
1871
|
+
* By default, the queue starts automatically.
|
|
1872
|
+
*
|
|
1873
|
+
* @since 0.12.0
|
|
1874
|
+
*/
|
|
1875
|
+
manuallyStartQueue?: boolean;
|
|
1876
|
+
/**
|
|
1877
|
+
* The canonical base URL of the server. This is used for constructing
|
|
1878
|
+
* absolute URLs and fediverse handles.
|
|
1879
|
+
* @since 1.5.0
|
|
1880
|
+
*/
|
|
1881
|
+
origin?: string | FederationOrigin;
|
|
1882
|
+
/**
|
|
1883
|
+
* A custom JSON-LD document loader factory. By default, this uses
|
|
1884
|
+
* the built-in cache-backed loader that fetches remote documents over
|
|
1885
|
+
* HTTP(S).
|
|
1886
|
+
* @since 1.4.0
|
|
1887
|
+
*/
|
|
1888
|
+
documentLoaderFactory?: DocumentLoaderFactory;
|
|
1889
|
+
/**
|
|
1890
|
+
* A custom JSON-LD context loader factory. By default, this uses the same
|
|
1891
|
+
* loader as the document loader.
|
|
1892
|
+
* @since 1.4.0
|
|
1893
|
+
*/
|
|
1894
|
+
contextLoaderFactory?: DocumentLoaderFactory;
|
|
1895
|
+
/**
|
|
1896
|
+
* A factory function that creates an authenticated document loader for a
|
|
1897
|
+
* given identity. This is used for fetching documents that require
|
|
1898
|
+
* authentication.
|
|
1899
|
+
*/
|
|
1900
|
+
authenticatedDocumentLoaderFactory?: AuthenticatedDocumentLoaderFactory;
|
|
1901
|
+
/**
|
|
1902
|
+
* Whether to allow fetching private network addresses in the document loader.
|
|
1903
|
+
*
|
|
1904
|
+
* If turned on, {@link FederationOptions.documentLoader},
|
|
1905
|
+
* {@link FederationOptions.contextLoader}, and
|
|
1906
|
+
* {@link FederationOptions.authenticatedDocumentLoaderFactory}
|
|
1907
|
+
* cannot be configured.
|
|
1908
|
+
*
|
|
1909
|
+
* Mostly useful for testing purposes. *Do not use in production.*
|
|
1910
|
+
*
|
|
1911
|
+
* Turned off by default.
|
|
1912
|
+
* @since 0.15.0
|
|
1913
|
+
*/
|
|
1914
|
+
allowPrivateAddress?: boolean;
|
|
1915
|
+
/**
|
|
1916
|
+
* Whether to enable cooperative benchmark mode. This mode exposes
|
|
1917
|
+
* benchmark-only endpoints and relaxes selected defaults for benchmark
|
|
1918
|
+
* targets. Pass an object to configure benchmark trigger delivery.
|
|
1919
|
+
* Do not enable this option in production.
|
|
1920
|
+
*
|
|
1921
|
+
* When enabled, {@link FederationOptions.allowPrivateAddress} defaults to
|
|
1922
|
+
* `true` unless {@link FederationOptions.documentLoaderFactory} or
|
|
1923
|
+
* {@link FederationOptions.contextLoaderFactory} is configured, and
|
|
1924
|
+
* {@link FederationOptions.signatureTimeWindow} defaults to `false`.
|
|
1925
|
+
*
|
|
1926
|
+
* Turned off by default.
|
|
1927
|
+
* @since 2.3.0
|
|
1928
|
+
*/
|
|
1929
|
+
benchmarkMode?: boolean | FederationBenchmarkOptions;
|
|
1930
|
+
/**
|
|
1931
|
+
* Options for making `User-Agent` strings for HTTP requests.
|
|
1932
|
+
* If a string is provided, it is used as the `User-Agent` header.
|
|
1933
|
+
* If an object is provided, it is passed to the {@link getUserAgent}
|
|
1934
|
+
* function.
|
|
1935
|
+
* @since 1.3.0
|
|
1936
|
+
*/
|
|
1937
|
+
userAgent?: GetUserAgentOptions | string;
|
|
1938
|
+
/**
|
|
1939
|
+
* A callback that handles errors during outbox processing. Note that this
|
|
1940
|
+
* callback can be called multiple times for the same activity, because
|
|
1941
|
+
* the delivery is retried according to the backoff schedule until it
|
|
1942
|
+
* succeeds or reaches the maximum retry count.
|
|
1943
|
+
*
|
|
1944
|
+
* If any errors are thrown in this callback, they are ignored.
|
|
1945
|
+
*/
|
|
1946
|
+
onOutboxError?: OutboxErrorHandler;
|
|
1947
|
+
/**
|
|
1948
|
+
* HTTP status codes that should be treated as permanent delivery failures.
|
|
1949
|
+
* When an inbox returns one of these codes, the delivery will not be retried
|
|
1950
|
+
* and the permanent failure handler (if registered via
|
|
1951
|
+
* {@link Federatable.setOutboxPermanentFailureHandler}) will be called.
|
|
1952
|
+
*
|
|
1953
|
+
* By default, `[404, 410]`.
|
|
1954
|
+
*
|
|
1955
|
+
* @since 2.0.0
|
|
1956
|
+
*/
|
|
1957
|
+
permanentFailureStatusCodes?: readonly number[];
|
|
1958
|
+
/**
|
|
1959
|
+
* The time window for verifying HTTP Signatures of incoming requests. If the
|
|
1960
|
+
* request is older or newer than this window, it is rejected. Or if it is
|
|
1961
|
+
* `false`, the request's timestamp is not checked at all.
|
|
1962
|
+
*
|
|
1963
|
+
* By default, the window is an hour.
|
|
1964
|
+
*/
|
|
1965
|
+
signatureTimeWindow?: Temporal.Duration | Temporal.DurationLike | false;
|
|
1966
|
+
/**
|
|
1967
|
+
* Whether to skip HTTP Signatures verification for incoming activities.
|
|
1968
|
+
* This is useful for testing purposes, but should not be used in production.
|
|
1969
|
+
*
|
|
1970
|
+
* By default, this is `false` (i.e., signatures are verified).
|
|
1971
|
+
* @since 0.13.0
|
|
1972
|
+
*/
|
|
1973
|
+
skipSignatureVerification?: boolean;
|
|
1974
|
+
/**
|
|
1975
|
+
* The HTTP Signatures specification to use for the first signature
|
|
1976
|
+
* attempt when communicating with unknown servers. This option affects
|
|
1977
|
+
* the "double-knocking" mechanism as described in the ActivityPub HTTP
|
|
1978
|
+
* Signature documentation.
|
|
1979
|
+
*
|
|
1980
|
+
* When making HTTP requests to servers that haven't been encountered before,
|
|
1981
|
+
* Fedify will first attempt to sign the request using the specified
|
|
1982
|
+
* signature specification. If the request fails, it will retry with the
|
|
1983
|
+
* alternative specification.
|
|
1984
|
+
*
|
|
1985
|
+
* Defaults to `"rfc9421"` (HTTP Message Signatures).
|
|
1986
|
+
*
|
|
1987
|
+
* @see {@link https://swicg.github.io/activitypub-http-signature/#how-to-upgrade-supported-versions}
|
|
1988
|
+
* @default `"rfc9421"`
|
|
1989
|
+
* @since 1.7.0
|
|
1990
|
+
*/
|
|
1991
|
+
firstKnock?: HttpMessageSignaturesSpec;
|
|
1992
|
+
/**
|
|
1993
|
+
* The policy for emitting `Accept-Signature` challenges on inbox `401`
|
|
1994
|
+
* responses (RFC 9421 §5). When enabled, failed HTTP Signature
|
|
1995
|
+
* verification responses will include an `Accept-Signature` header
|
|
1996
|
+
* telling the sender which components and parameters to include.
|
|
1997
|
+
*
|
|
1998
|
+
* Disabled by default (no `Accept-Signature` header is emitted).
|
|
1999
|
+
* @since 2.1.0
|
|
2000
|
+
*/
|
|
2001
|
+
inboxChallengePolicy?: InboxChallengePolicy;
|
|
2002
|
+
/**
|
|
2003
|
+
* The retry policy for sending activities to recipients' inboxes.
|
|
2004
|
+
* By default, this uses an exponential backoff strategy with a maximum of
|
|
2005
|
+
* 10 attempts and a maximum delay of 12 hours.
|
|
2006
|
+
* @since 0.12.0
|
|
2007
|
+
*/
|
|
2008
|
+
outboxRetryPolicy?: RetryPolicy;
|
|
2009
|
+
/**
|
|
2010
|
+
* The circuit breaker for queued outbound activity delivery. When enabled,
|
|
2011
|
+
* Fedify tracks repeated failures per remote host and temporarily holds
|
|
2012
|
+
* queued activities instead of repeatedly hammering an unreachable server.
|
|
2013
|
+
*
|
|
2014
|
+
* Passing `false` disables the circuit breaker.
|
|
2015
|
+
*
|
|
2016
|
+
* @since 2.3.0
|
|
2017
|
+
*/
|
|
2018
|
+
circuitBreaker?: false | CircuitBreakerOptions;
|
|
2019
|
+
/**
|
|
2020
|
+
* The retry policy for processing incoming activities. By default, this
|
|
2021
|
+
* uses an exponential backoff strategy with a maximum of 10 attempts and a
|
|
2022
|
+
* maximum delay of 12 hours.
|
|
2023
|
+
* @since 0.12.0
|
|
2024
|
+
*/
|
|
2025
|
+
inboxRetryPolicy?: RetryPolicy;
|
|
2026
|
+
/**
|
|
2027
|
+
* The retry policy for processing custom background tasks. By default,
|
|
2028
|
+
* this uses an exponential backoff strategy with a maximum of 10 attempts
|
|
2029
|
+
* and a maximum delay of 12 hours. A per-task retry policy
|
|
2030
|
+
* ({@link TaskDefinitionOptions.retryPolicy}) overrides this.
|
|
2031
|
+
* @since 2.4.0
|
|
2032
|
+
*/
|
|
2033
|
+
taskRetryPolicy?: RetryPolicy;
|
|
2034
|
+
/**
|
|
2035
|
+
* How a queue is resolved for a custom background task when neither
|
|
2036
|
+
* a per-task queue ({@link TaskDefinitionOptions.queue}) nor a dedicated
|
|
2037
|
+
* task queue ({@link FederationQueueOptions.task}) is configured.
|
|
2038
|
+
*
|
|
2039
|
+
* - `"fallback"` (the default): the task is routed to the outbox queue.
|
|
2040
|
+
* - `"strict"`: no fallback; enqueuing the task throws instead of
|
|
2041
|
+
* silently sharing the outbox queue.
|
|
2042
|
+
* @default `"fallback"`
|
|
2043
|
+
* @since 2.4.0
|
|
2044
|
+
*/
|
|
2045
|
+
taskQueueResolution?: "fallback" | "strict";
|
|
2046
|
+
/**
|
|
2047
|
+
* The time-to-live for a {@link TaskEnqueueOptions.deduplicationKey} marker
|
|
2048
|
+
* stored in the key–value deduplication fallback. A second enqueue with the
|
|
2049
|
+
* same key within this window is skipped; once it expires, the key may
|
|
2050
|
+
* enqueue again. Ignored when the task's queue declares
|
|
2051
|
+
* {@link MessageQueue.nativeDeduplication} (the backend owns the window).
|
|
2052
|
+
* @default `{ hours: 1 }`
|
|
2053
|
+
* @since 2.4.0
|
|
2054
|
+
*/
|
|
2055
|
+
taskDeduplicationTtl?: Temporal.DurationLike;
|
|
2056
|
+
/**
|
|
2057
|
+
* The behavior when a {@link TaskEnqueueOptions.deduplicationKey} is supplied
|
|
2058
|
+
* but the task's queue does not declare
|
|
2059
|
+
* {@link MessageQueue.nativeDeduplication} *and* the configured
|
|
2060
|
+
* {@link KvStore} exposes no `cas` (compare-and-swap) primitive:
|
|
2061
|
+
*
|
|
2062
|
+
* - `"open"` (the default): proceeds without deduplication after logging at
|
|
2063
|
+
* debug level.
|
|
2064
|
+
* - `"closed"`: rejects with a `TypeError` before enqueuing.
|
|
2065
|
+
*
|
|
2066
|
+
* @default `"open"`
|
|
2067
|
+
* @since 2.4.0
|
|
2068
|
+
*/
|
|
2069
|
+
taskDeduplicationFallback?: "open" | "closed";
|
|
2070
|
+
/**
|
|
2071
|
+
* Activity transformers that are applied to outgoing activities. It is
|
|
2072
|
+
* useful for adjusting outgoing activities to satisfy some ActivityPub
|
|
2073
|
+
* implementations.
|
|
2074
|
+
*
|
|
2075
|
+
* By default, {@link defaultActivityTransformers} are applied.
|
|
2076
|
+
* @since 1.4.0
|
|
2077
|
+
*/
|
|
2078
|
+
activityTransformers?: readonly ActivityTransformer<TContextData>[];
|
|
2079
|
+
/**
|
|
2080
|
+
* Whether the router should be insensitive to trailing slashes in the URL
|
|
2081
|
+
* paths. For example, if this option is `true`, `/foo` and `/foo/` are
|
|
2082
|
+
* treated as the same path. Turned off by default.
|
|
2083
|
+
* @since 0.12.0
|
|
2084
|
+
*/
|
|
2085
|
+
trailingSlashInsensitive?: boolean;
|
|
2086
|
+
/**
|
|
2087
|
+
* The OpenTelemetry tracer provider for tracing operations. If not provided,
|
|
2088
|
+
* the default global tracer provider is used.
|
|
2089
|
+
* @since 1.3.0
|
|
2090
|
+
*/
|
|
2091
|
+
tracerProvider?: TracerProvider;
|
|
2092
|
+
/**
|
|
2093
|
+
* The OpenTelemetry meter provider for recording metrics. If not provided,
|
|
2094
|
+
* the default global meter provider is used.
|
|
2095
|
+
* @since 2.3.0
|
|
2096
|
+
*/
|
|
2097
|
+
meterProvider?: MeterProvider;
|
|
2098
|
+
}
|
|
1167
2099
|
/**
|
|
1168
2100
|
* Additional settings for the actor dispatcher.
|
|
1169
2101
|
*
|
|
@@ -1887,6 +2819,48 @@ interface Context<TContextData> {
|
|
|
1887
2819
|
* @since 1.3.0
|
|
1888
2820
|
*/
|
|
1889
2821
|
routeActivity(recipient: string | null, activity: Activity, options?: RouteActivityOptions): Promise<boolean>;
|
|
2822
|
+
/**
|
|
2823
|
+
* Enqueues a custom background task. The payload is validated against
|
|
2824
|
+
* the task's schema, serialized, and processed by the task's handler on
|
|
2825
|
+
* a background worker.
|
|
2826
|
+
*
|
|
2827
|
+
* @example
|
|
2828
|
+
* ``` typescript
|
|
2829
|
+
* await ctx.enqueueTask(sendDigest, { userId: "alice" });
|
|
2830
|
+
* ```
|
|
2831
|
+
*
|
|
2832
|
+
* @template TData The type of the task payload, inferred from the task's
|
|
2833
|
+
* schema.
|
|
2834
|
+
* @param task The handle returned by {@link TaskRegistry.defineTask}.
|
|
2835
|
+
* @param data The task payload. It is validated against the task's
|
|
2836
|
+
* schema before being enqueued.
|
|
2837
|
+
* @param options Options for enqueuing the task.
|
|
2838
|
+
* @throws {TypeError} If the task is not defined on this federation,
|
|
2839
|
+
* if no message queue is configured for tasks, or if
|
|
2840
|
+
* the payload fails schema validation.
|
|
2841
|
+
* @since 2.4.0
|
|
2842
|
+
*/
|
|
2843
|
+
enqueueTask<TData>(task: TaskDefinition<TContextData, TData>, data: TData, options?: TaskEnqueueOptions): Promise<void>;
|
|
2844
|
+
/**
|
|
2845
|
+
* Enqueues multiple payloads for a custom background task at once.
|
|
2846
|
+
* Uses the queue's bulk enqueue operation when available. Without
|
|
2847
|
+
* deduplication, it may fall back to parallel single enqueues when the
|
|
2848
|
+
* queue does not implement bulk enqueue.
|
|
2849
|
+
* @template TData The type of the task payload, inferred from the task's
|
|
2850
|
+
* schema.
|
|
2851
|
+
* @param task The handle returned by {@link TaskRegistry.defineTask}.
|
|
2852
|
+
* @param payloads The task payloads. Each is validated against the
|
|
2853
|
+
* task's schema before being enqueued.
|
|
2854
|
+
* @param options Options for enqueuing the tasks.
|
|
2855
|
+
* @throws {TypeError} If the task is not defined on this federation,
|
|
2856
|
+
* if no message queue is configured for tasks, if
|
|
2857
|
+
* a payload fails schema validation, or if a
|
|
2858
|
+
* deduplicated multi-item batch cannot be enqueued
|
|
2859
|
+
* atomically because the queue does not implement
|
|
2860
|
+
* bulk enqueue.
|
|
2861
|
+
* @since 2.4.0
|
|
2862
|
+
*/
|
|
2863
|
+
enqueueTaskMany<TData>(task: TaskDefinition<TContextData, TData>, payloads: readonly TData[], options?: TaskEnqueueOptions): Promise<void>;
|
|
1890
2864
|
/**
|
|
1891
2865
|
* Builds the URI of a collection of objects with the given name and values.
|
|
1892
2866
|
* @param name The name of the collection, which can be a string or a symbol.
|
|
@@ -2470,9 +3444,64 @@ declare function createOutboxContext<TContextData>(args: Partial<OutboxContext<T
|
|
|
2470
3444
|
federation: Federation<TContextData>;
|
|
2471
3445
|
}): OutboxContext<TContextData>;
|
|
2472
3446
|
//#endregion
|
|
3447
|
+
//#region src/testing/tasks.d.ts
|
|
3448
|
+
/** Federation options (sans `queue`) shared by the task suites. */
|
|
3449
|
+
declare const baseOptions: Omit<FederationOptions<void>, "queue">;
|
|
3450
|
+
/**
|
|
3451
|
+
* Builds a minimal [Standard Schema](https://standardschema.dev/) from a type
|
|
3452
|
+
* guard, for use as a task payload schema in tests.
|
|
3453
|
+
*/
|
|
3454
|
+
declare const makeSchema: <T>(check: (data: unknown) => data is T) => StandardSchemaV1<unknown, T>;
|
|
3455
|
+
declare const stringSchema: StandardSchemaV1<unknown, string>;
|
|
3456
|
+
declare const numberSchema: StandardSchemaV1<unknown, number>;
|
|
3457
|
+
/** A task payload that carries a vocabulary object, to exercise the codec's
|
|
3458
|
+
* vocab-to-JSON-LD bridging. */
|
|
3459
|
+
interface Envelope {
|
|
3460
|
+
note: Note;
|
|
3461
|
+
title: string;
|
|
3462
|
+
}
|
|
3463
|
+
declare const envelopeSchema: StandardSchemaV1<unknown, Envelope>;
|
|
3464
|
+
/**
|
|
3465
|
+
* Options for the {@link MockQueue} constructor.
|
|
3466
|
+
*/
|
|
3467
|
+
interface MockQueueOptions {
|
|
3468
|
+
/** Sets {@link MessageQueue.nativeRetrial}. Defaults to `false`. */
|
|
3469
|
+
readonly nativeRetrial?: boolean;
|
|
3470
|
+
/** Sets {@link MessageQueue.nativeDeduplication}. Defaults to `false`. */
|
|
3471
|
+
readonly nativeDeduplication?: boolean;
|
|
3472
|
+
/**
|
|
3473
|
+
* When `true`, the queue exposes {@link MockQueue.enqueueMany} and records
|
|
3474
|
+
* bulk enqueues; when omitted, the method is absent so callers exercise the
|
|
3475
|
+
* per-message fan-out path.
|
|
3476
|
+
*/
|
|
3477
|
+
readonly supportsEnqueueMany?: boolean;
|
|
3478
|
+
}
|
|
3479
|
+
/**
|
|
3480
|
+
* An in-memory {@link MessageQueue} that records task enqueues for assertions
|
|
3481
|
+
* instead of delivering anything. Its {@link listen} resolves only when the
|
|
3482
|
+
* abort signal fires.
|
|
3483
|
+
*/
|
|
3484
|
+
declare class MockQueue implements MessageQueue {
|
|
3485
|
+
readonly nativeRetrial: boolean;
|
|
3486
|
+
readonly nativeDeduplication: boolean;
|
|
3487
|
+
readonly enqueued: {
|
|
3488
|
+
message: TaskMessage;
|
|
3489
|
+
options?: MessageQueueEnqueueOptions;
|
|
3490
|
+
}[];
|
|
3491
|
+
readonly enqueuedMany: {
|
|
3492
|
+
messages: readonly TaskMessage[];
|
|
3493
|
+
options?: MessageQueueEnqueueOptions;
|
|
3494
|
+
}[];
|
|
3495
|
+
listenCount: number;
|
|
3496
|
+
enqueueMany?: (messages: readonly TaskMessage[], options?: MessageQueueEnqueueOptions) => Promise<void>;
|
|
3497
|
+
constructor(options?: MockQueueOptions);
|
|
3498
|
+
enqueue(message: TaskMessage, options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
3499
|
+
listen(_handler: (message: TaskMessage) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
|
|
3500
|
+
}
|
|
3501
|
+
//#endregion
|
|
2473
3502
|
//#region ../fixture/dist/mod.d.ts
|
|
2474
3503
|
//#endregion
|
|
2475
3504
|
//#region src/test.d.ts
|
|
2476
3505
|
declare const testDefinitions: Deno.TestDefinition[];
|
|
2477
3506
|
//#endregion
|
|
2478
|
-
export { createInboxContext, createOutboxContext, createRequestContext, testDefinitions };
|
|
3507
|
+
export { type Envelope, MockQueue, type MockQueueOptions, baseOptions, createInboxContext, createOutboxContext, createRequestContext, envelopeSchema, makeSchema, numberSchema, stringSchema, testDefinitions };
|