Skip to content

Commit

Permalink
Merge pull request #183 from robin-maki/integration/svelte
Browse files Browse the repository at this point in the history
  • Loading branch information
dahlia authored Nov 23, 2024
2 parents e1affcf + a6eb859 commit fb2366f
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 2 deletions.
11 changes: 10 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,26 @@ To be released.

- Added `CreateFederationOptions.tracerProvider` option.

- Added `@fedify/fedify/x/sveltekit` module for integrating with [SvelteKit]
hook. [[#171], [#183] by Jiyu Park]

- Added `fedifyHook()` function.

- The scaffold project generated by `fedify init` command now enables
tracing data into log messages.

- Let the `fedify lookup` command take multiple arguments.
[[#173], [#186] by PGD]


[SvelteKit]: https://kit.svelte.dev/
[#162]: https://github.com/dahlia/fedify/issues/162
[#171]: https://github.com/dahlia/fedify/issues/171
[#173]: https://github.com/dahlia/fedify/issues/173
[#183]: https://github.com/dahlia/fedify/pull/183
[#186]: https://github.com/dahlia/fedify/pull/186


Version 1.2.8
-------------

Expand Down Expand Up @@ -2556,4 +2565,4 @@ Version 0.1.0

Initial release. Released on March 8, 2024.

<!-- cSpell: ignore Dogeon Fabien Wressell Emelia Hana Heesun Kyunghee -->
<!-- cSpell: ignore Dogeon Fabien Wressell Emelia Hana Heesun Kyunghee Jiyu -->
26 changes: 26 additions & 0 deletions docs/manual/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,32 @@ export const handler = integrateHandler(
[Fresh]: https://fresh.deno.dev/


SvelteKit
---------

*This API is available since Fedify 1.3.0.*

[SvelteKit] is a framework for building web applications with [Svelte]. Fedify
has the `@fedify/fedify/x/sveltekit` module that provides a hook handler to
integrate Fedify with SvelteKit. Put the following code in your
*hooks.server.ts* file:

~~~~ typescript
import { createFederation } from "@fedify/fedify";
import { fedifyHook } from "@fedify/fedify/x/sveltekit";

const federation = createFederation<string>({
// Omitted for brevity; see the related section for details.
});

// This is the entry point to the Fedify hook from the SvelteKit framework:
export const handle = fedifyHook(federation, (req) => "context data");
~~~~

[SvelteKit]: https://kit.svelte.dev/
[Svelte]: https://svelte.dev/


Custom middleware
-----------------

Expand Down
4 changes: 3 additions & 1 deletion src/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"./webfinger": "./webfinger/mod.ts",
"./x/denokv": "./x/denokv.ts",
"./x/fresh": "./x/fresh.ts",
"./x/hono": "./x/hono.ts"
"./x/hono": "./x/hono.ts",
"./x/sveltekit": "./x/sveltekit.ts"
},
"imports": {
"@cfworker/json-schema": "npm:@cfworker/json-schema@^2.0.1",
Expand All @@ -28,6 +29,7 @@
"@fedify/fedify/x/denokv": "./x/denokv.ts",
"@fedify/fedify/x/fresh": "./x/fresh.ts",
"@fedify/fedify/x/hono": "./x/hono.ts",
"@fedify/fedify/x/sveltekit": "./x/sveltekit.ts",
"@hongminhee/aitertools": "jsr:@hongminhee/aitertools@^0.6.0",
"@hugoalh/http-header-link": "jsr:@hugoalh/http-header-link@^1.0.2",
"@logtape/logtape": "jsr:@logtape/logtape@^0.8.0",
Expand Down
87 changes: 87 additions & 0 deletions src/x/sveltekit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Fedify with SvelteKit
* =====================
*
* This module provides a [SvelteKit] hook to integrate with the Fedify.
*
* [SvelteKit]: https://kit.svelte.dev/
*
* @module
* @since 1.3.0
*/

import type {
Federation,
FederationFetchOptions,
} from "../federation/federation.ts";

type RequestEvent = {
request: Request;
};

type HookParams = {
event: RequestEvent;
resolve: (event: RequestEvent) => Promise<Response>;
};

/**
* Create a SvelteKit hook handler to integrate with the {@link Federation}
* object.
*
* @example hooks.server.ts
* ``` typescript
* import { federation } from "./federation"; // Import the `Federation` object
*
* export const handle = fedifyHook(federation, () => undefined);
* ```
*
* @typeParam TContextData A type of the context data for the {@link Federation}
* object.
* @param federation A {@link Federation} object to integrate with SvelteKit.
* @param createContextData A function to create a context data for the
* {@link Federation} object.
* @returns A SvelteKit hook handler.
* @since 1.3.0
*/
export function fedifyHook<TContextData>(
federation: Federation<TContextData>,
createContextData: (
event: RequestEvent,
) => TContextData | Promise<TContextData>,
): (params: HookParams) => Promise<Response> {
return async ({ event, resolve }: HookParams) => {
return await federation.fetch(event.request, {
contextData: await createContextData(event),
...integrateFetchOptions({ event, resolve }),
});
};
}

function integrateFetchOptions(
{ event, resolve }: HookParams,
): Omit<FederationFetchOptions<void>, "contextData"> {
return {
async onNotFound(): Promise<Response> {
return await resolve(event);
},

// 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 `resolve`
// provided by the SvelteKit 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 SvelteKit to share the same routes
// and they do content negotiation depending on `Accept` header:
async onNotAcceptable(): Promise<Response> {
const res = await resolve(event);
if (res.status !== 404) return res;
return new Response("Not acceptable", {
status: 406,
headers: {
"Content-Type": "text/plain",
Vary: "Accept",
},
});
},
};
}

0 comments on commit fb2366f

Please sign in to comment.