@@ -46,11 +46,16 @@ Key features:
4646
4747### LitePub-style relay
4848
49- * LitePub relay support is planned for a future release.*
50-
5149The LitePub-style relay protocol uses bidirectional following relationships
5250and wraps activities in ` Announce ` activities for distribution.
5351
52+ Key features:
53+
54+ - Reciprocal following between relay and subscribers
55+ - Activities wrapped in ` Announce ` for distribution
56+ - Two-phase subscription (pending → accepted)
57+ - Enhanced federation capabilities
58+
5459
5560Installation
5661------------
@@ -83,43 +88,56 @@ bun add @fedify/relay
8388Usage
8489-----
8590
86- ### Creating a Mastodon-style relay
91+ ### Creating a relay
8792
88- Here's a simple example of creating a Mastodon-compatible relay server:
93+ Here's a simple example of creating a relay server using the factory function :
8994
9095~~~~ typescript
91- import { MastodonRelay } from " @fedify/relay" ;
96+ import { createRelay } from " @fedify/relay" ;
9297import { MemoryKvStore } from " @fedify/fedify" ;
9398
94- const relay = new MastodonRelay ({
99+ // Create a Mastodon-style relay
100+ const relay = createRelay (" mastodon" , {
95101 kv: new MemoryKvStore (),
96102 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 );
103+ // Optional: Set a custom subscription handler to approve/reject subscriptions
104+ subscriptionHandler : async (ctx , actor ) => {
105+ // Implement your approval logic here
106+ // Return true to approve, false to reject
107+ const domain = new URL (actor .id ! ).hostname ;
108+ const blockedDomains = [" spam.example" , " blocked.example" ];
109+ return ! blockedDomains .includes (domain );
110+ },
106111});
107112
108113// Serve the relay
109114Deno .serve ((request ) => relay .fetch (request ));
110115~~~~
111116
117+ You can also create a LitePub-style relay by changing the type:
118+
119+ ~~~~ typescript
120+ const relay = createRelay (" litepub" , {
121+ kv: new MemoryKvStore (),
122+ domain: " relay.example.com" ,
123+ });
124+ ~~~~
125+
112126### Subscription handling
113127
114128By default, the relay automatically rejects all subscription requests.
115- You can customize this behavior by setting a subscription handler:
129+ You can customize this behavior by providing a subscription handler in the options :
116130
117131~~~~ 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 );
132+ const relay = createRelay (" mastodon" , {
133+ kv: new MemoryKvStore (),
134+ domain: " relay.example.com" ,
135+ subscriptionHandler : async (ctx , actor ) => {
136+ // Example: Only allow subscriptions from specific domains
137+ const domain = new URL (actor .id ! ).hostname ;
138+ const allowedDomains = [" mastodon.social" , " fosstodon.org" ];
139+ return allowedDomains .includes (domain );
140+ },
123141});
124142~~~~
125143
@@ -131,11 +149,11 @@ example with Hono:
131149
132150~~~~ typescript
133151import { Hono } from " hono" ;
134- import { MastodonRelay } from " @fedify/relay" ;
152+ import { createRelay } from " @fedify/relay" ;
135153import { MemoryKvStore } from " @fedify/fedify" ;
136154
137155const app = new Hono ();
138- const relay = new MastodonRelay ( {
156+ const relay = createRelay ( " mastodon " , {
139157 kv: new MemoryKvStore (),
140158 domain: " relay.example.com" ,
141159});
@@ -191,38 +209,61 @@ details.
191209API reference
192210-------------
193211
194- ### ` MastodonRelay `
195-
196- A Mastodon-compatible ActivityPub relay implementation.
212+ ### ` createRelay() `
197213
198- #### Constructor
214+ Factory function to create a relay instance.
199215
200216~~~~ typescript
201- new MastodonRelay (options : RelayOptions )
217+ function createRelay(
218+ type : " mastodon" | " litepub" ,
219+ options : RelayOptions
220+ ): BaseRelay
202221~~~~
203222
204- #### Properties
223+ ** Parameters :**
224+
225+ - ` type ` : The type of relay to create (`"mastodon"` or `"litepub"`)
226+ - `options`: Configuration options for the relay
205227
206- - ` domain ` : The relay's domain name (read-only)
228+ ** Returns :** A relay instance (` MastodonRelay ` or ` LitePubRelay ` )
229+
230+ ### ` BaseRelay `
231+
232+ Abstract base class for relay implementations .
207233
208234#### Methods
209235
210236 - `fetch (request : Request ): Promise <Response >`: Handle incoming HTTP requests
211- - ` setSubscriptionHandler(handler: SubscriptionRequestHandler): this ` :
212- Set a custom handler for subscription approval/rejection
237+
238+ ### `MastodonRelay `
239+
240+ A Mastodon -compatible ActivityPub relay implementation that extends ` BaseRelay ` .
241+
242+ - Uses direct activity forwarding
243+ - Immediate subscription approval
244+ - Compatible with standard ActivityPub implementations
245+
246+ ### ` LitePubRelay `
247+
248+ A LitePub - compatible ActivityPub relay implementation that extends ` BaseRelay ` .
249+
250+ - Uses bidirectional following
251+ - Activities wrapped in ` Announce `
252+ - Two - phase subscription (pending → accepted )
213253
214254### ` RelayOptions `
215255
216256Configuration options for the relay :
217257
218258 - ` kv: KvStore ` (required ): Key –value store for persisting relay data
219259 - ` domain?: string ` : Relay ' s domain name (defaults to `"localhost"`)
260+ - ` name?: string ` : Relay ' s display name (defaults to `"ActivityPub Relay"`)
261+ - ` subscriptionHandler?: SubscriptionRequestHandler ` : Custom handler for
262+ subscription approval / rejection
220263 - ` documentLoaderFactory?: DocumentLoaderFactory ` : Custom document loader
221264 factory
222265 - ` authenticatedDocumentLoaderFactory?: AuthenticatedDocumentLoaderFactory ` :
223266 Custom authenticated document loader factory
224- - ` federation?: Federation<void> ` : Custom Federation instance (for advanced
225- use cases)
226267 - ` queue?: MessageQueue ` : Message queue for background activity processing
227268
228269### ` SubscriptionRequestHandler `
@@ -231,17 +272,17 @@ A function that determines whether to approve a subscription request:
231272
232273~~~~ typescript
233274type SubscriptionRequestHandler = (
234- ctx : Context <void >,
275+ ctx : Context <RelayOptions >,
235276 clientActor : Actor ,
236277) => Promise <boolean >
237278~~~~
238279
239- Parameters :
280+ ** Parameters:**
240281
241- - ` ctx ` : The Fedify context object
282+ - `ctx`: The Fedify context object with relay options
242283 - `clientActor`: The actor requesting to subscribe
243284
244- Returns :
285+ ** Returns:**
245286
246287 - `true` to approve the subscription
247288 - `false` to reject the subscription
0 commit comments