@zeno-lib/query 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/prefetched-queries.d.mts +17 -0
- package/dist/prefetched-queries.mjs +37 -0
- package/dist/query-defaults.d.mts +41 -0
- package/dist/query-defaults.mjs +37 -0
- package/dist/query-hydration-boundary.d.mts +37 -0
- package/dist/query-hydration-boundary.mjs +28 -0
- package/dist/query-suspense-loading.d.mts +11 -0
- package/dist/query-suspense-loading.mjs +17 -0
- package/dist/query-suspense.d.mts +30 -0
- package/dist/query-suspense.mjs +63 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DehydratedState } from "@tanstack/react-query";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/prefetched-queries.d.ts
|
|
4
|
+
/** Whether the nearest `PrefetchedQueries` above was handed at least one dehydrated query. */
|
|
5
|
+
declare function useHasPrefetchedQueries(): boolean;
|
|
6
|
+
type PrefetchedQueriesProps = {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
state: DehydratedState;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* TanStack's `HydrationBoundary` plus the flag above. It hydrates `state` into the cache **during
|
|
12
|
+
* render** (on the server pass as well as in the browser), so a `useSuspenseQuery` below it
|
|
13
|
+
* resolves synchronously in both and the two passes produce the same markup.
|
|
14
|
+
*/
|
|
15
|
+
declare function PrefetchedQueries({ children, state }: PrefetchedQueriesProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { PrefetchedQueries, PrefetchedQueriesProps, useHasPrefetchedQueries };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { HydrationBoundary } from "@tanstack/react-query";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/prefetched-queries.tsx
|
|
6
|
+
/**
|
|
7
|
+
* True inside a subtree that was handed a filled dehydrated cache.
|
|
8
|
+
*
|
|
9
|
+
* `QuerySuspense` reads it to skip the gate that otherwise keeps a suspense query off the server
|
|
10
|
+
* render. It is **derived from the payload**, not passed as a flag, so nothing can opt in without
|
|
11
|
+
* having prefetched: the only way to make it true is to arrive here with cache entries.
|
|
12
|
+
*
|
|
13
|
+
* What it does *not* promise is that every query below was prefetched. One that was not still runs
|
|
14
|
+
* its `queryFn` during the server render, so a route that opts in has to prefetch every suspense
|
|
15
|
+
* query its **server pass** reaches.
|
|
16
|
+
*/
|
|
17
|
+
const PrefetchedQueriesContext = createContext(false);
|
|
18
|
+
/** Whether the nearest `PrefetchedQueries` above was handed at least one dehydrated query. */
|
|
19
|
+
function useHasPrefetchedQueries() {
|
|
20
|
+
return useContext(PrefetchedQueriesContext);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* TanStack's `HydrationBoundary` plus the flag above. It hydrates `state` into the cache **during
|
|
24
|
+
* render** (on the server pass as well as in the browser), so a `useSuspenseQuery` below it
|
|
25
|
+
* resolves synchronously in both and the two passes produce the same markup.
|
|
26
|
+
*/
|
|
27
|
+
function PrefetchedQueries({ children, state }) {
|
|
28
|
+
return /* @__PURE__ */ jsx(HydrationBoundary, {
|
|
29
|
+
state,
|
|
30
|
+
children: /* @__PURE__ */ jsx(PrefetchedQueriesContext.Provider, {
|
|
31
|
+
value: state.queries.length > 0,
|
|
32
|
+
children
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { PrefetchedQueries, useHasPrefetchedQueries };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/query-defaults.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Timing presets to spread as the first property of a `queryOptions(…)` call, so freshness stays
|
|
4
|
+
* consistent across a codebase instead of every query inventing its own `staleTime`.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* queryOptions({ ...cachedQueryDefaults, queryKey: ["countries"], queryFn: fetchCountries })
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Every duration is in milliseconds.
|
|
11
|
+
*/
|
|
12
|
+
/** Fast-moving data that keeps updating even while the tab is hidden: 15 s, refetched in the background. */
|
|
13
|
+
declare const liveBackgroundQueryDefaults: {
|
|
14
|
+
readonly refetchInterval: number;
|
|
15
|
+
readonly refetchIntervalInBackground: true;
|
|
16
|
+
readonly staleTime: number;
|
|
17
|
+
};
|
|
18
|
+
/** Fast-moving data refreshed while it is on screen: 30 s. */
|
|
19
|
+
declare const liveQueryDefaults: {
|
|
20
|
+
readonly refetchInterval: number;
|
|
21
|
+
readonly staleTime: number;
|
|
22
|
+
};
|
|
23
|
+
/** Data that can be slightly stale: 1 min. */
|
|
24
|
+
declare const shortLivedQueryDefaults: {
|
|
25
|
+
readonly staleTime: number;
|
|
26
|
+
};
|
|
27
|
+
/** Slower-changing detail data: 2 min. */
|
|
28
|
+
declare const longLivedQueryDefaults: {
|
|
29
|
+
readonly staleTime: number;
|
|
30
|
+
};
|
|
31
|
+
/** Reference data worth keeping longer: 5 min stale, 30 min in the cache (the one preset that raises `gcTime`). */
|
|
32
|
+
declare const cachedQueryDefaults: {
|
|
33
|
+
readonly gcTime: number;
|
|
34
|
+
readonly staleTime: number;
|
|
35
|
+
};
|
|
36
|
+
/** Effectively immutable data: never stale. */
|
|
37
|
+
declare const staticQueryDefaults: {
|
|
38
|
+
readonly staleTime: number;
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
export { cachedQueryDefaults, liveBackgroundQueryDefaults, liveQueryDefaults, longLivedQueryDefaults, shortLivedQueryDefaults, staticQueryDefaults };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/query-defaults.ts
|
|
2
|
+
/**
|
|
3
|
+
* Timing presets to spread as the first property of a `queryOptions(…)` call, so freshness stays
|
|
4
|
+
* consistent across a codebase instead of every query inventing its own `staleTime`.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* queryOptions({ ...cachedQueryDefaults, queryKey: ["countries"], queryFn: fetchCountries })
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Every duration is in milliseconds.
|
|
11
|
+
*/
|
|
12
|
+
const SECOND = 1e3;
|
|
13
|
+
const MINUTE = 60 * SECOND;
|
|
14
|
+
/** Fast-moving data that keeps updating even while the tab is hidden: 15 s, refetched in the background. */
|
|
15
|
+
const liveBackgroundQueryDefaults = {
|
|
16
|
+
refetchInterval: 15 * SECOND,
|
|
17
|
+
refetchIntervalInBackground: true,
|
|
18
|
+
staleTime: 15 * SECOND
|
|
19
|
+
};
|
|
20
|
+
/** Fast-moving data refreshed while it is on screen: 30 s. */
|
|
21
|
+
const liveQueryDefaults = {
|
|
22
|
+
refetchInterval: 30 * SECOND,
|
|
23
|
+
staleTime: 30 * SECOND
|
|
24
|
+
};
|
|
25
|
+
/** Data that can be slightly stale: 1 min. */
|
|
26
|
+
const shortLivedQueryDefaults = { staleTime: MINUTE };
|
|
27
|
+
/** Slower-changing detail data: 2 min. */
|
|
28
|
+
const longLivedQueryDefaults = { staleTime: 2 * MINUTE };
|
|
29
|
+
/** Reference data worth keeping longer: 5 min stale, 30 min in the cache (the one preset that raises `gcTime`). */
|
|
30
|
+
const cachedQueryDefaults = {
|
|
31
|
+
gcTime: 30 * MINUTE,
|
|
32
|
+
staleTime: 5 * MINUTE
|
|
33
|
+
};
|
|
34
|
+
/** Effectively immutable data: never stale. */
|
|
35
|
+
const staticQueryDefaults = { staleTime: Number.POSITIVE_INFINITY };
|
|
36
|
+
//#endregion
|
|
37
|
+
export { cachedQueryDefaults, liveBackgroundQueryDefaults, liveQueryDefaults, longLivedQueryDefaults, shortLivedQueryDefaults, staticQueryDefaults };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { DehydrateOptions, QueryClient } from "@tanstack/react-query";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/query-hydration-boundary.d.ts
|
|
4
|
+
type QueryHydrationBoundaryProps = {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
/**
|
|
7
|
+
* Fills the server-side cache. Call each query through the same `queryOptions` factory the
|
|
8
|
+
* browser uses, unchanged, so the entry has the key *and* the value the client would build.
|
|
9
|
+
* Use `fetchQuery` for a read the route cannot render without (`prefetchQuery` swallows
|
|
10
|
+
* failures); everything else can be `prefetchQuery`.
|
|
11
|
+
*/
|
|
12
|
+
prefetch: (queryClient: QueryClient) => Promise<unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* Builds the per-request `QueryClient` handed to `prefetch`. Defaults to `new QueryClient()`.
|
|
15
|
+
* Pass one when your queries depend on client-level defaults (e.g. `defaultOptions.queries`).
|
|
16
|
+
*/
|
|
17
|
+
createQueryClient?: () => QueryClient;
|
|
18
|
+
/** Forwarded to TanStack's `dehydrate` (e.g. to also dehydrate pending queries). */
|
|
19
|
+
dehydrateOptions?: DehydrateOptions;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Async **server component**: runs `prefetch` against a fresh `QueryClient` and dehydrates the
|
|
23
|
+
* result into `PrefetchedQueries`, so the suspense queries below resolve from the cache in the
|
|
24
|
+
* server render *and* in the browser. That is what lets a `QuerySuspense` subtree render real
|
|
25
|
+
* HTML instead of holding its fallback until hydration.
|
|
26
|
+
*
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <QueryHydrationBoundary
|
|
29
|
+
* prefetch={(queryClient) => queryClient.fetchQuery(dealsQueryOptions(filters))}
|
|
30
|
+
* >
|
|
31
|
+
* <Deals />
|
|
32
|
+
* </QueryHydrationBoundary>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare function QueryHydrationBoundary({ children, createQueryClient, dehydrateOptions, prefetch }: QueryHydrationBoundaryProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { QueryHydrationBoundary, QueryHydrationBoundaryProps };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PrefetchedQueries } from "./prefetched-queries.mjs";
|
|
2
|
+
import { QueryClient, dehydrate } from "@tanstack/react-query";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/query-hydration-boundary.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Async **server component**: runs `prefetch` against a fresh `QueryClient` and dehydrates the
|
|
7
|
+
* result into `PrefetchedQueries`, so the suspense queries below resolve from the cache in the
|
|
8
|
+
* server render *and* in the browser. That is what lets a `QuerySuspense` subtree render real
|
|
9
|
+
* HTML instead of holding its fallback until hydration.
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* <QueryHydrationBoundary
|
|
13
|
+
* prefetch={(queryClient) => queryClient.fetchQuery(dealsQueryOptions(filters))}
|
|
14
|
+
* >
|
|
15
|
+
* <Deals />
|
|
16
|
+
* </QueryHydrationBoundary>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
async function QueryHydrationBoundary({ children, createQueryClient = () => new QueryClient(), dehydrateOptions, prefetch }) {
|
|
20
|
+
const queryClient = createQueryClient();
|
|
21
|
+
await prefetch(queryClient);
|
|
22
|
+
return /* @__PURE__ */ jsx(PrefetchedQueries, {
|
|
23
|
+
state: dehydrate(queryClient, dehydrateOptions),
|
|
24
|
+
children
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { QueryHydrationBoundary };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef } from "react";
|
|
2
|
+
//#region src/query-suspense-loading.d.ts
|
|
3
|
+
type QuerySuspenseLoadingProps = ComponentPropsWithoutRef<"div">;
|
|
4
|
+
/**
|
|
5
|
+
* Single layout root for Suspense loading UI: set `className` and children here so `aria-busy` /
|
|
6
|
+
* `aria-live` apply to the same element as your skeleton stack (no inner wrapper div). Accepts
|
|
7
|
+
* all `div` props; the `aria-busy` and `aria-live` defaults can be overridden.
|
|
8
|
+
*/
|
|
9
|
+
declare function QuerySuspenseLoading({ "aria-busy": ariaBusy, "aria-live": ariaLive, children, ...props }: QuerySuspenseLoadingProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { QuerySuspenseLoading, QuerySuspenseLoadingProps };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/query-suspense-loading.tsx
|
|
3
|
+
/**
|
|
4
|
+
* Single layout root for Suspense loading UI: set `className` and children here so `aria-busy` /
|
|
5
|
+
* `aria-live` apply to the same element as your skeleton stack (no inner wrapper div). Accepts
|
|
6
|
+
* all `div` props; the `aria-busy` and `aria-live` defaults can be overridden.
|
|
7
|
+
*/
|
|
8
|
+
function QuerySuspenseLoading({ "aria-busy": ariaBusy = true, "aria-live": ariaLive = "polite", children, ...props }) {
|
|
9
|
+
return /* @__PURE__ */ jsx("div", {
|
|
10
|
+
"aria-busy": ariaBusy,
|
|
11
|
+
"aria-live": ariaLive,
|
|
12
|
+
...props,
|
|
13
|
+
children
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { QuerySuspenseLoading };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/query-suspense.d.ts
|
|
3
|
+
type QuerySuspenseErrorFallbackProps = {
|
|
4
|
+
error: Error;
|
|
5
|
+
onRetry: () => void;
|
|
6
|
+
};
|
|
7
|
+
/** Dev/test only: force a boundary's loading or error UI (e.g. for screenshots). Ignored in production. */
|
|
8
|
+
type QuerySuspenseDebugState = "loading" | "error";
|
|
9
|
+
/** Exported so callers can type wrapper components that forward `fallback` / `errorFallback`. */
|
|
10
|
+
type QuerySuspenseProps = {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
/** Suspense fallback: usually a skeleton of the same layout. */
|
|
13
|
+
fallback: ReactNode;
|
|
14
|
+
/** Rendered when a query below throws; `onRetry` resets the failed queries and re-renders. */
|
|
15
|
+
errorFallback: (props: QuerySuspenseErrorFallbackProps) => ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Development / test only: render `fallback` or `errorFallback` without running queries.
|
|
18
|
+
* No effect when `NODE_ENV` is `"production"`.
|
|
19
|
+
*/
|
|
20
|
+
debugState?: QuerySuspenseDebugState;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* TanStack's recommended suspense stack (`QueryErrorResetBoundary` → error boundary →
|
|
24
|
+
* `Suspense`, see https://tanstack.com/query/v5/docs/framework/react/guides/suspense), plus a
|
|
25
|
+
* hydration gate: `fallback` is all it renders on the server and through hydration, unless a
|
|
26
|
+
* `PrefetchedQueries` (e.g. from `QueryHydrationBoundary`) above it was handed dehydrated queries.
|
|
27
|
+
*/
|
|
28
|
+
declare function QuerySuspense({ children, errorFallback, fallback, debugState }: QuerySuspenseProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { QuerySuspense, QuerySuspenseDebugState, QuerySuspenseErrorFallbackProps, QuerySuspenseProps };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useHasPrefetchedQueries } from "./prefetched-queries.mjs";
|
|
3
|
+
import { QueryErrorResetBoundary } from "@tanstack/react-query";
|
|
4
|
+
import { Component, Suspense, useSyncExternalStore } from "react";
|
|
5
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/query-suspense.tsx
|
|
7
|
+
const debugStateEnabled = typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
8
|
+
const subscribeToNothing = () => () => {};
|
|
9
|
+
const useIsHydrated = () => useSyncExternalStore(subscribeToNothing, () => true, () => false);
|
|
10
|
+
const debugError = Object.freeze(/* @__PURE__ */ new Error("QuerySuspense: debugState=\"error\" (development / test only; for screenshots)"));
|
|
11
|
+
const noop = () => {};
|
|
12
|
+
/** Next.js control-flow errors (`notFound()`, `redirect()`, …) carry a `NEXT_`-prefixed digest. */
|
|
13
|
+
const isNextControlFlowError = (error) => typeof error === "object" && error !== null && "digest" in error && typeof error.digest === "string" && error.digest.startsWith("NEXT_");
|
|
14
|
+
var QueryErrorBoundary = class extends Component {
|
|
15
|
+
constructor(props) {
|
|
16
|
+
super(props);
|
|
17
|
+
this.handleRetry = () => {
|
|
18
|
+
this.props.onQueryReset();
|
|
19
|
+
this.setState({ error: null });
|
|
20
|
+
};
|
|
21
|
+
this.state = { error: null };
|
|
22
|
+
}
|
|
23
|
+
static getDerivedStateFromError(error) {
|
|
24
|
+
if (isNextControlFlowError(error)) throw error;
|
|
25
|
+
return { error };
|
|
26
|
+
}
|
|
27
|
+
componentDidCatch(error) {
|
|
28
|
+
console.error("QueryErrorBoundary:", error);
|
|
29
|
+
}
|
|
30
|
+
render() {
|
|
31
|
+
if (this.state.error) return this.props.errorFallback({
|
|
32
|
+
error: this.state.error,
|
|
33
|
+
onRetry: this.handleRetry
|
|
34
|
+
});
|
|
35
|
+
return this.props.children;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* TanStack's recommended suspense stack (`QueryErrorResetBoundary` → error boundary →
|
|
40
|
+
* `Suspense`, see https://tanstack.com/query/v5/docs/framework/react/guides/suspense), plus a
|
|
41
|
+
* hydration gate: `fallback` is all it renders on the server and through hydration, unless a
|
|
42
|
+
* `PrefetchedQueries` (e.g. from `QueryHydrationBoundary`) above it was handed dehydrated queries.
|
|
43
|
+
*/
|
|
44
|
+
function QuerySuspense({ children, errorFallback, fallback, debugState }) {
|
|
45
|
+
const isHydrated = useIsHydrated();
|
|
46
|
+
const hasPrefetchedQueries = useHasPrefetchedQueries();
|
|
47
|
+
if (debugStateEnabled && debugState === "loading") return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
48
|
+
if (debugStateEnabled && debugState === "error") return /* @__PURE__ */ jsx(Fragment, { children: errorFallback({
|
|
49
|
+
error: debugError,
|
|
50
|
+
onRetry: noop
|
|
51
|
+
}) });
|
|
52
|
+
if (!(isHydrated || hasPrefetchedQueries)) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
|
|
53
|
+
return /* @__PURE__ */ jsx(QueryErrorResetBoundary, { children: ({ reset }) => /* @__PURE__ */ jsx(QueryErrorBoundary, {
|
|
54
|
+
errorFallback,
|
|
55
|
+
onQueryReset: reset,
|
|
56
|
+
children: /* @__PURE__ */ jsx(Suspense, {
|
|
57
|
+
fallback,
|
|
58
|
+
children
|
|
59
|
+
})
|
|
60
|
+
}) });
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { QuerySuspense };
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zeno-lib/query",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
"./prefetched-queries": {
|
|
7
|
+
"types": "./dist/prefetched-queries.d.mts",
|
|
8
|
+
"import": "./dist/prefetched-queries.mjs",
|
|
9
|
+
"default": "./dist/prefetched-queries.mjs"
|
|
10
|
+
},
|
|
11
|
+
"./query-defaults": {
|
|
12
|
+
"types": "./dist/query-defaults.d.mts",
|
|
13
|
+
"import": "./dist/query-defaults.mjs",
|
|
14
|
+
"default": "./dist/query-defaults.mjs"
|
|
15
|
+
},
|
|
16
|
+
"./query-hydration-boundary": {
|
|
17
|
+
"types": "./dist/query-hydration-boundary.d.mts",
|
|
18
|
+
"import": "./dist/query-hydration-boundary.mjs",
|
|
19
|
+
"default": "./dist/query-hydration-boundary.mjs"
|
|
20
|
+
},
|
|
21
|
+
"./query-suspense": {
|
|
22
|
+
"types": "./dist/query-suspense.d.mts",
|
|
23
|
+
"import": "./dist/query-suspense.mjs",
|
|
24
|
+
"default": "./dist/query-suspense.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./query-suspense-loading": {
|
|
27
|
+
"types": "./dist/query-suspense-loading.d.mts",
|
|
28
|
+
"import": "./dist/query-suspense-loading.mjs",
|
|
29
|
+
"default": "./dist/query-suspense-loading.mjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"url": "https://github.com/zeno-lib/zeno.git",
|
|
40
|
+
"directory": "packages/query"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@tanstack/react-query": ">=5",
|
|
44
|
+
"react": ">=19"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@tanstack/react-query": "^5.103.2",
|
|
48
|
+
"@types/node": "25.6.0",
|
|
49
|
+
"@types/react": "19.2.14",
|
|
50
|
+
"@types/react-dom": "19.2.3",
|
|
51
|
+
"react": "^19.2.5",
|
|
52
|
+
"react-dom": "^19.2.5",
|
|
53
|
+
"tsdown": "^0.22.14",
|
|
54
|
+
"typescript": "7.0.2",
|
|
55
|
+
"vite": "8.0.16",
|
|
56
|
+
"vitest": "4.1.11",
|
|
57
|
+
"@zeno-lib/test": "^0.0.3",
|
|
58
|
+
"@zeno-lib/typescript": "^1.1.0",
|
|
59
|
+
"@zeno-lib/ui": "^0.0.1"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsdown",
|
|
63
|
+
"test": "vitest --run",
|
|
64
|
+
"test:watch": "vitest watch",
|
|
65
|
+
"types:check": "tsc --noEmit"
|
|
66
|
+
}
|
|
67
|
+
}
|