Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/thick-bobcats-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-codegen/typescript-solid-urql': major
'@graphql-codegen/typescript-solidstart-urql': major
---

Added `solid-urql` and `solidstart-urql` plugins to the codegen library. The plugins generate fully typed Solid primitives for URQL, including `createQuery`, `createMutation`, and `createSubscription`. Both versions for Solid (client-side) and SolidStart (SSR framework) are provided.
10 changes: 9 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,13 @@
}
}
],
"ignorePatterns": ["dist", "node_modules", "dev-test", "test-files", "flow.js", "jest.project.js"]
"ignorePatterns": [
"dist",
"node_modules",
"dev-test",
"test-files",
"flow.js",
"jest.project.js",
"example"
Comment thread
davedbase marked this conversation as resolved.
Outdated
]
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"ts-jest": "29.4.6",
"ts-node": "10.9.2",
"tslib": "2.8.1",
"typescript": "5.9.3"
"typescript": "5.9.3",
"vitest": "^4.0.18"
Comment thread
davedbase marked this conversation as resolved.
Outdated
},
"resolutions": {
"babel-jest": "30.2.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/plugins/typescript/solid-urql/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
*.log
.DS_Store
19 changes: 19 additions & 0 deletions packages/plugins/typescript/solid-urql/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

## [1.0.0] - 2026-01-12

### Added
- Initial release of GraphQL Code Generator plugin for SolidJS and URQL
- Support for generating typed `createQuery` wrappers
- Support for generating typed `createMutation` wrappers
- Support for generating typed `createSubscription` wrappers
- Configuration option `withPrimitives` to enable/disable primitive generation
- Configuration option `urqlImportFrom` to customize import source
- Full TypeScript support with proper type inference
- Comprehensive documentation and examples

### Features
- Generates wrapper functions around solid-urql primitives
- Proper handling of required vs optional variables
- Compatible with @urql/core and solid-urql
- Follows SolidJS conventions (uses `create*` naming instead of `use*`)
Comment thread
davedbase marked this conversation as resolved.
215 changes: 215 additions & 0 deletions packages/plugins/typescript/solid-urql/COMPARISON.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# Comparison: typescript-solidstart-urql vs typescript-solid-urql

This document explains the differences between the two URQL plugins for SolidJS ecosystems.

## Package Comparison

| Feature | typescript-solid-urql | typescript-solidstart-urql |
|---------|----------------------|---------------------------|
| **Target Framework** | Solid (client-side) | SolidStart (SSR framework) |
| **Import Source** | `solid-urql` | `@urql/solid-start` |
| **Query Generation** | ✅ Yes (`createQuery`) | ✅ Yes (`createQuery`) |
| **Mutation Generation** | ✅ Yes (`createMutation`) | ✅ Yes (`createMutation` with actions) |
| **Subscription Generation** | ✅ Yes (`createSubscription`) | ✅ Yes (`createSubscription`) |
| **SSR Optimized** | ❌ No | ✅ Yes |
| **Action Integration** | ❌ No | ✅ Yes (SolidStart actions) |

## When to Use Each Plugin

### Use `typescript-solid-urql` when:
- Building a pure client-side Solid application
- Need subscriptions code generation
- Not using SolidStart framework
- Want client-side reactive patterns

### Use `typescript-solidstart-urql` when:
- Building a SolidStart application with SSR
- Want integration with SolidStart's routing and action patterns
- Need server-side rendering for queries
- Want progressive enhancement for mutations via actions

## Code Generation Differences

### typescript-solid-urql Output

```typescript
// Generates for Queries
export const useGetUserQuery = (args: Omit<CreateQueryArgs<...>, 'query'>) => {
Comment thread
davedbase marked this conversation as resolved.
Outdated
return createQuery<GetUserQuery, GetUserQueryVariables>({
...args,
query: GetUserDocument,
});
};

// Generates for Mutations
export const useCreateUserMutation = () => {
return createMutation<CreateUserMutation, CreateUserMutationVariables>(CreateUserDocument);
Comment thread
davedbase marked this conversation as resolved.
Outdated
};

// Generates for Subscriptions
export const useOnUserUpdatedSubscription = (args: Omit<CreateQueryArgs<...>, 'query'>) => {
Comment thread
davedbase marked this conversation as resolved.
Outdated
return createSubscription<OnUserUpdatedSubscription, OnUserUpdatedSubscriptionVariables>({
...args,
query: OnUserUpdatedDocument,
});
};
```

### typescript-solidstart-urql Output

```typescript
// Generates for Queries
export const queryGetUser = createQuery<GetUserQuery, GetUserQueryVariables>(
GetUserDocument,
'get-user'
);

// Generates for Mutations (as action wrappers)
export const actionCreateUser = () => createMutation<CreateUserMutation, CreateUserMutationVariables>(
CreateUserDocument,
'create-user'
);

// Does NOT generate for Subscriptions
// Use createSubscription directly from @urql/solid-start
Comment thread
davedbase marked this conversation as resolved.
Outdated
```

## Usage Pattern Differences

### typescript-solid-urql (Client-Side)

```tsx
import { Component } from 'solid-js';
import { useGetUserQuery, useCreateUserMutation } from './generated/graphql';

const UserProfile: Component = () => {
const [user] = useGetUserQuery({ variables: { id: '1' } });
const [state, createUser] = useCreateUserMutation();

const handleCreate = async () => {
await createUser({ name: 'John', email: 'john@example.com' });
};

return <div>{/* component code */}</div>;
};
```

### typescript-solidstart-urql (SSR with Actions)

```tsx
import { createAsync, useAction, useSubmission } from '@solidjs/router';
import { queryGetUser, actionCreateUser } from '~/generated/graphql';

export default function UserProfile() {
// Query with SSR support
const user = createAsync(() => queryGetUser({ id: '1' }));

// Mutation with SolidStart action
const createUserAction = actionCreateUser();
const createUser = useAction(createUserAction);
const submission = useSubmission(createUserAction);

const handleCreate = async () => {
await createUser({ name: 'John', email: 'john@example.com' });
};

return (
<div>
{/* Use user() and submission.pending */}
</div>
);
}
```

## Configuration Differences

Both plugins use the same configuration structure:

```yaml
# Both plugins
config:
withPrimitives: true
urqlImportFrom: "solid-urql" # for solid-urql plugin
# or
urqlImportFrom: "@urql/solid-start" # for solidstart-urql plugin
```

## Key Differences

### Queries
- **solid-urql**: Returns `createQuery` result directly (tuple with state)
- **solidstart-urql**: Returns a query function to use with `createAsync()`

### Mutations
- **solid-urql**: Returns `createMutation` result directly (tuple with state and execute)
- **solidstart-urql**: Returns an action factory that creates SolidStart actions
- Must call the action factory in your component
- Use with `useAction()` and `useSubmission()` for progressive enhancement

### Subscriptions
- **solid-urql**: Generates subscription helpers
- **solidstart-urql**: Does not generate (use `createSubscription` from `@urql/solid-start` directly)

## Migration Between Plugins

If migrating from `typescript-solid-urql` to `typescript-solidstart-urql`:

### Queries
```tsx
// Before (with typescript-solid-urql)
import { useGetUserQuery } from './generated/graphql';
const [user] = useGetUserQuery({ variables: { id: '1' } });

// After (with typescript-solidstart-urql)
import { createAsync } from '@solidjs/router';
import { queryGetUser } from './generated/graphql';
const user = createAsync(() => queryGetUser({ id: '1' }));
```

### Mutations
```tsx
// Before (with typescript-solid-urql)
import { useCreateUserMutation } from './generated/graphql';
const [state, createUser] = useCreateUserMutation();

// After (with typescript-solidstart-urql)
import { useAction, useSubmission } from '@solidjs/router';
import { actionCreateUser } from './generated/graphql';
const createUserAction = actionCreateUser();
const createUser = useAction(createUserAction);
const submission = useSubmission(createUserAction);
```

### Subscriptions
```tsx
// Before (with typescript-solid-urql)
import { useOnUserUpdatedSubscription } from './generated/graphql';
const [messages] = useOnUserUpdatedSubscription();

// After (with typescript-solidstart-urql)
import { createSubscription } from '@urql/solid-start';
import { OnUserUpdatedDocument } from './generated/graphql';
const [messages] = createSubscription({ query: OnUserUpdatedDocument });
```

## Architecture Rationale

### Why typescript-solidstart-urql Uses Actions for Mutations

1. **Progressive Enhancement**: SolidStart actions work without JavaScript
2. **SSR Integration**: Actions integrate with SolidStart's form handling
3. **Type Safety**: Generated actions maintain full type safety
4. **Router Integration**: Actions work with `useSubmission()` for loading states

### Why Different Query Patterns

1. **SSR First**: SolidStart queries run on server and stream to client
2. **Caching**: Integration with SolidStart's router-level caching
3. **Suspense**: Works with Solid Suspense boundaries
4. **createAsync**: Designed for SolidStart's data fetching patterns

## Recommendation

- **New SolidStart Project**: Use `typescript-solidstart-urql`
- **New Solid SPA**: Use `typescript-solid-urql`
- **Existing Project**: Choose based on whether you use SolidStart's SSR and routing features
Loading