Add @fedify/solidstart package for SolidStart integration#601
Add @fedify/solidstart package for SolidStart integration#601dodok8 wants to merge 7 commits intofedify-dev:mainfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands Fedify's ecosystem by introducing first-class support for SolidStart, a modern full-stack framework. It delivers a new integration package, a complete example application, and comprehensive documentation, enabling developers to easily build federated applications using SolidStart. Additionally, the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces SolidStart integration for Fedify through a new @fedify/solidstart package. The changes are comprehensive, including the new package, an example application, documentation updates, and support in fedify init. The implementation is well-structured and follows existing patterns in the repository. I've identified one high-severity type safety issue in the new fedifyMiddleware function and provided a suggestion to address it using function overloads. Overall, this is a great addition to the Fedify ecosystem.
I am having trouble creating individual review comments. Click here to see my feedback.
packages/solidstart/src/index.ts (54-104)
The current implementation of fedifyMiddleware has a potential type safety issue. If a Federation object is created with a specific context data type (e.g., createFederation<MyContext>()), but fedifyMiddleware is called without a createContextData function, the default implementation will provide undefined as the context data. This can lead to runtime TypeErrors in your dispatchers if they expect a MyContext object but receive undefined.
To enforce type safety at compile time, it's better to use function overloads. This will make the createContextData parameter required when the federation object has a context data type other than void.
export function fedifyMiddleware(
federation: Federation<void>,
): ReturnType<typeof createMiddleware>;
export function fedifyMiddleware<TContextData>(
federation: Federation<TContextData>,
createContextData: ContextDataFactory<TContextData>,
): ReturnType<typeof createMiddleware>;
export function fedifyMiddleware<TContextData>(
federation: Federation<TContextData>,
createContextData?: ContextDataFactory<TContextData>,
): ReturnType<typeof createMiddleware> {
return createMiddleware({
onRequest: async (event: FetchEvent) => {
const response = await federation.fetch(event.request, {
contextData: await (createContextData ?? (() => undefined))(event) as TContextData,
onNotFound: () =>
new Response("Not Found", { status: 404 }),
onNotAcceptable: () =>
new Response("Not Acceptable", {
status: 406,
headers: { "Content-Type": "text/plain", Vary: "Accept" },
}),
});
// If Fedify does not handle this route, let SolidStart handle it:
if (response.status === 404) return;
// If content negotiation failed (client does not want JSON-LD),
// store the 406 response and let SolidStart try to serve HTML.
// If SolidStart also cannot handle it, onBeforeResponse will
// return the 406:
if (response.status === 406) {
notAcceptableResponses.set(event.request, response);
return;
}
// Fedify handled the request successfully:
return response;
},
// Similar to onRequest, but slightly more tricky one.
// When the federation object finds a request not acceptable type-wise
// (i.e., a user-agent does not want JSON-LD), onRequest stores the 406
// response and lets SolidStart try to render HTML. If SolidStart also
// has no page for this route (404), we return the stored 406 instead.
// This enables Fedify and SolidStart to share the same routes and do
// content negotiation depending on the Accept header:
onBeforeResponse: (event: FetchEvent) => {
const stored = notAcceptableResponses.get(event.request);
if (stored != null) {
notAcceptableResponses.delete(event.request);
const status = event.response.status ?? 200;
if (status === 404) return stored;
}
},
});
}Extract the Fedify middleware for SolidStart into a dedicated package (@fedify/solidstart), providing a fedifyMiddleware() helper that handles ActivityPub content negotiation with SolidStart's middleware system. Uses a WeakMap<Request, Response> internally for 406 response storage, so users don't need to declare App.RequestEventLocals. Update the example to use the new package instead of inline middleware. fedify-dev#476 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a SolidStart section to docs/manual/integration.md with installation instructions, app.config.ts setup, and middleware usage example. Add @fedify/solidstart changelog entry under Version 2.1.0, and update packages/fedify/README.md with JSR link for the new package. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SolidStart as a web framework option in the `fedify init` command, allowing users to scaffold new Fedify+SolidStart projects. All boilerplate files (app config, middleware, routes, entry points) are provided as templates since no suitable degit template exists for SolidStart. The lookup test skips the solidstart+deno combination because Deno's `links` feature does not populate `node_modules/`, which Vite (used by vinxi) requires for SSR module resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds first-class SolidStart integration to Fedify by introducing a new @fedify/solidstart package, an example SolidStart app, documentation updates, and fedify init scaffolding for SolidStart projects.
Changes:
- Added
@fedify/solidstartpackage exposingfedifyMiddleware()for SolidStart middleware integration. - Added SolidStart example app plus integration docs and changelog entry.
- Extended
fedify initto scaffold SolidStart projects and refined lookup test filtering viaBANNED_COMBOS.
Reviewed changes
Copilot reviewed 34 out of 36 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Registers the new package and example in the workspace. |
| packages/solidstart/tsdown.config.ts | Build configuration for the new SolidStart integration package. |
| packages/solidstart/src/index.ts | Implements fedifyMiddleware() for SolidStart. |
| packages/solidstart/package.json | Declares package metadata, exports, build scripts, and peer deps. |
| packages/solidstart/deno.json | JSR/Deno publishing metadata for the new package. |
| packages/solidstart/README.md | Package-level usage docs for SolidStart integration. |
| packages/init/src/webframeworks/solidstart.ts | Adds SolidStart scaffolding configuration to fedify init. |
| packages/init/src/webframeworks/mod.ts | Registers SolidStart in the framework registry. |
| packages/init/src/test/lookup.ts | Adds per-(framework, package manager) skip support via BANNED_COMBOS. |
| packages/init/src/templates/solidstart/src/routes/index.tsx.tpl | SolidStart template: default home route. |
| packages/init/src/templates/solidstart/src/middleware/index.ts.tpl | SolidStart template: middleware entry using @fedify/solidstart. |
| packages/init/src/templates/solidstart/src/entry-server.tsx.tpl | SolidStart template: server entry point. |
| packages/init/src/templates/solidstart/src/entry-client.tsx.tpl | SolidStart template: client entry point. |
| packages/init/src/templates/solidstart/src/app.tsx.tpl | SolidStart template: app router shell. |
| packages/init/src/templates/solidstart/app.config.ts.tpl | SolidStart template: app config with middleware + server preset. |
| packages/init/src/const.ts | Adds "solidstart" to the list of supported web frameworks. |
| packages/fedify/README.md | Adds @fedify/solidstart to the package list and links. |
| examples/solidstart/tsconfig.json | TypeScript config for the SolidStart example. |
| examples/solidstart/src/routes/users/[identifier].tsx | Example user profile route demonstrating server query + rendering. |
| examples/solidstart/src/routes/index.tsx | Example root route redirect. |
| examples/solidstart/src/middleware/index.ts | Example middleware using fedifyMiddleware(). |
| examples/solidstart/src/lib/store.ts | Example in-memory/global stores for demo persistence. |
| examples/solidstart/src/lib/federation.ts | Example Fedify federation setup + dispatchers/listeners. |
| examples/solidstart/src/entry-server.tsx | Example SolidStart server entry point. |
| examples/solidstart/src/entry-client.tsx | Example SolidStart client entry point. |
| examples/solidstart/src/app.tsx | Example app shell with styles. |
| examples/solidstart/src/app.css | Example app styling. |
| examples/solidstart/package.json | Example app dependencies/scripts. |
| examples/solidstart/app.config.ts | Example app config enabling middleware. |
| examples/solidstart/.gitignore | Example app ignore rules. |
| examples/README.md | Adds SolidStart example link to examples index. |
| docs/manual/integration.md | Documents SolidStart integration + fixes Elysia code-group wrapping. |
| deno.lock | Updates lockfile for newly introduced npm dependencies. |
| deno.json | Adds workspace entry and import map entries for SolidStart subpaths. |
| CHANGES.md | Changelog entry for the new @fedify/solidstart package. |
| dependencies: pm === "deno" | ||
| ? { | ||
| ...defaultDenoDependencies, | ||
| "@solidjs/router": "npm:@solidjs/router@^0.15.4", | ||
| "@solidjs/start": "npm:@solidjs/start@^1.3.2", | ||
| "solid-js": "npm:solid-js@^1.9.11", | ||
| vinxi: "npm:vinxi@^0.5.11", | ||
| "@fedify/solidstart": PACKAGE_VERSION, | ||
| } | ||
| : { |
There was a problem hiding this comment.
For the Deno template, the generated deno.json imports will include an entry for "@solidjs/start", but @fedify/solidstart imports "@solidjs/start/middleware" and "@solidjs/start/server" as separate specifiers. Deno import maps do not resolve these subpaths from the base "@solidjs/start" entry, so the scaffolded SolidStart+Deno project is likely to fail type-checking/runtime module resolution unless these subpath mappings are also emitted. Consider adding explicit dependencies for "@solidjs/start/middleware" and "@solidjs/start/server" (with the appropriate npm: specifiers) to the Deno dependencies here, or changing @fedify/solidstart to avoid subpath imports that require separate import-map entries.
Summary
Add SolidStart integration support for Fedify, including a new
@fedify/solidstartpackage, example application, documentation,and
fedify initscaffolding support.Closes #476.
Related issue
Changes
@fedify/solidstartpackage (packages/solidstart/) providingfedifyMiddleware()for integrating Fedify with SolidStart'smiddleware system
demonstrating actor dispatching, WebFinger, and NodeInfo
(docs/manual/integration.md)
"solidstart"option tofedify initwith template filesfor app config, middleware, routes, and entry points
BANNED_COMBOSmechanism to the test-init lookup filterto support per-framework+PM granular test skipping
::: code-group/:::wrapping in the Elysiaintegration documentation section
for
@fedify/solidstartBenefits
modern full-stack framework built on SolidJS
fedify initsupports scaffolding SolidStart projects with allpackage managers (Deno, pnpm, npm)
BANNED_COMBOStest mechanism allows finer-grained controlover which framework+PM combinations are tested for server lookup,
rather than banning entire frameworks
Checklist
mise teston your machine?Additional notes
fedify initlookup test skips thesolidstart+denocombination because Deno's
linksfeature does not populatenode_modules/, which Vite (used internally by vinxi/SolidStart)requires for SSR module resolution. The
pnpmandnpmlookuptests pass fully.
@fedify/solidstartmiddleware converts SolidStart's H3 eventsto standard
Request/Responseobjects for Fedify's federationhandler, similar to how
@fedify/h3works.