diff --git a/bun.lock b/bun.lock
index 9ead317..c0936b8 100644
--- a/bun.lock
+++ b/bun.lock
@@ -18,6 +18,7 @@
"@effect/platform-browser": "^0.56.2",
"@radix-ui/themes": "^3.2.0",
"@reffuse/extension-lazyref": "workspace:*",
+ "@reffuse/extension-query": "workspace:*",
"@typed/id": "^0.17.1",
"@typed/lazy-ref": "^0.3.3",
"effect": "^3.13.2",
@@ -55,7 +56,7 @@
"@types/react": "^19.0.0",
"effect": "^3.13.0",
"react": "^19.0.0",
- "reffuse": "^0.1.1",
+ "reffuse": "^0.1.2",
},
},
"packages/extension-query": {
diff --git a/packages/example/package.json b/packages/example/package.json
index e1a234e..6d93aba 100644
--- a/packages/example/package.json
+++ b/packages/example/package.json
@@ -33,6 +33,7 @@
"@effect/platform-browser": "^0.56.2",
"@radix-ui/themes": "^3.2.0",
"@reffuse/extension-lazyref": "workspace:*",
+ "@reffuse/extension-query": "workspace:*",
"@typed/id": "^0.17.1",
"@typed/lazy-ref": "^0.3.3",
"effect": "^3.13.2",
diff --git a/packages/example/src/reffuse.ts b/packages/example/src/reffuse.ts
index 0aefd92..c5d008f 100644
--- a/packages/example/src/reffuse.ts
+++ b/packages/example/src/reffuse.ts
@@ -1,6 +1,7 @@
import { HttpClient } from "@effect/platform"
import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser"
import { LazyRefExtension } from "@reffuse/extension-lazyref"
+import { QueryExtension } from "@reffuse/extension-query"
import { Reffuse, ReffuseContext } from "reffuse"
@@ -13,6 +14,7 @@ export const GlobalContext = ReffuseContext.make<
export class GlobalReffuse extends Reffuse.Reffuse.pipe(
Reffuse.withExtension(LazyRefExtension),
+ Reffuse.withExtension(QueryExtension),
Reffuse.withContexts(GlobalContext),
) {}
diff --git a/packages/example/src/routeTree.gen.ts b/packages/example/src/routeTree.gen.ts
index 98b4224..20f3fba 100644
--- a/packages/example/src/routeTree.gen.ts
+++ b/packages/example/src/routeTree.gen.ts
@@ -13,6 +13,7 @@
import { Route as rootRoute } from './routes/__root'
import { Route as TimeImport } from './routes/time'
import { Route as TestsImport } from './routes/tests'
+import { Route as QueryImport } from './routes/query'
import { Route as PromiseImport } from './routes/promise'
import { Route as LazyrefImport } from './routes/lazyref'
import { Route as CountImport } from './routes/count'
@@ -33,6 +34,12 @@ const TestsRoute = TestsImport.update({
getParentRoute: () => rootRoute,
} as any)
+const QueryRoute = QueryImport.update({
+ id: '/query',
+ path: '/query',
+ getParentRoute: () => rootRoute,
+} as any)
+
const PromiseRoute = PromiseImport.update({
id: '/promise',
path: '/promise',
@@ -102,6 +109,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PromiseImport
parentRoute: typeof rootRoute
}
+ '/query': {
+ id: '/query'
+ path: '/query'
+ fullPath: '/query'
+ preLoaderRoute: typeof QueryImport
+ parentRoute: typeof rootRoute
+ }
'/tests': {
id: '/tests'
path: '/tests'
@@ -127,6 +141,7 @@ export interface FileRoutesByFullPath {
'/count': typeof CountRoute
'/lazyref': typeof LazyrefRoute
'/promise': typeof PromiseRoute
+ '/query': typeof QueryRoute
'/tests': typeof TestsRoute
'/time': typeof TimeRoute
}
@@ -137,6 +152,7 @@ export interface FileRoutesByTo {
'/count': typeof CountRoute
'/lazyref': typeof LazyrefRoute
'/promise': typeof PromiseRoute
+ '/query': typeof QueryRoute
'/tests': typeof TestsRoute
'/time': typeof TimeRoute
}
@@ -148,6 +164,7 @@ export interface FileRoutesById {
'/count': typeof CountRoute
'/lazyref': typeof LazyrefRoute
'/promise': typeof PromiseRoute
+ '/query': typeof QueryRoute
'/tests': typeof TestsRoute
'/time': typeof TimeRoute
}
@@ -160,10 +177,19 @@ export interface FileRouteTypes {
| '/count'
| '/lazyref'
| '/promise'
+ | '/query'
| '/tests'
| '/time'
fileRoutesByTo: FileRoutesByTo
- to: '/' | '/blank' | '/count' | '/lazyref' | '/promise' | '/tests' | '/time'
+ to:
+ | '/'
+ | '/blank'
+ | '/count'
+ | '/lazyref'
+ | '/promise'
+ | '/query'
+ | '/tests'
+ | '/time'
id:
| '__root__'
| '/'
@@ -171,6 +197,7 @@ export interface FileRouteTypes {
| '/count'
| '/lazyref'
| '/promise'
+ | '/query'
| '/tests'
| '/time'
fileRoutesById: FileRoutesById
@@ -182,6 +209,7 @@ export interface RootRouteChildren {
CountRoute: typeof CountRoute
LazyrefRoute: typeof LazyrefRoute
PromiseRoute: typeof PromiseRoute
+ QueryRoute: typeof QueryRoute
TestsRoute: typeof TestsRoute
TimeRoute: typeof TimeRoute
}
@@ -192,6 +220,7 @@ const rootRouteChildren: RootRouteChildren = {
CountRoute: CountRoute,
LazyrefRoute: LazyrefRoute,
PromiseRoute: PromiseRoute,
+ QueryRoute: QueryRoute,
TestsRoute: TestsRoute,
TimeRoute: TimeRoute,
}
@@ -211,6 +240,7 @@ export const routeTree = rootRoute
"/count",
"/lazyref",
"/promise",
+ "/query",
"/tests",
"/time"
]
@@ -230,6 +260,9 @@ export const routeTree = rootRoute
"/promise": {
"filePath": "promise.tsx"
},
+ "/query": {
+ "filePath": "query.tsx"
+ },
"/tests": {
"filePath": "tests.tsx"
},
diff --git a/packages/example/src/routes/query.tsx b/packages/example/src/routes/query.tsx
new file mode 100644
index 0000000..4d58212
--- /dev/null
+++ b/packages/example/src/routes/query.tsx
@@ -0,0 +1,40 @@
+import { R } from "@/reffuse"
+import { HttpClient } from "@effect/platform"
+import { Container, Text } from "@radix-ui/themes"
+import { createFileRoute } from "@tanstack/react-router"
+import * as AsyncData from "@typed/async-data"
+import { Effect, Schema } from "effect"
+
+
+export const Route = createFileRoute("/query")({
+ component: RouteComponent
+})
+
+
+const Result = Schema.Tuple(Schema.String)
+
+function RouteComponent() {
+ const { state } = R.useQuery({
+ effect: () => HttpClient.get("https://www.uuidtools.com/api/generate/v4").pipe(
+ HttpClient.withTracerPropagation(false),
+ Effect.flatMap(res => res.json),
+ Effect.flatMap(Schema.decodeUnknown(Result)),
+ ),
+ deps: [],
+ })
+
+ return (
+
+
+ {AsyncData.match(state, {
+ NoData: () => "No data yet",
+ Loading: () => "Loading...",
+ Success: (value, { isRefreshing, isOptimistic }) =>
+ `Value: ${value} ${isRefreshing ? "(refreshing)" : ""} ${isOptimistic ? "(optimistic)" : ""}`,
+ Failure: (cause, { isRefreshing }) =>
+ `Error: ${cause} ${isRefreshing ? "(refreshing)" : ""}`,
+ })}
+
+
+ )
+}
diff --git a/packages/extension-query/src/index.ts b/packages/extension-query/src/index.ts
index ebd3518..2694a64 100644
--- a/packages/extension-query/src/index.ts
+++ b/packages/extension-query/src/index.ts
@@ -1,12 +1,12 @@
import * as AsyncData from "@typed/async-data"
-import { Effect } from "effect"
+import { Effect, Scope } from "effect"
import * as React from "react"
import { useState } from "react"
import { ReffuseExtension, type ReffuseHelpers } from "reffuse"
export interface UseQueryProps {
- effect(): Effect.Effect
+ effect(): Effect.Effect
readonly deps?: React.DependencyList
}