diff --git a/examples/react/query-network-status/.gitignore b/examples/react/query-network-status/.gitignore
new file mode 100644
index 0000000..0c4423e
--- /dev/null
+++ b/examples/react/query-network-status/.gitignore
@@ -0,0 +1,29 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+# Lock files
+package-lock.json
+pnpm-lock.yaml
+yarn.lock
diff --git a/examples/react/query-network-status/README.md b/examples/react/query-network-status/README.md
new file mode 100644
index 0000000..1cf8892
--- /dev/null
+++ b/examples/react/query-network-status/README.md
@@ -0,0 +1,6 @@
+# Example
+
+To run this example:
+
+- `npm install`
+- `npm run dev`
diff --git a/examples/react/query-network-status/index.html b/examples/react/query-network-status/index.html
new file mode 100644
index 0000000..cf7fb58
--- /dev/null
+++ b/examples/react/query-network-status/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Floppy Disk - Query & Network Status
+
+
+
+
+
+
diff --git a/examples/react/query-network-status/index.jsx b/examples/react/query-network-status/index.jsx
new file mode 100644
index 0000000..ded5159
--- /dev/null
+++ b/examples/react/query-network-status/index.jsx
@@ -0,0 +1,84 @@
+import React, { useState } from 'react';
+import ReactDOM from 'react-dom/client';
+
+import { createQuery } from 'floppy-disk';
+
+const usePsyduckQuery = createQuery(
+ async () => {
+ const res = await fetch('https://pokeapi.co/api/v2/pokemon/psyduck');
+ if (res.ok) return res.json();
+ throw res;
+ },
+ {
+ defaultDeps: (state) => [state.data, state.error, state.isWaiting],
+ onBeforeFetch: (cancel) => {
+ if (!navigator.onLine) cancel();
+ },
+ },
+);
+
+const useEeveeQuery = createQuery(
+ async () => {
+ const res = await fetch('https://pokeapi.co/api/v2/pokemon/eevee-x'); // Expected wrong URL, to simulate error
+ if (res.ok) return res.json();
+ throw res;
+ },
+ {
+ defaultDeps: (state) => [state.data, state.error, state.isWaiting],
+ retry: () => {
+ if (navigator.onLine) return 2;
+ return 0;
+ },
+ },
+);
+
+function App() {
+ const [showQuery1, setShowQuery1] = useState(false);
+ const [showQuery2, setShowQuery2] = useState(false);
+
+ return (
+
+ 💾 Floppy Disk - Query & Network Status
+
+
+ Example 1: Disable fetch when offline
+
+ {showQuery1 && }
+
+
+ Example 2: Disable retries when offline
+
+ {showQuery2 && }
+
+ );
+}
+
+function Query1() {
+ const { data = {}, isWaiting } = usePsyduckQuery();
+ return (
+
+
+ - ID: {data.id}
+ - Name: {data.name}
+ - Height: {data.height}
+
+ {isWaiting && Fetching data... ⏳
}
+
+ );
+}
+
+function Query2() {
+ const { data = {}, isWaiting } = useEeveeQuery();
+ return (
+
+
+ - ID: {data.id}
+ - Name: {data.name}
+ - Height: {data.height}
+
+ {isWaiting && Fetching data... ⏳
}
+
+ );
+}
+
+ReactDOM.createRoot(document.getElementById('root')).render();
diff --git a/examples/react/query-network-status/package.json b/examples/react/query-network-status/package.json
new file mode 100644
index 0000000..fd0b15d
--- /dev/null
+++ b/examples/react/query-network-status/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "floppy-disk-example",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "floppy-disk": "^2.6.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.2.15",
+ "@types/react-dom": "^18.2.7",
+ "@vitejs/plugin-react": "^4.0.3",
+ "vite": "^4.4.5"
+ }
+}
diff --git a/examples/react/suspense/.gitignore b/examples/react/suspense/.gitignore
new file mode 100644
index 0000000..8f322f0
--- /dev/null
+++ b/examples/react/suspense/.gitignore
@@ -0,0 +1,35 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/examples/react/suspense/README.md b/examples/react/suspense/README.md
new file mode 100644
index 0000000..0dc9ea2
--- /dev/null
+++ b/examples/react/suspense/README.md
@@ -0,0 +1,36 @@
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+# or
+bun dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
+
+This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/examples/react/suspense/app/layout.js b/examples/react/suspense/app/layout.js
new file mode 100644
index 0000000..cd29ec9
--- /dev/null
+++ b/examples/react/suspense/app/layout.js
@@ -0,0 +1,11 @@
+export const metadata = {
+ title: 'Dependent Queries | Floppy Disk',
+};
+
+export default function RootLayout({ children }) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/examples/react/suspense/app/page.js b/examples/react/suspense/app/page.js
new file mode 100644
index 0000000..aebb1a0
--- /dev/null
+++ b/examples/react/suspense/app/page.js
@@ -0,0 +1,63 @@
+'use client';
+
+import { Suspense, useEffect, useState } from 'react';
+
+import { createQuery } from 'floppy-disk';
+
+const usePokemonQuery = createQuery(
+ async ({ pokemonName }) => {
+ const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonName}`);
+ if (res.ok) return res.json();
+ throw res;
+ },
+ {
+ enabled: ({ pokemonName }) => !!pokemonName,
+ onBeforeFetch: (_, state) => {
+ console.info(state);
+ },
+ },
+);
+
+export default function App() {
+ const [pokemonName, setPokemonName] = useState();
+
+ return (
+
+ 💾 Floppy Disk - Suspense
+
+ Loading... ⏳}>
+
+
+
+
+
+
+
+
+
+
+
+ {pokemonName ? (
+ Loading... ⏳}>
+
+
+ ) : (
+ Select a pokemon...
+ )}
+
+ );
+}
+
+function PokemonDetail({ pokemonName }) {
+ const { data } = usePokemonQuery.suspend({ pokemonName });
+ return (
+ <>
+ {data.name}
+
+ - Order: {data.order}
+ - Height: {data.height}
+ - Weight: {data.weight}
+
+ >
+ );
+}
diff --git a/examples/react/suspense/next.config.js b/examples/react/suspense/next.config.js
new file mode 100644
index 0000000..767719f
--- /dev/null
+++ b/examples/react/suspense/next.config.js
@@ -0,0 +1,4 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {}
+
+module.exports = nextConfig
diff --git a/examples/react/suspense/package.json b/examples/react/suspense/package.json
new file mode 100644
index 0000000..73e5fd8
--- /dev/null
+++ b/examples/react/suspense/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "floppy-disk-example",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "floppy-disk": "^2.6.0",
+ "next": "13.5.2",
+ "react": "18.2.0",
+ "react-dom": "18.2.0"
+ }
+}