Loading examples/blog/README.md +39 −0 Original line number Diff line number Diff line Loading @@ -50,3 +50,42 @@ fediverse handle: [ngrok]: https://ngrok.com/ [1]: https://ngrok.com/docs/getting-started/ Where to start reading ---------------------- In general, this project is a typical Fresh web app, except that it delegates federation-related tasks to the Fedify library. So, if you are not familiar with Fresh at all, you may want to start with the [Fresh documentation][2]. The most of the federation-related code is in the *federation/mod.ts* file. This file registers many callbacks to the Fedify library, which are called when the server receives a federation-related request. There are few code that interacts with the Fedify library from the Fresh app. For example, *routes/posts/index.ts* file contains logic to publish a new post, and there is few lines that enqueue a `Create` activity to the outbox: ~~~~ typescript // Gets a federation context for enqueueing an activity: const fedCtx = await federation.createContext(req); // Enqueues a `Create` activity to the outbox: await fedCtx.sendActivity( { handle: blog.handle }, await getFollowersAsActors(), new Create({ // (omitted for brevity) }), ); ~~~~ Lastly, you'll probably wonder how the `federation` object is integrated with the Fresh app. The answer is in the *routes/_middleware.ts* file. This file contains a Fresh middleware that intercepts federation-related requests and passes them to the `federation` object. We did the best to keep the federation-related logic elaborated in comments, so we hope you can understand the code by reading the comments too. [2]: https://fresh.deno.dev/docs No newline at end of file examples/blog/routes/_middleware.ts +23 −0 Original line number Diff line number Diff line import { FreshContext } from "$fresh/server.ts"; import { federation } from "../federation/mod.ts"; // This is the entry point to the Fedify middleware from the Fresh framework: export async function handler(request: Request, context: FreshContext) { // The `federation` object purposes to handle federation-related requests. // It is responsible for handling, for example, WebFinger queries, actor // dispatching, and incoming activities to the inbox. The definition of // the object is in the federation/mod.ts file. return await federation.handle(request, { // The context data is not used in this example, but it can be used to // store data (e.g., database connections) that is shared between // the different federation-related callbacks: contextData: undefined, // If the `federation` object finds a request not responsible for it // (i.e., not a federation-related request), it will call the `next` // provided by the Fresh framework to continue the request handling // by the Fresh: onNotFound: context.next.bind(context), // Similar to `onNotFound`, but slightly more tricky one. // When the `federation` object finds a request not acceptable type-wise // (i.e., a user-agent doesn't want JSON-LD), it will call the `next` // provided by the Fresh framework so that it renders HTML if there's some // page. Otherwise, it will simply return a 406 Not Acceptable response. // This kind of trick enables the Fedify and Fresh to share the same routes // and they do content negotiation depending on `Accept` header. // For instance, in this example, `/users/{handle}` can return JSON-LD // by the Fedify and redirects to the home page by the Fresh: async onNotAcceptable(_request: Request) { const response = await context.next(); if (response.status !== 404) return response; Loading examples/blog/routes/posts/index.tsx +2 −0 Original line number Diff line number Diff line Loading @@ -81,7 +81,9 @@ export const handler: Handlers<PostsData> = { content, published: Temporal.Now.instant(), }); // Gets a federation context for enqueueing an activity: const fedCtx = await federation.createContext(req); // Enqueues a `Create` activity to the outbox: await fedCtx.sendActivity( { handle: blog.handle }, await getFollowersAsActors(), Loading Loading
examples/blog/README.md +39 −0 Original line number Diff line number Diff line Loading @@ -50,3 +50,42 @@ fediverse handle: [ngrok]: https://ngrok.com/ [1]: https://ngrok.com/docs/getting-started/ Where to start reading ---------------------- In general, this project is a typical Fresh web app, except that it delegates federation-related tasks to the Fedify library. So, if you are not familiar with Fresh at all, you may want to start with the [Fresh documentation][2]. The most of the federation-related code is in the *federation/mod.ts* file. This file registers many callbacks to the Fedify library, which are called when the server receives a federation-related request. There are few code that interacts with the Fedify library from the Fresh app. For example, *routes/posts/index.ts* file contains logic to publish a new post, and there is few lines that enqueue a `Create` activity to the outbox: ~~~~ typescript // Gets a federation context for enqueueing an activity: const fedCtx = await federation.createContext(req); // Enqueues a `Create` activity to the outbox: await fedCtx.sendActivity( { handle: blog.handle }, await getFollowersAsActors(), new Create({ // (omitted for brevity) }), ); ~~~~ Lastly, you'll probably wonder how the `federation` object is integrated with the Fresh app. The answer is in the *routes/_middleware.ts* file. This file contains a Fresh middleware that intercepts federation-related requests and passes them to the `federation` object. We did the best to keep the federation-related logic elaborated in comments, so we hope you can understand the code by reading the comments too. [2]: https://fresh.deno.dev/docs No newline at end of file
examples/blog/routes/_middleware.ts +23 −0 Original line number Diff line number Diff line import { FreshContext } from "$fresh/server.ts"; import { federation } from "../federation/mod.ts"; // This is the entry point to the Fedify middleware from the Fresh framework: export async function handler(request: Request, context: FreshContext) { // The `federation` object purposes to handle federation-related requests. // It is responsible for handling, for example, WebFinger queries, actor // dispatching, and incoming activities to the inbox. The definition of // the object is in the federation/mod.ts file. return await federation.handle(request, { // The context data is not used in this example, but it can be used to // store data (e.g., database connections) that is shared between // the different federation-related callbacks: contextData: undefined, // If the `federation` object finds a request not responsible for it // (i.e., not a federation-related request), it will call the `next` // provided by the Fresh framework to continue the request handling // by the Fresh: onNotFound: context.next.bind(context), // Similar to `onNotFound`, but slightly more tricky one. // When the `federation` object finds a request not acceptable type-wise // (i.e., a user-agent doesn't want JSON-LD), it will call the `next` // provided by the Fresh framework so that it renders HTML if there's some // page. Otherwise, it will simply return a 406 Not Acceptable response. // This kind of trick enables the Fedify and Fresh to share the same routes // and they do content negotiation depending on `Accept` header. // For instance, in this example, `/users/{handle}` can return JSON-LD // by the Fedify and redirects to the home page by the Fresh: async onNotAcceptable(_request: Request) { const response = await context.next(); if (response.status !== 404) return response; Loading
examples/blog/routes/posts/index.tsx +2 −0 Original line number Diff line number Diff line Loading @@ -81,7 +81,9 @@ export const handler: Handlers<PostsData> = { content, published: Temporal.Now.instant(), }); // Gets a federation context for enqueueing an activity: const fedCtx = await federation.createContext(req); // Enqueues a `Create` activity to the outbox: await fedCtx.sendActivity( { handle: blog.handle }, await getFollowersAsActors(), Loading