@fedify/fedify 2.5.0-dev.2609 → 2.5.0-dev.2614
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{builder-BLCvt0zp.mjs → builder-B2H8GsyI.mjs} +82 -3
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-DNhLvscb.mjs → compound-proof-BavXW-ow.mjs} +2 -2
- package/dist/{context-ByflxsY9.d.cts → context-C1NqcIct.d.cts} +1061 -443
- package/dist/{context-uQUY5fQT.d.ts → context-xrqq4Hrq.d.ts} +1064 -446
- package/dist/{deno-DYkYmKp0.mjs → deno-CRXki9-m.mjs} +1 -1
- package/dist/{docloader-B9RO5nh9.mjs → docloader-Ca6i6ddp.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +4 -4
- package/dist/federation/hashlink-media.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox-actorless.test.mjs +5 -5
- package/dist/federation/inbox-report.test.mjs +220 -5
- package/dist/federation/inbox-view.test.mjs +1 -1
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +7 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +4 -4
- package/dist/federation/mod.js +1 -1
- package/dist/federation/mq.test.mjs +1 -1
- package/dist/federation/outbound-body.test.d.mts +2 -0
- package/dist/federation/outbound-body.test.mjs +149 -0
- package/dist/federation/outbound-capture.test.d.mts +2 -0
- package/dist/federation/outbound-capture.test.mjs +394 -0
- package/dist/federation/outbound-dispatch.test.d.mts +2 -0
- package/dist/federation/outbound-dispatch.test.mjs +368 -0
- package/dist/federation/outbound-document.test.d.mts +2 -0
- package/dist/federation/outbound-document.test.mjs +171 -0
- package/dist/federation/outbound-provenance.test.d.mts +2 -0
- package/dist/federation/outbound-provenance.test.mjs +543 -0
- package/dist/federation/outbound-report.test.d.mts +2 -0
- package/dist/federation/outbound-report.test.mjs +5475 -0
- package/dist/federation/outbound-workers.test.d.mts +2 -0
- package/dist/federation/outbound-workers.test.mjs +64 -0
- package/dist/federation/outbound-workflow.test.d.mts +2 -0
- package/dist/federation/outbound-workflow.test.mjs +154 -0
- package/dist/federation/outgoing-proof.test.mjs +4 -4
- package/dist/federation/portable-actor.test.mjs +3 -3
- package/dist/federation/portable-chain.test.mjs +3 -3
- package/dist/federation/portable-collection.test.mjs +4 -4
- package/dist/federation/portable-delivery.test.mjs +106 -7
- package/dist/federation/portable-gateway-keys.test.mjs +5 -5
- package/dist/federation/portable-inbox.test.mjs +430 -5
- package/dist/federation/portable-parse-uri.test.mjs +1 -1
- package/dist/federation/portable-route-activity.test.mjs +2 -2
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/send.test.mjs +44 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-DzMdu4zU.cjs → federation-DRl81KbJ.cjs} +2358 -405
- package/dist/{http-EoFzzh1s.js → http-C2H4DT6t.js} +62 -32
- package/dist/{http-BdTJujR0.cjs → http-DHSIMipE.cjs} +62 -32
- package/dist/{http-TgeyuTDM.mjs → http-DqOXkYbX.mjs} +64 -34
- package/dist/{inbox-ChkbRxCN.mjs → inbox-C4iW1g0F.mjs} +90 -3
- package/dist/{inbox-view-BosBZdlt.mjs → inbox-view-Bu_aSwFJ.mjs} +1 -1
- package/dist/{key-DbLNT-vA.d.ts → key-dwwAg5bA.d.ts} +1 -1
- package/dist/{kv-cache-CMgOYiLU.js → kv-cache-B-x_OrBo.js} +1 -1
- package/dist/{kv-cache-B0o18_Ni.cjs → kv-cache-CHR_BVyM.cjs} +1 -1
- package/dist/{kv-cache-CTA2i08a.mjs → kv-cache-DJsxu9nI.mjs} +1 -1
- package/dist/{ld-CZsMAfOw.mjs → ld-C5JOBBFj.mjs} +2 -2
- package/dist/{ld-Inagww4R.d.ts → ld-o4LnhCYY.d.ts} +2 -2
- package/dist/{metrics-Kc9mP1LD.mjs → metrics-CTteRnEr.mjs} +1 -1
- package/dist/{metrics-DoRtI0qU.d.ts → metrics-DVKYY6K1.d.ts} +1 -1
- package/dist/{middleware-B-pjIvQ8.js → middleware-B-tMVSUA.js} +2303 -351
- package/dist/{middleware-CIRoIVSU.mjs → middleware-BkRqMGPU.mjs} +1573 -325
- package/dist/{middleware-C1coPz8l.mjs → middleware-CPigKLnt.mjs} +1 -1
- package/dist/{mod-B7j30IQf.d.ts → mod-CQC9xlLZ.d.ts} +3 -3
- package/dist/{mod-B4kBw1-8.d.ts → mod-D22ZsiKi.d.ts} +2 -2
- package/dist/{mod-BN0TTfyQ.d.ts → mod-DO0epJGH.d.ts} +1 -1
- package/dist/{mod-DF2gbN_d.d.cts → mod-TwiQgEf3.d.cts} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +4 -4
- package/dist/mod.d.ts +8 -8
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/outbound-body-CckPA5gc.mjs +83 -0
- package/dist/outbound-capture-DVgnRzlf.mjs +184 -0
- package/dist/outbound-document-BMgwLXTY.mjs +179 -0
- package/dist/{owner-Dwz4fGUW.mjs → owner-CKlRIkeF.mjs} +3 -3
- package/dist/{portable-collection-Oxfavx8f.mjs → portable-collection-B7RBHVGl.mjs} +2 -2
- package/dist/{portable-collection-BikiijSk.js → portable-collection-CByyPjLc.js} +2 -2
- package/dist/{portable-collection-Ci6vIhbR.cjs → portable-collection-CmLjeKsP.cjs} +2 -2
- package/dist/{portable-key--fWpTNDN.mjs → portable-key-Clg0IH8C.mjs} +1 -1
- package/dist/{proof-D6Kb0Qq9.mjs → proof-tAb5_Dq4.mjs} +3 -3
- package/dist/{send-BFti0L3I.mjs → send-DzfFREML.mjs} +153 -40
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +38 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +1 -1
- package/dist/sig/mitra-receive-interop.test.mjs +4 -4
- package/dist/sig/mitra-send-interop.test.mjs +3 -3
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.ts +3 -3
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.mjs +1 -1
- package/dist/sig/portable-interop.test.mjs +3 -3
- package/dist/sig/portable-key.test.mjs +5 -5
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/sig/tootik-request-interop.test.mjs +4 -4
- package/dist/sig/tootik-send-interop.test.mjs +3 -3
- package/dist/sig/verification.test.mjs +3 -3
- package/dist/{temporal-DlYL_raW.mjs → temporal-D9Nt8Fm4.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +1030 -412
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +7 -7
- package/skills/fedify/SKILL.md +60 -1
|
@@ -9,6 +9,536 @@ import { Link as Link$1, LookupWebFingerOptions, ResourceDescriptor } from "@fed
|
|
|
9
9
|
import { MeterProvider, Span, Tracer, TracerProvider } from "@opentelemetry/api";
|
|
10
10
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
11
11
|
|
|
12
|
+
//#region src/federation/outbound-report.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* The current producer's preparation result, not delivery completion.
|
|
15
|
+
* @since 2.5.0
|
|
16
|
+
*/
|
|
17
|
+
type OutboundPreparationResult = {
|
|
18
|
+
/** The producer finished preparing its continuation. */readonly type: "prepared"; /** Fanout-ready work still needs worker-side delivery preparation. */
|
|
19
|
+
readonly preparedFor: "fanout" | "delivery"; /** Number of deduplicated destinations, not actors or successful sends. */
|
|
20
|
+
readonly destinationCount: number;
|
|
21
|
+
} | {
|
|
22
|
+
/** A deliberate no-send decision. */readonly type: "skipped"; /** The existing no-send decision made by this producer. */
|
|
23
|
+
readonly reason: "no-destinations" | "unsigned" | "forwarding-disabled" | "forwarding-unavailable" | "no-forwarding-targets";
|
|
24
|
+
} | {
|
|
25
|
+
/** Preparation failed before the producer reached readiness. */readonly type: "failed"; /** The operation that failed and its original thrown value. */
|
|
26
|
+
readonly failure: {
|
|
27
|
+
/** Local processing failure, or unavailable operation provenance. */readonly kind: "local" | "unknown"; /** The observed operation, not a diagnosis from the error message. */
|
|
28
|
+
readonly phase: "sender-resolution" | "key-resolution" | "recipient-resolution" | "transformation" | "validation" | "signing" | "destination-planning" | "serialization" | "request-preparation" | "unknown"; /** Original thrown value, including non-Error values. */
|
|
29
|
+
readonly error: unknown;
|
|
30
|
+
}; /** Whether a complete destination plan was established before failure. */
|
|
31
|
+
readonly planning: "not-started" | "incomplete" | "complete"; /** Confirmed planned obligations so far, not an audience estimate. */
|
|
32
|
+
readonly plannedDestinationCount: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Known Activity ID and type at a broadcast observation boundary.
|
|
36
|
+
*
|
|
37
|
+
* Fields are captured without serializing the Activity or loading contexts.
|
|
38
|
+
* Successful transformation refreshes both the ID and the Activity class type.
|
|
39
|
+
* A `started` event may have an empty reference, and later events may reflect
|
|
40
|
+
* Activity transformations that happened after that event.
|
|
41
|
+
* @since 2.5.0
|
|
42
|
+
*/
|
|
43
|
+
type OutboundActivityReference = {
|
|
44
|
+
/** Activity identifier, when available at the observation boundary. */readonly id?: string; /** Activity class type IRI, when available at the observation boundary. */
|
|
45
|
+
readonly type?: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A send, original-payload forwarding, or portable replication producer lifecycle.
|
|
49
|
+
*
|
|
50
|
+
* Preparation results do not report queue acceptance or delivery completion.
|
|
51
|
+
* @since 2.5.0
|
|
52
|
+
*/
|
|
53
|
+
type OutboundBroadcastEvent = OutboundSourceMetadata & {
|
|
54
|
+
/** Fresh opaque identity shared by producer events, independent of tracing. */readonly broadcastId: string; /** The outgoing operation being observed. */
|
|
55
|
+
readonly operation: "send" | "forward" | "portable-replication"; /** Immutable Activity identity facts captured by the send path. */
|
|
56
|
+
readonly activity: OutboundActivityReference;
|
|
57
|
+
} & ({
|
|
58
|
+
/** Entry before sender/recipient resolution or signing. */readonly stage: "started";
|
|
59
|
+
} | {
|
|
60
|
+
/** The current producer's preparation settled. */readonly stage: "preparation-finished"; /** Readiness, a deliberate skip, or the original preparation failure. */
|
|
61
|
+
readonly result: OutboundPreparationResult;
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* A producer-side destination obligation, not delivery completion.
|
|
65
|
+
*
|
|
66
|
+
* IDs group producer handoffs and their fanout expansion across queue tasks.
|
|
67
|
+
* Concrete sends use separate {@link OutboundAttemptReport} values; these
|
|
68
|
+
* events do not establish delivery completion or worker scheduling outcomes.
|
|
69
|
+
* An unvisited destination stays planned when another destination's preparation
|
|
70
|
+
* interrupts the producer.
|
|
71
|
+
* @since 2.5.0
|
|
72
|
+
*/
|
|
73
|
+
type OutboundDeliveryEvent = OutboundSourceMetadata & {
|
|
74
|
+
/** The originating invocation, or unknown for legacy fanout work. */readonly broadcast: {
|
|
75
|
+
readonly type: "known";
|
|
76
|
+
readonly id: string;
|
|
77
|
+
} | {
|
|
78
|
+
readonly type: "unknown";
|
|
79
|
+
}; /** Opaque identity allocated after deduplication or a confirmed claim. */
|
|
80
|
+
readonly deliveryId: string; /** Planned destination, unchanged by concrete gateway selection. */
|
|
81
|
+
readonly destinationInbox: string; /** Canonical portable inbox when the selected route represents one. */
|
|
82
|
+
readonly portableInbox?: string;
|
|
83
|
+
} & ({
|
|
84
|
+
/** This destination was established by the existing plan. */readonly stage: "planned"; /** Known actors sharing the destination, not an exhaustive audience. */
|
|
85
|
+
readonly actorIds: readonly string[]; /** Whether the selected destination uses a shared inbox. */
|
|
86
|
+
readonly sharedInbox: boolean; /** Fallback routes share one obligation; replication targets do not. */
|
|
87
|
+
readonly mode: "ordinary" | "portable-fallback" | "portable-replication";
|
|
88
|
+
} | {
|
|
89
|
+
/** Local execution entry or enqueue settlement, not remote success. */readonly stage: "handoff"; /** Evidence from the actual producer handoff. */
|
|
90
|
+
readonly result: {
|
|
91
|
+
readonly type: "direct";
|
|
92
|
+
} | {
|
|
93
|
+
readonly type: "enqueued";
|
|
94
|
+
readonly queue: "fanout" | "outbox";
|
|
95
|
+
readonly queueMessageId: string;
|
|
96
|
+
} | {
|
|
97
|
+
readonly type: "enqueue-failed";
|
|
98
|
+
readonly acceptance: "unknown";
|
|
99
|
+
readonly error: unknown;
|
|
100
|
+
};
|
|
101
|
+
} | {
|
|
102
|
+
/** Destination-local setup failed before entry into concrete sending. */readonly stage: "preparation-failed"; /** The original local setup failure, without inventing an attempt. */
|
|
103
|
+
readonly failure: {
|
|
104
|
+
readonly kind: "local";
|
|
105
|
+
readonly phase: "request-preparation";
|
|
106
|
+
readonly error: unknown;
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
/**
|
|
110
|
+
* The failure classification and available error evidence for a send attempt.
|
|
111
|
+
* @since 2.5.0
|
|
112
|
+
*/
|
|
113
|
+
type OutboundAttemptFailure = {
|
|
114
|
+
readonly kind: "http";
|
|
115
|
+
readonly phase: "response";
|
|
116
|
+
readonly error?: unknown;
|
|
117
|
+
} | {
|
|
118
|
+
readonly kind: "transport";
|
|
119
|
+
readonly phase: "validation" | "request";
|
|
120
|
+
readonly error: unknown;
|
|
121
|
+
} | {
|
|
122
|
+
readonly kind: "policy";
|
|
123
|
+
readonly phase: "validation";
|
|
124
|
+
readonly error: unknown;
|
|
125
|
+
} | {
|
|
126
|
+
readonly kind: "local";
|
|
127
|
+
readonly phase: "serialization" | "request-preparation" | "cleanup" | "signing" | "spec-lookup" | "post-response";
|
|
128
|
+
readonly error: unknown;
|
|
129
|
+
} | {
|
|
130
|
+
readonly kind: "unknown";
|
|
131
|
+
readonly phase: "unknown";
|
|
132
|
+
readonly error: unknown;
|
|
133
|
+
};
|
|
134
|
+
/** Immutable JSON data in a privacy projection. @since 2.5.0 */
|
|
135
|
+
type OutboundJsonValue = null | boolean | number | string | readonly OutboundJsonValue[] | {
|
|
136
|
+
readonly [key: string]: OutboundJsonValue;
|
|
137
|
+
};
|
|
138
|
+
/** Attempt input evidence, never proof of a particular exchange's wire body. @since 2.5.0 */
|
|
139
|
+
type OutboundSenderPayload = {
|
|
140
|
+
/** Concrete sender input, not a producer history or per-exchange wire body. */readonly stage: "sender-payload";
|
|
141
|
+
} & ({
|
|
142
|
+
/** A safe independent projection was established without extra processing. */readonly type: "available"; /** Always a projection; no signature/proof or exact-wire claim is retained. */
|
|
143
|
+
readonly representation: "privacy-projection"; /** At least one blind-recipient field was removed from the copied value. */
|
|
144
|
+
readonly redacted: boolean; /** Recursively immutable JSON data; transport/signing input is unchanged. */
|
|
145
|
+
readonly value: OutboundJsonValue;
|
|
146
|
+
} | {
|
|
147
|
+
/** No document value is exposed, including when export is disabled. */readonly type: "unavailable"; /** Opt-out, pre-snapshot failure, or unsupported privacy/context semantics. */
|
|
148
|
+
readonly reason: "disabled" | "not-materialized" | "privacy-filter-unavailable";
|
|
149
|
+
});
|
|
150
|
+
/** Result of an enabled response-body capture. Absence means disabled. @since 2.5.0 */
|
|
151
|
+
type OutboundBodyCaptureSummary = {
|
|
152
|
+
/** Bytes handed to the application, not bytes durably stored. */readonly bytesExposed: number;
|
|
153
|
+
} & ({
|
|
154
|
+
/** Selection, verified EOF, byte-cap uncertainty, or local lifetime end. */readonly type: "filtered" | "no-body" | "complete" | "limit-reached" | "deadline" | "callback-returned";
|
|
155
|
+
} | {
|
|
156
|
+
/** Application cancellation ended capture. */readonly type: "consumer-stopped"; /** Original consumer reason, including non-Error values. */
|
|
157
|
+
readonly reason: unknown;
|
|
158
|
+
} | {
|
|
159
|
+
/** Capture failed without changing received HTTP evidence. */readonly type: "failed"; /** Source reading versus application callback failure. */
|
|
160
|
+
readonly phase: "body" | "observer"; /** Original capture error; it does not become the attempt's failure. */
|
|
161
|
+
readonly error: unknown;
|
|
162
|
+
});
|
|
163
|
+
/** Bounded, revocable access to one selected response. @since 2.5.0 */
|
|
164
|
+
type OutboundResponseBodyEvent = Omit<OutboundHttpExchangeReport, "outcome" | "bodyCapture"> & {
|
|
165
|
+
/** Immutable response metadata, independently of eventual attempt outcome. */readonly response: Extract<OutboundHttpExchangeReport["outcome"], {
|
|
166
|
+
type: "response";
|
|
167
|
+
}>["response"]; /** Pull-driven bytes; access ends when the callback settles or its limits apply. */
|
|
168
|
+
readonly body: ReadableStream<Uint8Array>; /** Capture-only lifetime signal; aborting it does not cancel transport. */
|
|
169
|
+
readonly signal: AbortSignal;
|
|
170
|
+
};
|
|
171
|
+
/** Explicit opt-in response-body capture limits and consumer. @since 2.5.0 */
|
|
172
|
+
interface OutboundResponseBodyCapture<TContextData> {
|
|
173
|
+
/** Positive safe-integer exposure limit; exact cap without EOF stays uncertain. */
|
|
174
|
+
readonly maxBytes: number;
|
|
175
|
+
/** Positive finite absolute lifetime in milliseconds, rounded up; at most 2^31-1. */
|
|
176
|
+
readonly timeoutMs: number;
|
|
177
|
+
/** Actual response selector, defaulting to `all` only when enabled. */
|
|
178
|
+
readonly responses?: "all" | "non-success-http-responses";
|
|
179
|
+
/**
|
|
180
|
+
* Invoked after headers, before the terminal exchange report, with current data.
|
|
181
|
+
* Awaited within the absolute lifetime, including no-pull/slow-consumer time.
|
|
182
|
+
* Return/throw/cancel/cap/deadline revokes access even for retained locked readers.
|
|
183
|
+
* Errors cannot veto transport; ignoring the signal cannot be forcibly stopped.
|
|
184
|
+
*/
|
|
185
|
+
readonly onBody: (context: Context<TContextData>, event: OutboundResponseBodyEvent) => void | Promise<void>;
|
|
186
|
+
}
|
|
187
|
+
/** Opt-in policy for one side of an actual HTTP exchange. @since 2.5.0 */
|
|
188
|
+
interface OutboundHeaderPolicy {
|
|
189
|
+
/** Literal HTTP names, normalized to lowercase and deduplicated at registration. */
|
|
190
|
+
readonly allow: readonly string[];
|
|
191
|
+
/**
|
|
192
|
+
* Additional names whose selected values are always `[redacted]`.
|
|
193
|
+
* Credentials, signatures and cookies remain protected even without this list.
|
|
194
|
+
*/
|
|
195
|
+
readonly redact?: readonly string[];
|
|
196
|
+
/**
|
|
197
|
+
* Positive safe-integer UTF-8 budget for `name: value\r\n` after redaction.
|
|
198
|
+
* Whole oversized entries are omitted; later entries remain eligible.
|
|
199
|
+
*/
|
|
200
|
+
readonly maxBytes: number;
|
|
201
|
+
}
|
|
202
|
+
/** Immutable selected header values, using the runtime representation. @since 2.5.0 */
|
|
203
|
+
interface OutboundHeaderSnapshot {
|
|
204
|
+
/** Lowercase names in lexical order; credentials/signatures/cookies are redacted. */
|
|
205
|
+
readonly entries: readonly (readonly [string, string])[];
|
|
206
|
+
/** At least one selected entry was omitted because it exceeded the budget. */
|
|
207
|
+
readonly limitReached: boolean;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Immutable HTTP response facts captured from a received response.
|
|
211
|
+
* @since 2.5.0
|
|
212
|
+
*/
|
|
213
|
+
interface OutboundHttpResponseMetadata {
|
|
214
|
+
/** Actual HTTP status returned by fetch. */
|
|
215
|
+
readonly status: number;
|
|
216
|
+
/** Copied HTTP status text. */
|
|
217
|
+
readonly statusText: string;
|
|
218
|
+
/** Response URL when supplied by fetch. */
|
|
219
|
+
readonly url?: string;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Response evidence and finality established during a send attempt.
|
|
223
|
+
* @since 2.5.0
|
|
224
|
+
*/
|
|
225
|
+
type OutboundAttemptResponse = {
|
|
226
|
+
/** The HTTP flow selected this response before follow-up work. */readonly type: "final"; /** Actual submission index of the selected response. */
|
|
227
|
+
readonly exchangeIndex: number; /** Frozen response facts, retained across later local failures. */
|
|
228
|
+
readonly metadata: OutboundHttpResponseMetadata;
|
|
229
|
+
} | {
|
|
230
|
+
/** No response headers were received, including zero-fetch attempts. */readonly type: "not-observed";
|
|
231
|
+
} | {
|
|
232
|
+
/** Continued past the response, or failed before deciding finality. */readonly type: "intermediate-only" | "undetermined"; /** Latest received response, without a finality claim. */
|
|
233
|
+
readonly lastObserved: {
|
|
234
|
+
readonly exchangeIndex: number;
|
|
235
|
+
readonly metadata: OutboundHttpResponseMetadata;
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* The terminal result of one concrete send.
|
|
240
|
+
*
|
|
241
|
+
* A send that fails before submitting HTTP still constitutes an attempt, with
|
|
242
|
+
* zero exchanges. Each gateway send and retry gets a fresh attempt identity.
|
|
243
|
+
* Final response evidence follows the HTTP flow's selection, not the last
|
|
244
|
+
* observed status; later cache/cleanup failures can still fail the execution.
|
|
245
|
+
* @since 2.5.0
|
|
246
|
+
*/
|
|
247
|
+
type OutboundAttemptReport = OutboundSourceMetadata & {
|
|
248
|
+
/** Fresh opaque identity allocated at concrete sender entry. */readonly attemptId: string; /** The originating invocation, independent of tracing. */
|
|
249
|
+
readonly broadcast: OutboundDeliveryEvent["broadcast"]; /** Destination obligation shared with producer delivery events. */
|
|
250
|
+
readonly deliveryId: string; /** Original planned inbox; unavailable on legacy outbox tasks. */
|
|
251
|
+
readonly destinationInbox?: string; /** Canonical portable inbox when the planned destination represents one. */
|
|
252
|
+
readonly portableInbox?: string; /** Inbox selected for this invocation of the concrete sender. */
|
|
253
|
+
readonly inboxUrl: string; /** Actual fetch submissions, including challenges and redirects; may be zero. */
|
|
254
|
+
readonly httpExchangeCount: number; /** Opt-in independent sender input projection; unavailable states remain explicit. */
|
|
255
|
+
readonly senderPayload: OutboundSenderPayload; /** Current queue execution; absent on immediate sends. */
|
|
256
|
+
readonly queue?: {
|
|
257
|
+
readonly queueMessageId: string; /** Present when the queue message carries a Fedify retry counter. */
|
|
258
|
+
readonly queueAttempt?: number;
|
|
259
|
+
}; /** Settled execution result, separate from producer preparation. */
|
|
260
|
+
readonly outcome: {
|
|
261
|
+
readonly type: "succeeded"; /** Final response selected by the sender. */
|
|
262
|
+
readonly response: Extract<OutboundAttemptResponse, {
|
|
263
|
+
type: "final";
|
|
264
|
+
}>;
|
|
265
|
+
} | {
|
|
266
|
+
readonly type: "failed";
|
|
267
|
+
/**
|
|
268
|
+
* Bounded failure kind and operation phase, captured before broad wrapping.
|
|
269
|
+
* Unknown provenance stays unknown; exception names do not establish it.
|
|
270
|
+
* Final non-OK HTTP evidence remains primary alongside local diagnostics.
|
|
271
|
+
*/
|
|
272
|
+
readonly failure: OutboundAttemptFailure; /** Exact value escaping the sender, possibly different from failure.error. */
|
|
273
|
+
readonly error: unknown; /** Explicit final or last-observed response evidence, including absence. */
|
|
274
|
+
readonly response: OutboundAttemptResponse; /** Additional failures, without replacing the primary evidence. */
|
|
275
|
+
readonly diagnostics?: readonly OutboundAttemptFailure[];
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* One actual fetch submission within a concrete send attempt.
|
|
280
|
+
*
|
|
281
|
+
* A redirect response remains an observed response even if a later hop fails.
|
|
282
|
+
* This report does not establish the attempt's final response. Metadata is
|
|
283
|
+
* copied before callback awaiting; no live Request/Response/Headers are exposed.
|
|
284
|
+
* Enabled body capture uses a separate revocable callback; reports hold summaries.
|
|
285
|
+
* Exchange callbacks run after selected capture ends and may precede attempt settlement.
|
|
286
|
+
* @since 2.5.0
|
|
287
|
+
*/
|
|
288
|
+
type OutboundHttpExchangeReport = OutboundSourceMetadata & Pick<OutboundAttemptReport, "attemptId" | "broadcast" | "deliveryId" | "destinationInbox" | "portableInbox" | "inboxUrl" | "queue"> & {
|
|
289
|
+
/** Zero-based submission order within this attempt. */readonly exchangeIndex: number; /** Enabled capture result; absent when disabled or no response was received. */
|
|
290
|
+
readonly bodyCapture?: OutboundBodyCaptureSummary; /** Immutable facts of the request actually submitted. */
|
|
291
|
+
readonly request: {
|
|
292
|
+
readonly url: string;
|
|
293
|
+
readonly method: string; /** Selected header snapshot; absent when request header capture is disabled. */
|
|
294
|
+
readonly headers?: OutboundHeaderSnapshot;
|
|
295
|
+
}; /** A received response, including non-2xx, or the original fetch rejection. */
|
|
296
|
+
readonly outcome: {
|
|
297
|
+
readonly type: "response";
|
|
298
|
+
readonly response: OutboundHttpResponseMetadata & {
|
|
299
|
+
/** Selected snapshot; absent when response header capture is disabled. */readonly headers?: OutboundHeaderSnapshot;
|
|
300
|
+
};
|
|
301
|
+
} | {
|
|
302
|
+
readonly type: "failed";
|
|
303
|
+
readonly error: unknown;
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* A worker retry or deferral submission, separate from its enqueue outcome.
|
|
308
|
+
* @since 2.5.0
|
|
309
|
+
*/
|
|
310
|
+
type OutboundWorkerSchedule = {
|
|
311
|
+
readonly action: "retry" | "defer"; /** Actual continuation task and Fedify retry counter. */
|
|
312
|
+
readonly queue: NonNullable<OutboundAttemptReport["queue"]>; /** Actual affected routes, copied independently of the planned delivery. */
|
|
313
|
+
readonly inboxUrls: readonly string[]; /** ISO 8601 duration passed to enqueue after delay normalization. */
|
|
314
|
+
readonly delay: string; /** Per-route ISO instants retained by the scheduled continuation, if any. */
|
|
315
|
+
readonly notBefore?: Readonly<Record<string, string>>; /** Local preparation failures that contributed to this actual action. */
|
|
316
|
+
readonly preparationFailures?: readonly OutboundWorkerPreparationDiagnostic[];
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* One local preparation failure associated with a worker route.
|
|
320
|
+
* @since 2.5.0
|
|
321
|
+
*/
|
|
322
|
+
type OutboundWorkerPreparationDiagnostic = {
|
|
323
|
+
/** Route whose local setup produced the failure. */readonly inboxUrl: string; /** Existing worker preparation classification and original thrown value. */
|
|
324
|
+
readonly failure: Extract<OutboundWorkerReport["result"], {
|
|
325
|
+
type: "preparation-failed";
|
|
326
|
+
}>["failure"];
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* A child outbox task submitted by a fanout worker.
|
|
330
|
+
* @since 2.5.0
|
|
331
|
+
*/
|
|
332
|
+
type OutboundWorkerChild = {
|
|
333
|
+
readonly action: "enqueue"; /** Actual child task identity and initial Fedify retry counter. */
|
|
334
|
+
readonly queue: NonNullable<OutboundAttemptReport["queue"]>; /** Routes submitted with this child task. */
|
|
335
|
+
readonly inboxUrls: readonly string[]; /** Stable child obligation, independent of its task identity. */
|
|
336
|
+
readonly delivery?: OutboundWorkerReport["delivery"];
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* An observed worker handoff, scheduling outcome, or local abandonment.
|
|
340
|
+
* @since 2.5.0
|
|
341
|
+
*/
|
|
342
|
+
type OutboundWorkerAction = ((OutboundWorkerSchedule | OutboundWorkerChild) & {
|
|
343
|
+
readonly type: "scheduled";
|
|
344
|
+
}) | ((OutboundWorkerSchedule | OutboundWorkerChild) & {
|
|
345
|
+
readonly type: "action-failed";
|
|
346
|
+
readonly acceptance: "unknown";
|
|
347
|
+
readonly error: unknown;
|
|
348
|
+
}) | {
|
|
349
|
+
readonly type: "handoff";
|
|
350
|
+
readonly action: "direct"; /** Actual concrete sender target; entry does not establish HTTP success. */
|
|
351
|
+
readonly inboxUrls: readonly string[]; /** Planned obligation retained across gateway fallback targets. */
|
|
352
|
+
readonly delivery?: OutboundWorkerReport["delivery"];
|
|
353
|
+
} | {
|
|
354
|
+
readonly type: "abandoned";
|
|
355
|
+
readonly reason: "held-ttl-expired" | "permanent-failure" | "retry-policy-declined" | "queue-unavailable"; /** Routes locally abandoned; other routes of the delivery may continue. */
|
|
356
|
+
readonly inboxUrls: readonly string[]; /** Local preparation failures that contributed to this abandonment. */
|
|
357
|
+
readonly preparationFailures?: readonly OutboundWorkerPreparationDiagnostic[];
|
|
358
|
+
} | {
|
|
359
|
+
readonly type: "action-failed";
|
|
360
|
+
readonly action: "drop";
|
|
361
|
+
readonly inboxUrls: readonly string[];
|
|
362
|
+
readonly error: unknown;
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* One fanout or outbox worker execution after its local processing settles.
|
|
366
|
+
*
|
|
367
|
+
* Emitted after the local worker path and its instrumentation settle. A normal
|
|
368
|
+
* return can include handled send failures or abandonment; completion does not
|
|
369
|
+
* establish HTTP success or backend acknowledgment. Actions retain local route
|
|
370
|
+
* decisions and actual enqueue settlement, separately from attempt outcomes.
|
|
371
|
+
* A native rethrow does not establish a scheduled continuation or future replay.
|
|
372
|
+
* @since 2.5.0
|
|
373
|
+
*/
|
|
374
|
+
type OutboundWorkerReport = OutboundSourceMetadata & {
|
|
375
|
+
/** Current outgoing queue role; inbox/custom-task workers are separate. */readonly role: "fanout" | "outbox"; /** Actual task and available Fedify retry counter for this execution. */
|
|
376
|
+
readonly queue: NonNullable<OutboundAttemptReport["queue"]>; /** Concrete sender entries, independent of enabled attempt/exchange callbacks. */
|
|
377
|
+
readonly attemptsStarted: number;
|
|
378
|
+
/**
|
|
379
|
+
* Observed enqueue settlement, concrete direct-entry, and local abandonment.
|
|
380
|
+
* Accepted actions survive later worker failure; rejected batches leave each
|
|
381
|
+
* submitted child uncertain. Empty when no action was observed by settlement.
|
|
382
|
+
*/
|
|
383
|
+
readonly actions: readonly OutboundWorkerAction[];
|
|
384
|
+
/**
|
|
385
|
+
* Caught preparation failures retained when later routes succeed or when
|
|
386
|
+
* the worker exits without scheduling a continuation. Omitted when none.
|
|
387
|
+
*/
|
|
388
|
+
readonly preparationFailures?: readonly OutboundWorkerPreparationDiagnostic[];
|
|
389
|
+
/**
|
|
390
|
+
* Outbox obligation, with unavailable legacy relationships omitted.
|
|
391
|
+
* Fanout has no single delivery; its child actions carry their own references.
|
|
392
|
+
*/
|
|
393
|
+
readonly delivery?: Pick<OutboundAttemptReport, "broadcast" | "deliveryId" | "destinationInbox" | "portableInbox">;
|
|
394
|
+
/**
|
|
395
|
+
* Actual local settlement, separate from individual attempts and queue actions.
|
|
396
|
+
* Preparation failures identify the operation that produced the escaping error.
|
|
397
|
+
*/
|
|
398
|
+
readonly result: {
|
|
399
|
+
readonly type: "completed";
|
|
400
|
+
} | {
|
|
401
|
+
readonly type: "failed";
|
|
402
|
+
readonly error: unknown;
|
|
403
|
+
} | {
|
|
404
|
+
readonly type: "preparation-failed";
|
|
405
|
+
readonly failure: {
|
|
406
|
+
readonly kind: "local";
|
|
407
|
+
readonly phase: "key-import" | "activity-parsing" | "context-preparation" | "validation" | "key-resolution" | "signing" | "serialization" | "key-export" | "request-preparation";
|
|
408
|
+
readonly error: unknown;
|
|
409
|
+
}; /** Exact error escaping the worker preparation operation. */
|
|
410
|
+
readonly error: unknown;
|
|
411
|
+
};
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* Optional observers of outgoing activity processing.
|
|
415
|
+
*
|
|
416
|
+
* Send, original-payload forwarding, and automatic portable replication producer
|
|
417
|
+
* events are observed, including outbox-context operations and fanout
|
|
418
|
+
* continuation handoffs. Concrete attempts and actual fetch exchanges include
|
|
419
|
+
* queue workers, signature challenges, redirects, and alternate gateways.
|
|
420
|
+
* Worker reports describe local fanout/outbox settlement and actual queue
|
|
421
|
+
* actions; they do not establish backend acknowledgment or future execution.
|
|
422
|
+
* Known IDs and provenance survive queue continuations; callback context data
|
|
423
|
+
* belongs to the current execution. Each callback is independently optional.
|
|
424
|
+
* Metadata callbacks are awaited without a default timeout. An enabled body
|
|
425
|
+
* consumer instead uses its explicit bounded capture lifetime.
|
|
426
|
+
* Their errors, including errors logging observer failures, do not replace the
|
|
427
|
+
* send's result.
|
|
428
|
+
* A metadata callback that never settles can delay execution indefinitely. Detached
|
|
429
|
+
* recording must handle its own rejection and shutdown; no persistence is
|
|
430
|
+
* guaranteed. Existing portable forwarding deadlines may return while
|
|
431
|
+
* background preparation, sending, and observer callbacks continue.
|
|
432
|
+
* @template TContextData Application context data.
|
|
433
|
+
* @since 2.5.0
|
|
434
|
+
*/
|
|
435
|
+
interface OutboundObservers<TContextData> {
|
|
436
|
+
/**
|
|
437
|
+
* Opt-in immutable privacy projection of concrete sender input on attempt reports.
|
|
438
|
+
* Disabled by default. Unsupported context/data semantics yield no raw fallback;
|
|
439
|
+
* this is not exact wire evidence or proof that redirected requests kept a body.
|
|
440
|
+
*/
|
|
441
|
+
readonly senderPayload?: boolean;
|
|
442
|
+
/**
|
|
443
|
+
* Independent opt-in body consumer; explicit byte/time limits are required.
|
|
444
|
+
* Shares one source reader with separately bounded diagnostics, without cloning
|
|
445
|
+
* or whole-body accumulation for the application. Finished reports hold summaries.
|
|
446
|
+
*/
|
|
447
|
+
readonly responseBodyCapture?: OutboundResponseBodyCapture<TContextData>;
|
|
448
|
+
/**
|
|
449
|
+
* Opt-in actual request headers for exchange reports; disabled by default.
|
|
450
|
+
* Protected credentials, signatures, and cookies remain redacted even if allowed.
|
|
451
|
+
*/
|
|
452
|
+
readonly requestHeaders?: OutboundHeaderPolicy;
|
|
453
|
+
/** Independent opt-in response header policy for exchange reports. */
|
|
454
|
+
readonly responseHeaders?: OutboundHeaderPolicy;
|
|
455
|
+
/**
|
|
456
|
+
* Observes terminal outgoing worker processing with current context/data.
|
|
457
|
+
* Errors are isolated; results do not replace attempt outcomes or establish
|
|
458
|
+
* future backend execution. Actions retain actual accepted/uncertain child
|
|
459
|
+
* handoffs and retry/defer/drop facts, separately from attempt outcomes.
|
|
460
|
+
*/
|
|
461
|
+
readonly onWorker?: (context: Context<TContextData>, report: OutboundWorkerReport) => void | Promise<void>;
|
|
462
|
+
/**
|
|
463
|
+
* Observes each actual fetch after response headers or rejection, before
|
|
464
|
+
* subsequent challenge/redirect handling. Non-2xx responses are still response
|
|
465
|
+
* outcomes. Pre-fetch failures emit no exchange. Errors cannot veto transport.
|
|
466
|
+
*/
|
|
467
|
+
readonly onHttpExchange?: (context: Context<TContextData>, report: OutboundHttpExchangeReport) => void | Promise<void>;
|
|
468
|
+
/**
|
|
469
|
+
* Observes settlement of concrete sends and forwarding, including workers
|
|
470
|
+
* and pre-fetch failures. Holds, drops, and failures before sender entry emit
|
|
471
|
+
* no attempt. Final HTTP evidence, local diagnostics, and the outward error
|
|
472
|
+
* remain distinct. Callback errors cannot replace the sender's result.
|
|
473
|
+
*/
|
|
474
|
+
readonly onAttempt?: (context: Context<TContextData>, report: OutboundAttemptReport) => void | Promise<void>;
|
|
475
|
+
/**
|
|
476
|
+
* Observes invocation entry and the current producer's preparation result.
|
|
477
|
+
* The existing context is passed without loading data for observation.
|
|
478
|
+
* Returning or throwing cannot veto sending. Earlier immediate sends may
|
|
479
|
+
* already be running when preparation finishes; their outcomes are separate.
|
|
480
|
+
*/
|
|
481
|
+
readonly onBroadcast?: (context: Context<TContextData>, event: OutboundBroadcastEvent) => void | Promise<void>;
|
|
482
|
+
/**
|
|
483
|
+
* Observes producer-side planning, handoffs, and destination preparation
|
|
484
|
+
* failures, including fanout continuation handoffs. Filtered recipients do
|
|
485
|
+
* not become planned deliveries. Concrete attempts and exchanges have their
|
|
486
|
+
* own callbacks. These events do not report remote success or worker
|
|
487
|
+
* scheduling outcomes.
|
|
488
|
+
*/
|
|
489
|
+
readonly onDelivery?: (context: Context<TContextData>, event: OutboundDeliveryEvent) => void | Promise<void>;
|
|
490
|
+
}
|
|
491
|
+
/** URL facts captured independently of a mutable context URL. @since 2.5.0 */
|
|
492
|
+
interface OutboundLocalContext {
|
|
493
|
+
/** Scheme and authority of the context URL. */
|
|
494
|
+
readonly origin: string;
|
|
495
|
+
/** URL hostname with its optional port. */
|
|
496
|
+
readonly host: string;
|
|
497
|
+
/** URL hostname without a port. */
|
|
498
|
+
readonly hostname: string;
|
|
499
|
+
/** Configured canonical web origin, falling back to this context's origin. */
|
|
500
|
+
readonly canonicalOrigin: string;
|
|
501
|
+
}
|
|
502
|
+
/** The original routed HTTP inbox request that caused outgoing work. @since 2.5.0 */
|
|
503
|
+
interface OutboundInboxRequest {
|
|
504
|
+
/** Fresh server-generated identity, independent of Activity and trace IDs. */
|
|
505
|
+
readonly inboxRequestId: string;
|
|
506
|
+
/** Informational logging label; externally controlled and nonunique. */
|
|
507
|
+
readonly requestId: string;
|
|
508
|
+
/** Original request URL facts, preserved separately from current context. */
|
|
509
|
+
readonly context: OutboundLocalContext;
|
|
510
|
+
}
|
|
511
|
+
/** Explicit historical cause of outgoing work. @since 2.5.0 */
|
|
512
|
+
interface OutboundProvenance {
|
|
513
|
+
/**
|
|
514
|
+
* Exact application-owned correlation, up to 1,024 UTF-8 bytes; an empty
|
|
515
|
+
* string is valid. Never a Fedify deduplication key. Each new public call
|
|
516
|
+
* supplies its own value; queued continuations retain it.
|
|
517
|
+
*/
|
|
518
|
+
readonly dispatchId?: string;
|
|
519
|
+
/** Absent for independent contexts, programmatic routing, and unknown work. */
|
|
520
|
+
readonly inboxRequest?: OutboundInboxRequest;
|
|
521
|
+
/** Original logging label for request-derived work without an inbox cause. */
|
|
522
|
+
readonly originatingRequestId?: string;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Observation time, optional tracing, original provenance, and current context.
|
|
526
|
+
* @since 2.5.0
|
|
527
|
+
*/
|
|
528
|
+
interface OutboundSourceMetadata {
|
|
529
|
+
/** Unix milliseconds at observation; wall clocks do not ensure global ordering. */
|
|
530
|
+
readonly observedAt: number;
|
|
531
|
+
/** Valid IDs of this operation's own span, when one is available. */
|
|
532
|
+
readonly trace?: {
|
|
533
|
+
readonly traceId: string;
|
|
534
|
+
readonly spanId: string;
|
|
535
|
+
};
|
|
536
|
+
/** Immutable historical cause, distinct from this callback's context. */
|
|
537
|
+
readonly provenance: OutboundProvenance;
|
|
538
|
+
/** URL facts of the current callback context. */
|
|
539
|
+
readonly local: OutboundLocalContext;
|
|
540
|
+
}
|
|
541
|
+
//#endregion
|
|
12
542
|
//#region src/federation/activity-listener.d.ts
|
|
13
543
|
/**
|
|
14
544
|
* Options for an inbox listener.
|
|
@@ -46,6 +576,13 @@ interface InboxListenerOptions {
|
|
|
46
576
|
type InboxJsonValue = null | boolean | number | string | readonly InboxJsonValue[] | {
|
|
47
577
|
readonly [key: string]: InboxJsonValue;
|
|
48
578
|
};
|
|
579
|
+
/** Request-signal state at inbox report construction, separate from processing outcome. @since 2.5.0 */
|
|
580
|
+
type InboxRequestCancellation = {
|
|
581
|
+
readonly type: "not-aborted";
|
|
582
|
+
} | {
|
|
583
|
+
readonly type: "aborted"; /** Exact Request.signal reason, including non-Error values. */
|
|
584
|
+
readonly reason: unknown;
|
|
585
|
+
};
|
|
49
586
|
/**
|
|
50
587
|
* The final inbox authentication decision.
|
|
51
588
|
* @since 2.4.0
|
|
@@ -122,6 +659,31 @@ type InboxRequestOutcome = {
|
|
|
122
659
|
* @since 2.4.0
|
|
123
660
|
*/
|
|
124
661
|
interface InboxRequestReport {
|
|
662
|
+
/**
|
|
663
|
+
* Fresh server-generated identity for one routed HTTP inbox request,
|
|
664
|
+
* including preparation failures and duplicate deliveries. Preserved on
|
|
665
|
+
* outgoing causal descendants; absent without a known routed source.
|
|
666
|
+
* @since 2.5.0
|
|
667
|
+
*/
|
|
668
|
+
readonly inboxRequestId?: string;
|
|
669
|
+
/**
|
|
670
|
+
* Original informational logging label; externally controlled and nonunique,
|
|
671
|
+
* independent of inboxRequestId. Absent without a known routed source.
|
|
672
|
+
* @since 2.5.0
|
|
673
|
+
*/
|
|
674
|
+
readonly requestId?: string;
|
|
675
|
+
/**
|
|
676
|
+
* Original local URL facts from the routed request, independent of later contexts.
|
|
677
|
+
* Absent without a known routed source.
|
|
678
|
+
* @since 2.5.0
|
|
679
|
+
*/
|
|
680
|
+
readonly local?: OutboundLocalContext;
|
|
681
|
+
/**
|
|
682
|
+
* Request.signal state immediately before report construction. An aborted request
|
|
683
|
+
* does not imply processing stopped or retract confirmed processing/enqueue outcomes.
|
|
684
|
+
* @since 2.5.0
|
|
685
|
+
*/
|
|
686
|
+
readonly requestCancellation: InboxRequestCancellation;
|
|
125
687
|
/** The delivery route, including a portable gateway route. */
|
|
126
688
|
readonly inbox: {
|
|
127
689
|
readonly kind: "personal" | "shared" | "portable";
|
|
@@ -190,6 +752,414 @@ declare function digest(uris: Iterable<string | URL>): Promise<Uint8Array>;
|
|
|
190
752
|
*/
|
|
191
753
|
declare function buildCollectionSynchronizationHeader(collectionId: string | URL, actorIds: Iterable<string | URL>): Promise<string>;
|
|
192
754
|
//#endregion
|
|
755
|
+
//#region src/federation/inbox-authentication.d.ts
|
|
756
|
+
/**
|
|
757
|
+
* A party that Fedify authenticated for an incoming activity, independently
|
|
758
|
+
* of the activity's declared `actor`.
|
|
759
|
+
* @since 2.5.0
|
|
760
|
+
*/
|
|
761
|
+
interface InboxPrincipal {
|
|
762
|
+
/**
|
|
763
|
+
* What {@link InboxPrincipal.id} is:
|
|
764
|
+
*
|
|
765
|
+
* - `"actor"`: an actor whose ownership of the verifying key Fedify
|
|
766
|
+
* confirmed with the actor's own document.
|
|
767
|
+
* - `"portable-authority"`: a DID whose verification method made a valid
|
|
768
|
+
* Object Integrity Proof. It authenticates the [FEP-ef61] portable
|
|
769
|
+
* actors of that DID, and nothing else.
|
|
770
|
+
*
|
|
771
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
772
|
+
*/
|
|
773
|
+
readonly kind: "actor" | "portable-authority";
|
|
774
|
+
/** The actor ID, or the DID if {@link kind} is `"portable-authority"`. */
|
|
775
|
+
readonly id: URL;
|
|
776
|
+
/**
|
|
777
|
+
* How the principal was authenticated:
|
|
778
|
+
*
|
|
779
|
+
* - `"http-signatures"`: it signed the HTTP request.
|
|
780
|
+
* - `"linked-data-signatures"`: it made the Linked Data Signature of the
|
|
781
|
+
* activity.
|
|
782
|
+
* - `"object-integrity-proofs"`: it made an Object Integrity Proof of the
|
|
783
|
+
* activity.
|
|
784
|
+
* - `"origin"`: the activity was fetched again from the actor's own web
|
|
785
|
+
* origin, which happens only for `Context.routeActivity()`.
|
|
786
|
+
*/
|
|
787
|
+
readonly mechanism: "http-signatures" | "linked-data-signatures" | "object-integrity-proofs" | "origin";
|
|
788
|
+
/** The key or verification method that authenticated the principal. */
|
|
789
|
+
readonly keyId: URL | null;
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Who Fedify authenticated for an incoming activity, and the interpretation of
|
|
793
|
+
* the activity it authenticated. Inbox listeners receive it as
|
|
794
|
+
* {@link InboxContext.authentication}.
|
|
795
|
+
*
|
|
796
|
+
* Authenticated principals are independent of the activity's declared
|
|
797
|
+
* `actor`: an activity forwarded by a relay is signed by the relay in its
|
|
798
|
+
* HTTP request, but its document may be signed by its author, and some
|
|
799
|
+
* activities, such as [FEP-7aa9] `FeatureRequest`s sent by Mastodon, declare
|
|
800
|
+
* no `actor` at all. A valid signature alone does not authorize anything;
|
|
801
|
+
* use {@link isActorAuthenticated} to check whether a specific actor was
|
|
802
|
+
* authenticated.
|
|
803
|
+
*
|
|
804
|
+
* [FEP-7aa9]: https://w3id.org/fep/7aa9
|
|
805
|
+
* @since 2.5.0
|
|
806
|
+
*/
|
|
807
|
+
interface InboxAuthenticationEvidence {
|
|
808
|
+
/**
|
|
809
|
+
* Whether signatures were verified at all. It is `false` only when
|
|
810
|
+
* signature verification is skipped, or when there is no evidence, e.g.,
|
|
811
|
+
* for an activity queued by an older version of Fedify. In that case all
|
|
812
|
+
* the principal lists are empty.
|
|
813
|
+
*/
|
|
814
|
+
readonly verified: boolean;
|
|
815
|
+
/**
|
|
816
|
+
* The principals that signed the HTTP request, i.e., the server that
|
|
817
|
+
* delivered the activity, which may have forwarded it. It is empty when
|
|
818
|
+
* the activity document was authenticated by its own signatures, so that
|
|
819
|
+
* HTTP Signatures did not need to be verified.
|
|
820
|
+
*/
|
|
821
|
+
readonly requestSigners: readonly InboxPrincipal[];
|
|
822
|
+
/**
|
|
823
|
+
* The principals that made the verified Linked Data Signature or Object
|
|
824
|
+
* Integrity Proofs of the activity document. All of them are listed when
|
|
825
|
+
* there are several proofs.
|
|
826
|
+
*/
|
|
827
|
+
readonly documentSigners: readonly InboxPrincipal[];
|
|
828
|
+
/**
|
|
829
|
+
* The actors authenticated because `Context.routeActivity()` fetched the
|
|
830
|
+
* activity again from their own web origin. It is always empty for
|
|
831
|
+
* activities delivered to an inbox.
|
|
832
|
+
*/
|
|
833
|
+
readonly originAuthenticated: readonly InboxPrincipal[];
|
|
834
|
+
/**
|
|
835
|
+
* The activity as Fedify interpreted it while authenticating it, in
|
|
836
|
+
* expanded JSON-LD. Typed vocabulary objects omit some values, such as
|
|
837
|
+
* blank node references and values they cannot decode, so authorization
|
|
838
|
+
* that has to count every value of a property, e.g., that a property has
|
|
839
|
+
* exactly one value, should inspect this instead. It is deeply frozen.
|
|
840
|
+
* It is empty when there is no evidence.
|
|
841
|
+
*/
|
|
842
|
+
readonly expandedActivity: readonly Record<string, unknown>[];
|
|
843
|
+
/**
|
|
844
|
+
* The base URL the activity was decoded with, e.g., the URL an activity
|
|
845
|
+
* fetched by `Context.routeActivity()` was finally retrieved from, or
|
|
846
|
+
* `null` if none was given. Relative IRIs left in
|
|
847
|
+
* {@link expandedActivity} resolve against it, or against the activity's
|
|
848
|
+
* own `@id` if it is `null`, as the decoder resolves them.
|
|
849
|
+
*/
|
|
850
|
+
readonly baseUrl: URL | null;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Options for {@link isActorAuthenticated}.
|
|
854
|
+
* @since 2.5.0
|
|
855
|
+
*/
|
|
856
|
+
interface IsActorAuthenticatedOptions {
|
|
857
|
+
/**
|
|
858
|
+
* Which principals to consider:
|
|
859
|
+
*
|
|
860
|
+
* - `"effective"` (default): the document signers if there are any,
|
|
861
|
+
* otherwise the request signers if there are any, otherwise the actors
|
|
862
|
+
* authenticated by their origin.
|
|
863
|
+
* - `"document"`: the document signers only.
|
|
864
|
+
*/
|
|
865
|
+
readonly scope?: "effective" | "document";
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Checks whether the given evidence authenticates the given actor.
|
|
869
|
+
*
|
|
870
|
+
* Actor IDs are compared exactly, except that [FEP-ef61] portable IDs and
|
|
871
|
+
* compatible identifiers are compared by their canonical portable IDs, and
|
|
872
|
+
* a portable authority (a DID) authenticates the portable actors of that DID.
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ``` typescript
|
|
876
|
+
* federation
|
|
877
|
+
* .setInboxListeners("/users/{identifier}/inbox", "/inbox")
|
|
878
|
+
* .on(Follow, async (ctx, follow) => {
|
|
879
|
+
* if (follow.actorId == null) return;
|
|
880
|
+
* // The actor is always authenticated for activities that declare one,
|
|
881
|
+
* // but the same check works for any actor an activity names:
|
|
882
|
+
* isActorAuthenticated(ctx.authentication, follow.actorId);
|
|
883
|
+
* });
|
|
884
|
+
* ```
|
|
885
|
+
*
|
|
886
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
887
|
+
* @param evidence The authentication evidence, usually
|
|
888
|
+
* {@link InboxContext.authentication}.
|
|
889
|
+
* @param actorId The actor ID to check.
|
|
890
|
+
* @param options Options.
|
|
891
|
+
* @returns `true` if the actor is authenticated.
|
|
892
|
+
* @since 2.5.0
|
|
893
|
+
*/
|
|
894
|
+
declare function isActorAuthenticated(evidence: InboxAuthenticationEvidence, actorId: URL, options?: IsActorAuthenticatedOptions): boolean;
|
|
895
|
+
/**
|
|
896
|
+
* A {@link InboxPrincipal} as stored in a queued message.
|
|
897
|
+
* The wire spellings remain independent of the public API spellings.
|
|
898
|
+
* @internal
|
|
899
|
+
*/
|
|
900
|
+
interface SerializedInboxPrincipal {
|
|
901
|
+
readonly kind: "actor" | "portableAuthority";
|
|
902
|
+
readonly id: string;
|
|
903
|
+
readonly mechanism: "httpSignatures" | "linkedDataSignatures" | "objectIntegrityProofs" | "origin";
|
|
904
|
+
readonly keyId: string | null;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* The principals of an {@link InboxAuthenticationEvidence} as stored in
|
|
908
|
+
* a queued message. The expanded activity and the base URL are restored
|
|
909
|
+
* from the queued verified view instead.
|
|
910
|
+
* @internal
|
|
911
|
+
*/
|
|
912
|
+
interface SerializedInboxAuthentication {
|
|
913
|
+
readonly verified: boolean;
|
|
914
|
+
readonly requestSigners: readonly SerializedInboxPrincipal[];
|
|
915
|
+
readonly documentSigners: readonly SerializedInboxPrincipal[];
|
|
916
|
+
readonly originAuthenticated: readonly SerializedInboxPrincipal[];
|
|
917
|
+
}
|
|
918
|
+
//#endregion
|
|
919
|
+
//#region src/federation/inbox-view.d.ts
|
|
920
|
+
/**
|
|
921
|
+
* A {@link ContextSnapshotEntry} as stored in a queued message. A response
|
|
922
|
+
* that equals the one Fedify bundles for the URL is stored as a reference to
|
|
923
|
+
* the bundled context, along with its hash for diagnostics.
|
|
924
|
+
* @internal
|
|
925
|
+
*/
|
|
926
|
+
type SerializedContextSnapshotEntry = {
|
|
927
|
+
readonly policy: EffectiveContextLoaderPolicy;
|
|
928
|
+
readonly url: string; /** The SHA-256 of the canonical JSON of the whole response. */
|
|
929
|
+
readonly sha256: string;
|
|
930
|
+
} & ({
|
|
931
|
+
readonly bundled: true;
|
|
932
|
+
} | {
|
|
933
|
+
readonly response: RemoteDocument;
|
|
934
|
+
});
|
|
935
|
+
/**
|
|
936
|
+
* The interpretation of an incoming activity that Fedify authenticated, as
|
|
937
|
+
* stored in a queued message. The document itself is not copied; it is
|
|
938
|
+
* a field of the message.
|
|
939
|
+
* @internal
|
|
940
|
+
*/
|
|
941
|
+
interface SerializedVerifiedActivityView {
|
|
942
|
+
/** The format version. */
|
|
943
|
+
readonly version: 1;
|
|
944
|
+
/** The context loader policy the activity was parsed with. */
|
|
945
|
+
readonly policy: EffectiveContextLoaderPolicy;
|
|
946
|
+
/**
|
|
947
|
+
* Which document the activity was parsed from, with its Linked Data
|
|
948
|
+
* Signature detached: the `activity` of the message, i.e., the payload as
|
|
949
|
+
* received, or its `normalizedActivity`, i.e., the payload compacted for
|
|
950
|
+
* Linked Data Signatures.
|
|
951
|
+
*/
|
|
952
|
+
readonly source: "activity" | "normalizedActivity";
|
|
953
|
+
/** The `baseUrl` option the activity was parsed with. */
|
|
954
|
+
readonly baseUrl: string | null;
|
|
955
|
+
/** The context responses the interpretation used. */
|
|
956
|
+
readonly contexts: readonly SerializedContextSnapshotEntry[];
|
|
957
|
+
/** The digest of the expanded activity. */
|
|
958
|
+
readonly expandedDigest: string;
|
|
959
|
+
}
|
|
960
|
+
//#endregion
|
|
961
|
+
//#region src/federation/queue.d.ts
|
|
962
|
+
/** Serializable grouping facts, separate from queue task identity. @internal */
|
|
963
|
+
interface SerializedOutboundDelivery {
|
|
964
|
+
readonly broadcast: {
|
|
965
|
+
readonly type: "known";
|
|
966
|
+
readonly id: string;
|
|
967
|
+
} | {
|
|
968
|
+
readonly type: "unknown";
|
|
969
|
+
};
|
|
970
|
+
readonly deliveryId: string;
|
|
971
|
+
readonly destinationInbox: string;
|
|
972
|
+
readonly portableInbox?: string;
|
|
973
|
+
}
|
|
974
|
+
interface SenderKeyJwkPair {
|
|
975
|
+
readonly keyId: string;
|
|
976
|
+
readonly privateKey: JsonWebKey;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* A message that represents a task to be processed by the background worker.
|
|
980
|
+
* The concrete type of the message depends on the `type` property.
|
|
981
|
+
*
|
|
982
|
+
* Please do not depend on the concrete types of the messages, as they may
|
|
983
|
+
* change in the future. You should treat the `Message` type as an opaque
|
|
984
|
+
* type.
|
|
985
|
+
* @since 1.6.0
|
|
986
|
+
*/
|
|
987
|
+
type Message = FanoutMessage | OutboxMessage | InboxMessage | TaskMessage;
|
|
988
|
+
interface FanoutMessage {
|
|
989
|
+
/** Historical source facts; absent on legacy/independent messages. */
|
|
990
|
+
readonly provenance?: OutboundProvenance;
|
|
991
|
+
readonly type: "fanout";
|
|
992
|
+
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
993
|
+
readonly baseUrl: string;
|
|
994
|
+
readonly keys: readonly SenderKeyJwkPair[];
|
|
995
|
+
readonly inboxes: Readonly<Record<string, {
|
|
996
|
+
readonly actorIds: readonly string[];
|
|
997
|
+
readonly sharedInbox: boolean; /** Optional for continuations created before outbound observation. */
|
|
998
|
+
readonly outbound?: SerializedOutboundDelivery;
|
|
999
|
+
/**
|
|
1000
|
+
* The canonical form of the FEP-ef61 portable inbox that the inbox
|
|
1001
|
+
* stands for.
|
|
1002
|
+
* @internal
|
|
1003
|
+
*/
|
|
1004
|
+
readonly portableInbox?: string;
|
|
1005
|
+
/**
|
|
1006
|
+
* The compatible identifiers of the portable inbox on each gateway to
|
|
1007
|
+
* deliver through, in order.
|
|
1008
|
+
* @internal
|
|
1009
|
+
*/
|
|
1010
|
+
readonly gatewayInboxes?: readonly string[];
|
|
1011
|
+
}>>;
|
|
1012
|
+
readonly activity: unknown;
|
|
1013
|
+
readonly activityId?: string;
|
|
1014
|
+
readonly activityType: string;
|
|
1015
|
+
readonly collectionSync?: string;
|
|
1016
|
+
readonly orderingKey?: string;
|
|
1017
|
+
/**
|
|
1018
|
+
* Whether to apply outgoing JSON-LD wire-format normalization to queued
|
|
1019
|
+
* activities that already carry Object Integrity Proofs.
|
|
1020
|
+
*
|
|
1021
|
+
* `true` is used for proofs Fedify created before fanout, or when callers
|
|
1022
|
+
* explicitly request normalization for locally pre-signed activities.
|
|
1023
|
+
* `false`/`undefined` preserves existing proofs as-is.
|
|
1024
|
+
*/
|
|
1025
|
+
readonly normalizeExistingProofs?: boolean;
|
|
1026
|
+
readonly traceContext: Readonly<Record<string, string>>;
|
|
1027
|
+
}
|
|
1028
|
+
interface OutboxMessage {
|
|
1029
|
+
/** Historical source facts; absent on legacy/independent messages. */
|
|
1030
|
+
readonly provenance?: OutboundProvenance;
|
|
1031
|
+
readonly type: "outbox";
|
|
1032
|
+
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1033
|
+
/** Original delivery identity; absent on legacy/unobserved producers. */
|
|
1034
|
+
readonly outbound?: SerializedOutboundDelivery;
|
|
1035
|
+
readonly baseUrl: string;
|
|
1036
|
+
readonly keys: readonly SenderKeyJwkPair[];
|
|
1037
|
+
readonly activity: unknown;
|
|
1038
|
+
readonly activityId?: string;
|
|
1039
|
+
readonly activityType: string;
|
|
1040
|
+
readonly inbox: string;
|
|
1041
|
+
readonly sharedInbox: boolean;
|
|
1042
|
+
readonly actorIds?: readonly string[];
|
|
1043
|
+
readonly started: string;
|
|
1044
|
+
readonly attempt: number;
|
|
1045
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
1046
|
+
readonly orderingKey?: string;
|
|
1047
|
+
/**
|
|
1048
|
+
* Whether this message is currently held by the outbound circuit breaker.
|
|
1049
|
+
* @internal
|
|
1050
|
+
*/
|
|
1051
|
+
readonly circuitHeld?: true;
|
|
1052
|
+
/**
|
|
1053
|
+
* When Fedify first held this message because the remote host circuit was
|
|
1054
|
+
* open.
|
|
1055
|
+
* @internal
|
|
1056
|
+
*/
|
|
1057
|
+
readonly circuitHeldSince?: string;
|
|
1058
|
+
/**
|
|
1059
|
+
* The canonical form of the FEP-ef61 portable inbox that {@link inbox}, its
|
|
1060
|
+
* compatible identifier on a gateway, stands for.
|
|
1061
|
+
* @internal
|
|
1062
|
+
*/
|
|
1063
|
+
readonly portableInbox?: string;
|
|
1064
|
+
/**
|
|
1065
|
+
* The compatible identifiers of the FEP-ef61 portable inbox on each gateway
|
|
1066
|
+
* that is still to be tried, in order. {@link inbox} is the first one.
|
|
1067
|
+
* If there is more than one, the activity is delivered through the first
|
|
1068
|
+
* gateway that accepts it.
|
|
1069
|
+
* @internal
|
|
1070
|
+
*/
|
|
1071
|
+
readonly gatewayInboxes?: readonly string[];
|
|
1072
|
+
/**
|
|
1073
|
+
* The times before which each of {@link gatewayInboxes} must not be tried
|
|
1074
|
+
* again, as their responses' `Retry-After` headers requested, keyed by
|
|
1075
|
+
* the inbox URL, in ISO 8601.
|
|
1076
|
+
* @internal
|
|
1077
|
+
*/
|
|
1078
|
+
readonly gatewayNotBefore?: Readonly<Record<string, string>>;
|
|
1079
|
+
readonly traceContext: Readonly<Record<string, string>>;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* A message that carries a custom background task. Every field is
|
|
1083
|
+
* a string, number, or plain record so that the message survives both
|
|
1084
|
+
* JSON serialization and structured clone on every queue backend.
|
|
1085
|
+
* @since 2.4.0
|
|
1086
|
+
*/
|
|
1087
|
+
interface TaskMessage {
|
|
1088
|
+
readonly type: "task";
|
|
1089
|
+
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1090
|
+
readonly baseUrl: string;
|
|
1091
|
+
readonly taskName: string;
|
|
1092
|
+
/** devalue-encoded task data; vocab objects bridged to expanded JSON-LD. */
|
|
1093
|
+
readonly data: string;
|
|
1094
|
+
readonly started: string;
|
|
1095
|
+
readonly attempt: number;
|
|
1096
|
+
readonly orderingKey?: string;
|
|
1097
|
+
readonly traceContext: Readonly<Record<string, string>>;
|
|
1098
|
+
}
|
|
1099
|
+
interface InboxMessage {
|
|
1100
|
+
/** Historical source facts; absent on legacy/independent messages. */
|
|
1101
|
+
readonly provenance?: OutboundProvenance;
|
|
1102
|
+
readonly type: "inbox";
|
|
1103
|
+
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1104
|
+
readonly baseUrl: string;
|
|
1105
|
+
readonly activity: unknown;
|
|
1106
|
+
/**
|
|
1107
|
+
* The normalized JSON-LD representation of a signed inbox activity that
|
|
1108
|
+
* Fedify already compacted successfully while accepting the request. Queue
|
|
1109
|
+
* workers can reuse this producer-side parse cache under stricter loader or
|
|
1110
|
+
* network constraints without changing the raw payload preserved for
|
|
1111
|
+
* forwarding.
|
|
1112
|
+
*
|
|
1113
|
+
* This may exist even when {@link ldSignatureVerified} is `false`, because
|
|
1114
|
+
* fallback-authenticated traffic and already-queued backlog items can still
|
|
1115
|
+
* depend on the cached normalized form to avoid re-fetching remote custom
|
|
1116
|
+
* contexts during worker processing.
|
|
1117
|
+
*
|
|
1118
|
+
* This is optional for backward compatibility with messages that were
|
|
1119
|
+
* queued by older Fedify versions or that were already in a queue before
|
|
1120
|
+
* upgrading.
|
|
1121
|
+
*
|
|
1122
|
+
* Fedify keeps this on the queued message itself instead of an external
|
|
1123
|
+
* sidecar because generic queue backends do not provide reliable lifecycle
|
|
1124
|
+
* guarantees for auxiliary storage across retries and redeliveries.
|
|
1125
|
+
*
|
|
1126
|
+
* @internal
|
|
1127
|
+
*/
|
|
1128
|
+
readonly normalizedActivity?: unknown;
|
|
1129
|
+
/**
|
|
1130
|
+
* Whether the producer actually verified the Linked Data Signature before
|
|
1131
|
+
* queueing this message. This lets workers distinguish verified LDS replay
|
|
1132
|
+
* from other authenticated inbox traffic that merely happened to include a
|
|
1133
|
+
* signature block. This provenance marker is separate from the optional
|
|
1134
|
+
* normalizedActivity parse cache.
|
|
1135
|
+
*
|
|
1136
|
+
* `undefined` preserves backward compatibility with older queued messages
|
|
1137
|
+
* that predate this marker.
|
|
1138
|
+
*
|
|
1139
|
+
* @internal
|
|
1140
|
+
*/
|
|
1141
|
+
readonly ldSignatureVerified?: boolean;
|
|
1142
|
+
/**
|
|
1143
|
+
* The interpretation of the activity that Fedify authenticated, i.e., which
|
|
1144
|
+
* document it was parsed from and every JSON-LD context response the parse
|
|
1145
|
+
* used, so that the worker and its retries dispatch the very same
|
|
1146
|
+
* interpretation without loading contexts again. Absent in messages queued
|
|
1147
|
+
* by older Fedify versions.
|
|
1148
|
+
* @internal
|
|
1149
|
+
*/
|
|
1150
|
+
readonly verifiedView?: SerializedVerifiedActivityView;
|
|
1151
|
+
/**
|
|
1152
|
+
* Who Fedify authenticated for the activity. Absent in messages queued by
|
|
1153
|
+
* older Fedify versions.
|
|
1154
|
+
* @internal
|
|
1155
|
+
*/
|
|
1156
|
+
readonly authentication?: SerializedInboxAuthentication;
|
|
1157
|
+
readonly started: string;
|
|
1158
|
+
readonly attempt: number;
|
|
1159
|
+
readonly identifier: string | null;
|
|
1160
|
+
readonly traceContext: Readonly<Record<string, string>>;
|
|
1161
|
+
}
|
|
1162
|
+
//#endregion
|
|
193
1163
|
//#region src/federation/send.d.ts
|
|
194
1164
|
/**
|
|
195
1165
|
* A key pair for an actor who sends an activity.
|
|
@@ -224,7 +1194,9 @@ declare class SendActivityError extends Error {
|
|
|
224
1194
|
* The response body from the inbox, if any. Note that this may be
|
|
225
1195
|
* truncated to a maximum of 1 KiB to prevent excessive memory consumption
|
|
226
1196
|
* when remote servers return large error pages (e.g., Cloudflare error pages).
|
|
227
|
-
* If truncated, the string will end with `"… (truncated)"`.
|
|
1197
|
+
* If truncated, the string will end with `"… (truncated)"`. Diagnostic reading
|
|
1198
|
+
* has a separate one-second budget; a deadline retains any partial preview and
|
|
1199
|
+
* appends `"… (timed out)"`. This is independent of application body capture.
|
|
228
1200
|
*/
|
|
229
1201
|
readonly responseBody: string;
|
|
230
1202
|
/**
|
|
@@ -1084,269 +2056,63 @@ declare class InProcessMessageQueue implements MessageQueue {
|
|
|
1084
2056
|
* are not running in separate threads or processes. They are running in the
|
|
1085
2057
|
* same process, but are scheduled to run in parallel. Hence, this is useful
|
|
1086
2058
|
* for I/O-bound tasks, but not for CPU-bound tasks, which is okay for Fedify's
|
|
1087
|
-
* workloads.
|
|
1088
|
-
*
|
|
1089
|
-
* When using `ParallelMessageQueue`, the ordering guarantee is preserved
|
|
1090
|
-
* *only if* the underlying queue implementation delivers messages in a wrapper
|
|
1091
|
-
* format that includes the `__fedify_ordering_key__` property. Currently,
|
|
1092
|
-
* only `DenoKvMessageQueue` and `WorkersMessageQueue` use this format.
|
|
1093
|
-
* For other queue implementations (e.g., `InProcessMessageQueue`,
|
|
1094
|
-
* `RedisMessageQueue`, `PostgresMessageQueue`, `SqliteMessageQueue`,
|
|
1095
|
-
* `AmqpMessageQueue`), the ordering key cannot be detected by
|
|
1096
|
-
* `ParallelMessageQueue`, so ordering guarantees are handled by those
|
|
1097
|
-
* implementations directly rather than at the `ParallelMessageQueue` level.
|
|
1098
|
-
*
|
|
1099
|
-
* Messages with the same ordering key will never be processed concurrently
|
|
1100
|
-
* by different workers, ensuring sequential processing within each key.
|
|
1101
|
-
* Messages with different ordering keys (or no ordering key) can still be
|
|
1102
|
-
* processed in parallel.
|
|
1103
|
-
*
|
|
1104
|
-
* @since 1.0.0
|
|
1105
|
-
*/
|
|
1106
|
-
declare class ParallelMessageQueue implements MessageQueue {
|
|
1107
|
-
#private;
|
|
1108
|
-
readonly queue: MessageQueue;
|
|
1109
|
-
readonly workers: number;
|
|
1110
|
-
/**
|
|
1111
|
-
* Inherits the native retry capability from the wrapped queue.
|
|
1112
|
-
* @since 1.7.0
|
|
1113
|
-
*/
|
|
1114
|
-
readonly nativeRetrial?: boolean;
|
|
1115
|
-
/**
|
|
1116
|
-
* Inherits the native deduplication capability from the wrapped queue.
|
|
1117
|
-
* @since 2.4.0
|
|
1118
|
-
*/
|
|
1119
|
-
readonly nativeDeduplication?: boolean;
|
|
1120
|
-
/**
|
|
1121
|
-
* Inherits the atomic batch capability from the wrapped queue.
|
|
1122
|
-
* @since 2.4.0
|
|
1123
|
-
*/
|
|
1124
|
-
readonly atomicEnqueueMany?: boolean;
|
|
1125
|
-
/**
|
|
1126
|
-
* Inherits the message size limit from the wrapped queue.
|
|
1127
|
-
* @since 2.5.0
|
|
1128
|
-
*/
|
|
1129
|
-
readonly maxMessageSize?: number;
|
|
1130
|
-
readonly getDepth?: () => Promise<MessageQueueDepth>;
|
|
1131
|
-
/**
|
|
1132
|
-
* Constructs a new {@link ParallelMessageQueue} with the given queue and
|
|
1133
|
-
* number of workers.
|
|
1134
|
-
* @param queue The message queue to use under the hood. Note that
|
|
1135
|
-
* {@link ParallelMessageQueue} cannot be nested.
|
|
1136
|
-
* @param workers The number of workers to process messages in parallel.
|
|
1137
|
-
* @throws {TypeError} If the given queue is an instance of
|
|
1138
|
-
* {@link ParallelMessageQueue}.
|
|
1139
|
-
*/
|
|
1140
|
-
constructor(queue: MessageQueue, workers: number);
|
|
1141
|
-
enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
1142
|
-
enqueueMany(messages: readonly any[], options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
1143
|
-
listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
|
|
1144
|
-
}
|
|
1145
|
-
//#endregion
|
|
1146
|
-
//#region src/federation/inbox-authentication.d.ts
|
|
1147
|
-
/**
|
|
1148
|
-
* A party that Fedify authenticated for an incoming activity, independently
|
|
1149
|
-
* of the activity's declared `actor`.
|
|
1150
|
-
* @since 2.5.0
|
|
1151
|
-
*/
|
|
1152
|
-
interface InboxPrincipal {
|
|
1153
|
-
/**
|
|
1154
|
-
* What {@link InboxPrincipal.id} is:
|
|
1155
|
-
*
|
|
1156
|
-
* - `"actor"`: an actor whose ownership of the verifying key Fedify
|
|
1157
|
-
* confirmed with the actor's own document.
|
|
1158
|
-
* - `"portable-authority"`: a DID whose verification method made a valid
|
|
1159
|
-
* Object Integrity Proof. It authenticates the [FEP-ef61] portable
|
|
1160
|
-
* actors of that DID, and nothing else.
|
|
1161
|
-
*
|
|
1162
|
-
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
1163
|
-
*/
|
|
1164
|
-
readonly kind: "actor" | "portable-authority";
|
|
1165
|
-
/** The actor ID, or the DID if {@link kind} is `"portable-authority"`. */
|
|
1166
|
-
readonly id: URL;
|
|
1167
|
-
/**
|
|
1168
|
-
* How the principal was authenticated:
|
|
1169
|
-
*
|
|
1170
|
-
* - `"http-signatures"`: it signed the HTTP request.
|
|
1171
|
-
* - `"linked-data-signatures"`: it made the Linked Data Signature of the
|
|
1172
|
-
* activity.
|
|
1173
|
-
* - `"object-integrity-proofs"`: it made an Object Integrity Proof of the
|
|
1174
|
-
* activity.
|
|
1175
|
-
* - `"origin"`: the activity was fetched again from the actor's own web
|
|
1176
|
-
* origin, which happens only for `Context.routeActivity()`.
|
|
1177
|
-
*/
|
|
1178
|
-
readonly mechanism: "http-signatures" | "linked-data-signatures" | "object-integrity-proofs" | "origin";
|
|
1179
|
-
/** The key or verification method that authenticated the principal. */
|
|
1180
|
-
readonly keyId: URL | null;
|
|
1181
|
-
}
|
|
1182
|
-
/**
|
|
1183
|
-
* Who Fedify authenticated for an incoming activity, and the interpretation of
|
|
1184
|
-
* the activity it authenticated. Inbox listeners receive it as
|
|
1185
|
-
* {@link InboxContext.authentication}.
|
|
1186
|
-
*
|
|
1187
|
-
* Authenticated principals are independent of the activity's declared
|
|
1188
|
-
* `actor`: an activity forwarded by a relay is signed by the relay in its
|
|
1189
|
-
* HTTP request, but its document may be signed by its author, and some
|
|
1190
|
-
* activities, such as [FEP-7aa9] `FeatureRequest`s sent by Mastodon, declare
|
|
1191
|
-
* no `actor` at all. A valid signature alone does not authorize anything;
|
|
1192
|
-
* use {@link isActorAuthenticated} to check whether a specific actor was
|
|
1193
|
-
* authenticated.
|
|
1194
|
-
*
|
|
1195
|
-
* [FEP-7aa9]: https://w3id.org/fep/7aa9
|
|
1196
|
-
* @since 2.5.0
|
|
1197
|
-
*/
|
|
1198
|
-
interface InboxAuthenticationEvidence {
|
|
1199
|
-
/**
|
|
1200
|
-
* Whether signatures were verified at all. It is `false` only when
|
|
1201
|
-
* signature verification is skipped, or when there is no evidence, e.g.,
|
|
1202
|
-
* for an activity queued by an older version of Fedify. In that case all
|
|
1203
|
-
* the principal lists are empty.
|
|
1204
|
-
*/
|
|
1205
|
-
readonly verified: boolean;
|
|
1206
|
-
/**
|
|
1207
|
-
* The principals that signed the HTTP request, i.e., the server that
|
|
1208
|
-
* delivered the activity, which may have forwarded it. It is empty when
|
|
1209
|
-
* the activity document was authenticated by its own signatures, so that
|
|
1210
|
-
* HTTP Signatures did not need to be verified.
|
|
1211
|
-
*/
|
|
1212
|
-
readonly requestSigners: readonly InboxPrincipal[];
|
|
1213
|
-
/**
|
|
1214
|
-
* The principals that made the verified Linked Data Signature or Object
|
|
1215
|
-
* Integrity Proofs of the activity document. All of them are listed when
|
|
1216
|
-
* there are several proofs.
|
|
1217
|
-
*/
|
|
1218
|
-
readonly documentSigners: readonly InboxPrincipal[];
|
|
1219
|
-
/**
|
|
1220
|
-
* The actors authenticated because `Context.routeActivity()` fetched the
|
|
1221
|
-
* activity again from their own web origin. It is always empty for
|
|
1222
|
-
* activities delivered to an inbox.
|
|
1223
|
-
*/
|
|
1224
|
-
readonly originAuthenticated: readonly InboxPrincipal[];
|
|
1225
|
-
/**
|
|
1226
|
-
* The activity as Fedify interpreted it while authenticating it, in
|
|
1227
|
-
* expanded JSON-LD. Typed vocabulary objects omit some values, such as
|
|
1228
|
-
* blank node references and values they cannot decode, so authorization
|
|
1229
|
-
* that has to count every value of a property, e.g., that a property has
|
|
1230
|
-
* exactly one value, should inspect this instead. It is deeply frozen.
|
|
1231
|
-
* It is empty when there is no evidence.
|
|
1232
|
-
*/
|
|
1233
|
-
readonly expandedActivity: readonly Record<string, unknown>[];
|
|
1234
|
-
/**
|
|
1235
|
-
* The base URL the activity was decoded with, e.g., the URL an activity
|
|
1236
|
-
* fetched by `Context.routeActivity()` was finally retrieved from, or
|
|
1237
|
-
* `null` if none was given. Relative IRIs left in
|
|
1238
|
-
* {@link expandedActivity} resolve against it, or against the activity's
|
|
1239
|
-
* own `@id` if it is `null`, as the decoder resolves them.
|
|
1240
|
-
*/
|
|
1241
|
-
readonly baseUrl: URL | null;
|
|
1242
|
-
}
|
|
1243
|
-
/**
|
|
1244
|
-
* Options for {@link isActorAuthenticated}.
|
|
1245
|
-
* @since 2.5.0
|
|
1246
|
-
*/
|
|
1247
|
-
interface IsActorAuthenticatedOptions {
|
|
1248
|
-
/**
|
|
1249
|
-
* Which principals to consider:
|
|
1250
|
-
*
|
|
1251
|
-
* - `"effective"` (default): the document signers if there are any,
|
|
1252
|
-
* otherwise the request signers if there are any, otherwise the actors
|
|
1253
|
-
* authenticated by their origin.
|
|
1254
|
-
* - `"document"`: the document signers only.
|
|
1255
|
-
*/
|
|
1256
|
-
readonly scope?: "effective" | "document";
|
|
1257
|
-
}
|
|
1258
|
-
/**
|
|
1259
|
-
* Checks whether the given evidence authenticates the given actor.
|
|
1260
|
-
*
|
|
1261
|
-
* Actor IDs are compared exactly, except that [FEP-ef61] portable IDs and
|
|
1262
|
-
* compatible identifiers are compared by their canonical portable IDs, and
|
|
1263
|
-
* a portable authority (a DID) authenticates the portable actors of that DID.
|
|
1264
|
-
*
|
|
1265
|
-
* @example
|
|
1266
|
-
* ``` typescript
|
|
1267
|
-
* federation
|
|
1268
|
-
* .setInboxListeners("/users/{identifier}/inbox", "/inbox")
|
|
1269
|
-
* .on(Follow, async (ctx, follow) => {
|
|
1270
|
-
* if (follow.actorId == null) return;
|
|
1271
|
-
* // The actor is always authenticated for activities that declare one,
|
|
1272
|
-
* // but the same check works for any actor an activity names:
|
|
1273
|
-
* isActorAuthenticated(ctx.authentication, follow.actorId);
|
|
1274
|
-
* });
|
|
1275
|
-
* ```
|
|
1276
|
-
*
|
|
1277
|
-
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
1278
|
-
* @param evidence The authentication evidence, usually
|
|
1279
|
-
* {@link InboxContext.authentication}.
|
|
1280
|
-
* @param actorId The actor ID to check.
|
|
1281
|
-
* @param options Options.
|
|
1282
|
-
* @returns `true` if the actor is authenticated.
|
|
1283
|
-
* @since 2.5.0
|
|
1284
|
-
*/
|
|
1285
|
-
declare function isActorAuthenticated(evidence: InboxAuthenticationEvidence, actorId: URL, options?: IsActorAuthenticatedOptions): boolean;
|
|
1286
|
-
/**
|
|
1287
|
-
* A {@link InboxPrincipal} as stored in a queued message.
|
|
1288
|
-
* The wire spellings remain independent of the public API spellings.
|
|
1289
|
-
* @internal
|
|
1290
|
-
*/
|
|
1291
|
-
interface SerializedInboxPrincipal {
|
|
1292
|
-
readonly kind: "actor" | "portableAuthority";
|
|
1293
|
-
readonly id: string;
|
|
1294
|
-
readonly mechanism: "httpSignatures" | "linkedDataSignatures" | "objectIntegrityProofs" | "origin";
|
|
1295
|
-
readonly keyId: string | null;
|
|
1296
|
-
}
|
|
1297
|
-
/**
|
|
1298
|
-
* The principals of an {@link InboxAuthenticationEvidence} as stored in
|
|
1299
|
-
* a queued message. The expanded activity and the base URL are restored
|
|
1300
|
-
* from the queued verified view instead.
|
|
1301
|
-
* @internal
|
|
1302
|
-
*/
|
|
1303
|
-
interface SerializedInboxAuthentication {
|
|
1304
|
-
readonly verified: boolean;
|
|
1305
|
-
readonly requestSigners: readonly SerializedInboxPrincipal[];
|
|
1306
|
-
readonly documentSigners: readonly SerializedInboxPrincipal[];
|
|
1307
|
-
readonly originAuthenticated: readonly SerializedInboxPrincipal[];
|
|
1308
|
-
}
|
|
1309
|
-
//#endregion
|
|
1310
|
-
//#region src/federation/inbox-view.d.ts
|
|
1311
|
-
/**
|
|
1312
|
-
* A {@link ContextSnapshotEntry} as stored in a queued message. A response
|
|
1313
|
-
* that equals the one Fedify bundles for the URL is stored as a reference to
|
|
1314
|
-
* the bundled context, along with its hash for diagnostics.
|
|
1315
|
-
* @internal
|
|
1316
|
-
*/
|
|
1317
|
-
type SerializedContextSnapshotEntry = {
|
|
1318
|
-
readonly policy: EffectiveContextLoaderPolicy;
|
|
1319
|
-
readonly url: string; /** The SHA-256 of the canonical JSON of the whole response. */
|
|
1320
|
-
readonly sha256: string;
|
|
1321
|
-
} & ({
|
|
1322
|
-
readonly bundled: true;
|
|
1323
|
-
} | {
|
|
1324
|
-
readonly response: RemoteDocument;
|
|
1325
|
-
});
|
|
1326
|
-
/**
|
|
1327
|
-
* The interpretation of an incoming activity that Fedify authenticated, as
|
|
1328
|
-
* stored in a queued message. The document itself is not copied; it is
|
|
1329
|
-
* a field of the message.
|
|
1330
|
-
* @internal
|
|
2059
|
+
* workloads.
|
|
2060
|
+
*
|
|
2061
|
+
* When using `ParallelMessageQueue`, the ordering guarantee is preserved
|
|
2062
|
+
* *only if* the underlying queue implementation delivers messages in a wrapper
|
|
2063
|
+
* format that includes the `__fedify_ordering_key__` property. Currently,
|
|
2064
|
+
* only `DenoKvMessageQueue` and `WorkersMessageQueue` use this format.
|
|
2065
|
+
* For other queue implementations (e.g., `InProcessMessageQueue`,
|
|
2066
|
+
* `RedisMessageQueue`, `PostgresMessageQueue`, `SqliteMessageQueue`,
|
|
2067
|
+
* `AmqpMessageQueue`), the ordering key cannot be detected by
|
|
2068
|
+
* `ParallelMessageQueue`, so ordering guarantees are handled by those
|
|
2069
|
+
* implementations directly rather than at the `ParallelMessageQueue` level.
|
|
2070
|
+
*
|
|
2071
|
+
* Messages with the same ordering key will never be processed concurrently
|
|
2072
|
+
* by different workers, ensuring sequential processing within each key.
|
|
2073
|
+
* Messages with different ordering keys (or no ordering key) can still be
|
|
2074
|
+
* processed in parallel.
|
|
2075
|
+
*
|
|
2076
|
+
* @since 1.0.0
|
|
1331
2077
|
*/
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
readonly
|
|
1335
|
-
|
|
1336
|
-
readonly policy: EffectiveContextLoaderPolicy;
|
|
2078
|
+
declare class ParallelMessageQueue implements MessageQueue {
|
|
2079
|
+
#private;
|
|
2080
|
+
readonly queue: MessageQueue;
|
|
2081
|
+
readonly workers: number;
|
|
1337
2082
|
/**
|
|
1338
|
-
*
|
|
1339
|
-
*
|
|
1340
|
-
* received, or its `normalizedActivity`, i.e., the payload compacted for
|
|
1341
|
-
* Linked Data Signatures.
|
|
2083
|
+
* Inherits the native retry capability from the wrapped queue.
|
|
2084
|
+
* @since 1.7.0
|
|
1342
2085
|
*/
|
|
1343
|
-
readonly
|
|
1344
|
-
/**
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
2086
|
+
readonly nativeRetrial?: boolean;
|
|
2087
|
+
/**
|
|
2088
|
+
* Inherits the native deduplication capability from the wrapped queue.
|
|
2089
|
+
* @since 2.4.0
|
|
2090
|
+
*/
|
|
2091
|
+
readonly nativeDeduplication?: boolean;
|
|
2092
|
+
/**
|
|
2093
|
+
* Inherits the atomic batch capability from the wrapped queue.
|
|
2094
|
+
* @since 2.4.0
|
|
2095
|
+
*/
|
|
2096
|
+
readonly atomicEnqueueMany?: boolean;
|
|
2097
|
+
/**
|
|
2098
|
+
* Inherits the message size limit from the wrapped queue.
|
|
2099
|
+
* @since 2.5.0
|
|
2100
|
+
*/
|
|
2101
|
+
readonly maxMessageSize?: number;
|
|
2102
|
+
readonly getDepth?: () => Promise<MessageQueueDepth>;
|
|
2103
|
+
/**
|
|
2104
|
+
* Constructs a new {@link ParallelMessageQueue} with the given queue and
|
|
2105
|
+
* number of workers.
|
|
2106
|
+
* @param queue The message queue to use under the hood. Note that
|
|
2107
|
+
* {@link ParallelMessageQueue} cannot be nested.
|
|
2108
|
+
* @param workers The number of workers to process messages in parallel.
|
|
2109
|
+
* @throws {TypeError} If the given queue is an instance of
|
|
2110
|
+
* {@link ParallelMessageQueue}.
|
|
2111
|
+
*/
|
|
2112
|
+
constructor(queue: MessageQueue, workers: number);
|
|
2113
|
+
enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
2114
|
+
enqueueMany(messages: readonly any[], options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
2115
|
+
listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
|
|
1350
2116
|
}
|
|
1351
2117
|
//#endregion
|
|
1352
2118
|
//#region src/federation/handler.d.ts
|
|
@@ -1603,187 +2369,6 @@ interface TaskEnqueueOptions {
|
|
|
1603
2369
|
*/
|
|
1604
2370
|
declare function createFederationBuilder<TContextData>(): FederationBuilder<TContextData>;
|
|
1605
2371
|
//#endregion
|
|
1606
|
-
//#region src/federation/queue.d.ts
|
|
1607
|
-
interface SenderKeyJwkPair {
|
|
1608
|
-
readonly keyId: string;
|
|
1609
|
-
readonly privateKey: JsonWebKey;
|
|
1610
|
-
}
|
|
1611
|
-
/**
|
|
1612
|
-
* A message that represents a task to be processed by the background worker.
|
|
1613
|
-
* The concrete type of the message depends on the `type` property.
|
|
1614
|
-
*
|
|
1615
|
-
* Please do not depend on the concrete types of the messages, as they may
|
|
1616
|
-
* change in the future. You should treat the `Message` type as an opaque
|
|
1617
|
-
* type.
|
|
1618
|
-
* @since 1.6.0
|
|
1619
|
-
*/
|
|
1620
|
-
type Message = FanoutMessage | OutboxMessage | InboxMessage | TaskMessage;
|
|
1621
|
-
interface FanoutMessage {
|
|
1622
|
-
readonly type: "fanout";
|
|
1623
|
-
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1624
|
-
readonly baseUrl: string;
|
|
1625
|
-
readonly keys: readonly SenderKeyJwkPair[];
|
|
1626
|
-
readonly inboxes: Readonly<Record<string, {
|
|
1627
|
-
readonly actorIds: readonly string[];
|
|
1628
|
-
readonly sharedInbox: boolean;
|
|
1629
|
-
/**
|
|
1630
|
-
* The canonical form of the FEP-ef61 portable inbox that the inbox
|
|
1631
|
-
* stands for.
|
|
1632
|
-
* @internal
|
|
1633
|
-
*/
|
|
1634
|
-
readonly portableInbox?: string;
|
|
1635
|
-
/**
|
|
1636
|
-
* The compatible identifiers of the portable inbox on each gateway to
|
|
1637
|
-
* deliver through, in order.
|
|
1638
|
-
* @internal
|
|
1639
|
-
*/
|
|
1640
|
-
readonly gatewayInboxes?: readonly string[];
|
|
1641
|
-
}>>;
|
|
1642
|
-
readonly activity: unknown;
|
|
1643
|
-
readonly activityId?: string;
|
|
1644
|
-
readonly activityType: string;
|
|
1645
|
-
readonly collectionSync?: string;
|
|
1646
|
-
readonly orderingKey?: string;
|
|
1647
|
-
/**
|
|
1648
|
-
* Whether to apply outgoing JSON-LD wire-format normalization to queued
|
|
1649
|
-
* activities that already carry Object Integrity Proofs.
|
|
1650
|
-
*
|
|
1651
|
-
* `true` is used for proofs Fedify created before fanout, or when callers
|
|
1652
|
-
* explicitly request normalization for locally pre-signed activities.
|
|
1653
|
-
* `false`/`undefined` preserves existing proofs as-is.
|
|
1654
|
-
*/
|
|
1655
|
-
readonly normalizeExistingProofs?: boolean;
|
|
1656
|
-
readonly traceContext: Readonly<Record<string, string>>;
|
|
1657
|
-
}
|
|
1658
|
-
interface OutboxMessage {
|
|
1659
|
-
readonly type: "outbox";
|
|
1660
|
-
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1661
|
-
readonly baseUrl: string;
|
|
1662
|
-
readonly keys: readonly SenderKeyJwkPair[];
|
|
1663
|
-
readonly activity: unknown;
|
|
1664
|
-
readonly activityId?: string;
|
|
1665
|
-
readonly activityType: string;
|
|
1666
|
-
readonly inbox: string;
|
|
1667
|
-
readonly sharedInbox: boolean;
|
|
1668
|
-
readonly actorIds?: readonly string[];
|
|
1669
|
-
readonly started: string;
|
|
1670
|
-
readonly attempt: number;
|
|
1671
|
-
readonly headers: Readonly<Record<string, string>>;
|
|
1672
|
-
readonly orderingKey?: string;
|
|
1673
|
-
/**
|
|
1674
|
-
* Whether this message is currently held by the outbound circuit breaker.
|
|
1675
|
-
* @internal
|
|
1676
|
-
*/
|
|
1677
|
-
readonly circuitHeld?: true;
|
|
1678
|
-
/**
|
|
1679
|
-
* When Fedify first held this message because the remote host circuit was
|
|
1680
|
-
* open.
|
|
1681
|
-
* @internal
|
|
1682
|
-
*/
|
|
1683
|
-
readonly circuitHeldSince?: string;
|
|
1684
|
-
/**
|
|
1685
|
-
* The canonical form of the FEP-ef61 portable inbox that {@link inbox}, its
|
|
1686
|
-
* compatible identifier on a gateway, stands for.
|
|
1687
|
-
* @internal
|
|
1688
|
-
*/
|
|
1689
|
-
readonly portableInbox?: string;
|
|
1690
|
-
/**
|
|
1691
|
-
* The compatible identifiers of the FEP-ef61 portable inbox on each gateway
|
|
1692
|
-
* that is still to be tried, in order. {@link inbox} is the first one.
|
|
1693
|
-
* If there is more than one, the activity is delivered through the first
|
|
1694
|
-
* gateway that accepts it.
|
|
1695
|
-
* @internal
|
|
1696
|
-
*/
|
|
1697
|
-
readonly gatewayInboxes?: readonly string[];
|
|
1698
|
-
/**
|
|
1699
|
-
* The times before which each of {@link gatewayInboxes} must not be tried
|
|
1700
|
-
* again, as their responses' `Retry-After` headers requested, keyed by
|
|
1701
|
-
* the inbox URL, in ISO 8601.
|
|
1702
|
-
* @internal
|
|
1703
|
-
*/
|
|
1704
|
-
readonly gatewayNotBefore?: Readonly<Record<string, string>>;
|
|
1705
|
-
readonly traceContext: Readonly<Record<string, string>>;
|
|
1706
|
-
}
|
|
1707
|
-
/**
|
|
1708
|
-
* A message that carries a custom background task. Every field is
|
|
1709
|
-
* a string, number, or plain record so that the message survives both
|
|
1710
|
-
* JSON serialization and structured clone on every queue backend.
|
|
1711
|
-
* @since 2.4.0
|
|
1712
|
-
*/
|
|
1713
|
-
interface TaskMessage {
|
|
1714
|
-
readonly type: "task";
|
|
1715
|
-
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1716
|
-
readonly baseUrl: string;
|
|
1717
|
-
readonly taskName: string;
|
|
1718
|
-
/** devalue-encoded task data; vocab objects bridged to expanded JSON-LD. */
|
|
1719
|
-
readonly data: string;
|
|
1720
|
-
readonly started: string;
|
|
1721
|
-
readonly attempt: number;
|
|
1722
|
-
readonly orderingKey?: string;
|
|
1723
|
-
readonly traceContext: Readonly<Record<string, string>>;
|
|
1724
|
-
}
|
|
1725
|
-
interface InboxMessage {
|
|
1726
|
-
readonly type: "inbox";
|
|
1727
|
-
readonly id: ReturnType<typeof crypto.randomUUID>;
|
|
1728
|
-
readonly baseUrl: string;
|
|
1729
|
-
readonly activity: unknown;
|
|
1730
|
-
/**
|
|
1731
|
-
* The normalized JSON-LD representation of a signed inbox activity that
|
|
1732
|
-
* Fedify already compacted successfully while accepting the request. Queue
|
|
1733
|
-
* workers can reuse this producer-side parse cache under stricter loader or
|
|
1734
|
-
* network constraints without changing the raw payload preserved for
|
|
1735
|
-
* forwarding.
|
|
1736
|
-
*
|
|
1737
|
-
* This may exist even when {@link ldSignatureVerified} is `false`, because
|
|
1738
|
-
* fallback-authenticated traffic and already-queued backlog items can still
|
|
1739
|
-
* depend on the cached normalized form to avoid re-fetching remote custom
|
|
1740
|
-
* contexts during worker processing.
|
|
1741
|
-
*
|
|
1742
|
-
* This is optional for backward compatibility with messages that were
|
|
1743
|
-
* queued by older Fedify versions or that were already in a queue before
|
|
1744
|
-
* upgrading.
|
|
1745
|
-
*
|
|
1746
|
-
* Fedify keeps this on the queued message itself instead of an external
|
|
1747
|
-
* sidecar because generic queue backends do not provide reliable lifecycle
|
|
1748
|
-
* guarantees for auxiliary storage across retries and redeliveries.
|
|
1749
|
-
*
|
|
1750
|
-
* @internal
|
|
1751
|
-
*/
|
|
1752
|
-
readonly normalizedActivity?: unknown;
|
|
1753
|
-
/**
|
|
1754
|
-
* Whether the producer actually verified the Linked Data Signature before
|
|
1755
|
-
* queueing this message. This lets workers distinguish verified LDS replay
|
|
1756
|
-
* from other authenticated inbox traffic that merely happened to include a
|
|
1757
|
-
* signature block. This provenance marker is separate from the optional
|
|
1758
|
-
* normalizedActivity parse cache.
|
|
1759
|
-
*
|
|
1760
|
-
* `undefined` preserves backward compatibility with older queued messages
|
|
1761
|
-
* that predate this marker.
|
|
1762
|
-
*
|
|
1763
|
-
* @internal
|
|
1764
|
-
*/
|
|
1765
|
-
readonly ldSignatureVerified?: boolean;
|
|
1766
|
-
/**
|
|
1767
|
-
* The interpretation of the activity that Fedify authenticated, i.e., which
|
|
1768
|
-
* document it was parsed from and every JSON-LD context response the parse
|
|
1769
|
-
* used, so that the worker and its retries dispatch the very same
|
|
1770
|
-
* interpretation without loading contexts again. Absent in messages queued
|
|
1771
|
-
* by older Fedify versions.
|
|
1772
|
-
* @internal
|
|
1773
|
-
*/
|
|
1774
|
-
readonly verifiedView?: SerializedVerifiedActivityView;
|
|
1775
|
-
/**
|
|
1776
|
-
* Who Fedify authenticated for the activity. Absent in messages queued by
|
|
1777
|
-
* older Fedify versions.
|
|
1778
|
-
* @internal
|
|
1779
|
-
*/
|
|
1780
|
-
readonly authentication?: SerializedInboxAuthentication;
|
|
1781
|
-
readonly started: string;
|
|
1782
|
-
readonly attempt: number;
|
|
1783
|
-
readonly identifier: string | null;
|
|
1784
|
-
readonly traceContext: Readonly<Record<string, string>>;
|
|
1785
|
-
}
|
|
1786
|
-
//#endregion
|
|
1787
2372
|
//#region src/federation/middleware.d.ts
|
|
1788
2373
|
/**
|
|
1789
2374
|
* Configures the task queues for sending and receiving activities.
|
|
@@ -1930,6 +2515,31 @@ interface FederationStartQueueOptions {
|
|
|
1930
2515
|
* @since 1.6.0
|
|
1931
2516
|
*/
|
|
1932
2517
|
interface Federatable<TContextData> extends TaskRegistry<TContextData> {
|
|
2518
|
+
/**
|
|
2519
|
+
* Registers observers for outgoing activity processing.
|
|
2520
|
+
*
|
|
2521
|
+
* Each call replaces all previously registered outbound observers.
|
|
2522
|
+
* Pass an empty object to clear them. Fedify copies callbacks and capture policies;
|
|
2523
|
+
* later changes to the supplied object do not affect registration.
|
|
2524
|
+
* Available on builders and directly created federations. Building copies
|
|
2525
|
+
* the callbacks, and an active send keeps the callback selected at entry.
|
|
2526
|
+
* Observes send, original-payload forwarding, and automatic portable
|
|
2527
|
+
* replication preparation, destination planning, and handoffs, including
|
|
2528
|
+
* outbox-context operations and fanout continuation handoffs. Separate
|
|
2529
|
+
* callbacks report concrete send attempts and actual HTTP exchanges, including
|
|
2530
|
+
* queued retries and gateway fallback. Worker reports retain local execution
|
|
2531
|
+
* results and actual enqueue, retry, deferral, and abandonment actions,
|
|
2532
|
+
* separately from attempts and backend acknowledgment.
|
|
2533
|
+
* Known IDs, original inbox source, and
|
|
2534
|
+
* application correlation survive queue work; workers use current context data.
|
|
2535
|
+
* Header values, bounded response-body streaming and sender-payload projections
|
|
2536
|
+
* are independently opt-in. Body consumers require explicit byte/time limits;
|
|
2537
|
+
* other metadata callbacks have no default timeout.
|
|
2538
|
+
* This is separate from incoming C2S {@link Federatable.setOutboxListeners}.
|
|
2539
|
+
* @param observers The optional callbacks to register.
|
|
2540
|
+
* @since 2.5.0
|
|
2541
|
+
*/
|
|
2542
|
+
setOutboundObservers(observers: OutboundObservers<TContextData>): void;
|
|
1933
2543
|
/**
|
|
1934
2544
|
* Registers a NodeInfo dispatcher.
|
|
1935
2545
|
* @param path The URI path pattern for the NodeInfo dispatcher. The syntax
|
|
@@ -5002,6 +5612,14 @@ type ParseUriResult = {
|
|
|
5002
5612
|
* Options for {@link Context.sendActivity} method.
|
|
5003
5613
|
*/
|
|
5004
5614
|
interface SendActivityOptions {
|
|
5615
|
+
/**
|
|
5616
|
+
* Application-owned correlation for this invocation, never a deduplication
|
|
5617
|
+
* key. Preserved exactly, including an empty string. At most 1,024 UTF-8
|
|
5618
|
+
* bytes; invalid types and oversized values are rejected before preparation.
|
|
5619
|
+
* Omission means no application dispatch ID for this new invocation.
|
|
5620
|
+
* @since 2.5.0
|
|
5621
|
+
*/
|
|
5622
|
+
readonly dispatchId?: string;
|
|
5005
5623
|
/**
|
|
5006
5624
|
* Whether to prefer the shared inbox for the recipients.
|
|
5007
5625
|
*/
|
|
@@ -5163,4 +5781,4 @@ interface ActorKeyPair extends CryptoKeyPair {
|
|
|
5163
5781
|
readonly multikey: Multikey;
|
|
5164
5782
|
}
|
|
5165
5783
|
//#endregion
|
|
5166
|
-
export {
|
|
5784
|
+
export { respondWithObjectIfAcceptable as $, IsActorAuthenticatedOptions as $t, InboxChallengePolicy as A, OutboundResponseBodyEvent as An, HashlinkMediaDispatcher as At, createFederation as B, OutboxListenerErrorHandler as Bt, FederationBenchmarkOptions as C, OutboundInboxRequest as Cn, AuthorizePredicate as Ct, FederationStartQueueOptions as D, OutboundPreparationResult as Dn, CustomCollectionCounter as Dt, FederationOptions as E, OutboundObservers as En, CollectionDispatcher as Et, PortableInboxForwardingOptions as F, OutboundWorkerPreparationDiagnostic as Fn, NodeInfoDispatcher as Ft, TaskHandler as G, UnverifiedActivityHandler as Gt, TaskDefinition as H, PortableActorIdMapper as Ht, Rfc6570Expression as I, OutboundWorkerReport as In, ObjectAuthorizePredicate as It, RetryContext as J, SendActivityError as Jt, TaskRegistry as K, UnverifiedActivityReason as Kt, FederationKvPrefixes as L, OutboundWorkerSchedule as Ln, ObjectDispatcher as Lt, MediaUploaderSetters as M, OutboundSourceMetadata as Mn, InboxErrorHandler as Mt, ObjectCallbackSetters as N, OutboundWorkerAction as Nn, InboxListener as Nt, IdempotencyKeyCallback as O, OutboundProvenance as On, CustomCollectionCursor as Ot, OutboxListenerSetters as P, OutboundWorkerChild as Pn, MediaUploaderCallback as Pt, respondWithObject as Q, InboxPrincipal as Qt, FederationOrigin as R, OutboxErrorHandler as Rt, Federation as S, OutboundHttpResponseMetadata as Sn, ActorKeyPairsDispatcher as St, FederationFetchOptions as T, OutboundLocalContext as Tn, CollectionCursor as Tt, TaskDefinitionOptions as U, PortableCollectionOwnerMapper as Ut, createFederationBuilder as V, OutboxPermanentFailureHandler as Vt, TaskEnqueueOptions as W, SharedInboxKeyDispatcher as Wt, createExponentialBackoffPolicy as X, Message as Xt, RetryPolicy as Y, SenderKeyPair as Yt, RespondWithObjectOptions as Z, InboxAuthenticationEvidence as Zt, ActorCallbackSetters as _, OutboundBroadcastEvent as _n, normalizeCircuitBreakerOptions as _t, GetObjectOptions as a, InboxAuthentication as an, MessageQueueListenOptions as at, CustomCollectionCallbackSetters as b, OutboundHeaderSnapshot as bn, ActorDispatcher as bt, IsSignedByAudienceOptions as c, InboxRequestFinishedHandler as cn, CircuitBreakerActivityDrop as ct, ParseUriResult as d, InboxListenerOptions as dn, CircuitBreakerFailurePolicy as dt, isActorAuthenticated as en, InProcessMessageQueue as et, PortableRequest as f, OutboundActivityReference as fn, CircuitBreakerKvState as ft, SendActivityOptionsForCollection as g, OutboundBodyCaptureSummary as gn, NormalizedCircuitBreakerOptions as gt, SendActivityOptions as h, OutboundAttemptResponse as hn, CircuitBreakerStateChange as ht, GetActorOptions as i, ActivityTransformer as in, MessageQueueEnqueueOptions as it, InboxListenerSetters as j, OutboundSenderPayload as jn, HashlinkMediaRequest as jt, IdempotencyStrategy as k, OutboundResponseBodyCapture as kn, CustomCollectionDispatcher as kt, OutboxContext as l, InboxRequestOutcome as ln, CircuitBreakerBeforeSendDecision as lt, RouteActivityOptions as m, OutboundAttemptReport as mn, CircuitBreakerState as mt, Context as n, buildCollectionSynchronizationHeader as nn, MessageQueue as nt, GetSignedKeyOptions as o, InboxJsonValue as on, ParallelMessageQueue as ot, RequestContext as p, OutboundAttemptFailure as pn, CircuitBreakerOptions as pt, CreateExponentialBackoffPolicyOptions as q, WebFingerLinksDispatcher as qt, ForwardActivityOptions as r, digest as rn, MessageQueueDepth as rt, InboxContext as s, InboxRequestCancellation as sn, CircuitBreaker as st, ActorKeyPair as t, PageItems as tn, InProcessMessageQueueOptions as tt, ParseUriOptions as u, InboxRequestReport as un, CircuitBreakerCreateOptions as ut, CollectionCallbackSetters as v, OutboundDeliveryEvent as vn, parseCircuitBreakerKvState as vt, FederationBuilder as w, OutboundJsonValue as wn, CollectionCounter as wt, Federatable as x, OutboundHttpExchangeReport as xn, ActorHandleMapper as xt, ConstructorWithTypeId as y, OutboundHeaderPolicy as yn, ActorAliasMapper as yt, FederationQueueOptions as z, OutboxListener as zt };
|