@daouy/query 0.1.82
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/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.esm.js +225 -0
- package/dist/index.esm.js.map +7 -0
- package/dist/index.js +252 -0
- package/dist/index.js.map +7 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Chung Wu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @daouy/query
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This is a mini, isomorphic, _component-level_ data-fetching library, built around [swr](https://github.com/vercel/swr).
|
|
6
|
+
It lets you fetch data in a React environment client-side or server-side.
|
|
7
|
+
On the server, it lets you prefetch data from any component, Suspense-style.
|
|
8
|
+
|
|
9
|
+
Normally in frameworks like Next.js pages router, you cannot couple your data fetches with your components--you need to fetch at the page-level with `getStaticProps`/`getServerSideProps`.
|
|
10
|
+
Component-level fetches would happen client-side instead of server-side (ultimately via a `useEffect` or similar).
|
|
11
|
+
|
|
12
|
+
Paired with @daouy/prepass, this library allows you to express data fetches directly in your components while prefetching all data on the server-side.
|
|
13
|
+
|
|
14
|
+
## Usage with Daouy
|
|
15
|
+
|
|
16
|
+
Learn more about how this can be used with Daouy specifically in the docs: https://docs.quocuy.cloud/learn/data-code-components/.
|
|
17
|
+
|
|
18
|
+
## Notes
|
|
19
|
+
|
|
20
|
+
- This library is NOT for React Server Components, only for server rendering environments like Next.js pages router.
|
|
21
|
+
- This library is NOT specific to Daouy in any way.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Cache as Cache_2 } from 'swr';
|
|
2
|
+
import { Fetcher } from 'swr';
|
|
3
|
+
import { Key } from 'swr';
|
|
4
|
+
import { PropsWithChildren } from 'react';
|
|
5
|
+
import { default as React_2 } from 'react';
|
|
6
|
+
import { SWRConfiguration } from 'swr';
|
|
7
|
+
import { SWRResponse } from 'swr';
|
|
8
|
+
import { useSWRConfig } from 'swr';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to whether any loading is happening via @daouy/query.
|
|
12
|
+
* Returns a function to unsubscribe.
|
|
13
|
+
*/
|
|
14
|
+
export declare function addLoadingStateListener(listener: LoadingStateListener, opts?: {
|
|
15
|
+
immediate?: boolean;
|
|
16
|
+
}): () => void;
|
|
17
|
+
|
|
18
|
+
export declare function DaouyPrepassContext(props: PropsWithChildren<{
|
|
19
|
+
cache: Map<string, any>;
|
|
20
|
+
}>): React_2.JSX.Element;
|
|
21
|
+
|
|
22
|
+
export declare function DaouyQueryDataProvider(props: {
|
|
23
|
+
children: React_2.ReactNode;
|
|
24
|
+
suspense?: boolean;
|
|
25
|
+
prefetchedCache?: Record<string, any>;
|
|
26
|
+
provider?: () => Cache_2;
|
|
27
|
+
}): React_2.JSX.Element;
|
|
28
|
+
|
|
29
|
+
export declare type HeadMetadata = {
|
|
30
|
+
title?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
image?: string;
|
|
33
|
+
canonical?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export declare const HeadMetadataContext: React_2.Context<HeadMetadata>;
|
|
37
|
+
|
|
38
|
+
export declare function isDaouyPrepass(): boolean;
|
|
39
|
+
|
|
40
|
+
export declare type LoadingStateListener = (isLoading: boolean) => void;
|
|
41
|
+
|
|
42
|
+
export { SWRResponse }
|
|
43
|
+
|
|
44
|
+
export declare const useDaouyDataConfig: typeof useSWRConfig;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Fetches data asynchronously. This data should be considered immutable for the
|
|
48
|
+
* session -- there is no way to invalidate or re-fetch this data.
|
|
49
|
+
*
|
|
50
|
+
* @param key a unique key for this data fetch; if data already exists under this
|
|
51
|
+
* key, that data is returned immediately.
|
|
52
|
+
* @param fetcher an async function that resolves to the fetched data.
|
|
53
|
+
* @returns an object with either a "data" key with the fetched data if the fetch
|
|
54
|
+
* was successful, or an "error" key with the thrown Error if the fetch failed.
|
|
55
|
+
*/
|
|
56
|
+
export declare function useDaouyQueryData<T>(key: Key, fetcher: Fetcher<T>): {
|
|
57
|
+
data?: T;
|
|
58
|
+
error?: Error;
|
|
59
|
+
isLoading?: boolean;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Fetches data asynchronously using SWR Hook (https://swr.vercel.app/)
|
|
64
|
+
*
|
|
65
|
+
* @param key a unique key for this data fetch; if data already exists under this
|
|
66
|
+
* key, that data is returned immediately.
|
|
67
|
+
* @param fetcher an async function that resolves to the fetched data.
|
|
68
|
+
* @param options (optional) an object of options for this hook (https://swr.vercel.app/docs/options).
|
|
69
|
+
* @returns an object with either a "data" key with the fetched data if the fetch
|
|
70
|
+
* was successful, or an "error" key with the thrown Error if the fetch failed.
|
|
71
|
+
*/
|
|
72
|
+
export declare function useMutableDaouyQueryData<T, E>(key: Key, fetcher: Fetcher<T>, options?: SWRConfiguration<T, E>): SWRResponse<T, E> & {
|
|
73
|
+
isLoading?: boolean;
|
|
74
|
+
isLagging?: boolean;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export { useSWRConfig }
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Instruments an async function to increment and decrement the number of
|
|
81
|
+
* simultaneous async loads. You can then subscribe to whether there
|
|
82
|
+
* are any loads happening via addLoadingStateListener().
|
|
83
|
+
*/
|
|
84
|
+
export declare function wrapLoadingFetcher<T extends (...args: any[]) => Promise<any> | any>(fetcher: T): T;
|
|
85
|
+
|
|
86
|
+
export { }
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __spreadValues = (a, b) => {
|
|
8
|
+
for (var prop in b || (b = {}))
|
|
9
|
+
if (__hasOwnProp.call(b, prop))
|
|
10
|
+
__defNormalProp(a, prop, b[prop]);
|
|
11
|
+
if (__getOwnPropSymbols)
|
|
12
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
13
|
+
if (__propIsEnum.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
}
|
|
16
|
+
return a;
|
|
17
|
+
};
|
|
18
|
+
var __async = (__this, __arguments, generator) => {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
var fulfilled = (value) => {
|
|
21
|
+
try {
|
|
22
|
+
step(generator.next(value));
|
|
23
|
+
} catch (e) {
|
|
24
|
+
reject(e);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var rejected = (value) => {
|
|
28
|
+
try {
|
|
29
|
+
step(generator.throw(value));
|
|
30
|
+
} catch (e) {
|
|
31
|
+
reject(e);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
35
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/query-data.tsx
|
|
40
|
+
import React from "react";
|
|
41
|
+
import useSWR, {
|
|
42
|
+
SWRConfig,
|
|
43
|
+
useSWRConfig
|
|
44
|
+
} from "swr";
|
|
45
|
+
var __SWRConfig = void 0;
|
|
46
|
+
var mutateKeys = (invalidateKey) => {
|
|
47
|
+
if (__SWRConfig) {
|
|
48
|
+
const { cache, mutate } = __SWRConfig;
|
|
49
|
+
(invalidateKey != null ? [invalidateKey] : Array.from(cache.keys())).forEach((key) => {
|
|
50
|
+
mutate(key);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function getDaouyDefaultSWROptions(opts) {
|
|
55
|
+
return {
|
|
56
|
+
revalidateIfStale: !!(opts == null ? void 0 : opts.isMutable),
|
|
57
|
+
revalidateOnFocus: false,
|
|
58
|
+
revalidateOnReconnect: false
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function useDaouyQueryData(key, fetcher) {
|
|
62
|
+
const prepassCtx = React.useContext(PrepassContext);
|
|
63
|
+
const opts = getDaouyDefaultSWROptions();
|
|
64
|
+
if (prepassCtx) {
|
|
65
|
+
opts.suspense = true;
|
|
66
|
+
}
|
|
67
|
+
const config = useSWRConfig();
|
|
68
|
+
React.useEffect(() => {
|
|
69
|
+
__SWRConfig = config;
|
|
70
|
+
}, [config]);
|
|
71
|
+
const wrappedFetcher = React.useMemo(
|
|
72
|
+
() => wrapLoadingFetcher(fetcher),
|
|
73
|
+
[fetcher]
|
|
74
|
+
);
|
|
75
|
+
const resp = useSWR(key, wrappedFetcher, opts);
|
|
76
|
+
if (resp.data !== void 0) {
|
|
77
|
+
return { data: resp.data };
|
|
78
|
+
} else if (resp.error) {
|
|
79
|
+
return { error: resp.error };
|
|
80
|
+
} else {
|
|
81
|
+
return { isLoading: true };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function useMutableDaouyQueryData(key, fetcher, options) {
|
|
85
|
+
const prepassCtx = React.useContext(PrepassContext);
|
|
86
|
+
const opts = __spreadValues(__spreadValues({}, getDaouyDefaultSWROptions({ isMutable: true })), options);
|
|
87
|
+
if (prepassCtx) {
|
|
88
|
+
opts.suspense = true;
|
|
89
|
+
}
|
|
90
|
+
const config = useSWRConfig();
|
|
91
|
+
React.useEffect(() => {
|
|
92
|
+
__SWRConfig = config;
|
|
93
|
+
}, [config]);
|
|
94
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
95
|
+
const fetcherWrapper = React.useCallback(
|
|
96
|
+
(...args) => __async(this, null, function* () {
|
|
97
|
+
setIsLoading(true);
|
|
98
|
+
try {
|
|
99
|
+
return yield wrapLoadingFetcher(fetcher)(...args);
|
|
100
|
+
} finally {
|
|
101
|
+
setIsLoading(false);
|
|
102
|
+
}
|
|
103
|
+
}),
|
|
104
|
+
[fetcher]
|
|
105
|
+
);
|
|
106
|
+
const laggyDataRef = React.useRef();
|
|
107
|
+
const { isValidating, mutate, data, error } = useSWR(
|
|
108
|
+
key,
|
|
109
|
+
fetcherWrapper,
|
|
110
|
+
opts
|
|
111
|
+
);
|
|
112
|
+
React.useEffect(() => {
|
|
113
|
+
if (data !== void 0) {
|
|
114
|
+
laggyDataRef.current = data;
|
|
115
|
+
}
|
|
116
|
+
}, [data]);
|
|
117
|
+
return React.useMemo(
|
|
118
|
+
() => __spreadValues(__spreadValues({
|
|
119
|
+
isValidating,
|
|
120
|
+
mutate,
|
|
121
|
+
isLoading: data === void 0 && error === void 0 || isLoading
|
|
122
|
+
}, data !== void 0 ? { data } : error === void 0 && laggyDataRef.current ? (
|
|
123
|
+
// Show previous data if available
|
|
124
|
+
{ data: laggyDataRef.current, isLagging: true }
|
|
125
|
+
) : {}), error !== void 0 ? { error } : {}),
|
|
126
|
+
[isValidating, mutate, data, error, isLoading]
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
function DaouyQueryDataProvider(props) {
|
|
130
|
+
const { children, suspense, prefetchedCache, provider } = props;
|
|
131
|
+
const prepass = React.useContext(PrepassContext);
|
|
132
|
+
if (prepass) {
|
|
133
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
134
|
+
} else {
|
|
135
|
+
return /* @__PURE__ */ React.createElement(
|
|
136
|
+
SWRConfig,
|
|
137
|
+
{
|
|
138
|
+
value: {
|
|
139
|
+
fallback: prefetchedCache != null ? prefetchedCache : {},
|
|
140
|
+
suspense,
|
|
141
|
+
provider
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
children
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
var PrepassContext = React.createContext(false);
|
|
149
|
+
function DaouyPrepassContext(props) {
|
|
150
|
+
const { cache, children } = props;
|
|
151
|
+
return /* @__PURE__ */ React.createElement(PrepassContext.Provider, { value: true }, /* @__PURE__ */ React.createElement(
|
|
152
|
+
SWRConfig,
|
|
153
|
+
{
|
|
154
|
+
value: {
|
|
155
|
+
provider: () => cache,
|
|
156
|
+
suspense: true,
|
|
157
|
+
fallback: {}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
children
|
|
161
|
+
));
|
|
162
|
+
}
|
|
163
|
+
var useDaouyDataConfig = useSWRConfig;
|
|
164
|
+
var loadingCount = 0;
|
|
165
|
+
var listeners = [];
|
|
166
|
+
function addLoadingStateListener(listener, opts) {
|
|
167
|
+
listeners.push(listener);
|
|
168
|
+
if (opts == null ? void 0 : opts.immediate) {
|
|
169
|
+
listener(loadingCount > 0);
|
|
170
|
+
}
|
|
171
|
+
return () => {
|
|
172
|
+
listeners.splice(listeners.indexOf(listener), 1);
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function wrapLoadingFetcher(fetcher) {
|
|
176
|
+
return (...args) => __async(this, null, function* () {
|
|
177
|
+
if (loadingCount === 0) {
|
|
178
|
+
listeners.forEach((listener) => listener(true));
|
|
179
|
+
}
|
|
180
|
+
loadingCount += 1;
|
|
181
|
+
try {
|
|
182
|
+
const res = fetcher(...args);
|
|
183
|
+
return isPromiseLike(res) ? yield res : res;
|
|
184
|
+
} finally {
|
|
185
|
+
loadingCount -= 1;
|
|
186
|
+
if (loadingCount === 0) {
|
|
187
|
+
listeners.forEach((listener) => listener(false));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function isPromiseLike(x) {
|
|
193
|
+
return !!x && typeof x === "object" && "then" in x && typeof x.then === "function";
|
|
194
|
+
}
|
|
195
|
+
function isDaouyPrepass() {
|
|
196
|
+
var _a, _b, _c;
|
|
197
|
+
return !!((_c = (_b = (_a = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED) == null ? void 0 : _a.ReactCurrentDispatcher) == null ? void 0 : _b.current) == null ? void 0 : _c.isDaouyPrepass);
|
|
198
|
+
}
|
|
199
|
+
var HeadMetadataContext = React.createContext({});
|
|
200
|
+
|
|
201
|
+
// src/index.tsx
|
|
202
|
+
import { useSWRConfig as useSWRConfig2 } from "swr";
|
|
203
|
+
if (typeof window !== "undefined") {
|
|
204
|
+
const root = window;
|
|
205
|
+
const maybeExistingMutateAllKeys = root.__SWRMutateAllKeys;
|
|
206
|
+
root.__SWRMutateAllKeys = (invalidateKey) => {
|
|
207
|
+
mutateKeys(invalidateKey);
|
|
208
|
+
if (typeof maybeExistingMutateAllKeys === "function") {
|
|
209
|
+
maybeExistingMutateAllKeys(invalidateKey);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
export {
|
|
214
|
+
DaouyPrepassContext,
|
|
215
|
+
DaouyQueryDataProvider,
|
|
216
|
+
HeadMetadataContext,
|
|
217
|
+
addLoadingStateListener,
|
|
218
|
+
isDaouyPrepass,
|
|
219
|
+
useDaouyDataConfig,
|
|
220
|
+
useDaouyQueryData,
|
|
221
|
+
useMutableDaouyQueryData,
|
|
222
|
+
useSWRConfig2 as useSWRConfig,
|
|
223
|
+
wrapLoadingFetcher
|
|
224
|
+
};
|
|
225
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/query-data.tsx", "../src/index.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { PropsWithChildren } from \"react\";\nimport useSWR, {\n Cache,\n Fetcher,\n Key,\n SWRConfig,\n SWRConfiguration,\n SWRResponse,\n useSWRConfig,\n} from \"swr\";\n\nexport type { SWRResponse } from \"swr\";\n\nlet __SWRConfig: ReturnType<typeof useSWRConfig> | undefined = undefined;\nexport const mutateKeys = (invalidateKey?: string) => {\n if (__SWRConfig) {\n const { cache, mutate } = __SWRConfig;\n (invalidateKey != null\n ? [invalidateKey]\n : Array.from((cache as Map<string, any>).keys())\n ).forEach((key) => {\n mutate(key);\n });\n }\n};\n\n// @daouy/query is optimized for SSR, so we do not revalidate\n// automatically upon hydration; as if the data is immutable.\nfunction getDaouyDefaultSWROptions(opts?: {\n isMutable?: boolean;\n}): SWRConfiguration {\n return {\n revalidateIfStale: !!opts?.isMutable,\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n };\n}\n\n/**\n * Fetches data asynchronously. This data should be considered immutable for the\n * session -- there is no way to invalidate or re-fetch this data.\n *\n * @param key a unique key for this data fetch; if data already exists under this\n * key, that data is returned immediately.\n * @param fetcher an async function that resolves to the fetched data.\n * @returns an object with either a \"data\" key with the fetched data if the fetch\n * was successful, or an \"error\" key with the thrown Error if the fetch failed.\n */\nexport function useDaouyQueryData<T>(\n key: Key,\n fetcher: Fetcher<T>\n): { data?: T; error?: Error; isLoading?: boolean } {\n const prepassCtx = React.useContext(PrepassContext);\n\n const opts = getDaouyDefaultSWROptions();\n if (prepassCtx) {\n // If we're doing prepass, then we are always in suspense mode, because\n // react-ssr-prepass only works with suspense-throwing data fetching.\n opts.suspense = true;\n }\n\n const config = useSWRConfig();\n React.useEffect(() => {\n __SWRConfig = config;\n }, [config]);\n\n const wrappedFetcher = React.useMemo(\n () => wrapLoadingFetcher(fetcher),\n [fetcher]\n );\n\n const resp = useSWR(key, wrappedFetcher, opts);\n if (resp.data !== undefined) {\n return { data: resp.data };\n } else if (resp.error) {\n return { error: resp.error };\n } else {\n return { isLoading: true };\n }\n}\n\n/**\n * Fetches data asynchronously using SWR Hook (https://swr.vercel.app/)\n *\n * @param key a unique key for this data fetch; if data already exists under this\n * key, that data is returned immediately.\n * @param fetcher an async function that resolves to the fetched data.\n * @param options (optional) an object of options for this hook (https://swr.vercel.app/docs/options).\n * @returns an object with either a \"data\" key with the fetched data if the fetch\n * was successful, or an \"error\" key with the thrown Error if the fetch failed.\n */\nexport function useMutableDaouyQueryData<T, E>(\n key: Key,\n fetcher: Fetcher<T>,\n options?: SWRConfiguration<T, E>\n): SWRResponse<T, E> & { isLoading?: boolean; isLagging?: boolean } {\n const prepassCtx = React.useContext(PrepassContext);\n\n const opts = {\n ...getDaouyDefaultSWROptions({ isMutable: true }),\n ...options,\n };\n if (prepassCtx) {\n opts.suspense = true;\n }\n\n const config = useSWRConfig();\n React.useEffect(() => {\n __SWRConfig = config;\n }, [config]);\n\n const [isLoading, setIsLoading] = React.useState(false);\n const fetcherWrapper = React.useCallback(\n async (...args: any[]) => {\n setIsLoading(true);\n try {\n return await wrapLoadingFetcher(fetcher)(...args);\n } finally {\n setIsLoading(false);\n }\n },\n [fetcher]\n );\n\n // Based on https://swr.vercel.app/docs/middleware#keep-previous-result\n const laggyDataRef = React.useRef<any>();\n\n const { isValidating, mutate, data, error } = useSWR(\n key,\n fetcherWrapper,\n opts\n );\n\n React.useEffect(() => {\n if (data !== undefined) {\n laggyDataRef.current = data;\n }\n }, [data]);\n\n return React.useMemo(\n () => ({\n isValidating,\n mutate,\n isLoading: (data === undefined && error === undefined) || isLoading,\n ...(data !== undefined\n ? { data }\n : error === undefined && laggyDataRef.current\n ? // Show previous data if available\n { data: laggyDataRef.current, isLagging: true }\n : {}),\n ...(error !== undefined ? { error } : {}),\n }),\n [isValidating, mutate, data, error, isLoading]\n );\n}\n\nexport function DaouyQueryDataProvider(props: {\n children: React.ReactNode;\n suspense?: boolean;\n prefetchedCache?: Record<string, any>;\n provider?: () => Cache;\n}) {\n const { children, suspense, prefetchedCache, provider } = props;\n const prepass = React.useContext(PrepassContext);\n if (prepass) {\n // If we're in prepass, then there's already a wrappign SWRConfig;\n // don't interfere with it.\n return <>{children}</>;\n } else {\n return (\n <SWRConfig\n value={{\n fallback: prefetchedCache ?? {},\n suspense,\n provider,\n }}\n >\n {children}\n </SWRConfig>\n );\n }\n}\n\nconst PrepassContext = React.createContext<boolean>(false);\n\nexport function DaouyPrepassContext(\n props: PropsWithChildren<{\n cache: Map<string, any>;\n }>\n) {\n const { cache, children } = props;\n return (\n <PrepassContext.Provider value={true}>\n <SWRConfig\n value={{\n provider: () => cache,\n suspense: true,\n fallback: {},\n }}\n >\n {children}\n </SWRConfig>\n </PrepassContext.Provider>\n );\n}\n\nexport const useDaouyDataConfig: typeof useSWRConfig = useSWRConfig;\n\nlet loadingCount = 0;\nexport type LoadingStateListener = (isLoading: boolean) => void;\nconst listeners: LoadingStateListener[] = [];\n\n/**\n * Subscribes to whether any loading is happening via @daouy/query.\n * Returns a function to unsubscribe.\n */\nexport function addLoadingStateListener(\n listener: LoadingStateListener,\n opts?: { immediate?: boolean }\n) {\n listeners.push(listener);\n if (opts?.immediate) {\n listener(loadingCount > 0);\n }\n return () => {\n listeners.splice(listeners.indexOf(listener), 1);\n };\n}\n\n/**\n * Instruments an async function to increment and decrement the number of\n * simultaneous async loads. You can then subscribe to whether there\n * are any loads happening via addLoadingStateListener().\n */\nexport function wrapLoadingFetcher<\n T extends (...args: any[]) => Promise<any> | any\n>(fetcher: T): T {\n return (async (...args: any) => {\n if (loadingCount === 0) {\n listeners.forEach((listener) => listener(true));\n }\n loadingCount += 1;\n try {\n const res = fetcher(...args);\n return isPromiseLike(res) ? await res : res;\n } finally {\n loadingCount -= 1;\n if (loadingCount === 0) {\n listeners.forEach((listener) => listener(false));\n }\n }\n }) as T;\n}\n\nfunction isPromiseLike(x: any) {\n return (\n !!x && typeof x === \"object\" && \"then\" in x && typeof x.then === \"function\"\n );\n}\n\nexport function isDaouyPrepass() {\n return !!(React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n ?.ReactCurrentDispatcher?.current?.isDaouyPrepass;\n}\n\nexport type HeadMetadata = {\n title?: string;\n description?: string;\n image?: string;\n canonical?: string;\n};\n\nexport const HeadMetadataContext = React.createContext<HeadMetadata>({});\n", "import { mutateKeys } from \"./query-data\";\nexport { useSWRConfig } from \"swr\";\nexport {\n addLoadingStateListener,\n HeadMetadataContext,\n isDaouyPrepass,\n DaouyPrepassContext,\n DaouyQueryDataProvider,\n useMutableDaouyQueryData,\n useDaouyDataConfig,\n useDaouyQueryData,\n wrapLoadingFetcher,\n} from \"./query-data\";\nexport type {\n HeadMetadata,\n LoadingStateListener,\n SWRResponse,\n} from \"./query-data\";\n\nif (typeof window !== \"undefined\") {\n const root = window as any;\n const maybeExistingMutateAllKeys = root.__SWRMutateAllKeys;\n root.__SWRMutateAllKeys = (invalidateKey?: string) => {\n mutateKeys(invalidateKey);\n if (typeof maybeExistingMutateAllKeys === \"function\") {\n maybeExistingMutateAllKeys(invalidateKey);\n }\n };\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,WAAkC;AACzC,OAAO;AAAA,EAIL;AAAA,EAGA;AAAA,OACK;AAIP,IAAI,cAA2D;AACxD,IAAM,aAAa,CAAC,kBAA2B;AACpD,MAAI,aAAa;AACf,UAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,KAAC,iBAAiB,OACd,CAAC,aAAa,IACd,MAAM,KAAM,MAA2B,KAAK,CAAC,GAC/C,QAAQ,CAAC,QAAQ;AACjB,aAAO,GAAG;AAAA,IACZ,CAAC;AAAA,EACH;AACF;AAIA,SAAS,0BAA0B,MAEd;AACnB,SAAO;AAAA,IACL,mBAAmB,CAAC,EAAC,6BAAM;AAAA,IAC3B,mBAAmB;AAAA,IACnB,uBAAuB;AAAA,EACzB;AACF;AAYO,SAAS,kBACd,KACA,SACkD;AAClD,QAAM,aAAa,MAAM,WAAW,cAAc;AAElD,QAAM,OAAO,0BAA0B;AACvC,MAAI,YAAY;AAGd,SAAK,WAAW;AAAA,EAClB;AAEA,QAAM,SAAS,aAAa;AAC5B,QAAM,UAAU,MAAM;AACpB,kBAAc;AAAA,EAChB,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,iBAAiB,MAAM;AAAA,IAC3B,MAAM,mBAAmB,OAAO;AAAA,IAChC,CAAC,OAAO;AAAA,EACV;AAEA,QAAM,OAAO,OAAO,KAAK,gBAAgB,IAAI;AAC7C,MAAI,KAAK,SAAS,QAAW;AAC3B,WAAO,EAAE,MAAM,KAAK,KAAK;AAAA,EAC3B,WAAW,KAAK,OAAO;AACrB,WAAO,EAAE,OAAO,KAAK,MAAM;AAAA,EAC7B,OAAO;AACL,WAAO,EAAE,WAAW,KAAK;AAAA,EAC3B;AACF;AAYO,SAAS,yBACd,KACA,SACA,SACkE;AAClE,QAAM,aAAa,MAAM,WAAW,cAAc;AAElD,QAAM,OAAO,kCACR,0BAA0B,EAAE,WAAW,KAAK,CAAC,IAC7C;AAEL,MAAI,YAAY;AACd,SAAK,WAAW;AAAA,EAClB;AAEA,QAAM,SAAS,aAAa;AAC5B,QAAM,UAAU,MAAM;AACpB,kBAAc;AAAA,EAChB,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,KAAK;AACtD,QAAM,iBAAiB,MAAM;AAAA,IAC3B,IAAU,SAAgB;AACxB,mBAAa,IAAI;AACjB,UAAI;AACF,eAAO,MAAM,mBAAmB,OAAO,EAAE,GAAG,IAAI;AAAA,MAClD,UAAE;AACA,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAGA,QAAM,eAAe,MAAM,OAAY;AAEvC,QAAM,EAAE,cAAc,QAAQ,MAAM,MAAM,IAAI;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,SAAS,QAAW;AACtB,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,SAAO,MAAM;AAAA,IACX,MAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAY,SAAS,UAAa,UAAU,UAAc;AAAA,OACtD,SAAS,SACT,EAAE,KAAK,IACP,UAAU,UAAa,aAAa;AAAA;AAAA,MAEpC,EAAE,MAAM,aAAa,SAAS,WAAW,KAAK;AAAA,QAC9C,CAAC,IACD,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,IAEzC,CAAC,cAAc,QAAQ,MAAM,OAAO,SAAS;AAAA,EAC/C;AACF;AAEO,SAAS,uBAAuB,OAKpC;AACD,QAAM,EAAE,UAAU,UAAU,iBAAiB,SAAS,IAAI;AAC1D,QAAM,UAAU,MAAM,WAAW,cAAc;AAC/C,MAAI,SAAS;AAGX,WAAO,0DAAG,QAAS;AAAA,EACrB,OAAO;AACL,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU,4CAAmB,CAAC;AAAA,UAC9B;AAAA,UACA;AAAA,QACF;AAAA;AAAA,MAEC;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,IAAM,iBAAiB,MAAM,cAAuB,KAAK;AAElD,SAAS,oBACd,OAGA;AACA,QAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,SACE,oCAAC,eAAe,UAAf,EAAwB,OAAO,QAC9B;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU,MAAM;AAAA,QAChB,UAAU;AAAA,QACV,UAAU,CAAC;AAAA,MACb;AAAA;AAAA,IAEC;AAAA,EACH,CACF;AAEJ;AAEO,IAAM,qBAA0C;AAEvD,IAAI,eAAe;AAEnB,IAAM,YAAoC,CAAC;AAMpC,SAAS,wBACd,UACA,MACA;AACA,YAAU,KAAK,QAAQ;AACvB,MAAI,6BAAM,WAAW;AACnB,aAAS,eAAe,CAAC;AAAA,EAC3B;AACA,SAAO,MAAM;AACX,cAAU,OAAO,UAAU,QAAQ,QAAQ,GAAG,CAAC;AAAA,EACjD;AACF;AAOO,SAAS,mBAEd,SAAe;AACf,SAAQ,IAAU,SAAc;AAC9B,QAAI,iBAAiB,GAAG;AACtB,gBAAU,QAAQ,CAAC,aAAa,SAAS,IAAI,CAAC;AAAA,IAChD;AACA,oBAAgB;AAChB,QAAI;AACF,YAAM,MAAM,QAAQ,GAAG,IAAI;AAC3B,aAAO,cAAc,GAAG,IAAI,MAAM,MAAM;AAAA,IAC1C,UAAE;AACA,sBAAgB;AAChB,UAAI,iBAAiB,GAAG;AACtB,kBAAU,QAAQ,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,GAAQ;AAC7B,SACE,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,UAAU,KAAK,OAAO,EAAE,SAAS;AAErE;AAEO,SAAS,iBAAiB;AApQjC;AAqQE,SAAO,CAAC,GAAE,uBAAc,uDAAd,mBACN,2BADM,mBACkB,YADlB,mBAC2B;AACvC;AASO,IAAM,sBAAsB,MAAM,cAA4B,CAAC,CAAC;;;AC/QvE,SAAS,gBAAAA,qBAAoB;AAkB7B,IAAI,OAAO,WAAW,aAAa;AACjC,QAAM,OAAO;AACb,QAAM,6BAA6B,KAAK;AACxC,OAAK,qBAAqB,CAAC,kBAA2B;AACpD,eAAW,aAAa;AACxB,QAAI,OAAO,+BAA+B,YAAY;AACpD,iCAA2B,aAAa;AAAA,IAC1C;AAAA,EACF;AACF;",
|
|
6
|
+
"names": ["useSWRConfig"]
|
|
7
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __export = (target, all) => {
|
|
24
|
+
for (var name in all)
|
|
25
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
|
+
};
|
|
27
|
+
var __copyProps = (to, from, except, desc) => {
|
|
28
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
29
|
+
for (let key of __getOwnPropNames(from))
|
|
30
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
31
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
32
|
+
}
|
|
33
|
+
return to;
|
|
34
|
+
};
|
|
35
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
36
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
37
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
38
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
39
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
40
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
41
|
+
mod
|
|
42
|
+
));
|
|
43
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
44
|
+
var __async = (__this, __arguments, generator) => {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
var fulfilled = (value) => {
|
|
47
|
+
try {
|
|
48
|
+
step(generator.next(value));
|
|
49
|
+
} catch (e) {
|
|
50
|
+
reject(e);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var rejected = (value) => {
|
|
54
|
+
try {
|
|
55
|
+
step(generator.throw(value));
|
|
56
|
+
} catch (e) {
|
|
57
|
+
reject(e);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
61
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/index.tsx
|
|
66
|
+
var src_exports = {};
|
|
67
|
+
__export(src_exports, {
|
|
68
|
+
DaouyPrepassContext: () => DaouyPrepassContext,
|
|
69
|
+
DaouyQueryDataProvider: () => DaouyQueryDataProvider,
|
|
70
|
+
HeadMetadataContext: () => HeadMetadataContext,
|
|
71
|
+
addLoadingStateListener: () => addLoadingStateListener,
|
|
72
|
+
isDaouyPrepass: () => isDaouyPrepass,
|
|
73
|
+
useDaouyDataConfig: () => useDaouyDataConfig,
|
|
74
|
+
useDaouyQueryData: () => useDaouyQueryData,
|
|
75
|
+
useMutableDaouyQueryData: () => useMutableDaouyQueryData,
|
|
76
|
+
useSWRConfig: () => import_swr2.useSWRConfig,
|
|
77
|
+
wrapLoadingFetcher: () => wrapLoadingFetcher
|
|
78
|
+
});
|
|
79
|
+
module.exports = __toCommonJS(src_exports);
|
|
80
|
+
|
|
81
|
+
// src/query-data.tsx
|
|
82
|
+
var import_react = __toESM(require("react"));
|
|
83
|
+
var import_swr = __toESM(require("swr"));
|
|
84
|
+
var __SWRConfig = void 0;
|
|
85
|
+
var mutateKeys = (invalidateKey) => {
|
|
86
|
+
if (__SWRConfig) {
|
|
87
|
+
const { cache, mutate } = __SWRConfig;
|
|
88
|
+
(invalidateKey != null ? [invalidateKey] : Array.from(cache.keys())).forEach((key) => {
|
|
89
|
+
mutate(key);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
function getDaouyDefaultSWROptions(opts) {
|
|
94
|
+
return {
|
|
95
|
+
revalidateIfStale: !!(opts == null ? void 0 : opts.isMutable),
|
|
96
|
+
revalidateOnFocus: false,
|
|
97
|
+
revalidateOnReconnect: false
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function useDaouyQueryData(key, fetcher) {
|
|
101
|
+
const prepassCtx = import_react.default.useContext(PrepassContext);
|
|
102
|
+
const opts = getDaouyDefaultSWROptions();
|
|
103
|
+
if (prepassCtx) {
|
|
104
|
+
opts.suspense = true;
|
|
105
|
+
}
|
|
106
|
+
const config = (0, import_swr.useSWRConfig)();
|
|
107
|
+
import_react.default.useEffect(() => {
|
|
108
|
+
__SWRConfig = config;
|
|
109
|
+
}, [config]);
|
|
110
|
+
const wrappedFetcher = import_react.default.useMemo(
|
|
111
|
+
() => wrapLoadingFetcher(fetcher),
|
|
112
|
+
[fetcher]
|
|
113
|
+
);
|
|
114
|
+
const resp = (0, import_swr.default)(key, wrappedFetcher, opts);
|
|
115
|
+
if (resp.data !== void 0) {
|
|
116
|
+
return { data: resp.data };
|
|
117
|
+
} else if (resp.error) {
|
|
118
|
+
return { error: resp.error };
|
|
119
|
+
} else {
|
|
120
|
+
return { isLoading: true };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function useMutableDaouyQueryData(key, fetcher, options) {
|
|
124
|
+
const prepassCtx = import_react.default.useContext(PrepassContext);
|
|
125
|
+
const opts = __spreadValues(__spreadValues({}, getDaouyDefaultSWROptions({ isMutable: true })), options);
|
|
126
|
+
if (prepassCtx) {
|
|
127
|
+
opts.suspense = true;
|
|
128
|
+
}
|
|
129
|
+
const config = (0, import_swr.useSWRConfig)();
|
|
130
|
+
import_react.default.useEffect(() => {
|
|
131
|
+
__SWRConfig = config;
|
|
132
|
+
}, [config]);
|
|
133
|
+
const [isLoading, setIsLoading] = import_react.default.useState(false);
|
|
134
|
+
const fetcherWrapper = import_react.default.useCallback(
|
|
135
|
+
(...args) => __async(this, null, function* () {
|
|
136
|
+
setIsLoading(true);
|
|
137
|
+
try {
|
|
138
|
+
return yield wrapLoadingFetcher(fetcher)(...args);
|
|
139
|
+
} finally {
|
|
140
|
+
setIsLoading(false);
|
|
141
|
+
}
|
|
142
|
+
}),
|
|
143
|
+
[fetcher]
|
|
144
|
+
);
|
|
145
|
+
const laggyDataRef = import_react.default.useRef();
|
|
146
|
+
const { isValidating, mutate, data, error } = (0, import_swr.default)(
|
|
147
|
+
key,
|
|
148
|
+
fetcherWrapper,
|
|
149
|
+
opts
|
|
150
|
+
);
|
|
151
|
+
import_react.default.useEffect(() => {
|
|
152
|
+
if (data !== void 0) {
|
|
153
|
+
laggyDataRef.current = data;
|
|
154
|
+
}
|
|
155
|
+
}, [data]);
|
|
156
|
+
return import_react.default.useMemo(
|
|
157
|
+
() => __spreadValues(__spreadValues({
|
|
158
|
+
isValidating,
|
|
159
|
+
mutate,
|
|
160
|
+
isLoading: data === void 0 && error === void 0 || isLoading
|
|
161
|
+
}, data !== void 0 ? { data } : error === void 0 && laggyDataRef.current ? (
|
|
162
|
+
// Show previous data if available
|
|
163
|
+
{ data: laggyDataRef.current, isLagging: true }
|
|
164
|
+
) : {}), error !== void 0 ? { error } : {}),
|
|
165
|
+
[isValidating, mutate, data, error, isLoading]
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
function DaouyQueryDataProvider(props) {
|
|
169
|
+
const { children, suspense, prefetchedCache, provider } = props;
|
|
170
|
+
const prepass = import_react.default.useContext(PrepassContext);
|
|
171
|
+
if (prepass) {
|
|
172
|
+
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, children);
|
|
173
|
+
} else {
|
|
174
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
175
|
+
import_swr.SWRConfig,
|
|
176
|
+
{
|
|
177
|
+
value: {
|
|
178
|
+
fallback: prefetchedCache != null ? prefetchedCache : {},
|
|
179
|
+
suspense,
|
|
180
|
+
provider
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
children
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
var PrepassContext = import_react.default.createContext(false);
|
|
188
|
+
function DaouyPrepassContext(props) {
|
|
189
|
+
const { cache, children } = props;
|
|
190
|
+
return /* @__PURE__ */ import_react.default.createElement(PrepassContext.Provider, { value: true }, /* @__PURE__ */ import_react.default.createElement(
|
|
191
|
+
import_swr.SWRConfig,
|
|
192
|
+
{
|
|
193
|
+
value: {
|
|
194
|
+
provider: () => cache,
|
|
195
|
+
suspense: true,
|
|
196
|
+
fallback: {}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
children
|
|
200
|
+
));
|
|
201
|
+
}
|
|
202
|
+
var useDaouyDataConfig = import_swr.useSWRConfig;
|
|
203
|
+
var loadingCount = 0;
|
|
204
|
+
var listeners = [];
|
|
205
|
+
function addLoadingStateListener(listener, opts) {
|
|
206
|
+
listeners.push(listener);
|
|
207
|
+
if (opts == null ? void 0 : opts.immediate) {
|
|
208
|
+
listener(loadingCount > 0);
|
|
209
|
+
}
|
|
210
|
+
return () => {
|
|
211
|
+
listeners.splice(listeners.indexOf(listener), 1);
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function wrapLoadingFetcher(fetcher) {
|
|
215
|
+
return (...args) => __async(this, null, function* () {
|
|
216
|
+
if (loadingCount === 0) {
|
|
217
|
+
listeners.forEach((listener) => listener(true));
|
|
218
|
+
}
|
|
219
|
+
loadingCount += 1;
|
|
220
|
+
try {
|
|
221
|
+
const res = fetcher(...args);
|
|
222
|
+
return isPromiseLike(res) ? yield res : res;
|
|
223
|
+
} finally {
|
|
224
|
+
loadingCount -= 1;
|
|
225
|
+
if (loadingCount === 0) {
|
|
226
|
+
listeners.forEach((listener) => listener(false));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
function isPromiseLike(x) {
|
|
232
|
+
return !!x && typeof x === "object" && "then" in x && typeof x.then === "function";
|
|
233
|
+
}
|
|
234
|
+
function isDaouyPrepass() {
|
|
235
|
+
var _a, _b, _c;
|
|
236
|
+
return !!((_c = (_b = (_a = import_react.default.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED) == null ? void 0 : _a.ReactCurrentDispatcher) == null ? void 0 : _b.current) == null ? void 0 : _c.isDaouyPrepass);
|
|
237
|
+
}
|
|
238
|
+
var HeadMetadataContext = import_react.default.createContext({});
|
|
239
|
+
|
|
240
|
+
// src/index.tsx
|
|
241
|
+
var import_swr2 = require("swr");
|
|
242
|
+
if (typeof window !== "undefined") {
|
|
243
|
+
const root = window;
|
|
244
|
+
const maybeExistingMutateAllKeys = root.__SWRMutateAllKeys;
|
|
245
|
+
root.__SWRMutateAllKeys = (invalidateKey) => {
|
|
246
|
+
mutateKeys(invalidateKey);
|
|
247
|
+
if (typeof maybeExistingMutateAllKeys === "function") {
|
|
248
|
+
maybeExistingMutateAllKeys(invalidateKey);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.tsx", "../src/query-data.tsx"],
|
|
4
|
+
"sourcesContent": ["import { mutateKeys } from \"./query-data\";\nexport { useSWRConfig } from \"swr\";\nexport {\n addLoadingStateListener,\n HeadMetadataContext,\n isDaouyPrepass,\n DaouyPrepassContext,\n DaouyQueryDataProvider,\n useMutableDaouyQueryData,\n useDaouyDataConfig,\n useDaouyQueryData,\n wrapLoadingFetcher,\n} from \"./query-data\";\nexport type {\n HeadMetadata,\n LoadingStateListener,\n SWRResponse,\n} from \"./query-data\";\n\nif (typeof window !== \"undefined\") {\n const root = window as any;\n const maybeExistingMutateAllKeys = root.__SWRMutateAllKeys;\n root.__SWRMutateAllKeys = (invalidateKey?: string) => {\n mutateKeys(invalidateKey);\n if (typeof maybeExistingMutateAllKeys === \"function\") {\n maybeExistingMutateAllKeys(invalidateKey);\n }\n };\n}\n", "import React, { PropsWithChildren } from \"react\";\nimport useSWR, {\n Cache,\n Fetcher,\n Key,\n SWRConfig,\n SWRConfiguration,\n SWRResponse,\n useSWRConfig,\n} from \"swr\";\n\nexport type { SWRResponse } from \"swr\";\n\nlet __SWRConfig: ReturnType<typeof useSWRConfig> | undefined = undefined;\nexport const mutateKeys = (invalidateKey?: string) => {\n if (__SWRConfig) {\n const { cache, mutate } = __SWRConfig;\n (invalidateKey != null\n ? [invalidateKey]\n : Array.from((cache as Map<string, any>).keys())\n ).forEach((key) => {\n mutate(key);\n });\n }\n};\n\n// @daouy/query is optimized for SSR, so we do not revalidate\n// automatically upon hydration; as if the data is immutable.\nfunction getDaouyDefaultSWROptions(opts?: {\n isMutable?: boolean;\n}): SWRConfiguration {\n return {\n revalidateIfStale: !!opts?.isMutable,\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n };\n}\n\n/**\n * Fetches data asynchronously. This data should be considered immutable for the\n * session -- there is no way to invalidate or re-fetch this data.\n *\n * @param key a unique key for this data fetch; if data already exists under this\n * key, that data is returned immediately.\n * @param fetcher an async function that resolves to the fetched data.\n * @returns an object with either a \"data\" key with the fetched data if the fetch\n * was successful, or an \"error\" key with the thrown Error if the fetch failed.\n */\nexport function useDaouyQueryData<T>(\n key: Key,\n fetcher: Fetcher<T>\n): { data?: T; error?: Error; isLoading?: boolean } {\n const prepassCtx = React.useContext(PrepassContext);\n\n const opts = getDaouyDefaultSWROptions();\n if (prepassCtx) {\n // If we're doing prepass, then we are always in suspense mode, because\n // react-ssr-prepass only works with suspense-throwing data fetching.\n opts.suspense = true;\n }\n\n const config = useSWRConfig();\n React.useEffect(() => {\n __SWRConfig = config;\n }, [config]);\n\n const wrappedFetcher = React.useMemo(\n () => wrapLoadingFetcher(fetcher),\n [fetcher]\n );\n\n const resp = useSWR(key, wrappedFetcher, opts);\n if (resp.data !== undefined) {\n return { data: resp.data };\n } else if (resp.error) {\n return { error: resp.error };\n } else {\n return { isLoading: true };\n }\n}\n\n/**\n * Fetches data asynchronously using SWR Hook (https://swr.vercel.app/)\n *\n * @param key a unique key for this data fetch; if data already exists under this\n * key, that data is returned immediately.\n * @param fetcher an async function that resolves to the fetched data.\n * @param options (optional) an object of options for this hook (https://swr.vercel.app/docs/options).\n * @returns an object with either a \"data\" key with the fetched data if the fetch\n * was successful, or an \"error\" key with the thrown Error if the fetch failed.\n */\nexport function useMutableDaouyQueryData<T, E>(\n key: Key,\n fetcher: Fetcher<T>,\n options?: SWRConfiguration<T, E>\n): SWRResponse<T, E> & { isLoading?: boolean; isLagging?: boolean } {\n const prepassCtx = React.useContext(PrepassContext);\n\n const opts = {\n ...getDaouyDefaultSWROptions({ isMutable: true }),\n ...options,\n };\n if (prepassCtx) {\n opts.suspense = true;\n }\n\n const config = useSWRConfig();\n React.useEffect(() => {\n __SWRConfig = config;\n }, [config]);\n\n const [isLoading, setIsLoading] = React.useState(false);\n const fetcherWrapper = React.useCallback(\n async (...args: any[]) => {\n setIsLoading(true);\n try {\n return await wrapLoadingFetcher(fetcher)(...args);\n } finally {\n setIsLoading(false);\n }\n },\n [fetcher]\n );\n\n // Based on https://swr.vercel.app/docs/middleware#keep-previous-result\n const laggyDataRef = React.useRef<any>();\n\n const { isValidating, mutate, data, error } = useSWR(\n key,\n fetcherWrapper,\n opts\n );\n\n React.useEffect(() => {\n if (data !== undefined) {\n laggyDataRef.current = data;\n }\n }, [data]);\n\n return React.useMemo(\n () => ({\n isValidating,\n mutate,\n isLoading: (data === undefined && error === undefined) || isLoading,\n ...(data !== undefined\n ? { data }\n : error === undefined && laggyDataRef.current\n ? // Show previous data if available\n { data: laggyDataRef.current, isLagging: true }\n : {}),\n ...(error !== undefined ? { error } : {}),\n }),\n [isValidating, mutate, data, error, isLoading]\n );\n}\n\nexport function DaouyQueryDataProvider(props: {\n children: React.ReactNode;\n suspense?: boolean;\n prefetchedCache?: Record<string, any>;\n provider?: () => Cache;\n}) {\n const { children, suspense, prefetchedCache, provider } = props;\n const prepass = React.useContext(PrepassContext);\n if (prepass) {\n // If we're in prepass, then there's already a wrappign SWRConfig;\n // don't interfere with it.\n return <>{children}</>;\n } else {\n return (\n <SWRConfig\n value={{\n fallback: prefetchedCache ?? {},\n suspense,\n provider,\n }}\n >\n {children}\n </SWRConfig>\n );\n }\n}\n\nconst PrepassContext = React.createContext<boolean>(false);\n\nexport function DaouyPrepassContext(\n props: PropsWithChildren<{\n cache: Map<string, any>;\n }>\n) {\n const { cache, children } = props;\n return (\n <PrepassContext.Provider value={true}>\n <SWRConfig\n value={{\n provider: () => cache,\n suspense: true,\n fallback: {},\n }}\n >\n {children}\n </SWRConfig>\n </PrepassContext.Provider>\n );\n}\n\nexport const useDaouyDataConfig: typeof useSWRConfig = useSWRConfig;\n\nlet loadingCount = 0;\nexport type LoadingStateListener = (isLoading: boolean) => void;\nconst listeners: LoadingStateListener[] = [];\n\n/**\n * Subscribes to whether any loading is happening via @daouy/query.\n * Returns a function to unsubscribe.\n */\nexport function addLoadingStateListener(\n listener: LoadingStateListener,\n opts?: { immediate?: boolean }\n) {\n listeners.push(listener);\n if (opts?.immediate) {\n listener(loadingCount > 0);\n }\n return () => {\n listeners.splice(listeners.indexOf(listener), 1);\n };\n}\n\n/**\n * Instruments an async function to increment and decrement the number of\n * simultaneous async loads. You can then subscribe to whether there\n * are any loads happening via addLoadingStateListener().\n */\nexport function wrapLoadingFetcher<\n T extends (...args: any[]) => Promise<any> | any\n>(fetcher: T): T {\n return (async (...args: any) => {\n if (loadingCount === 0) {\n listeners.forEach((listener) => listener(true));\n }\n loadingCount += 1;\n try {\n const res = fetcher(...args);\n return isPromiseLike(res) ? await res : res;\n } finally {\n loadingCount -= 1;\n if (loadingCount === 0) {\n listeners.forEach((listener) => listener(false));\n }\n }\n }) as T;\n}\n\nfunction isPromiseLike(x: any) {\n return (\n !!x && typeof x === \"object\" && \"then\" in x && typeof x.then === \"function\"\n );\n}\n\nexport function isDaouyPrepass() {\n return !!(React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n ?.ReactCurrentDispatcher?.current?.isDaouyPrepass;\n}\n\nexport type HeadMetadata = {\n title?: string;\n description?: string;\n image?: string;\n canonical?: string;\n};\n\nexport const HeadMetadataContext = React.createContext<HeadMetadata>({});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["React", "useSWR", "import_swr"]
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.1.82",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"types": "./dist/index.d.ts",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.esm.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.esm.js",
|
|
11
|
+
"require": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=10"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "yarn build:types && yarn build:index",
|
|
22
|
+
"build:types": "yarn tsc",
|
|
23
|
+
"build:index": "node ../../build.mjs ./src/index.tsx --use-client",
|
|
24
|
+
"test": "TEST_CWD=`pwd` yarn --cwd=../.. test --passWithNoTests",
|
|
25
|
+
"lint": "eslint",
|
|
26
|
+
"prepublishOnly": "npm run build",
|
|
27
|
+
"postpublish": "bash ../../scripts/publish-api-doc-model.sh",
|
|
28
|
+
"size": "size-limit",
|
|
29
|
+
"analyze": "size-limit --why"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": ">=16.8.0"
|
|
33
|
+
},
|
|
34
|
+
"name": "@daouy/query",
|
|
35
|
+
"author": "Chung Wu",
|
|
36
|
+
"size-limit": [
|
|
37
|
+
{
|
|
38
|
+
"path": "dist/index.js",
|
|
39
|
+
"limit": "10 KB"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/react": "^18.0.27",
|
|
44
|
+
"@types/react-dom": "^18.0.10",
|
|
45
|
+
"react": "^18.2.0",
|
|
46
|
+
"react-dom": "^18.2.0",
|
|
47
|
+
"typescript": "^5.9.3"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"swr": "^1.0.0"
|
|
51
|
+
}
|
|
52
|
+
}
|