@fedify/relay 2.0.0-dev.1908 → 2.0.0-dev.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,6 +13,9 @@ This package provides ActivityPub relay functionality for the [Fedify]
13
13
  ecosystem, enabling the creation and management of relay servers that can
14
14
  forward activities between federated instances.
15
15
 
16
+ For comprehensive documentation on building and operating relay servers,
17
+ see the [*Relay server* section in the Fedify manual][manual].
18
+
16
19
 
17
20
  What is an ActivityPub relay?
18
21
  ------------------------------
@@ -33,7 +36,7 @@ This package supports two popular relay protocols used in the fediverse:
33
36
  ### Mastodon-style relay
34
37
 
35
38
  The Mastodon-style relay protocol uses LD signatures for activity
36
- verification and follows the Public collection. This protocol is widely
39
+ verification and follows the Public collection. This protocol is widely
37
40
  supported by Mastodon and many other ActivityPub implementations.
38
41
 
39
42
  Key features:
@@ -46,11 +49,16 @@ Key features:
46
49
 
47
50
  ### LitePub-style relay
48
51
 
49
- *LitePub relay support is planned for a future release.*
50
-
51
52
  The LitePub-style relay protocol uses bidirectional following relationships
52
53
  and wraps activities in `Announce` activities for distribution.
53
54
 
55
+ Key features:
56
+
57
+ - Reciprocal following between relay and subscribers
58
+ - Activities wrapped in `Announce` for distribution
59
+ - Two-phase subscription (pending → accepted)
60
+ - Enhanced federation capabilities
61
+
54
62
 
55
63
  Installation
56
64
  ------------
@@ -83,43 +91,69 @@ bun add @fedify/relay
83
91
  Usage
84
92
  -----
85
93
 
86
- ### Creating a Mastodon-style relay
94
+ ### Creating a relay
87
95
 
88
- Here's a simple example of creating a Mastodon-compatible relay server:
96
+ Here's a simple example of creating a relay server using the factory function:
89
97
 
90
98
  ~~~~ typescript
91
- import { MastodonRelay } from "@fedify/relay";
99
+ import { createRelay } from "@fedify/relay";
92
100
  import { MemoryKvStore } from "@fedify/fedify";
93
101
 
94
- const relay = new MastodonRelay({
102
+ // Create a Mastodon-style relay
103
+ const relay = createRelay("mastodon", {
95
104
  kv: new MemoryKvStore(),
96
105
  domain: "relay.example.com",
97
- });
98
-
99
- // Optional: Set a custom subscription handler to approve/reject subscriptions
100
- relay.setSubscriptionHandler(async (ctx, actor) => {
101
- // Implement your approval logic here
102
- // Return true to approve, false to reject
103
- const domain = new URL(actor.id!).hostname;
104
- const blockedDomains = ["spam.example", "blocked.example"];
105
- return !blockedDomains.includes(domain);
106
+ // Required: Set a subscription handler to approve/reject subscriptions
107
+ subscriptionHandler: async (ctx, actor) => {
108
+ // For an open relay, simply return true
109
+ // return true;
110
+
111
+ // Or implement custom approval logic:
112
+ const domain = new URL(actor.id!).hostname;
113
+ const blockedDomains = ["spam.example", "blocked.example"];
114
+ return !blockedDomains.includes(domain);
115
+ },
106
116
  });
107
117
 
108
118
  // Serve the relay
109
119
  Deno.serve((request) => relay.fetch(request));
110
120
  ~~~~
111
121
 
122
+ You can also create a LitePub-style relay by changing the type:
123
+
124
+ ~~~~ typescript
125
+ const relay = createRelay("litepub", {
126
+ kv: new MemoryKvStore(),
127
+ domain: "relay.example.com",
128
+ subscriptionHandler: async (ctx, actor) => true,
129
+ });
130
+ ~~~~
131
+
112
132
  ### Subscription handling
113
133
 
114
- By default, the relay automatically rejects all subscription requests.
115
- You can customize this behavior by setting a subscription handler:
134
+ The `subscriptionHandler` is required and determines whether to approve or reject
135
+ subscription requests. For an open relay that accepts all subscriptions:
116
136
 
117
137
  ~~~~ typescript
118
- relay.setSubscriptionHandler(async (ctx, actor) => {
119
- // Example: Only allow subscriptions from specific domains
120
- const domain = new URL(actor.id!).hostname;
121
- const allowedDomains = ["mastodon.social", "fosstodon.org"];
122
- return allowedDomains.includes(domain);
138
+ const relay = createRelay("mastodon", {
139
+ kv: new MemoryKvStore(),
140
+ domain: "relay.example.com",
141
+ subscriptionHandler: async (ctx, actor) => true, // Accept all
142
+ });
143
+ ~~~~
144
+
145
+ You can also implement custom approval logic:
146
+
147
+ ~~~~ typescript
148
+ const relay = createRelay("mastodon", {
149
+ kv: new MemoryKvStore(),
150
+ domain: "relay.example.com",
151
+ subscriptionHandler: async (ctx, actor) => {
152
+ // Example: Only allow subscriptions from specific domains
153
+ const domain = new URL(actor.id!).hostname;
154
+ const allowedDomains = ["mastodon.social", "fosstodon.org"];
155
+ return allowedDomains.includes(domain);
156
+ },
123
157
  });
124
158
  ~~~~
125
159
 
@@ -131,13 +165,14 @@ example with Hono:
131
165
 
132
166
  ~~~~ typescript
133
167
  import { Hono } from "hono";
134
- import { MastodonRelay } from "@fedify/relay";
168
+ import { createRelay } from "@fedify/relay";
135
169
  import { MemoryKvStore } from "@fedify/fedify";
136
170
 
137
171
  const app = new Hono();
138
- const relay = new MastodonRelay({
172
+ const relay = createRelay("mastodon", {
139
173
  kv: new MemoryKvStore(),
140
174
  domain: "relay.example.com",
175
+ subscriptionHandler: async (ctx, actor) => true,
141
176
  });
142
177
 
143
178
  app.use("*", async (c) => {
@@ -191,25 +226,47 @@ details.
191
226
  API reference
192
227
  -------------
193
228
 
194
- ### `MastodonRelay`
195
-
196
- A Mastodon-compatible ActivityPub relay implementation.
229
+ ### `createRelay()`
197
230
 
198
- #### Constructor
231
+ Factory function to create a relay instance.
199
232
 
200
233
  ~~~~ typescript
201
- new MastodonRelay(options: RelayOptions)
234
+ function createRelay(
235
+ type: "mastodon" | "litepub",
236
+ options: RelayOptions
237
+ ): BaseRelay
202
238
  ~~~~
203
239
 
204
- #### Properties
240
+ **Parameters:**
241
+
242
+ - `type`: The type of relay to create (`"mastodon"` or `"litepub"`)
243
+ - `options`: Configuration options for the relay
244
+
245
+ **Returns:** A relay instance (`MastodonRelay` or `LitePubRelay`)
205
246
 
206
- - `domain`: The relay's domain name (read-only)
247
+ ### `BaseRelay`
248
+
249
+ Abstract base class for relay implementations.
207
250
 
208
251
  #### Methods
209
252
 
210
253
  - `fetch(request: Request): Promise<Response>`: Handle incoming HTTP requests
211
- - `setSubscriptionHandler(handler: SubscriptionRequestHandler): this`:
212
- Set a custom handler for subscription approval/rejection
254
+
255
+ ### `MastodonRelay`
256
+
257
+ A Mastodon-compatible ActivityPub relay implementation that extends `BaseRelay`.
258
+
259
+ - Uses direct activity forwarding
260
+ - Immediate subscription approval
261
+ - Compatible with standard ActivityPub implementations
262
+
263
+ ### `LitePubRelay`
264
+
265
+ A LitePub-compatible ActivityPub relay implementation that extends `BaseRelay`.
266
+
267
+ - Uses bidirectional following
268
+ - Activities wrapped in `Announce`
269
+ - Two-phase subscription (pending → accepted)
213
270
 
214
271
  ### `RelayOptions`
215
272
 
@@ -217,12 +274,13 @@ Configuration options for the relay:
217
274
 
218
275
  - `kv: KvStore` (required): Key–value store for persisting relay data
219
276
  - `domain?: string`: Relay's domain name (defaults to `"localhost"`)
277
+ - `name?: string`: Relay's display name (defaults to `"ActivityPub Relay"`)
278
+ - `subscriptionHandler: SubscriptionRequestHandler` (required): Handler for
279
+ subscription approval/rejection
220
280
  - `documentLoaderFactory?: DocumentLoaderFactory`: Custom document loader
221
281
  factory
222
282
  - `authenticatedDocumentLoaderFactory?: AuthenticatedDocumentLoaderFactory`:
223
283
  Custom authenticated document loader factory
224
- - `federation?: Federation<void>`: Custom Federation instance (for advanced
225
- use cases)
226
284
  - `queue?: MessageQueue`: Message queue for background activity processing
227
285
 
228
286
  ### `SubscriptionRequestHandler`
@@ -231,17 +289,17 @@ A function that determines whether to approve a subscription request:
231
289
 
232
290
  ~~~~ typescript
233
291
  type SubscriptionRequestHandler = (
234
- ctx: Context<void>,
292
+ ctx: Context<RelayOptions>,
235
293
  clientActor: Actor,
236
294
  ) => Promise<boolean>
237
295
  ~~~~
238
296
 
239
- Parameters:
297
+ **Parameters:**
240
298
 
241
- - `ctx`: The Fedify context object
299
+ - `ctx`: The Fedify context object with relay options
242
300
  - `clientActor`: The actor requesting to subscribe
243
301
 
244
- Returns:
302
+ **Returns:**
245
303
 
246
304
  - `true` to approve the subscription
247
305
  - `false` to reject the subscription
@@ -255,3 +313,4 @@ Returns:
255
313
  [@fedify@hollo.social]: https://hollo.social/@fedify
256
314
  [Fedify]: https://fedify.dev/
257
315
  [Fedify documentation on key–value stores]: https://fedify.dev/manual/kv
316
+ [manual]: https://fedify.dev/manual/relay