@effector-tanstack-query/react 0.2.0 → 0.3.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.
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+ var effectorReact = require('effector-react');
6
+ var reactQuery = require('@tanstack/react-query');
7
+ var core = require('@effector-tanstack-query/core');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
+
30
+ function QueryClientCompatProvider({
31
+ children,
32
+ defaultOptions
33
+ }) {
34
+ const fromEffector = effectorReact.useUnit(core.$queryClient);
35
+ const [serverFallback] = React__namespace.useState(
36
+ () => reactQuery.isServer ? new reactQuery.QueryClient({ defaultOptions }) : null
37
+ );
38
+ const qc = fromEffector ?? serverFallback;
39
+ if (!qc) {
40
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
41
+ }
42
+ return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: qc, children });
43
+ }
44
+
45
+ exports.QueryClientCompatProvider = QueryClientCompatProvider;
46
+ //# sourceMappingURL=compat.cjs.map
47
+ //# sourceMappingURL=compat.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/compat.tsx"],"names":["useUnit","$queryClient","React","isServer","QueryClient","jsx","QueryClientProvider"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DO,SAAS,yBAAA,CAA0B;AAAA,EACxC,QAAA;AAAA,EACA;AACF,CAAA,EAAuD;AACrD,EAAA,MAAM,YAAA,GAAeA,sBAAQC,iBAAY,CAAA;AACzC,EAAA,MAAM,CAAC,cAAc,CAAA,GAAUC,gBAAA,CAAA,QAAA;AAAA,IAA6B,MAC1DC,mBAAA,GAAW,IAAIC,uBAAY,EAAE,cAAA,EAAgB,CAAA,GAAI;AAAA,GACnD;AAEA,EAAA,MAAM,KAAK,YAAA,IAAgB,cAAA;AAC3B,EAAA,IAAI,CAAC,EAAA,EAAI;AAMP,IAAA,6DAAU,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,uBAAOC,cAAA,CAACC,8BAAA,EAAA,EAAoB,MAAA,EAAQ,EAAA,EAAK,QAAA,EAAS,CAAA;AACpD","file":"compat.cjs","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useUnit } from 'effector-react'\nimport {\n isServer,\n QueryClient,\n QueryClientProvider,\n} from '@tanstack/react-query'\nimport { $queryClient } from '@effector-tanstack-query/core'\n\ntype DefaultOptions = NonNullable<\n ConstructorParameters<typeof QueryClient>[0]\n>['defaultOptions']\n\nexport interface QueryClientCompatProviderProps {\n children: React.ReactNode\n /**\n * `defaultOptions` for the per-render server fallback `QueryClient`\n * (see below). Has no effect on the client — the browser singleton\n * built in your own top-level `<EffectorNext>` setup is what `useQuery`\n * from `@tanstack/react-query` resolves to there. Keep these aligned\n * with your `createQuery({ staleTime, retry, ... })` definitions so\n * server-rendered HTML matches what the client will produce after\n * hydration.\n */\n defaultOptions?: DefaultOptions\n}\n\n/**\n * SSR-safe `QueryClientProvider` bridge for users mixing\n * `@tanstack/react-query` and `@effector-tanstack-query` — the typical\n * \"we're migrating page by page\" case.\n *\n * Why a dedicated component:\n *\n * - **Client**: `useUnit($queryClient)` returns the singleton browser\n * `QueryClient` already mounted by your top-level provider (whichever\n * module calls `setQueryClient(qc)` + `allSettled($queryClient, ...)`\n * for `getClientScope()`). Handing that same instance to\n * `<QueryClientProvider>` means **both APIs share a cache**: prefetch\n * with one, read with the other; `setQueryData` /\n * `invalidateQueries` from one re-renders the other.\n *\n * - **Server (RSC)**: `$queryClient` is `serialize: 'ignore'` (its\n * value is a class instance — not JSON-safe — and per-request\n * QueryClients must NEVER be a module-level singleton on the\n * server). So inside the RSC rendering scope produced by\n * `<EffectorNext values={serialize(scope)}>`, `useUnit($queryClient)`\n * resolves to `null`. We fall back to a throwaway per-render\n * `QueryClient` solely so vanilla `useQuery` has a provider during\n * the server pass. Pair this component with `<HydrationBoundary>`\n * from `@tanstack/react-query` — the boundary will hydrate this\n * fallback client with the prefetched cache, so server-rendered\n * HTML shows data instead of a loading flash. On client hydration\n * the provider re-renders with the singleton browser client and\n * react-query re-subscribes its observers.\n *\n * `useState` makes the fallback per-component-instance (one per render\n * tree), not a module-level singleton — concurrent SSR requests don't\n * share it.\n */\nexport function QueryClientCompatProvider({\n children,\n defaultOptions,\n}: QueryClientCompatProviderProps): React.ReactElement {\n const fromEffector = useUnit($queryClient)\n const [serverFallback] = React.useState<QueryClient | null>(() =>\n isServer ? new QueryClient({ defaultOptions }) : null,\n )\n\n const qc = fromEffector ?? serverFallback\n if (!qc) {\n // Defensive: on the client `fromEffector` is set synchronously by\n // your top-level provider before any render, so this branch is\n // unreachable in practice. If it fires, rendering children without\n // a provider would crash any descendant `useQuery` from\n // `@tanstack/react-query`.\n return <>{children}</>\n }\n\n return <QueryClientProvider client={qc}>{children}</QueryClientProvider>\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import * as React from 'react';
2
+ import { QueryClient } from '@tanstack/react-query';
3
+
4
+ type DefaultOptions = NonNullable<ConstructorParameters<typeof QueryClient>[0]>['defaultOptions'];
5
+ interface QueryClientCompatProviderProps {
6
+ children: React.ReactNode;
7
+ /**
8
+ * `defaultOptions` for the per-render server fallback `QueryClient`
9
+ * (see below). Has no effect on the client — the browser singleton
10
+ * built in your own top-level `<EffectorNext>` setup is what `useQuery`
11
+ * from `@tanstack/react-query` resolves to there. Keep these aligned
12
+ * with your `createQuery({ staleTime, retry, ... })` definitions so
13
+ * server-rendered HTML matches what the client will produce after
14
+ * hydration.
15
+ */
16
+ defaultOptions?: DefaultOptions;
17
+ }
18
+ /**
19
+ * SSR-safe `QueryClientProvider` bridge for users mixing
20
+ * `@tanstack/react-query` and `@effector-tanstack-query` — the typical
21
+ * "we're migrating page by page" case.
22
+ *
23
+ * Why a dedicated component:
24
+ *
25
+ * - **Client**: `useUnit($queryClient)` returns the singleton browser
26
+ * `QueryClient` already mounted by your top-level provider (whichever
27
+ * module calls `setQueryClient(qc)` + `allSettled($queryClient, ...)`
28
+ * for `getClientScope()`). Handing that same instance to
29
+ * `<QueryClientProvider>` means **both APIs share a cache**: prefetch
30
+ * with one, read with the other; `setQueryData` /
31
+ * `invalidateQueries` from one re-renders the other.
32
+ *
33
+ * - **Server (RSC)**: `$queryClient` is `serialize: 'ignore'` (its
34
+ * value is a class instance — not JSON-safe — and per-request
35
+ * QueryClients must NEVER be a module-level singleton on the
36
+ * server). So inside the RSC rendering scope produced by
37
+ * `<EffectorNext values={serialize(scope)}>`, `useUnit($queryClient)`
38
+ * resolves to `null`. We fall back to a throwaway per-render
39
+ * `QueryClient` solely so vanilla `useQuery` has a provider during
40
+ * the server pass. Pair this component with `<HydrationBoundary>`
41
+ * from `@tanstack/react-query` — the boundary will hydrate this
42
+ * fallback client with the prefetched cache, so server-rendered
43
+ * HTML shows data instead of a loading flash. On client hydration
44
+ * the provider re-renders with the singleton browser client and
45
+ * react-query re-subscribes its observers.
46
+ *
47
+ * `useState` makes the fallback per-component-instance (one per render
48
+ * tree), not a module-level singleton — concurrent SSR requests don't
49
+ * share it.
50
+ */
51
+ declare function QueryClientCompatProvider({ children, defaultOptions, }: QueryClientCompatProviderProps): React.ReactElement;
52
+
53
+ export { QueryClientCompatProvider, type QueryClientCompatProviderProps };
@@ -0,0 +1,53 @@
1
+ import * as React from 'react';
2
+ import { QueryClient } from '@tanstack/react-query';
3
+
4
+ type DefaultOptions = NonNullable<ConstructorParameters<typeof QueryClient>[0]>['defaultOptions'];
5
+ interface QueryClientCompatProviderProps {
6
+ children: React.ReactNode;
7
+ /**
8
+ * `defaultOptions` for the per-render server fallback `QueryClient`
9
+ * (see below). Has no effect on the client — the browser singleton
10
+ * built in your own top-level `<EffectorNext>` setup is what `useQuery`
11
+ * from `@tanstack/react-query` resolves to there. Keep these aligned
12
+ * with your `createQuery({ staleTime, retry, ... })` definitions so
13
+ * server-rendered HTML matches what the client will produce after
14
+ * hydration.
15
+ */
16
+ defaultOptions?: DefaultOptions;
17
+ }
18
+ /**
19
+ * SSR-safe `QueryClientProvider` bridge for users mixing
20
+ * `@tanstack/react-query` and `@effector-tanstack-query` — the typical
21
+ * "we're migrating page by page" case.
22
+ *
23
+ * Why a dedicated component:
24
+ *
25
+ * - **Client**: `useUnit($queryClient)` returns the singleton browser
26
+ * `QueryClient` already mounted by your top-level provider (whichever
27
+ * module calls `setQueryClient(qc)` + `allSettled($queryClient, ...)`
28
+ * for `getClientScope()`). Handing that same instance to
29
+ * `<QueryClientProvider>` means **both APIs share a cache**: prefetch
30
+ * with one, read with the other; `setQueryData` /
31
+ * `invalidateQueries` from one re-renders the other.
32
+ *
33
+ * - **Server (RSC)**: `$queryClient` is `serialize: 'ignore'` (its
34
+ * value is a class instance — not JSON-safe — and per-request
35
+ * QueryClients must NEVER be a module-level singleton on the
36
+ * server). So inside the RSC rendering scope produced by
37
+ * `<EffectorNext values={serialize(scope)}>`, `useUnit($queryClient)`
38
+ * resolves to `null`. We fall back to a throwaway per-render
39
+ * `QueryClient` solely so vanilla `useQuery` has a provider during
40
+ * the server pass. Pair this component with `<HydrationBoundary>`
41
+ * from `@tanstack/react-query` — the boundary will hydrate this
42
+ * fallback client with the prefetched cache, so server-rendered
43
+ * HTML shows data instead of a loading flash. On client hydration
44
+ * the provider re-renders with the singleton browser client and
45
+ * react-query re-subscribes its observers.
46
+ *
47
+ * `useState` makes the fallback per-component-instance (one per render
48
+ * tree), not a module-level singleton — concurrent SSR requests don't
49
+ * share it.
50
+ */
51
+ declare function QueryClientCompatProvider({ children, defaultOptions, }: QueryClientCompatProviderProps): React.ReactElement;
52
+
53
+ export { QueryClientCompatProvider, type QueryClientCompatProviderProps };
package/dist/compat.js ADDED
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { useUnit } from 'effector-react';
4
+ import { QueryClient, isServer, QueryClientProvider } from '@tanstack/react-query';
5
+ import { $queryClient } from '@effector-tanstack-query/core';
6
+ import { jsx, Fragment } from 'react/jsx-runtime';
7
+
8
+ function QueryClientCompatProvider({
9
+ children,
10
+ defaultOptions
11
+ }) {
12
+ const fromEffector = useUnit($queryClient);
13
+ const [serverFallback] = React.useState(
14
+ () => isServer ? new QueryClient({ defaultOptions }) : null
15
+ );
16
+ const qc = fromEffector ?? serverFallback;
17
+ if (!qc) {
18
+ return /* @__PURE__ */ jsx(Fragment, { children });
19
+ }
20
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: qc, children });
21
+ }
22
+
23
+ export { QueryClientCompatProvider };
24
+ //# sourceMappingURL=compat.js.map
25
+ //# sourceMappingURL=compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/compat.tsx"],"names":[],"mappings":";;;;;;AA8DO,SAAS,yBAAA,CAA0B;AAAA,EACxC,QAAA;AAAA,EACA;AACF,CAAA,EAAuD;AACrD,EAAA,MAAM,YAAA,GAAe,QAAQ,YAAY,CAAA;AACzC,EAAA,MAAM,CAAC,cAAc,CAAA,GAAU,KAAA,CAAA,QAAA;AAAA,IAA6B,MAC1D,QAAA,GAAW,IAAI,YAAY,EAAE,cAAA,EAAgB,CAAA,GAAI;AAAA,GACnD;AAEA,EAAA,MAAM,KAAK,YAAA,IAAgB,cAAA;AAC3B,EAAA,IAAI,CAAC,EAAA,EAAI;AAMP,IAAA,uCAAU,QAAA,EAAS,CAAA;AAAA,EACrB;AAEA,EAAA,uBAAO,GAAA,CAAC,mBAAA,EAAA,EAAoB,MAAA,EAAQ,EAAA,EAAK,QAAA,EAAS,CAAA;AACpD","file":"compat.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useUnit } from 'effector-react'\nimport {\n isServer,\n QueryClient,\n QueryClientProvider,\n} from '@tanstack/react-query'\nimport { $queryClient } from '@effector-tanstack-query/core'\n\ntype DefaultOptions = NonNullable<\n ConstructorParameters<typeof QueryClient>[0]\n>['defaultOptions']\n\nexport interface QueryClientCompatProviderProps {\n children: React.ReactNode\n /**\n * `defaultOptions` for the per-render server fallback `QueryClient`\n * (see below). Has no effect on the client — the browser singleton\n * built in your own top-level `<EffectorNext>` setup is what `useQuery`\n * from `@tanstack/react-query` resolves to there. Keep these aligned\n * with your `createQuery({ staleTime, retry, ... })` definitions so\n * server-rendered HTML matches what the client will produce after\n * hydration.\n */\n defaultOptions?: DefaultOptions\n}\n\n/**\n * SSR-safe `QueryClientProvider` bridge for users mixing\n * `@tanstack/react-query` and `@effector-tanstack-query` — the typical\n * \"we're migrating page by page\" case.\n *\n * Why a dedicated component:\n *\n * - **Client**: `useUnit($queryClient)` returns the singleton browser\n * `QueryClient` already mounted by your top-level provider (whichever\n * module calls `setQueryClient(qc)` + `allSettled($queryClient, ...)`\n * for `getClientScope()`). Handing that same instance to\n * `<QueryClientProvider>` means **both APIs share a cache**: prefetch\n * with one, read with the other; `setQueryData` /\n * `invalidateQueries` from one re-renders the other.\n *\n * - **Server (RSC)**: `$queryClient` is `serialize: 'ignore'` (its\n * value is a class instance — not JSON-safe — and per-request\n * QueryClients must NEVER be a module-level singleton on the\n * server). So inside the RSC rendering scope produced by\n * `<EffectorNext values={serialize(scope)}>`, `useUnit($queryClient)`\n * resolves to `null`. We fall back to a throwaway per-render\n * `QueryClient` solely so vanilla `useQuery` has a provider during\n * the server pass. Pair this component with `<HydrationBoundary>`\n * from `@tanstack/react-query` — the boundary will hydrate this\n * fallback client with the prefetched cache, so server-rendered\n * HTML shows data instead of a loading flash. On client hydration\n * the provider re-renders with the singleton browser client and\n * react-query re-subscribes its observers.\n *\n * `useState` makes the fallback per-component-instance (one per render\n * tree), not a module-level singleton — concurrent SSR requests don't\n * share it.\n */\nexport function QueryClientCompatProvider({\n children,\n defaultOptions,\n}: QueryClientCompatProviderProps): React.ReactElement {\n const fromEffector = useUnit($queryClient)\n const [serverFallback] = React.useState<QueryClient | null>(() =>\n isServer ? new QueryClient({ defaultOptions }) : null,\n )\n\n const qc = fromEffector ?? serverFallback\n if (!qc) {\n // Defensive: on the client `fromEffector` is set synchronously by\n // your top-level provider before any render, so this branch is\n // unreachable in practice. If it fires, rendering children without\n // a provider would crash any descendant `useQuery` from\n // `@tanstack/react-query`.\n return <>{children}</>\n }\n\n return <QueryClientProvider client={qc}>{children}</QueryClientProvider>\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effector-tanstack-query/react",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "React hooks for @effector-tanstack-query/core — useQuery, useMutation, useInfiniteQuery, useSuspenseQuery, useSuspenseInfiniteQuery",
5
5
  "license": "MIT",
6
6
  "author": "Ilya Agarkov <ilya.al.ag@gmail.com>",
@@ -36,6 +36,16 @@
36
36
  "default": "./dist/index.cjs"
37
37
  }
38
38
  },
39
+ "./compat": {
40
+ "import": {
41
+ "types": "./dist/compat.d.ts",
42
+ "default": "./dist/compat.js"
43
+ },
44
+ "require": {
45
+ "types": "./dist/compat.d.cts",
46
+ "default": "./dist/compat.cjs"
47
+ }
48
+ },
39
49
  "./package.json": "./package.json"
40
50
  },
41
51
  "files": [
@@ -45,14 +55,23 @@
45
55
  ],
46
56
  "sideEffects": false,
47
57
  "dependencies": {
48
- "@effector-tanstack-query/core": "0.2.0"
58
+ "@effector-tanstack-query/core": "0.3.0"
59
+ },
60
+ "devDependencies": {
61
+ "@tanstack/react-query": "^5.0.0"
49
62
  },
50
63
  "peerDependencies": {
51
64
  "@tanstack/query-core": "^5.0.0",
65
+ "@tanstack/react-query": "^5.0.0",
52
66
  "effector": ">=23.0.0",
53
67
  "effector-react": ">=23.0.0",
54
68
  "react": "^18.0.0 || ^19.0.0"
55
69
  },
70
+ "peerDependenciesMeta": {
71
+ "@tanstack/react-query": {
72
+ "optional": true
73
+ }
74
+ },
56
75
  "scripts": {
57
76
  "build": "tsup && node ./scripts/inject-use-client.mjs",
58
77
  "build:watch": "tsup --watch",
package/src/compat.tsx ADDED
@@ -0,0 +1,83 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { useUnit } from 'effector-react'
5
+ import {
6
+ isServer,
7
+ QueryClient,
8
+ QueryClientProvider,
9
+ } from '@tanstack/react-query'
10
+ import { $queryClient } from '@effector-tanstack-query/core'
11
+
12
+ type DefaultOptions = NonNullable<
13
+ ConstructorParameters<typeof QueryClient>[0]
14
+ >['defaultOptions']
15
+
16
+ export interface QueryClientCompatProviderProps {
17
+ children: React.ReactNode
18
+ /**
19
+ * `defaultOptions` for the per-render server fallback `QueryClient`
20
+ * (see below). Has no effect on the client — the browser singleton
21
+ * built in your own top-level `<EffectorNext>` setup is what `useQuery`
22
+ * from `@tanstack/react-query` resolves to there. Keep these aligned
23
+ * with your `createQuery({ staleTime, retry, ... })` definitions so
24
+ * server-rendered HTML matches what the client will produce after
25
+ * hydration.
26
+ */
27
+ defaultOptions?: DefaultOptions
28
+ }
29
+
30
+ /**
31
+ * SSR-safe `QueryClientProvider` bridge for users mixing
32
+ * `@tanstack/react-query` and `@effector-tanstack-query` — the typical
33
+ * "we're migrating page by page" case.
34
+ *
35
+ * Why a dedicated component:
36
+ *
37
+ * - **Client**: `useUnit($queryClient)` returns the singleton browser
38
+ * `QueryClient` already mounted by your top-level provider (whichever
39
+ * module calls `setQueryClient(qc)` + `allSettled($queryClient, ...)`
40
+ * for `getClientScope()`). Handing that same instance to
41
+ * `<QueryClientProvider>` means **both APIs share a cache**: prefetch
42
+ * with one, read with the other; `setQueryData` /
43
+ * `invalidateQueries` from one re-renders the other.
44
+ *
45
+ * - **Server (RSC)**: `$queryClient` is `serialize: 'ignore'` (its
46
+ * value is a class instance — not JSON-safe — and per-request
47
+ * QueryClients must NEVER be a module-level singleton on the
48
+ * server). So inside the RSC rendering scope produced by
49
+ * `<EffectorNext values={serialize(scope)}>`, `useUnit($queryClient)`
50
+ * resolves to `null`. We fall back to a throwaway per-render
51
+ * `QueryClient` solely so vanilla `useQuery` has a provider during
52
+ * the server pass. Pair this component with `<HydrationBoundary>`
53
+ * from `@tanstack/react-query` — the boundary will hydrate this
54
+ * fallback client with the prefetched cache, so server-rendered
55
+ * HTML shows data instead of a loading flash. On client hydration
56
+ * the provider re-renders with the singleton browser client and
57
+ * react-query re-subscribes its observers.
58
+ *
59
+ * `useState` makes the fallback per-component-instance (one per render
60
+ * tree), not a module-level singleton — concurrent SSR requests don't
61
+ * share it.
62
+ */
63
+ export function QueryClientCompatProvider({
64
+ children,
65
+ defaultOptions,
66
+ }: QueryClientCompatProviderProps): React.ReactElement {
67
+ const fromEffector = useUnit($queryClient)
68
+ const [serverFallback] = React.useState<QueryClient | null>(() =>
69
+ isServer ? new QueryClient({ defaultOptions }) : null,
70
+ )
71
+
72
+ const qc = fromEffector ?? serverFallback
73
+ if (!qc) {
74
+ // Defensive: on the client `fromEffector` is set synchronously by
75
+ // your top-level provider before any render, so this branch is
76
+ // unreachable in practice. If it fires, rendering children without
77
+ // a provider would crash any descendant `useQuery` from
78
+ // `@tanstack/react-query`.
79
+ return <>{children}</>
80
+ }
81
+
82
+ return <QueryClientProvider client={qc}>{children}</QueryClientProvider>
83
+ }