Skip to content

Frank-III/solid-effect-query

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Solid Effect Query

A powerful integration of Effect with TanStack Query for SolidJS applications, bringing functional programming patterns and type-safe error handling to your data fetching layer.

πŸ“¦ Packages

This monorepo contains three packages that work together to provide a complete Effect + TanStack Query solution for SolidJS:

Package Description Version
solid-effect-query Core Effect integration with TanStack Query 0.1.0
solid-effect-query-http-api Effect Platform HTTP API integration 0.1.0
solid-effect-query-rpc Effect RPC client integration 0.1.0

πŸš€ Quick Start

Installation

# Core package
npm install solid-effect-query @tanstack/solid-query effect

# For HTTP API support
npm install solid-effect-query-http-api @effect/platform

# For RPC support
npm install solid-effect-query-rpc @effect/rpc @effect/rpc-http

Basic Usage

import { makeEffectRuntime } from "solid-effect-query";
import { Effect, Layer } from "effect";
import { createSignal, Show } from "solid-js";

// Create a runtime with your services
const { Provider, useEffectQuery, useEffectMutation } = makeEffectRuntime(() => 
  Layer.empty // Add your services here
);

function App() {
  return (
    <Provider>
      <TodoList />
    </Provider>
  );
}

function TodoList() {
  const query = useEffectQuery(() => ({
    queryKey: ["todos"],
    queryFn: () => 
      Effect.gen(function* () {
        const response = yield* Effect.tryPromise({
          try: () => fetch("/api/todos").then(r => r.json()),
          catch: (error) => new Error(`Failed to fetch: ${error}`)
        });
        return response;
      })
  }));

  return (
    <div>
      <Show when={query.isPending}>
        <div>Loading...</div>
      </Show>
      <Show when={query.isError}>
        <div>Error: {query.error?.message}</div>
      </Show>
      <Show when={query.isSuccess}>
        <ul>
          {query.data.map(todo => (
            <li>{todo.title}</li>
          ))}
        </ul>
      </Show>
    </div>
  );
}

✨ Features

  • 🎯 Type-safe error handling - Leverage Effect's powerful error management system
  • πŸ”„ Runtime management - Manage Effect services and dependencies with SolidJS context
  • 🌐 HTTP API integration - Type-safe API clients with schema validation
  • πŸ“‘ RPC support - Seamless client-server communication with automatic batching
  • πŸ’ͺ Full TanStack Query features - Caching, mutations, optimistic updates, infinite queries, and more
  • πŸ”’ Compile-time safety - Catch errors at build time, not runtime
  • ⚑ SolidJS reactive - Built specifically for SolidJS's fine-grained reactivity

πŸ“š Examples

With Services and Dependencies

import { Context, Layer, Effect } from "effect";
import { makeEffectRuntime } from "solid-effect-query";

// Define a service
class LoggerService extends Context.Tag("Logger")<
  LoggerService,
  { log: (message: string) => Effect.Effect<void> }
>() {}

// Create layer
const LoggerLive = Layer.succeed(
  LoggerService,
  { log: (message) => Effect.log(message) }
);

// Create runtime with the service
const { Provider, useEffectQuery } = makeEffectRuntime(() => LoggerLive);

function DataComponent() {
  const query = useEffectQuery(() => ({
    queryKey: ["data-with-logging"],
    queryFn: () =>
      Effect.gen(function* () {
        const logger = yield* LoggerService;
        yield* logger.log("Fetching data...");
        const data = yield* fetchData();
        yield* logger.log("Data fetched successfully");
        return data;
      })
  }));

  return <div>{/* render data */}</div>;
}

HTTP API Client

import { makeHttpApiQuery } from "solid-effect-query-http-api";
import { Schema } from "effect";
import * as HttpApi from "@effect/platform/HttpApi";

// Define your API schema
class TodosApi extends HttpApi.make("todos").pipe(
  HttpApi.add(
    HttpApi.get("list", "/todos").pipe(
      HttpApi.setSuccess(Schema.Array(TodoSchema))
    )
  )
) {}

// Use in component
function TodoList() {
  const query = makeHttpApiQuery(
    TodosApi,
    runtime,
    "list",
    () => ({ queryKey: ["todos"] })
  );

  return <div>{/* render todos */}</div>;
}

πŸ› οΈ Development

This project uses pnpm workspaces for managing the monorepo.

# Clone the repository
git clone https://github.com/Frank-III/solid-effect-query.git
cd solid-effect-query

# Install dependencies
pnpm install

# Build all packages
pnpm build

# Run the demo application
pnpm dev --filter=demo-app

# Run tests
pnpm test

# Type checking
pnpm typecheck

# Linting
pnpm lint

Project Structure

solid-effect-query/
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ solid-effect-query/           # Core package
β”‚   β”œβ”€β”€ solid-effect-query-http-api/  # HTTP API integration
β”‚   └── solid-effect-query-rpc/       # RPC integration
β”œβ”€β”€ examples/
β”‚   └── demo-app/                     # Demo application
└── docs/                              # Documentation

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please make sure to:

  • Update tests as appropriate
  • Update documentation
  • Follow the existing code style
  • Add changeset for version management

πŸ“„ License

MIT Β© Frank Wang

πŸ™ Acknowledgments

  • Effect - The standard library for TypeScript
  • TanStack Query - Powerful asynchronous state management
  • SolidJS - A declarative, efficient, and flexible JavaScript library
  • effect-react-query - Inspiration for this SolidJS version

πŸ”— Links

About

Effect integration for TanStack Query in SolidJS applications

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors