@effector-tanstack-query/core 0.1.1 → 0.2.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/dist/index.cjs CHANGED
@@ -5,6 +5,7 @@ var createInfiniteQuery_cjs = require('./createInfiniteQuery.cjs');
5
5
  var createMutation_cjs = require('./createMutation.cjs');
6
6
  var createInvalidate_cjs = require('./createInvalidate.cjs');
7
7
  var queryClient_cjs = require('./queryClient.cjs');
8
+ var prefetchQueries_cjs = require('./prefetchQueries.cjs');
8
9
 
9
10
 
10
11
 
@@ -32,5 +33,9 @@ Object.defineProperty(exports, "setQueryClient", {
32
33
  enumerable: true,
33
34
  get: function () { return queryClient_cjs.setQueryClient; }
34
35
  });
36
+ Object.defineProperty(exports, "prefetchQueries", {
37
+ enumerable: true,
38
+ get: function () { return prefetchQueries_cjs.prefetchQueries; }
39
+ });
35
40
  //# sourceMappingURL=index.cjs.map
36
41
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -3,6 +3,7 @@ export { createInfiniteQuery } from './createInfiniteQuery.cjs';
3
3
  export { createMutation } from './createMutation.cjs';
4
4
  export { CreateInvalidateOptions, createInvalidate } from './createInvalidate.cjs';
5
5
  export { $queryClient, setQueryClient } from './queryClient.cjs';
6
+ export { PrefetchQueriesConfig, PrefetchableQuery, prefetchQueries } from './prefetchQueries.cjs';
6
7
  export { CreateInfiniteQueryOptions, CreateMutationOptions, CreateQueryOptions, EffectorQueryKey, InfiniteQueryResult, MutationResult, MutationStatus, QueryResult, StoreOrValue } from './types.cjs';
7
8
  import '@tanstack/query-core';
8
9
  import 'effector';
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { createInfiniteQuery } from './createInfiniteQuery.js';
3
3
  export { createMutation } from './createMutation.js';
4
4
  export { CreateInvalidateOptions, createInvalidate } from './createInvalidate.js';
5
5
  export { $queryClient, setQueryClient } from './queryClient.js';
6
+ export { PrefetchQueriesConfig, PrefetchableQuery, prefetchQueries } from './prefetchQueries.js';
6
7
  export { CreateInfiniteQueryOptions, CreateMutationOptions, CreateQueryOptions, EffectorQueryKey, InfiniteQueryResult, MutationResult, MutationStatus, QueryResult, StoreOrValue } from './types.js';
7
8
  import '@tanstack/query-core';
8
9
  import 'effector';
package/dist/index.js CHANGED
@@ -3,5 +3,6 @@ export { createInfiniteQuery } from './createInfiniteQuery.js';
3
3
  export { createMutation } from './createMutation.js';
4
4
  export { createInvalidate } from './createInvalidate.js';
5
5
  export { $queryClient, setQueryClient } from './queryClient.js';
6
+ export { prefetchQueries } from './prefetchQueries.js';
6
7
  //# sourceMappingURL=index.js.map
7
8
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ var effector = require('effector');
4
+
5
+ // src/prefetchQueries.ts
6
+ async function prefetchQueries(queries, config) {
7
+ const { scope } = config;
8
+ await Promise.all(queries.map((q) => effector.allSettled(q.prefetch, { scope })));
9
+ await Promise.all(queries.map((q) => effector.allSettled(q.mounted, { scope })));
10
+ }
11
+
12
+ exports.prefetchQueries = prefetchQueries;
13
+ //# sourceMappingURL=prefetchQueries.cjs.map
14
+ //# sourceMappingURL=prefetchQueries.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prefetchQueries.ts"],"names":["allSettled"],"mappings":";;;;;AA2DA,eAAsB,eAAA,CACpB,SACA,MAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAClB,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAMA,mBAAA,CAAW,CAAA,CAAE,QAAA,EAAU,EAAE,KAAA,EAAO,CAAC,CAAC,CAAA;AACvE,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAMA,mBAAA,CAAW,CAAA,CAAE,OAAA,EAAS,EAAE,KAAA,EAAO,CAAC,CAAC,CAAA;AACxE","file":"prefetchQueries.cjs","sourcesContent":["import { allSettled } from 'effector'\nimport type { EventCallable, Scope } from 'effector'\n\n/**\n * Structural shape of any factory result that exposes the two SSR\n * lifecycle events. Both `QueryResult` and `InfiniteQueryResult` satisfy\n * this without forcing the caller to widen their `TData` / `TError` type\n * parameters.\n */\nexport interface PrefetchableQuery {\n prefetch: EventCallable<void>\n mounted: EventCallable<void>\n}\n\nexport interface PrefetchQueriesConfig {\n /** Scope to run the lifecycle events in. Required — `allSettled` cannot\n * await unit triggers outside of a scope. */\n scope: Scope\n}\n\n/**\n * Server-side helper that fills **both** SSR layers for a set of queries:\n *\n * 1. `await allSettled(q.prefetch, { scope })` for each query — awaits\n * `queryClient.fetchQuery(...)` so by the time the promise resolves\n * the cache holds the data.\n * 2. `await allSettled(q.mounted, { scope })` for each query — creates\n * the per-scope observer; its synchronous `getCurrentResult()`\n * dispatch reads from the now-populated cache and writes into the\n * effector stores (`$data`, `$status`, …). This is what makes\n * `serialize(scope)` ship populated stores, which in turn lets the\n * server-rendered HTML show data on first paint.\n *\n * Skipping step 2 (calling only `prefetch`) leaves the effector stores at\n * their defaults — `serialize(scope)` returns nothing useful, the\n * server-rendered HTML shows loading, and the user sees a flash on\n * hydration. This helper exists so that bug is impossible to write.\n *\n * Both phases run in parallel within themselves (`Promise.all`) but\n * sequentially across phases (`mounted` must see a populated cache).\n *\n * Snapshot the layers yourself afterwards — `dehydrate(queryClient)` for\n * the cache and `serialize(scope)` for the stores — and ship both to the\n * client (e.g. via `<HydrationBoundary state={...}>` + `<EffectorNext\n * values={...}>` or `fork({ values: ... })`).\n *\n * @example\n * ```ts\n * const queryClient = new QueryClient()\n * const scope = fork({ values: [[$queryClient, queryClient]] })\n *\n * await prefetchQueries([listQuery, pokemonQuery], { scope })\n *\n * return {\n * dehydratedQueryClient: dehydrate(queryClient),\n * serializedScope: serialize(scope),\n * }\n * ```\n */\nexport async function prefetchQueries(\n queries: ReadonlyArray<PrefetchableQuery>,\n config: PrefetchQueriesConfig,\n): Promise<void> {\n const { scope } = config\n await Promise.all(queries.map((q) => allSettled(q.prefetch, { scope })))\n await Promise.all(queries.map((q) => allSettled(q.mounted, { scope })))\n}\n"]}
@@ -0,0 +1,59 @@
1
+ import { Scope, EventCallable } from 'effector';
2
+
3
+ /**
4
+ * Structural shape of any factory result that exposes the two SSR
5
+ * lifecycle events. Both `QueryResult` and `InfiniteQueryResult` satisfy
6
+ * this without forcing the caller to widen their `TData` / `TError` type
7
+ * parameters.
8
+ */
9
+ interface PrefetchableQuery {
10
+ prefetch: EventCallable<void>;
11
+ mounted: EventCallable<void>;
12
+ }
13
+ interface PrefetchQueriesConfig {
14
+ /** Scope to run the lifecycle events in. Required — `allSettled` cannot
15
+ * await unit triggers outside of a scope. */
16
+ scope: Scope;
17
+ }
18
+ /**
19
+ * Server-side helper that fills **both** SSR layers for a set of queries:
20
+ *
21
+ * 1. `await allSettled(q.prefetch, { scope })` for each query — awaits
22
+ * `queryClient.fetchQuery(...)` so by the time the promise resolves
23
+ * the cache holds the data.
24
+ * 2. `await allSettled(q.mounted, { scope })` for each query — creates
25
+ * the per-scope observer; its synchronous `getCurrentResult()`
26
+ * dispatch reads from the now-populated cache and writes into the
27
+ * effector stores (`$data`, `$status`, …). This is what makes
28
+ * `serialize(scope)` ship populated stores, which in turn lets the
29
+ * server-rendered HTML show data on first paint.
30
+ *
31
+ * Skipping step 2 (calling only `prefetch`) leaves the effector stores at
32
+ * their defaults — `serialize(scope)` returns nothing useful, the
33
+ * server-rendered HTML shows loading, and the user sees a flash on
34
+ * hydration. This helper exists so that bug is impossible to write.
35
+ *
36
+ * Both phases run in parallel within themselves (`Promise.all`) but
37
+ * sequentially across phases (`mounted` must see a populated cache).
38
+ *
39
+ * Snapshot the layers yourself afterwards — `dehydrate(queryClient)` for
40
+ * the cache and `serialize(scope)` for the stores — and ship both to the
41
+ * client (e.g. via `<HydrationBoundary state={...}>` + `<EffectorNext
42
+ * values={...}>` or `fork({ values: ... })`).
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const queryClient = new QueryClient()
47
+ * const scope = fork({ values: [[$queryClient, queryClient]] })
48
+ *
49
+ * await prefetchQueries([listQuery, pokemonQuery], { scope })
50
+ *
51
+ * return {
52
+ * dehydratedQueryClient: dehydrate(queryClient),
53
+ * serializedScope: serialize(scope),
54
+ * }
55
+ * ```
56
+ */
57
+ declare function prefetchQueries(queries: ReadonlyArray<PrefetchableQuery>, config: PrefetchQueriesConfig): Promise<void>;
58
+
59
+ export { type PrefetchQueriesConfig, type PrefetchableQuery, prefetchQueries };
@@ -0,0 +1,59 @@
1
+ import { Scope, EventCallable } from 'effector';
2
+
3
+ /**
4
+ * Structural shape of any factory result that exposes the two SSR
5
+ * lifecycle events. Both `QueryResult` and `InfiniteQueryResult` satisfy
6
+ * this without forcing the caller to widen their `TData` / `TError` type
7
+ * parameters.
8
+ */
9
+ interface PrefetchableQuery {
10
+ prefetch: EventCallable<void>;
11
+ mounted: EventCallable<void>;
12
+ }
13
+ interface PrefetchQueriesConfig {
14
+ /** Scope to run the lifecycle events in. Required — `allSettled` cannot
15
+ * await unit triggers outside of a scope. */
16
+ scope: Scope;
17
+ }
18
+ /**
19
+ * Server-side helper that fills **both** SSR layers for a set of queries:
20
+ *
21
+ * 1. `await allSettled(q.prefetch, { scope })` for each query — awaits
22
+ * `queryClient.fetchQuery(...)` so by the time the promise resolves
23
+ * the cache holds the data.
24
+ * 2. `await allSettled(q.mounted, { scope })` for each query — creates
25
+ * the per-scope observer; its synchronous `getCurrentResult()`
26
+ * dispatch reads from the now-populated cache and writes into the
27
+ * effector stores (`$data`, `$status`, …). This is what makes
28
+ * `serialize(scope)` ship populated stores, which in turn lets the
29
+ * server-rendered HTML show data on first paint.
30
+ *
31
+ * Skipping step 2 (calling only `prefetch`) leaves the effector stores at
32
+ * their defaults — `serialize(scope)` returns nothing useful, the
33
+ * server-rendered HTML shows loading, and the user sees a flash on
34
+ * hydration. This helper exists so that bug is impossible to write.
35
+ *
36
+ * Both phases run in parallel within themselves (`Promise.all`) but
37
+ * sequentially across phases (`mounted` must see a populated cache).
38
+ *
39
+ * Snapshot the layers yourself afterwards — `dehydrate(queryClient)` for
40
+ * the cache and `serialize(scope)` for the stores — and ship both to the
41
+ * client (e.g. via `<HydrationBoundary state={...}>` + `<EffectorNext
42
+ * values={...}>` or `fork({ values: ... })`).
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const queryClient = new QueryClient()
47
+ * const scope = fork({ values: [[$queryClient, queryClient]] })
48
+ *
49
+ * await prefetchQueries([listQuery, pokemonQuery], { scope })
50
+ *
51
+ * return {
52
+ * dehydratedQueryClient: dehydrate(queryClient),
53
+ * serializedScope: serialize(scope),
54
+ * }
55
+ * ```
56
+ */
57
+ declare function prefetchQueries(queries: ReadonlyArray<PrefetchableQuery>, config: PrefetchQueriesConfig): Promise<void>;
58
+
59
+ export { type PrefetchQueriesConfig, type PrefetchableQuery, prefetchQueries };
@@ -0,0 +1,12 @@
1
+ import { allSettled } from 'effector';
2
+
3
+ // src/prefetchQueries.ts
4
+ async function prefetchQueries(queries, config) {
5
+ const { scope } = config;
6
+ await Promise.all(queries.map((q) => allSettled(q.prefetch, { scope })));
7
+ await Promise.all(queries.map((q) => allSettled(q.mounted, { scope })));
8
+ }
9
+
10
+ export { prefetchQueries };
11
+ //# sourceMappingURL=prefetchQueries.js.map
12
+ //# sourceMappingURL=prefetchQueries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prefetchQueries.ts"],"names":[],"mappings":";;;AA2DA,eAAsB,eAAA,CACpB,SACA,MAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAClB,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,QAAA,EAAU,EAAE,KAAA,EAAO,CAAC,CAAC,CAAA;AACvE,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,UAAA,CAAW,CAAA,CAAE,OAAA,EAAS,EAAE,KAAA,EAAO,CAAC,CAAC,CAAA;AACxE","file":"prefetchQueries.js","sourcesContent":["import { allSettled } from 'effector'\nimport type { EventCallable, Scope } from 'effector'\n\n/**\n * Structural shape of any factory result that exposes the two SSR\n * lifecycle events. Both `QueryResult` and `InfiniteQueryResult` satisfy\n * this without forcing the caller to widen their `TData` / `TError` type\n * parameters.\n */\nexport interface PrefetchableQuery {\n prefetch: EventCallable<void>\n mounted: EventCallable<void>\n}\n\nexport interface PrefetchQueriesConfig {\n /** Scope to run the lifecycle events in. Required — `allSettled` cannot\n * await unit triggers outside of a scope. */\n scope: Scope\n}\n\n/**\n * Server-side helper that fills **both** SSR layers for a set of queries:\n *\n * 1. `await allSettled(q.prefetch, { scope })` for each query — awaits\n * `queryClient.fetchQuery(...)` so by the time the promise resolves\n * the cache holds the data.\n * 2. `await allSettled(q.mounted, { scope })` for each query — creates\n * the per-scope observer; its synchronous `getCurrentResult()`\n * dispatch reads from the now-populated cache and writes into the\n * effector stores (`$data`, `$status`, …). This is what makes\n * `serialize(scope)` ship populated stores, which in turn lets the\n * server-rendered HTML show data on first paint.\n *\n * Skipping step 2 (calling only `prefetch`) leaves the effector stores at\n * their defaults — `serialize(scope)` returns nothing useful, the\n * server-rendered HTML shows loading, and the user sees a flash on\n * hydration. This helper exists so that bug is impossible to write.\n *\n * Both phases run in parallel within themselves (`Promise.all`) but\n * sequentially across phases (`mounted` must see a populated cache).\n *\n * Snapshot the layers yourself afterwards — `dehydrate(queryClient)` for\n * the cache and `serialize(scope)` for the stores — and ship both to the\n * client (e.g. via `<HydrationBoundary state={...}>` + `<EffectorNext\n * values={...}>` or `fork({ values: ... })`).\n *\n * @example\n * ```ts\n * const queryClient = new QueryClient()\n * const scope = fork({ values: [[$queryClient, queryClient]] })\n *\n * await prefetchQueries([listQuery, pokemonQuery], { scope })\n *\n * return {\n * dehydratedQueryClient: dehydrate(queryClient),\n * serializedScope: serialize(scope),\n * }\n * ```\n */\nexport async function prefetchQueries(\n queries: ReadonlyArray<PrefetchableQuery>,\n config: PrefetchQueriesConfig,\n): Promise<void> {\n const { scope } = config\n await Promise.all(queries.map((q) => allSettled(q.prefetch, { scope })))\n await Promise.all(queries.map((q) => allSettled(q.mounted, { scope })))\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effector-tanstack-query/core",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Effector bindings for TanStack Query — core factories (createQuery, createMutation, createInfiniteQuery)",
5
5
  "license": "MIT",
6
6
  "author": "Ilya Agarkov <ilya.al.ag@gmail.com>",
package/src/index.ts CHANGED
@@ -4,6 +4,11 @@ export { createMutation } from './createMutation'
4
4
  export { createInvalidate } from './createInvalidate'
5
5
  export type { CreateInvalidateOptions } from './createInvalidate'
6
6
  export { $queryClient, setQueryClient } from './queryClient'
7
+ export { prefetchQueries } from './prefetchQueries'
8
+ export type {
9
+ PrefetchableQuery,
10
+ PrefetchQueriesConfig,
11
+ } from './prefetchQueries'
7
12
  export type {
8
13
  CreateInfiniteQueryOptions,
9
14
  CreateMutationOptions,
@@ -0,0 +1,67 @@
1
+ import { allSettled } from 'effector'
2
+ import type { EventCallable, Scope } from 'effector'
3
+
4
+ /**
5
+ * Structural shape of any factory result that exposes the two SSR
6
+ * lifecycle events. Both `QueryResult` and `InfiniteQueryResult` satisfy
7
+ * this without forcing the caller to widen their `TData` / `TError` type
8
+ * parameters.
9
+ */
10
+ export interface PrefetchableQuery {
11
+ prefetch: EventCallable<void>
12
+ mounted: EventCallable<void>
13
+ }
14
+
15
+ export interface PrefetchQueriesConfig {
16
+ /** Scope to run the lifecycle events in. Required — `allSettled` cannot
17
+ * await unit triggers outside of a scope. */
18
+ scope: Scope
19
+ }
20
+
21
+ /**
22
+ * Server-side helper that fills **both** SSR layers for a set of queries:
23
+ *
24
+ * 1. `await allSettled(q.prefetch, { scope })` for each query — awaits
25
+ * `queryClient.fetchQuery(...)` so by the time the promise resolves
26
+ * the cache holds the data.
27
+ * 2. `await allSettled(q.mounted, { scope })` for each query — creates
28
+ * the per-scope observer; its synchronous `getCurrentResult()`
29
+ * dispatch reads from the now-populated cache and writes into the
30
+ * effector stores (`$data`, `$status`, …). This is what makes
31
+ * `serialize(scope)` ship populated stores, which in turn lets the
32
+ * server-rendered HTML show data on first paint.
33
+ *
34
+ * Skipping step 2 (calling only `prefetch`) leaves the effector stores at
35
+ * their defaults — `serialize(scope)` returns nothing useful, the
36
+ * server-rendered HTML shows loading, and the user sees a flash on
37
+ * hydration. This helper exists so that bug is impossible to write.
38
+ *
39
+ * Both phases run in parallel within themselves (`Promise.all`) but
40
+ * sequentially across phases (`mounted` must see a populated cache).
41
+ *
42
+ * Snapshot the layers yourself afterwards — `dehydrate(queryClient)` for
43
+ * the cache and `serialize(scope)` for the stores — and ship both to the
44
+ * client (e.g. via `<HydrationBoundary state={...}>` + `<EffectorNext
45
+ * values={...}>` or `fork({ values: ... })`).
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const queryClient = new QueryClient()
50
+ * const scope = fork({ values: [[$queryClient, queryClient]] })
51
+ *
52
+ * await prefetchQueries([listQuery, pokemonQuery], { scope })
53
+ *
54
+ * return {
55
+ * dehydratedQueryClient: dehydrate(queryClient),
56
+ * serializedScope: serialize(scope),
57
+ * }
58
+ * ```
59
+ */
60
+ export async function prefetchQueries(
61
+ queries: ReadonlyArray<PrefetchableQuery>,
62
+ config: PrefetchQueriesConfig,
63
+ ): Promise<void> {
64
+ const { scope } = config
65
+ await Promise.all(queries.map((q) => allSettled(q.prefetch, { scope })))
66
+ await Promise.all(queries.map((q) => allSettled(q.mounted, { scope })))
67
+ }