npm package: @orbitalhq/taxiql-client
Description: A Typescript client for executing TaxiQL from client side libraries
Latest version: 0.1.1

# @orbitalhq/taxiql-client

A TypeScript client for executing TaxiQL from client-side libraries.

## Installation

```sh
npm install @orbitalhq/taxiql-client
```

## Features
- Typed API for executing TaxiQL queries and subscriptions.
- React hooks for seamless integration into React applications.
- Context provider for managing TaxiQL client state.

## Requirements
### TaxiQL Queries
The library allows you to execute TaxiQL queries from client-side applications. However, in order to ensure correct execution, any query must be wrapped using the taxiQl function, which is imported from the Taxi types generated by the @orbitalhq/taxiql-codegen library.

Here's an example:

```typescript
import { taxiQl } from './generated/queries.ts';

const QUERY = taxiQl(`
query FindFilms {
  find { Film[] }
}
`);

```
In this example, the query is wrapped by the `taxiQl` function to ensure the query is valid and conforms to the expected TaxiQL format. The `taxiQl` function ensures that the query is processed correctly before being sent to the backend for execution.

You need to install the `@orbitalhq/taxiql-codegen` package to generate the necessary Taxi types and support the `taxiQl` function.

```sh
npm install @orbitalhq/taxiql-codegen
```

## Usage

### Vanilla TS Usage with TaxiClient

Once you've written your TaxiQL, you'll need to use 

```typescript
import { TaxiClient } from "@orbitalhq/taxiql-client";
import { taxiQl } from './generated/queries.ts';

const QUERY = taxiQl(`
query FindFilms {
   find { Film[] }
}`)

const client = new TaxiClient({ orbitalServerUrl: "https://your-orbitalServerUrl.com/api" });

client.query(QUERY).then(response => console.log(response));
```

To create a streaming subscription, you can use

```typescript
import { TaxiClient } from "@orbitalhq/taxiql-client";
import { taxiQl } from './generated/queries.ts';

const QUERY = taxiQl(`
query StreamAnnouncement {
   stream { demo.petflix.NewFilmReleaseAnnouncement } }
}`)

const client = new TaxiClient({ orbitalServerUrl: "https://your-orbitalServerUrl.com/api" });

client.subscribe(QUERY).then(response => console.log(response));
```

## React

### TaxiProvider

Ensure you wrap your root component in the `TaxiProvider` to ensure the hooks have access to the `TaxiClient` which is stored in `context`

```typescript jsx
import { TaxiClient, TaxiProvider } from "@orbitalhq/taxiql-client";

const client = new TaxiClient({ orbitalServerUrl: "https://your-orbitalServerUrl.com/api" });

function App() {
  return (
    <TaxiProvider client={client}>
      <YourComponents />
    </TaxiProvider>
  );
}
```

### Using React Hooks

#### useQuery

```typescript jsx
import { useQuery } from "@orbitalhq/taxiql-client";

const QUERY = taxiQl(`
query FindFilms {
   find { Film[] }
}`)

function UsersList() {
  const { data, loading, error } = useQuery(QUERY);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
```

#### useLazyQuery

```typescript jsx
import { useLazyQuery } from "@orbitalhq/taxiql-client";

const QUERY = taxiQl(`
query FindFilms {
   find { Film[] }
}`)

function UserProfile() {
  const [fetchUser, { data, loading, error }] = useLazyQuery(query);

  return (
    <div>
      <button onClick={() => fetchUser()}>Fetch User</button>
      {loading && <p>Loading...</p>}
      {error && <p>Error: {error.message}</p>}
      {data && <p>{data.user.name}</p>}
    </div>
  );
}
```

#### useSubscription

```typescript jsx
import { useSubscription } from "@orbitalhq/taxiql-client";

const STREAM = taxiQl(`query TestStream { stream { demo.netflix.NewFilmReleaseAnnouncement } }`)

function Messages() {
  const { data } = useSubscription(STREAM);

  return (
    <div>
      {data?.rating && <p>{data.rating.provider}</p>}
    </div>
  );
}
```

#### useLazySubscription

```typescript jsx
import { useLazySubscription } from "@orbitalhq/taxiql-client";

const STREAM = taxiQl(`query TestStream { stream { demo.netflix.NewFilmReleaseAnnouncement } }`)

function Messages() {
  const [executeQuery, { data }] = useLazySubscription(STREAM);

  return (
    <div>
      <button onClick={executeQuery}>Stream query</button>
      {data?.rating && <p>{data.rating.provider}</p>}
    </div>
  );
}
```


## Build & Development

To build the package, run:

```sh
npm run build
```

## TODO
- [ ] Pagination (ie. `fetchMore` from Apollo)
- [ ] Refetch in useQuery/useSubscription (though perhaps just point the user to the useLazy hooks?)
- [ ] Allow `find` operations to be "streamed" back to the client
- [ ] WS subscription implementation

## License

This project is licensed under the Apache-2.0 License.