Skip to content

DOC-215(tanstack-query): It adds the Tanstack Query #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
18 changes: 18 additions & 0 deletions tanstack-query/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
34 changes: 34 additions & 0 deletions tanstack-query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# How to Use SurrealDB with Tanstack Query

This tutorial will guide you through the steps to integrate SurrealDB with a React application using Tanstack Query (formerly React Query). We'll cover setting up the database, fetching data, and displaying it in a React component.

## Prerequisites

- Node.js and npm installed
- Basic knowledge of React and TypeScript
- SurrealDB installed

## Step 1: Setting Up SurrealDB

First, ensure that SurrealDB is installed and running.

```bash
surreal start --user root --pass root
```

## Step 2: Create the React Application

Create a new React application using Create React App with TypeScript. In this example we use Vite.

```bash
npm create vite@latest surrealdb-query --template react-ts
cd surrealdb-query
```

## Step 3: Install Dependencies

Install Tanstack Query (React Query) and SurrealDB client.

```bash
npm install @tanstack/react-query surrealdb.js
```
Binary file added tanstack-query/bun.lockb
Binary file not shown.
13 changes: 13 additions & 0 deletions tanstack-query/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SurrealDB Query</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "surrealdb-query",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@tanstack/react-query": "^5.51.16",
"@tanstack/react-query-devtools": "^5.51.16",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"surrealdb.js": "^1.0.0-beta.9"
},
"devDependencies": {
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.15.0",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"typescript": "^5.2.2",
"vite": "^5.3.4"
}
}
1 change: 1 addition & 0 deletions tanstack-query/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions tanstack-query/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
68 changes: 68 additions & 0 deletions tanstack-query/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { initDb, getAllPosts } from './db';

interface Post {
id: string;
title: string;
content: string;
}

const fetchAllPosts = async (): Promise<Post[]> => {
await initDb();
const posts = await getAllPosts();
if (!posts || posts.length === 0) {
throw new Error('No posts found');
}
return posts;
};

const fetchPostByTitle = async (title: string): Promise<Post> => {
await initDb();
const posts = await getAllPosts();
const post = posts.find(p => p.title === title);
if (!post) {
throw new Error(`No post found with title ${title}`);
}
return post;
};

const App: React.FC = () => {
const { data: posts, isLoading: isLoadingPosts, error: postsError } = useQuery<Post[]>({
queryKey: ['posts'],
queryFn: fetchAllPosts,
});

const { data: post, isLoading: isLoadingPost, error: postError } = useQuery<Post>({
queryKey: ['postByTitle', 'Hello from SurrealDB'],
queryFn: () => fetchPostByTitle('Hello from SurrealDB'),
});

if (isLoadingPosts || isLoadingPost) return <div>Loading...</div>;
if (postsError) return <div>Error loading posts: {postsError.message}</div>;
if (postError) return <div>Error loading post: {postError.message}</div>;

return (
<div>
<h1>Fetching All Posts</h1>
<ul>
{posts?.map(post => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</li>
))}
</ul>

<h1>Post by Title</h1>
{post && (
<div>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
)}
</div>
);
};

export default App;
1 change: 1 addition & 0 deletions tanstack-query/src/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions tanstack-query/src/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Surreal from 'surrealdb.js';

let db: Surreal | undefined;

export async function initDb(): Promise<Surreal | undefined> {
if (db) return db;
db = new Surreal();
try {
await db.connect("http://127.0.0.1:8000/rpc");
await db.use({ namespace: "test", database: "test" });
await db.signin({ username: 'root', password: 'root' })

await db.query(`
CREATE post CONTENT {
title: 'Hello from SurrealDB',
content: 'This is a hello from SurrealDB'
};
CREATE post CONTENT {
title: 'SurrealDB is Awesome',
content: 'This is a post about SurrealDB'
};
`);

return db;
} catch (err) {
console.error("Failed to connect to SurrealDB:", err);
throw err;
}
}

interface Post {
id: string;
title: string;
content: string;
}

export const getAllPosts = async (): Promise<Post[]> => {
const posts = await db?.select('post');
if (!posts) {
throw new Error("Failed to fetch posts");
}
return posts.map(post => ({
id: post.id as unknown as string,
title: post.title as string,
content: post.content as string,
})) as Post[];
};
68 changes: 68 additions & 0 deletions tanstack-query/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}

h1 {
font-size: 3.2em;
line-height: 1.1;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
17 changes: 17 additions & 0 deletions tanstack-query/src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

const queryClient = new QueryClient()

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools />
</QueryClientProvider>
</React.StrictMode>,
)
1 change: 1 addition & 0 deletions tanstack-query/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
27 changes: 27 additions & 0 deletions tanstack-query/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
11 changes: 11 additions & 0 deletions tanstack-query/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.node.json"
}
]
}
13 changes: 13 additions & 0 deletions tanstack-query/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true,
"noEmit": true
},
"include": ["vite.config.ts"]
}
7 changes: 7 additions & 0 deletions tanstack-query/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})