next-sanity 0.2.0 → 0.5.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 CHANGED
@@ -5,8 +5,6 @@
5
5
  **Features:**
6
6
 
7
7
  - Client-side live real-time preview for authenticated users
8
- - URL-helper for Sanity’s image pipeline
9
- - Rich-text component for Portable Text
10
8
  - GROQ syntax highlighting
11
9
 
12
10
  ## Table of contents
@@ -18,14 +16,15 @@
18
16
  - [Optimizing bundle size](#optimizing-bundle-size)
19
17
  - [Usage](#usage)
20
18
  - [Example: Minimal blog post template](#example-minimal-blog-post-template)
19
+ - [Migrate](#migrate)
21
20
  - [License](#license)
22
21
 
23
22
  ## Installation
24
23
 
25
24
  ```sh
26
- $ npm install next-sanity
25
+ $ npm install next-sanity @portabletext/react @sanity/image-url
27
26
  // or
28
- $ yarn add next-sanity
27
+ $ yarn add next-sanity @portabletext/react @sanity/image-url
29
28
  ```
30
29
 
31
30
  ## Live real-time preview
@@ -42,9 +41,9 @@ We have plans for optimizations in the roadmap.
42
41
 
43
42
  ## Optimizing bundle size
44
43
 
45
- The first version of `next-sanity` shipped with the [`picosanity`](https://github.com/rexxars/picosanity) client built in. This caused some confusion for people who wants not only to pull data from their Sanity.io content lake, but also send patches and mutations via API routes. Since `picosanity` only supported fetching content, it had a smaller bundle size than the full SDK.
44
+ The first version of `next-sanity` shipped with the [`picosanity`](https://github.com/rexxars/picosanity) client built-in. This caused some confusion for people who wants not only to pull data from their Sanity.io content lake, but also send patches and mutations via API routes. Since `picosanity` only supported fetching content, it had a smaller bundle size than the full SDK.
46
45
 
47
- You can leverage Next.js' treeshaking to avoid shipping unnecessary code to the browser. In order to do so, you first need to isolate the client configuration in its own file, and be sure to only use it inside of the data fetching functions (`getStaticProps`, `getServerProps`, and `getStaticPaths`) or in the function that goes into the API routes (`/pages/api/<your-serverless-function>.js`).
46
+ You can leverage Next.js' [tree shaking](https://developers.google.com/web/fundamentals/performance/optimizing-javascript/tree-shaking) to avoid shipping unnecessary code to the browser. In order to do so, you first need to isolate the client configuration in its own file, and be sure to only use it inside of the data fetching functions (`getStaticProps`, `getServerProps`, and `getStaticPaths`) or in the function that goes into the API routes (`/pages/api/<your-serverless-function>.js`).
48
47
 
49
48
  You can follow the approach from the official Next.js preview example:
50
49
 
@@ -57,7 +56,7 @@ Should you want to do queries from the client side but want to avoid bundling th
57
56
 
58
57
  ## Usage
59
58
 
60
- It’s practical to set up a decicated files where you import and set up your client etc. Below is a comprehensive example of the different things you can set up.
59
+ It’s practical to set up dedicated files where you import and set up your client etc. Below is a comprehensive example of the different things you can set up.
61
60
 
62
61
  ```js
63
62
  // lib/config.js
@@ -71,7 +70,7 @@ export const config = {
71
70
  **/
72
71
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',
73
72
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
74
- apiVersion: '2021-03-25',
73
+ apiVersion: '2021-10-21', // Learn more: https://www.sanity.io/docs/api-versioning
75
74
  /**
76
75
  * Set useCdn to `false` if your application require the freshest possible
77
76
  * data always (potentially slightly slower and a bit more expensive).
@@ -83,12 +82,8 @@ export const config = {
83
82
 
84
83
  ```js
85
84
  // lib/sanity.js
86
- import {
87
- createImageUrlBuilder,
88
- createPortableTextComponent,
89
- createPreviewSubscriptionHook,
90
- createCurrentUserHook,
91
- } from 'next-sanity'
85
+ import {createPreviewSubscriptionHook, createCurrentUserHook} from 'next-sanity'
86
+ import createImageUrlBuilder from '@sanity/image-url'
92
87
  import {config} from './config'
93
88
 
94
89
  /**
@@ -100,14 +95,6 @@ export const urlFor = (source) => createImageUrlBuilder(config).image(source)
100
95
  // Set up the live preview subscription hook
101
96
  export const usePreviewSubscription = createPreviewSubscriptionHook(config)
102
97
 
103
- // Set up Portable Text serialization
104
- export const PortableText = createPortableTextComponent({
105
- ...config,
106
- // Serializers passed to @sanity/block-content-to-react
107
- // (https://github.com/sanity-io/block-content-to-react)
108
- serializers: {},
109
- })
110
-
111
98
  // Helper function for using the current logged in user account
112
99
  export const useCurrentUser = createCurrentUserHook(config)
113
100
  ```
@@ -140,7 +127,8 @@ A minimal example for a blog post template using the schema from from the Sanity
140
127
  import ErrorPage from 'next/error'
141
128
  import {useRouter} from 'next/router'
142
129
  import {groq} from 'next-sanity'
143
- import {getClient, usePreviewSubscription, urlFor, PortableText} from '../../lib/sanity'
130
+ import {PortableText} from '@portabletext/react'
131
+ import {usePreviewSubscription, urlFor} from '../../lib/sanity'
144
132
  import {getClient} from '../../lib/sanity.server'
145
133
 
146
134
  const postQuery = groq`
@@ -159,16 +147,17 @@ const postQuery = groq`
159
147
 
160
148
  export default function Post({data, preview}) {
161
149
  const router = useRouter()
162
- if (!router.isFallback && !data.post?.slug) {
163
- return <ErrorPage statusCode={404} />
164
- }
165
150
 
166
151
  const {data: post} = usePreviewSubscription(postQuery, {
167
- params: {slug: data.post.slug},
152
+ params: {slug: data.post?.slug},
168
153
  initialData: data.post,
169
- enabled: preview,
154
+ enabled: preview && data.post?.slug,
170
155
  })
171
156
 
157
+ if (!router.isFallback && !data.post?.slug) {
158
+ return <ErrorPage statusCode={404} />
159
+ }
160
+
172
161
  const {title, mainImage, body} = post
173
162
 
174
163
  return (
@@ -177,7 +166,7 @@ export default function Post({data, preview}) {
177
166
  <figure>
178
167
  <img src={urlFor(mainImage).url()} />
179
168
  </figure>
180
- <PortableText blocks={body} />
169
+ <PortableText value={body} />
181
170
  </article>
182
171
  )
183
172
  }
@@ -207,6 +196,47 @@ export async function getStaticPaths() {
207
196
  }
208
197
  ```
209
198
 
199
+ ## Migrate
200
+
201
+ ### From `v0.4`
202
+
203
+ #### `createPortableTextComponent` is removed
204
+
205
+ This utility used to wrap `@sanity/block-content-to-react`. It's encouraged to upgrade to `@portabletext/react`.
206
+
207
+ ```sh
208
+ $ npm install @portabletext/react
209
+ // or
210
+ $ yarn add @portabletext/react
211
+ ```
212
+
213
+ ```diff
214
+ -import { createPortableTextComponent } from 'next-sanity'
215
+ +import { PortableText as PortableTextComponent } from '@portabletext/react'
216
+
217
+ -export const PortableText = createPortableTextComponent({ serializers: {} })
218
+ +export const PortableText = (props) => <PortableTextComponent components={{}} {...props} />
219
+ ```
220
+
221
+ Please note that the `serializers` and `components` are not 100% equivalent.
222
+
223
+ [Check the full migration guide.](https://github.com/portabletext/react-portabletext/blob/main/MIGRATING.md)
224
+
225
+ #### `createImageUrlBuilder` is removed
226
+
227
+ This utility is no longer wrapped by `next-sanity` and you'll need to install the dependency yourself:
228
+
229
+ ```sh
230
+ $ npm install @sanity/image-url
231
+ // or
232
+ $ yarn add @sanity/image-url
233
+ ```
234
+
235
+ ```diff
236
+ -import { createImageUrlBuilder } from 'next-sanity'
237
+ +import createImageUrlBuilder from '@sanity/image-url'
238
+ ```
239
+
210
240
  ## License
211
241
 
212
242
  MIT-licensed. See LICENSE.
package/dist/aborter.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export interface Aborter {
2
2
  abort(): void;
3
- signal?: AbortSignal;
3
+ signal: AbortSignal;
4
4
  }
5
5
  export declare function getAborter(): Aborter;
@@ -8,4 +8,4 @@ export declare function createCurrentUserHook({ projectId }: {
8
8
  error: Error | undefined;
9
9
  loading: boolean;
10
10
  };
11
- export declare function getCurrentUser(projectId: string, abort?: Aborter): Promise<CurrentUser | null>;
11
+ export declare function getCurrentUser(projectId: string, abort: Aborter): Promise<CurrentUser | null>;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export * from './types';
2
2
  export { createClient } from './client';
3
- export { createImageUrlBuilder } from './imageUrlBuilder';
4
3
  export { createCurrentUserHook } from './currentUser';
5
4
  export { createPreviewSubscriptionHook } from './useSubscription';
6
- export { createPortableTextComponent } from './portableText';
7
5
  export { default as groq } from 'groq';
@@ -24,34 +24,57 @@ function _interopNamespace(e) {
24
24
  }
25
25
 
26
26
  var sanityClient = _interopDefault(require('@sanity/client'));
27
- var getImageUrlBuilder = _interopDefault(require('@sanity/image-url'));
28
- var React = require('react');
29
- var React__default = _interopDefault(React);
30
- var useDeepCompareEffect = require('use-deep-compare-effect');
31
- var SanityPortableText = _interopDefault(require('@sanity/block-content-to-react'));
27
+ var react = require('react');
32
28
  var groq = _interopDefault(require('groq'));
33
29
 
34
30
  function createClient(config) {
35
31
  return sanityClient(config);
36
32
  }
37
33
 
38
- function createImageUrlBuilder(_ref) {
39
- var projectId = _ref.projectId,
40
- dataset = _ref.dataset;
41
- return getImageUrlBuilder({
42
- projectId: projectId,
43
- dataset: dataset
44
- });
34
+ function _defineProperties(target, props) {
35
+ for (var i = 0; i < props.length; i++) {
36
+ var descriptor = props[i];
37
+ descriptor.enumerable = descriptor.enumerable || false;
38
+ descriptor.configurable = true;
39
+ if ("value" in descriptor) descriptor.writable = true;
40
+ Object.defineProperty(target, descriptor.key, descriptor);
41
+ }
45
42
  }
46
43
 
47
- function getAborter() {
48
- return typeof AbortController === 'undefined' ? {
49
- signal: undefined,
50
- abort: noop
51
- } : new AbortController();
44
+ function _createClass(Constructor, protoProps, staticProps) {
45
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
46
+ if (staticProps) _defineProperties(Constructor, staticProps);
47
+ Object.defineProperty(Constructor, "prototype", {
48
+ writable: false
49
+ });
50
+ return Constructor;
52
51
  }
53
52
 
54
- function noop() {// intentional noop
53
+ var MockAbortController = /*#__PURE__*/function () {
54
+ function MockAbortController() {
55
+ this._signal = {
56
+ aborted: false
57
+ };
58
+ }
59
+
60
+ var _proto = MockAbortController.prototype;
61
+
62
+ _proto.abort = function abort() {
63
+ this._signal.aborted = true;
64
+ };
65
+
66
+ _createClass(MockAbortController, [{
67
+ key: "signal",
68
+ get: function get() {
69
+ return this._signal;
70
+ }
71
+ }]);
72
+
73
+ return MockAbortController;
74
+ }();
75
+
76
+ function getAborter() {
77
+ return typeof AbortController === 'undefined' ? new MockAbortController() : new AbortController();
55
78
  }
56
79
 
57
80
  function createCurrentUserHook(_ref) {
@@ -63,30 +86,30 @@ function createCurrentUserHook(_ref) {
63
86
  function getCurrentUser(projectId, abort) {
64
87
  return fetch("https://" + projectId + ".api.sanity.io/v1/users/me", {
65
88
  credentials: 'include',
66
- signal: abort == null ? void 0 : abort.signal
89
+ signal: abort.signal
67
90
  }).then(function (res) {
68
91
  return res.json();
69
92
  }).then(function (res) {
70
93
  return res != null && res.id ? res : null;
71
- }).catch(function (err) {
72
- return err.name === 'AbortError' ? null : Promise.reject(err);
73
94
  });
74
95
  }
75
96
 
76
97
  function useCurrentUser(projectId) {
77
- var _useState = React.useState(),
98
+ var _useState = react.useState(),
78
99
  data = _useState[0],
79
100
  setUser = _useState[1];
80
101
 
81
- var _useState2 = React.useState(),
102
+ var _useState2 = react.useState(),
82
103
  error = _useState2[0],
83
104
  setError = _useState2[1];
84
105
 
85
- React.useEffect(function () {
106
+ react.useEffect(function () {
86
107
  var aborter = getAborter();
87
- getCurrentUser(projectId, aborter).then(setUser).catch(setError);
108
+ getCurrentUser(projectId, aborter).then(setUser).catch(function (err) {
109
+ return err.name !== 'AbortError' && setError(err);
110
+ });
88
111
  return function () {
89
- return aborter.abort();
112
+ aborter.abort();
90
113
  };
91
114
  }, [projectId]);
92
115
  return {
@@ -124,10 +147,19 @@ function createPreviewSubscriptionHook(_ref) {
124
147
  });
125
148
  };
126
149
 
127
- function getStore() {
150
+ function getStore(abort) {
128
151
  if (!store) {
129
152
  store = new Promise(function (resolve) { resolve(_interopNamespace(require('@sanity/groq-store'))); }).then(function (_ref2) {
130
153
  var groqStore = _ref2.groqStore;
154
+
155
+ // Skip creating the groq store if we've been unmounted to save memory and reduce gc pressure
156
+ if (abort.signal.aborted) {
157
+ var error = new Error('Cancelling groq store creation'); // This ensures we can skip it in the catch block same way
158
+
159
+ error.name = 'AbortError';
160
+ return Promise.reject(error);
161
+ }
162
+
131
163
  return groqStore({
132
164
  projectId: projectId,
133
165
  dataset: dataset,
@@ -147,30 +179,28 @@ function useQuerySubscription(options) {
147
179
  var getStore = options.getStore,
148
180
  projectId = options.projectId,
149
181
  query = options.query,
150
- params = options.params,
151
182
  initialData = options.initialData,
152
183
  _options$enabled = options.enabled,
153
184
  enabled = _options$enabled === void 0 ? false : _options$enabled;
154
185
 
155
- var _useState = React.useState(),
186
+ var _useState = react.useState(),
156
187
  error = _useState[0],
157
188
  setError = _useState[1];
158
189
 
159
- var _useState2 = React.useState(false),
190
+ var _useState2 = react.useState(false),
160
191
  loading = _useState2[0],
161
192
  setLoading = _useState2[1];
162
193
 
163
- var _useState3 = React.useState(),
194
+ var _useState3 = react.useState(),
164
195
  data = _useState3[0],
165
- setData = _useState3[1]; // Use "deep" dependency comparison because params are often not _referentially_ equal,
166
- // but contains the same shallow properties, eg `{"slug": "some-slug"}`
196
+ setData = _useState3[1];
167
197
 
198
+ var params = useParams(options.params); // Use "deep" dependency comparison because params are often not _referentially_ equal,
199
+ // but contains the same shallow properties, eg `{"slug": "some-slug"}`
168
200
 
169
- useDeepCompareEffect.useDeepCompareEffectNoCheck(function () {
201
+ react.useEffect(function () {
170
202
  if (!enabled) {
171
- return function () {
172
- /* intentional noop */
173
- };
203
+ return;
174
204
  }
175
205
 
176
206
  setLoading(true);
@@ -184,7 +214,9 @@ function useQuerySubscription(options) {
184
214
 
185
215
  console.warn('Not authenticated - preview not available');
186
216
  throw new Error('Not authenticated - preview not available');
187
- }).then(getStore).then(function (store) {
217
+ }).then(function () {
218
+ return getStore(aborter);
219
+ }).then(function (store) {
188
220
  subscription = store.subscribe(query, params, function (err, result) {
189
221
  if (err) {
190
222
  setError(err);
@@ -192,9 +224,12 @@ function useQuerySubscription(options) {
192
224
  setData(result);
193
225
  }
194
226
  });
195
- }).catch(setError).finally(function () {
227
+ }).catch(function (err) {
228
+ return err.name === 'AbortError' ? null : setError(err);
229
+ }).finally(function () {
196
230
  return setLoading(false);
197
- });
231
+ }); // eslint-disable-next-line consistent-return
232
+
198
233
  return function () {
199
234
  if (subscription) {
200
235
  subscription.unsubscribe();
@@ -208,25 +243,20 @@ function useQuerySubscription(options) {
208
243
  loading: loading,
209
244
  error: error
210
245
  };
211
- }
246
+ } // Return params that are stable with deep equal as long as the key order is the same
212
247
 
213
- function createPortableTextComponent(_ref) {
214
- var projectId = _ref.projectId,
215
- dataset = _ref.dataset,
216
- serializers = _ref.serializers;
217
- return function PortableText(props) {
218
- return React__default.createElement(SanityPortableText, Object.assign({
219
- projectId: projectId,
220
- dataset: dataset,
221
- serializers: serializers
222
- }, props));
223
- };
248
+
249
+ function useParams(params) {
250
+ var stringifiedParams = react.useMemo(function () {
251
+ return JSON.stringify(params);
252
+ }, [params]);
253
+ return react.useMemo(function () {
254
+ return JSON.parse(stringifiedParams);
255
+ }, [stringifiedParams]);
224
256
  }
225
257
 
226
258
  exports.groq = groq;
227
259
  exports.createClient = createClient;
228
260
  exports.createCurrentUserHook = createCurrentUserHook;
229
- exports.createImageUrlBuilder = createImageUrlBuilder;
230
- exports.createPortableTextComponent = createPortableTextComponent;
231
261
  exports.createPreviewSubscriptionHook = createPreviewSubscriptionHook;
232
262
  //# sourceMappingURL=next-sanity.cjs.development.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"next-sanity.cjs.development.js","sources":["../src/client.ts","../src/imageUrlBuilder.ts","../src/aborter.ts","../src/currentUser.ts","../src/useSubscription.ts","../src/portableText.tsx"],"sourcesContent":["import sanityClient from '@sanity/client'\nimport {ClientConfig} from './types'\n\nexport function createClient(config: ClientConfig) {\n return sanityClient(config)\n}\n","import getImageUrlBuilder from '@sanity/image-url'\nimport {ProjectConfig} from './types'\n\nexport function createImageUrlBuilder({projectId, dataset}: ProjectConfig) {\n return getImageUrlBuilder({projectId, dataset})\n}\n","export interface Aborter {\n abort(): void\n signal?: AbortSignal\n}\n\nexport function getAborter(): Aborter {\n return typeof AbortController === 'undefined'\n ? {signal: undefined, abort: noop}\n : new AbortController()\n}\n\nfunction noop() {\n // intentional noop\n}\n","import {useEffect, useState} from 'react'\nimport {CurrentUser} from './types'\nimport {getAborter, Aborter} from './aborter'\n\nexport function createCurrentUserHook({projectId}: {projectId: string; dataset?: string}) {\n return () => useCurrentUser(projectId)\n}\n\nexport function getCurrentUser(projectId: string, abort?: Aborter): Promise<CurrentUser | null> {\n return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {\n credentials: 'include',\n signal: abort?.signal,\n })\n .then((res) => res.json())\n .then((res) => (res?.id ? res : null))\n .catch((err: Error) => (err.name === 'AbortError' ? null : Promise.reject(err)))\n}\n\nfunction useCurrentUser(projectId: string) {\n const [data, setUser] = useState<CurrentUser | null>()\n const [error, setError] = useState<Error>()\n\n useEffect(() => {\n const aborter = getAborter()\n getCurrentUser(projectId, aborter).then(setUser).catch(setError)\n return () => aborter.abort()\n }, [projectId])\n\n return {data, error, loading: data !== null || !error}\n}\n","import {useState} from 'react'\nimport {GroqStore, Subscription} from '@sanity/groq-store'\nimport {useDeepCompareEffectNoCheck as useDeepCompareEffect} from 'use-deep-compare-effect'\nimport {ProjectConfig} from './types'\nimport {getCurrentUser} from './currentUser'\nimport {getAborter} from './aborter'\n\nconst EMPTY_PARAMS = {}\n\ninterface SubscriptionOptions<R = any> {\n enabled?: boolean\n params?: Record<string, unknown>\n initialData?: R\n}\n\nexport function createPreviewSubscriptionHook({\n projectId,\n dataset,\n documentLimit = 3000,\n}: ProjectConfig & {documentLimit?: number}) {\n // Only construct/setup the store when `getStore()` is called\n let store: Promise<GroqStore>\n\n return function usePreviewSubscription<R = any>(\n query: string,\n options: SubscriptionOptions<R> = {}\n ) {\n const {params = EMPTY_PARAMS, initialData, enabled} = options\n return useQuerySubscription<R>({\n getStore,\n projectId,\n query,\n params,\n initialData: initialData as any,\n enabled: enabled ? typeof window !== 'undefined' : false,\n })\n }\n\n function getStore() {\n if (!store) {\n store = import('@sanity/groq-store').then(({groqStore}) =>\n groqStore({\n projectId,\n dataset,\n documentLimit,\n listen: true,\n overlayDrafts: true,\n subscriptionThrottleMs: 10,\n })\n )\n }\n return store\n }\n}\n\nfunction useQuerySubscription<R = any>(options: {\n getStore: () => Promise<GroqStore>\n projectId: string\n query: string\n params: Record<string, unknown>\n initialData: R\n enabled: boolean\n}) {\n const {getStore, projectId, query, params, initialData, enabled = false} = options\n const [error, setError] = useState<Error>()\n const [loading, setLoading] = useState(false)\n const [data, setData] = useState<R>()\n\n // Use \"deep\" dependency comparison because params are often not _referentially_ equal,\n // but contains the same shallow properties, eg `{\"slug\": \"some-slug\"}`\n useDeepCompareEffect(() => {\n if (!enabled) {\n return () => {\n /* intentional noop */\n }\n }\n\n setLoading(true)\n\n const aborter = getAborter()\n let subscription: Subscription | undefined\n getCurrentUser(projectId, aborter)\n .then((user) => {\n if (user) {\n return\n }\n\n // eslint-disable-next-line no-console\n console.warn('Not authenticated - preview not available')\n throw new Error('Not authenticated - preview not available')\n })\n .then(getStore)\n .then((store) => {\n subscription = store.subscribe(query, params, (err, result) => {\n if (err) {\n setError(err)\n } else {\n setData(result)\n }\n })\n })\n .catch(setError)\n .finally(() => setLoading(false))\n\n return () => {\n if (subscription) {\n subscription.unsubscribe()\n }\n\n aborter.abort()\n }\n }, [getStore, query, params, enabled])\n\n return {\n data: typeof data === 'undefined' ? initialData : data,\n loading,\n error,\n }\n}\n","import React from 'react'\nimport SanityPortableText, {\n PortableTextProps,\n PortableTextSerializers,\n} from '@sanity/block-content-to-react'\nimport {ProjectConfig} from './types'\n\nexport function createPortableTextComponent({\n projectId,\n dataset,\n serializers,\n}: ProjectConfig & {serializers?: PortableTextSerializers}) {\n return function PortableText(props: PortableTextProps) {\n return (\n <SanityPortableText\n projectId={projectId}\n dataset={dataset}\n serializers={serializers}\n {...props}\n />\n )\n }\n}\n"],"names":["createClient","config","sanityClient","createImageUrlBuilder","projectId","dataset","getImageUrlBuilder","getAborter","AbortController","signal","undefined","abort","noop","createCurrentUserHook","useCurrentUser","getCurrentUser","fetch","credentials","then","res","json","id","catch","err","name","Promise","reject","useState","data","setUser","error","setError","useEffect","aborter","loading","EMPTY_PARAMS","createPreviewSubscriptionHook","documentLimit","store","usePreviewSubscription","query","options","params","initialData","enabled","useQuerySubscription","getStore","window","groqStore","listen","overlayDrafts","subscriptionThrottleMs","setLoading","setData","useDeepCompareEffect","subscription","user","console","warn","Error","subscribe","result","finally","unsubscribe","createPortableTextComponent","serializers","PortableText","props","React","SanityPortableText"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAGgBA,aAAaC;AAC3B,SAAOC,YAAY,CAACD,MAAD,CAAnB;AACD;;SCFeE;MAAuBC,iBAAAA;MAAWC,eAAAA;AAChD,SAAOC,kBAAkB,CAAC;AAACF,IAAAA,SAAS,EAATA,SAAD;AAAYC,IAAAA,OAAO,EAAPA;AAAZ,GAAD,CAAzB;AACD;;SCAeE;AACd,SAAO,OAAOC,eAAP,KAA2B,WAA3B,GACH;AAACC,IAAAA,MAAM,EAAEC,SAAT;AAAoBC,IAAAA,KAAK,EAAEC;AAA3B,GADG,GAEH,IAAIJ,eAAJ,EAFJ;AAGD;;AAED,SAASI,IAAT;AAEC;;SCTeC;MAAuBT,iBAAAA;AACrC,SAAO;AAAA,WAAMU,cAAc,CAACV,SAAD,CAApB;AAAA,GAAP;AACD;AAED,SAAgBW,eAAeX,WAAmBO;AAChD,SAAOK,KAAK,cAAYZ,SAAZ,iCAAmD;AAC7Da,IAAAA,WAAW,EAAE,SADgD;AAE7DR,IAAAA,MAAM,EAAEE,KAAF,oBAAEA,KAAK,CAAEF;AAF8C,GAAnD,CAAL,CAIJS,IAJI,CAIC,UAACC,GAAD;AAAA,WAASA,GAAG,CAACC,IAAJ,EAAT;AAAA,GAJD,EAKJF,IALI,CAKC,UAACC,GAAD;AAAA,WAAUA,GAAG,QAAH,IAAAA,GAAG,CAAEE,EAAL,GAAUF,GAAV,GAAgB,IAA1B;AAAA,GALD,EAMJG,KANI,CAME,UAACC,GAAD;AAAA,WAAiBA,GAAG,CAACC,IAAJ,KAAa,YAAb,GAA4B,IAA5B,GAAmCC,OAAO,CAACC,MAAR,CAAeH,GAAf,CAApD;AAAA,GANF,CAAP;AAOD;;AAED,SAAST,cAAT,CAAwBV,SAAxB;kBAC0BuB,cAAQ;MAAzBC;MAAMC;;mBACaF,cAAQ;MAA3BG;MAAOC;;AAEdC,EAAAA,eAAS,CAAC;AACR,QAAMC,OAAO,GAAG1B,UAAU,EAA1B;AACAQ,IAAAA,cAAc,CAACX,SAAD,EAAY6B,OAAZ,CAAd,CAAmCf,IAAnC,CAAwCW,OAAxC,EAAiDP,KAAjD,CAAuDS,QAAvD;AACA,WAAO;AAAA,aAAME,OAAO,CAACtB,KAAR,EAAN;AAAA,KAAP;AACD,GAJQ,EAIN,CAACP,SAAD,CAJM,CAAT;AAMA,SAAO;AAACwB,IAAAA,IAAI,EAAJA,IAAD;AAAOE,IAAAA,KAAK,EAALA,KAAP;AAAcI,IAAAA,OAAO,EAAEN,IAAI,KAAK,IAAT,IAAiB,CAACE;AAAzC,GAAP;AACD;;ACtBD,IAAMK,YAAY,GAAG,EAArB;AAQA,SAAgBC;MACdhC,iBAAAA;MACAC,eAAAA;gCACAgC;MAAAA,gDAAgB;AAEhB;AACA,MAAIC,KAAJ;AAEA,SAAO,SAASC,sBAAT,CACLC,KADK,EAELC,OAFK;QAELA;AAAAA,MAAAA,UAAkC;;;mBAEoBA;mCAA/CC;QAAAA,sCAASP;QAAcQ,uBAAAA;QAAaC,mBAAAA;AAC3C,WAAOC,oBAAoB,CAAI;AAC7BC,MAAAA,QAAQ,EAARA,QAD6B;AAE7B1C,MAAAA,SAAS,EAATA,SAF6B;AAG7BoC,MAAAA,KAAK,EAALA,KAH6B;AAI7BE,MAAAA,MAAM,EAANA,MAJ6B;AAK7BC,MAAAA,WAAW,EAAEA,WALgB;AAM7BC,MAAAA,OAAO,EAAEA,OAAO,GAAG,OAAOG,MAAP,KAAkB,WAArB,GAAmC;AANtB,KAAJ,CAA3B;AAQD,GAbD;;AAeA,WAASD,QAAT;AACE,QAAI,CAACR,KAAL,EAAY;AACVA,MAAAA,KAAK,GAAG,mEAAO,oBAAP,QAA6BpB,IAA7B,CAAkC;AAAA,YAAE8B,SAAF,SAAEA,SAAF;AAAA,eACxCA,SAAS,CAAC;AACR5C,UAAAA,SAAS,EAATA,SADQ;AAERC,UAAAA,OAAO,EAAPA,OAFQ;AAGRgC,UAAAA,aAAa,EAAbA,aAHQ;AAIRY,UAAAA,MAAM,EAAE,IAJA;AAKRC,UAAAA,aAAa,EAAE,IALP;AAMRC,UAAAA,sBAAsB,EAAE;AANhB,SAAD,CAD+B;AAAA,OAAlC,CAAR;AAUD;;AACD,WAAOb,KAAP;AACD;AACF;;AAED,SAASO,oBAAT,CAAuCJ,OAAvC;MAQSK,WAAoEL,QAApEK;MAAU1C,YAA0DqC,QAA1DrC;MAAWoC,QAA+CC,QAA/CD;MAAOE,SAAwCD,QAAxCC;MAAQC,cAAgCF,QAAhCE;yBAAgCF,QAAnBG;MAAAA,wCAAU;;kBACxCjB,cAAQ;MAA3BG;MAAOC;;mBACgBJ,cAAQ,CAAC,KAAD;MAA/BO;MAASkB;;mBACQzB,cAAQ;MAAzBC;MAAMyB;AAGb;;;AACAC,EAAAA,gDAAoB,CAAC;AACnB,QAAI,CAACV,OAAL,EAAc;AACZ,aAAO;AACL;AACD,OAFD;AAGD;;AAEDQ,IAAAA,UAAU,CAAC,IAAD,CAAV;AAEA,QAAMnB,OAAO,GAAG1B,UAAU,EAA1B;AACA,QAAIgD,YAAJ;AACAxC,IAAAA,cAAc,CAACX,SAAD,EAAY6B,OAAZ,CAAd,CACGf,IADH,CACQ,UAACsC,IAAD;AACJ,UAAIA,IAAJ,EAAU;AACR;AACD;;;AAGDC,MAAAA,OAAO,CAACC,IAAR,CAAa,2CAAb;AACA,YAAM,IAAIC,KAAJ,CAAU,2CAAV,CAAN;AACD,KATH,EAUGzC,IAVH,CAUQ4B,QAVR,EAWG5B,IAXH,CAWQ,UAACoB,KAAD;AACJiB,MAAAA,YAAY,GAAGjB,KAAK,CAACsB,SAAN,CAAgBpB,KAAhB,EAAuBE,MAAvB,EAA+B,UAACnB,GAAD,EAAMsC,MAAN;AAC5C,YAAItC,GAAJ,EAAS;AACPQ,UAAAA,QAAQ,CAACR,GAAD,CAAR;AACD,SAFD,MAEO;AACL8B,UAAAA,OAAO,CAACQ,MAAD,CAAP;AACD;AACF,OANc,CAAf;AAOD,KAnBH,EAoBGvC,KApBH,CAoBSS,QApBT,EAqBG+B,OArBH,CAqBW;AAAA,aAAMV,UAAU,CAAC,KAAD,CAAhB;AAAA,KArBX;AAuBA,WAAO;AACL,UAAIG,YAAJ,EAAkB;AAChBA,QAAAA,YAAY,CAACQ,WAAb;AACD;;AAED9B,MAAAA,OAAO,CAACtB,KAAR;AACD,KAND;AAOD,GAzCmB,EAyCjB,CAACmC,QAAD,EAAWN,KAAX,EAAkBE,MAAlB,EAA0BE,OAA1B,CAzCiB,CAApB;AA2CA,SAAO;AACLhB,IAAAA,IAAI,EAAE,OAAOA,IAAP,KAAgB,WAAhB,GAA8Be,WAA9B,GAA4Cf,IAD7C;AAELM,IAAAA,OAAO,EAAPA,OAFK;AAGLJ,IAAAA,KAAK,EAALA;AAHK,GAAP;AAKD;;SC/GekC;MACd5D,iBAAAA;MACAC,eAAAA;MACA4D,mBAAAA;AAEA,SAAO,SAASC,YAAT,CAAsBC,KAAtB;AACL,WACEC,4BAAA,CAACC,kBAAD;AACEjE,MAAAA,SAAS,EAAEA;AACXC,MAAAA,OAAO,EAAEA;AACT4D,MAAAA,WAAW,EAAEA;OACTE,MAJN,CADF;AAQD,GATD;AAUD;;;;;;;;;"}
1
+ {"version":3,"file":"next-sanity.cjs.development.js","sources":["../src/client.ts","../src/aborter.ts","../src/currentUser.ts","../src/useSubscription.ts"],"sourcesContent":["import sanityClient from '@sanity/client'\nimport {ClientConfig} from './types'\n\nexport function createClient(config: ClientConfig) {\n return sanityClient(config)\n}\n","export interface Aborter {\n abort(): void\n signal: AbortSignal\n}\n\nclass MockAbortController {\n _signal = {aborted: false}\n get signal() {\n return this._signal as AbortSignal\n }\n abort() {\n this._signal.aborted = true\n }\n}\n\nexport function getAborter(): Aborter {\n return typeof AbortController === 'undefined'\n ? new MockAbortController()\n : new AbortController()\n}\n","import {useEffect, useState} from 'react'\nimport {CurrentUser} from './types'\nimport {getAborter, Aborter} from './aborter'\n\nexport function createCurrentUserHook({projectId}: {projectId: string; dataset?: string}) {\n return () => useCurrentUser(projectId)\n}\n\nexport function getCurrentUser(projectId: string, abort: Aborter): Promise<CurrentUser | null> {\n return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {\n credentials: 'include',\n signal: abort.signal,\n })\n .then((res) => res.json())\n .then((res) => (res?.id ? res : null))\n}\n\nfunction useCurrentUser(projectId: string) {\n const [data, setUser] = useState<CurrentUser | null>()\n const [error, setError] = useState<Error>()\n\n useEffect(() => {\n const aborter = getAborter()\n getCurrentUser(projectId, aborter)\n .then(setUser)\n .catch((err: Error) => err.name !== 'AbortError' && setError(err))\n\n return () => {\n aborter.abort()\n }\n }, [projectId])\n\n return {data, error, loading: data !== null || !error}\n}\n","import {useState, useEffect, useMemo} from 'react'\nimport {GroqStore, Subscription} from '@sanity/groq-store'\nimport {ProjectConfig} from './types'\nimport {getCurrentUser} from './currentUser'\nimport {getAborter, Aborter} from './aborter'\n\nconst EMPTY_PARAMS = {}\n\ntype Params = Record<string, unknown>\ninterface SubscriptionOptions<R = any> {\n enabled?: boolean\n params?: Params\n initialData?: R\n}\n\nexport function createPreviewSubscriptionHook({\n projectId,\n dataset,\n documentLimit = 3000,\n}: ProjectConfig & {documentLimit?: number}) {\n // Only construct/setup the store when `getStore()` is called\n let store: Promise<GroqStore>\n\n return function usePreviewSubscription<R = any>(\n query: string,\n options: SubscriptionOptions<R> = {}\n ) {\n const {params = EMPTY_PARAMS, initialData, enabled} = options\n return useQuerySubscription<R>({\n getStore,\n projectId,\n query,\n params,\n initialData: initialData as any,\n enabled: enabled ? typeof window !== 'undefined' : false,\n })\n }\n\n function getStore(abort: Aborter) {\n if (!store) {\n store = import('@sanity/groq-store').then(({groqStore}) => {\n // Skip creating the groq store if we've been unmounted to save memory and reduce gc pressure\n if (abort.signal.aborted) {\n const error = new Error('Cancelling groq store creation')\n // This ensures we can skip it in the catch block same way\n error.name = 'AbortError'\n return Promise.reject(error)\n }\n\n return groqStore({\n projectId,\n dataset,\n documentLimit,\n listen: true,\n overlayDrafts: true,\n subscriptionThrottleMs: 10,\n })\n })\n }\n return store\n }\n}\n\nfunction useQuerySubscription<R = any>(options: {\n getStore: (abort: Aborter) => Promise<GroqStore>\n projectId: string\n query: string\n params: Params\n initialData: R\n enabled: boolean\n}) {\n const {getStore, projectId, query, initialData, enabled = false} = options\n const [error, setError] = useState<Error>()\n const [loading, setLoading] = useState(false)\n const [data, setData] = useState<R>()\n const params = useParams(options.params)\n\n // Use \"deep\" dependency comparison because params are often not _referentially_ equal,\n // but contains the same shallow properties, eg `{\"slug\": \"some-slug\"}`\n useEffect(() => {\n if (!enabled) {\n return\n }\n\n setLoading(true)\n\n const aborter = getAborter()\n let subscription: Subscription | undefined\n getCurrentUser(projectId, aborter)\n .then((user) => {\n if (user) {\n return\n }\n\n // eslint-disable-next-line no-console\n console.warn('Not authenticated - preview not available')\n throw new Error('Not authenticated - preview not available')\n })\n .then(() => getStore(aborter))\n .then((store) => {\n subscription = store.subscribe(query, params, (err, result) => {\n if (err) {\n setError(err)\n } else {\n setData(result)\n }\n })\n })\n .catch((err: Error) => (err.name === 'AbortError' ? null : setError(err)))\n .finally(() => setLoading(false))\n\n // eslint-disable-next-line consistent-return\n return () => {\n if (subscription) {\n subscription.unsubscribe()\n }\n\n aborter.abort()\n }\n }, [getStore, query, params, enabled])\n\n return {\n data: typeof data === 'undefined' ? initialData : data,\n loading,\n error,\n }\n}\n\n// Return params that are stable with deep equal as long as the key order is the same\nfunction useParams(params: Params): Params {\n const stringifiedParams = useMemo(() => JSON.stringify(params), [params])\n return useMemo(() => JSON.parse(stringifiedParams), [stringifiedParams])\n}\n"],"names":["createClient","config","sanityClient","MockAbortController","aborted","abort","_signal","getAborter","AbortController","createCurrentUserHook","projectId","useCurrentUser","getCurrentUser","fetch","credentials","signal","then","res","json","id","useState","data","setUser","error","setError","useEffect","aborter","catch","err","name","loading","EMPTY_PARAMS","createPreviewSubscriptionHook","dataset","documentLimit","store","usePreviewSubscription","query","options","params","initialData","enabled","useQuerySubscription","getStore","window","groqStore","Error","Promise","reject","listen","overlayDrafts","subscriptionThrottleMs","setLoading","setData","useParams","subscription","user","console","warn","subscribe","result","finally","unsubscribe","stringifiedParams","useMemo","JSON","stringify","parse"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("@sanity/client")),r=e(require("@sanity/image-url")),n=require("react"),o=e(n),i=require("use-deep-compare-effect"),a=e(require("@sanity/block-content-to-react")),u=e(require("groq"));function c(){return"undefined"==typeof AbortController?{signal:void 0,abort:s}:new AbortController}function s(){}function f(e,t){return fetch("https://"+e+".api.sanity.io/v1/users/me",{credentials:"include",signal:null==t?void 0:t.signal}).then((function(e){return e.json()})).then((function(e){return null!=e&&e.id?e:null})).catch((function(e){return"AbortError"===e.name?null:Promise.reject(e)}))}var l={};exports.groq=u,exports.createClient=function(e){return t(e)},exports.createCurrentUserHook=function(e){var t=e.projectId;return function(){return function(e){var t=n.useState(),r=t[0],o=t[1],i=n.useState(),a=i[0],u=i[1];return n.useEffect((function(){var t=c();return f(e,t).then(o).catch(u),function(){return t.abort()}}),[e]),{data:r,error:a,loading:null!==r||!a}}(t)}},exports.createImageUrlBuilder=function(e){return r({projectId:e.projectId,dataset:e.dataset})},exports.createPortableTextComponent=function(e){var t=e.projectId,r=e.dataset,n=e.serializers;return function(e){return o.createElement(a,Object.assign({projectId:t,dataset:r,serializers:n},e))}},exports.createPreviewSubscriptionHook=function(e){var t,r=e.projectId,o=e.dataset,a=e.documentLimit,u=void 0===a?3e3:a;return function(e,t){void 0===t&&(t={});var o=t.params;return function(e){var t=e.getStore,r=e.projectId,o=e.query,a=e.params,u=e.initialData,s=e.enabled,l=void 0!==s&&s,d=n.useState(),p=d[0],v=d[1],b=n.useState(!1),h=b[0],m=b[1],g=n.useState(),j=g[0],y=g[1];return i.useDeepCompareEffectNoCheck((function(){if(!l)return function(){};m(!0);var e,n=c();return f(r,n).then((function(e){if(!e)throw console.warn("Not authenticated - preview not available"),new Error("Not authenticated - preview not available")})).then(t).then((function(t){e=t.subscribe(o,a,(function(e,t){e?v(e):y(t)}))})).catch(v).finally((function(){return m(!1)})),function(){e&&e.unsubscribe(),n.abort()}}),[t,o,a,l]),{data:void 0===j?u:j,loading:h,error:p}}({getStore:s,projectId:r,query:e,params:void 0===o?l:o,initialData:t.initialData,enabled:!!t.enabled&&"undefined"!=typeof window})};function s(){return t||(t=new Promise((function(e){e(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach((function(r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})})),t.default=e,t}(require("@sanity/groq-store")))})).then((function(e){return(0,e.groqStore)({projectId:r,dataset:o,documentLimit:u,listen:!0,overlayDrafts:!0,subscriptionThrottleMs:10})}))),t}};
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("@sanity/client")),r=require("react"),n=e(require("groq")),o=function(){function e(){this._signal={aborted:!1}}var t,r;return e.prototype.abort=function(){this._signal.aborted=!0},t=e,(r=[{key:"signal",get:function(){return this._signal}}])&&function(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}(t.prototype,r),Object.defineProperty(t,"prototype",{writable:!1}),e}();function i(){return"undefined"==typeof AbortController?new o:new AbortController}function u(e,t){return fetch("https://"+e+".api.sanity.io/v1/users/me",{credentials:"include",signal:t.signal}).then((function(e){return e.json()})).then((function(e){return null!=e&&e.id?e:null}))}var a={};exports.groq=n,exports.createClient=function(e){return t(e)},exports.createCurrentUserHook=function(e){var t=e.projectId;return function(){return function(e){var t=r.useState(),n=t[0],o=t[1],a=r.useState(),c=a[0],f=a[1];return r.useEffect((function(){var t=i();return u(e,t).then(o).catch((function(e){return"AbortError"!==e.name&&f(e)})),function(){t.abort()}}),[e]),{data:n,error:c,loading:null!==n||!c}}(t)}},exports.createPreviewSubscriptionHook=function(e){var t,n=e.projectId,o=e.dataset,c=e.documentLimit,f=void 0===c?3e3:c;return function(e,t){void 0===t&&(t={});var o=t.params;return function(e){var t=e.getStore,n=e.projectId,o=e.query,a=e.initialData,c=e.enabled,f=void 0!==c&&c,s=r.useState(),l=s[0],d=s[1],b=r.useState(!1),p=b[0],v=b[1],g=r.useState(),y=g[0],h=g[1],m=function(e){var t=r.useMemo((function(){return JSON.stringify(e)}),[e]);return r.useMemo((function(){return JSON.parse(t)}),[t])}(e.params);return r.useEffect((function(){if(f){v(!0);var e,r=i();return u(n,r).then((function(e){if(!e)throw console.warn("Not authenticated - preview not available"),new Error("Not authenticated - preview not available")})).then((function(){return t(r)})).then((function(t){e=t.subscribe(o,m,(function(e,t){e?d(e):h(t)}))})).catch((function(e){return"AbortError"===e.name?null:d(e)})).finally((function(){return v(!1)})),function(){e&&e.unsubscribe(),r.abort()}}}),[t,o,m,f]),{data:void 0===y?a:y,loading:p,error:l}}({getStore:s,projectId:n,query:e,params:void 0===o?a:o,initialData:t.initialData,enabled:!!t.enabled&&"undefined"!=typeof window})};function s(e){return t||(t=new Promise((function(e){e(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach((function(r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})})),t.default=e,t}(require("@sanity/groq-store")))})).then((function(t){var r=t.groqStore;if(e.signal.aborted){var i=new Error("Cancelling groq store creation");return i.name="AbortError",Promise.reject(i)}return r({projectId:n,dataset:o,documentLimit:f,listen:!0,overlayDrafts:!0,subscriptionThrottleMs:10})}))),t}};
2
2
  //# sourceMappingURL=next-sanity.cjs.production.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"next-sanity.cjs.production.min.js","sources":["../src/aborter.ts","../src/currentUser.ts","../src/useSubscription.ts","../src/client.ts","../src/imageUrlBuilder.ts","../src/portableText.tsx"],"sourcesContent":["export interface Aborter {\n abort(): void\n signal?: AbortSignal\n}\n\nexport function getAborter(): Aborter {\n return typeof AbortController === 'undefined'\n ? {signal: undefined, abort: noop}\n : new AbortController()\n}\n\nfunction noop() {\n // intentional noop\n}\n","import {useEffect, useState} from 'react'\nimport {CurrentUser} from './types'\nimport {getAborter, Aborter} from './aborter'\n\nexport function createCurrentUserHook({projectId}: {projectId: string; dataset?: string}) {\n return () => useCurrentUser(projectId)\n}\n\nexport function getCurrentUser(projectId: string, abort?: Aborter): Promise<CurrentUser | null> {\n return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {\n credentials: 'include',\n signal: abort?.signal,\n })\n .then((res) => res.json())\n .then((res) => (res?.id ? res : null))\n .catch((err: Error) => (err.name === 'AbortError' ? null : Promise.reject(err)))\n}\n\nfunction useCurrentUser(projectId: string) {\n const [data, setUser] = useState<CurrentUser | null>()\n const [error, setError] = useState<Error>()\n\n useEffect(() => {\n const aborter = getAborter()\n getCurrentUser(projectId, aborter).then(setUser).catch(setError)\n return () => aborter.abort()\n }, [projectId])\n\n return {data, error, loading: data !== null || !error}\n}\n","import {useState} from 'react'\nimport {GroqStore, Subscription} from '@sanity/groq-store'\nimport {useDeepCompareEffectNoCheck as useDeepCompareEffect} from 'use-deep-compare-effect'\nimport {ProjectConfig} from './types'\nimport {getCurrentUser} from './currentUser'\nimport {getAborter} from './aborter'\n\nconst EMPTY_PARAMS = {}\n\ninterface SubscriptionOptions<R = any> {\n enabled?: boolean\n params?: Record<string, unknown>\n initialData?: R\n}\n\nexport function createPreviewSubscriptionHook({\n projectId,\n dataset,\n documentLimit = 3000,\n}: ProjectConfig & {documentLimit?: number}) {\n // Only construct/setup the store when `getStore()` is called\n let store: Promise<GroqStore>\n\n return function usePreviewSubscription<R = any>(\n query: string,\n options: SubscriptionOptions<R> = {}\n ) {\n const {params = EMPTY_PARAMS, initialData, enabled} = options\n return useQuerySubscription<R>({\n getStore,\n projectId,\n query,\n params,\n initialData: initialData as any,\n enabled: enabled ? typeof window !== 'undefined' : false,\n })\n }\n\n function getStore() {\n if (!store) {\n store = import('@sanity/groq-store').then(({groqStore}) =>\n groqStore({\n projectId,\n dataset,\n documentLimit,\n listen: true,\n overlayDrafts: true,\n subscriptionThrottleMs: 10,\n })\n )\n }\n return store\n }\n}\n\nfunction useQuerySubscription<R = any>(options: {\n getStore: () => Promise<GroqStore>\n projectId: string\n query: string\n params: Record<string, unknown>\n initialData: R\n enabled: boolean\n}) {\n const {getStore, projectId, query, params, initialData, enabled = false} = options\n const [error, setError] = useState<Error>()\n const [loading, setLoading] = useState(false)\n const [data, setData] = useState<R>()\n\n // Use \"deep\" dependency comparison because params are often not _referentially_ equal,\n // but contains the same shallow properties, eg `{\"slug\": \"some-slug\"}`\n useDeepCompareEffect(() => {\n if (!enabled) {\n return () => {\n /* intentional noop */\n }\n }\n\n setLoading(true)\n\n const aborter = getAborter()\n let subscription: Subscription | undefined\n getCurrentUser(projectId, aborter)\n .then((user) => {\n if (user) {\n return\n }\n\n // eslint-disable-next-line no-console\n console.warn('Not authenticated - preview not available')\n throw new Error('Not authenticated - preview not available')\n })\n .then(getStore)\n .then((store) => {\n subscription = store.subscribe(query, params, (err, result) => {\n if (err) {\n setError(err)\n } else {\n setData(result)\n }\n })\n })\n .catch(setError)\n .finally(() => setLoading(false))\n\n return () => {\n if (subscription) {\n subscription.unsubscribe()\n }\n\n aborter.abort()\n }\n }, [getStore, query, params, enabled])\n\n return {\n data: typeof data === 'undefined' ? initialData : data,\n loading,\n error,\n }\n}\n","import sanityClient from '@sanity/client'\nimport {ClientConfig} from './types'\n\nexport function createClient(config: ClientConfig) {\n return sanityClient(config)\n}\n","import getImageUrlBuilder from '@sanity/image-url'\nimport {ProjectConfig} from './types'\n\nexport function createImageUrlBuilder({projectId, dataset}: ProjectConfig) {\n return getImageUrlBuilder({projectId, dataset})\n}\n","import React from 'react'\nimport SanityPortableText, {\n PortableTextProps,\n PortableTextSerializers,\n} from '@sanity/block-content-to-react'\nimport {ProjectConfig} from './types'\n\nexport function createPortableTextComponent({\n projectId,\n dataset,\n serializers,\n}: ProjectConfig & {serializers?: PortableTextSerializers}) {\n return function PortableText(props: PortableTextProps) {\n return (\n <SanityPortableText\n projectId={projectId}\n dataset={dataset}\n serializers={serializers}\n {...props}\n />\n )\n }\n}\n"],"names":["getAborter","AbortController","signal","undefined","abort","noop","getCurrentUser","projectId","fetch","credentials","then","res","json","id","catch","err","name","Promise","reject","EMPTY_PARAMS","config","sanityClient","useState","data","setUser","error","setError","useEffect","aborter","loading","useCurrentUser","getImageUrlBuilder","dataset","serializers","props","React","SanityPortableText","store","documentLimit","query","options","params","getStore","initialData","enabled","setLoading","setData","useDeepCompareEffect","subscription","user","console","warn","Error","subscribe","result","finally","unsubscribe","useQuerySubscription","window","groqStore","listen","overlayDrafts","subscriptionThrottleMs"],"mappings":"2VAKgBA,UACoB,oBAApBC,gBACV,CAACC,YAAQC,EAAWC,MAAOC,GAC3B,IAAIJ,gBAGV,SAASI,cCHOC,EAAeC,EAAmBH,UACzCI,iBAAiBD,+BAAuC,CAC7DE,YAAa,UACbP,aAAQE,SAAAA,EAAOF,SAEdQ,MAAK,SAACC,UAAQA,EAAIC,UAClBF,MAAK,SAACC,gBAASA,GAAAA,EAAKE,GAAKF,EAAM,QAC/BG,OAAM,SAACC,SAA6B,eAAbA,EAAIC,KAAwB,KAAOC,QAAQC,OAAOH,MCR9E,IAAMI,EAAe,gDCJQC,UACpBC,EAAaD,kDFAiBb,IAAAA,iBAC9B,kBAaT,SAAwBA,SACEe,aAAjBC,OAAMC,SACaF,aAAnBG,OAAOC,cAEdC,aAAU,eACFC,EAAU5B,WAChBM,EAAeC,EAAWqB,GAASlB,KAAKc,GAASV,MAAMY,GAChD,kBAAME,EAAQxB,WACpB,CAACG,IAEG,CAACgB,KAAAA,EAAME,MAAAA,EAAOI,QAAkB,OAATN,IAAkBE,GAvBnCK,CAAevB,sDGDrBwB,EAAmB,CAACxB,YADUA,UACCyB,UADUA,+DCKhDzB,IAAAA,UACAyB,IAAAA,QACAC,IAAAA,mBAEO,SAAsBC,UAEzBC,gBAACC,iBACC7B,UAAWA,EACXyB,QAASA,EACTC,YAAaA,GACTC,4DHGNG,EALJ9B,IAAAA,UACAyB,IAAAA,YACAM,cAAAA,aAAgB,aAKT,SACLC,EACAC,YAAAA,IAAAA,EAAkC,UAEoBA,EAA/CC,cA4BX,SAAuCD,OAQ9BE,EAAoEF,EAApEE,SAAUnC,EAA0DiC,EAA1DjC,UAAWgC,EAA+CC,EAA/CD,MAAOE,EAAwCD,EAAxCC,OAAQE,EAAgCH,EAAhCG,cAAgCH,EAAnBI,QAAAA,kBAC9BtB,aAAnBG,OAAOC,SACgBJ,YAAS,GAAhCO,OAASgB,SACQvB,aAAjBC,OAAMuB,cAIbC,+BAAqB,eACdH,SACI,aAKTC,GAAW,OAGPG,EADEpB,EAAU5B,WAEhBM,EAAeC,EAAWqB,GACvBlB,MAAK,SAACuC,OACDA,QAKJC,QAAQC,KAAK,6CACP,IAAIC,MAAM,gDAEjB1C,KAAKgC,GACLhC,MAAK,SAAC2B,GACLW,EAAeX,EAAMgB,UAAUd,EAAOE,GAAQ,SAAC1B,EAAKuC,GAC9CvC,EACFW,EAASX,GAET+B,EAAQQ,SAIbxC,MAAMY,GACN6B,SAAQ,kBAAMV,GAAW,MAErB,WACDG,GACFA,EAAaQ,cAGf5B,EAAQxB,WAET,CAACsC,EAAUH,EAAOE,EAAQG,IAEtB,CACLrB,UAAsB,IAATA,EAAuBoB,EAAcpB,EAClDM,QAAAA,EACAJ,MAAAA,GAxFOgC,CAAwB,CAC7Bf,SAAAA,EACAnC,UAAAA,EACAgC,MAAAA,EACAE,kBALctB,IAMdwB,YANoDH,EAAxBG,YAO5BC,UAPoDJ,EAAXI,SAOJ,oBAAXc,mBAIrBhB,WACFL,IACHA,EAAQ,8QAAO,2BAAsB3B,MAAK,mBACxCiD,IAD0CA,WAChC,CACRpD,UAAAA,EACAyB,QAAAA,EACAM,cAAAA,EACAsB,QAAQ,EACRC,eAAe,EACfC,uBAAwB,SAIvBzB"}
1
+ {"version":3,"file":"next-sanity.cjs.production.min.js","sources":["../src/aborter.ts","../src/currentUser.ts","../src/useSubscription.ts","../src/client.ts"],"sourcesContent":["export interface Aborter {\n abort(): void\n signal: AbortSignal\n}\n\nclass MockAbortController {\n _signal = {aborted: false}\n get signal() {\n return this._signal as AbortSignal\n }\n abort() {\n this._signal.aborted = true\n }\n}\n\nexport function getAborter(): Aborter {\n return typeof AbortController === 'undefined'\n ? new MockAbortController()\n : new AbortController()\n}\n","import {useEffect, useState} from 'react'\nimport {CurrentUser} from './types'\nimport {getAborter, Aborter} from './aborter'\n\nexport function createCurrentUserHook({projectId}: {projectId: string; dataset?: string}) {\n return () => useCurrentUser(projectId)\n}\n\nexport function getCurrentUser(projectId: string, abort: Aborter): Promise<CurrentUser | null> {\n return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {\n credentials: 'include',\n signal: abort.signal,\n })\n .then((res) => res.json())\n .then((res) => (res?.id ? res : null))\n}\n\nfunction useCurrentUser(projectId: string) {\n const [data, setUser] = useState<CurrentUser | null>()\n const [error, setError] = useState<Error>()\n\n useEffect(() => {\n const aborter = getAborter()\n getCurrentUser(projectId, aborter)\n .then(setUser)\n .catch((err: Error) => err.name !== 'AbortError' && setError(err))\n\n return () => {\n aborter.abort()\n }\n }, [projectId])\n\n return {data, error, loading: data !== null || !error}\n}\n","import {useState, useEffect, useMemo} from 'react'\nimport {GroqStore, Subscription} from '@sanity/groq-store'\nimport {ProjectConfig} from './types'\nimport {getCurrentUser} from './currentUser'\nimport {getAborter, Aborter} from './aborter'\n\nconst EMPTY_PARAMS = {}\n\ntype Params = Record<string, unknown>\ninterface SubscriptionOptions<R = any> {\n enabled?: boolean\n params?: Params\n initialData?: R\n}\n\nexport function createPreviewSubscriptionHook({\n projectId,\n dataset,\n documentLimit = 3000,\n}: ProjectConfig & {documentLimit?: number}) {\n // Only construct/setup the store when `getStore()` is called\n let store: Promise<GroqStore>\n\n return function usePreviewSubscription<R = any>(\n query: string,\n options: SubscriptionOptions<R> = {}\n ) {\n const {params = EMPTY_PARAMS, initialData, enabled} = options\n return useQuerySubscription<R>({\n getStore,\n projectId,\n query,\n params,\n initialData: initialData as any,\n enabled: enabled ? typeof window !== 'undefined' : false,\n })\n }\n\n function getStore(abort: Aborter) {\n if (!store) {\n store = import('@sanity/groq-store').then(({groqStore}) => {\n // Skip creating the groq store if we've been unmounted to save memory and reduce gc pressure\n if (abort.signal.aborted) {\n const error = new Error('Cancelling groq store creation')\n // This ensures we can skip it in the catch block same way\n error.name = 'AbortError'\n return Promise.reject(error)\n }\n\n return groqStore({\n projectId,\n dataset,\n documentLimit,\n listen: true,\n overlayDrafts: true,\n subscriptionThrottleMs: 10,\n })\n })\n }\n return store\n }\n}\n\nfunction useQuerySubscription<R = any>(options: {\n getStore: (abort: Aborter) => Promise<GroqStore>\n projectId: string\n query: string\n params: Params\n initialData: R\n enabled: boolean\n}) {\n const {getStore, projectId, query, initialData, enabled = false} = options\n const [error, setError] = useState<Error>()\n const [loading, setLoading] = useState(false)\n const [data, setData] = useState<R>()\n const params = useParams(options.params)\n\n // Use \"deep\" dependency comparison because params are often not _referentially_ equal,\n // but contains the same shallow properties, eg `{\"slug\": \"some-slug\"}`\n useEffect(() => {\n if (!enabled) {\n return\n }\n\n setLoading(true)\n\n const aborter = getAborter()\n let subscription: Subscription | undefined\n getCurrentUser(projectId, aborter)\n .then((user) => {\n if (user) {\n return\n }\n\n // eslint-disable-next-line no-console\n console.warn('Not authenticated - preview not available')\n throw new Error('Not authenticated - preview not available')\n })\n .then(() => getStore(aborter))\n .then((store) => {\n subscription = store.subscribe(query, params, (err, result) => {\n if (err) {\n setError(err)\n } else {\n setData(result)\n }\n })\n })\n .catch((err: Error) => (err.name === 'AbortError' ? null : setError(err)))\n .finally(() => setLoading(false))\n\n // eslint-disable-next-line consistent-return\n return () => {\n if (subscription) {\n subscription.unsubscribe()\n }\n\n aborter.abort()\n }\n }, [getStore, query, params, enabled])\n\n return {\n data: typeof data === 'undefined' ? initialData : data,\n loading,\n error,\n }\n}\n\n// Return params that are stable with deep equal as long as the key order is the same\nfunction useParams(params: Params): Params {\n const stringifiedParams = useMemo(() => JSON.stringify(params), [params])\n return useMemo(() => JSON.parse(stringifiedParams), [stringifiedParams])\n}\n","import sanityClient from '@sanity/client'\nimport {ClientConfig} from './types'\n\nexport function createClient(config: ClientConfig) {\n return sanityClient(config)\n}\n"],"names":["MockAbortController","aborted","abort","_signal","this","getAborter","AbortController","getCurrentUser","projectId","fetch","credentials","signal","then","res","json","id","EMPTY_PARAMS","config","sanityClient","useState","data","setUser","error","setError","useEffect","aborter","catch","err","name","loading","useCurrentUser","store","dataset","documentLimit","query","options","params","getStore","initialData","enabled","setLoading","setData","stringifiedParams","useMemo","JSON","stringify","parse","useParams","subscription","user","console","warn","Error","subscribe","result","finally","unsubscribe","useQuerySubscription","window","groqStore","Promise","reject","listen","overlayDrafts","subscriptionThrottleMs"],"mappings":"qNAKMA,uCACM,CAACC,SAAS,8BAIpBC,MAAA,gBACOC,QAAQF,SAAU,6BAJzB,kBACSG,KAAKD,yPAOhB,SAAgBE,UACoB,oBAApBC,gBACV,IAAIN,EACJ,IAAIM,yBCVMC,EAAeC,EAAmBN,UACzCO,iBAAiBD,+BAAuC,CAC7DE,YAAa,UACbC,OAAQT,EAAMS,SAEbC,MAAK,SAACC,UAAQA,EAAIC,UAClBF,MAAK,SAACC,gBAASA,GAAAA,EAAKE,GAAKF,EAAM,QCRpC,IAAMG,EAAe,gDCHQC,UACpBC,EAAaD,kDFAiBT,IAAAA,iBAC9B,kBAYT,SAAwBA,SACEW,aAAjBC,OAAMC,SACaF,aAAnBG,OAAOC,cAEdC,aAAU,eACFC,EAAUpB,WAChBE,EAAeC,EAAWiB,GACvBb,KAAKS,GACLK,OAAM,SAACC,SAA4B,eAAbA,EAAIC,MAAyBL,EAASI,MAExD,WACLF,EAAQvB,WAET,CAACM,IAEG,CAACY,KAAAA,EAAME,MAAAA,EAAOO,QAAkB,OAATT,IAAkBE,GA3BnCQ,CAAetB,2DCgBxBuB,EALJvB,IAAAA,UACAwB,IAAAA,YACAC,cAAAA,aAAgB,aAKT,SACLC,EACAC,YAAAA,IAAAA,EAAkC,UAEoBA,EAA/CC,cAoCX,SAAuCD,OAQ9BE,EAA4DF,EAA5DE,SAAU7B,EAAkD2B,EAAlD3B,UAAW0B,EAAuCC,EAAvCD,MAAOI,EAAgCH,EAAhCG,cAAgCH,EAAnBI,QAAAA,kBACtBpB,aAAnBG,OAAOC,SACgBJ,YAAS,GAAhCU,OAASW,SACQrB,aAAjBC,OAAMqB,OACPL,EAsDR,SAAmBA,OACXM,EAAoBC,WAAQ,kBAAMC,KAAKC,UAAUT,KAAS,CAACA,WAC1DO,WAAQ,kBAAMC,KAAKE,MAAMJ,KAAoB,CAACA,IAxDtCK,CAAUZ,EAAQC,eAIjCZ,aAAU,cACHe,GAILC,GAAW,OAGPQ,EADEvB,EAAUpB,WAEhBE,EAAeC,EAAWiB,GACvBb,MAAK,SAACqC,OACDA,QAKJC,QAAQC,KAAK,6CACP,IAAIC,MAAM,gDAEjBxC,MAAK,kBAAMyB,EAASZ,MACpBb,MAAK,SAACmB,GACLiB,EAAejB,EAAMsB,UAAUnB,EAAOE,GAAQ,SAACT,EAAK2B,GAC9C3B,EACFJ,EAASI,GAETc,EAAQa,SAIb5B,OAAM,SAACC,SAA6B,eAAbA,EAAIC,KAAwB,KAAOL,EAASI,MACnE4B,SAAQ,kBAAMf,GAAW,MAGrB,WACDQ,GACFA,EAAaQ,cAGf/B,EAAQvB,YAET,CAACmC,EAAUH,EAAOE,EAAQG,IAEtB,CACLnB,UAAsB,IAATA,EAAuBkB,EAAclB,EAClDS,QAAAA,EACAP,MAAAA,GAhGOmC,CAAwB,CAC7BpB,SAAAA,EACA7B,UAAAA,EACA0B,MAAAA,EACAE,kBALcpB,IAMdsB,YANoDH,EAAxBG,YAO5BC,UAPoDJ,EAAXI,SAOJ,oBAAXmB,mBAIrBrB,EAASnC,UACX6B,IACHA,EAAQ,8QAAO,2BAAsBnB,MAAK,gBAAE+C,IAAAA,aAEtCzD,EAAMS,OAAOV,QAAS,KAClBqB,EAAQ,IAAI8B,MAAM,yCAExB9B,EAAMM,KAAO,aACNgC,QAAQC,OAAOvC,UAGjBqC,EAAU,CACfnD,UAAAA,EACAwB,QAAAA,EACAC,cAAAA,EACA6B,QAAQ,EACRC,eAAe,EACfC,uBAAwB,SAIvBjC"}
@@ -1,31 +1,55 @@
1
1
  import sanityClient from '@sanity/client';
2
- import getImageUrlBuilder from '@sanity/image-url';
3
- import React, { useState, useEffect } from 'react';
4
- import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect';
5
- import SanityPortableText from '@sanity/block-content-to-react';
2
+ import { useState, useEffect, useMemo } from 'react';
6
3
  export { default as groq } from 'groq';
7
4
 
8
5
  function createClient(config) {
9
6
  return sanityClient(config);
10
7
  }
11
8
 
12
- function createImageUrlBuilder(_ref) {
13
- var projectId = _ref.projectId,
14
- dataset = _ref.dataset;
15
- return getImageUrlBuilder({
16
- projectId: projectId,
17
- dataset: dataset
18
- });
9
+ function _defineProperties(target, props) {
10
+ for (var i = 0; i < props.length; i++) {
11
+ var descriptor = props[i];
12
+ descriptor.enumerable = descriptor.enumerable || false;
13
+ descriptor.configurable = true;
14
+ if ("value" in descriptor) descriptor.writable = true;
15
+ Object.defineProperty(target, descriptor.key, descriptor);
16
+ }
19
17
  }
20
18
 
21
- function getAborter() {
22
- return typeof AbortController === 'undefined' ? {
23
- signal: undefined,
24
- abort: noop
25
- } : new AbortController();
19
+ function _createClass(Constructor, protoProps, staticProps) {
20
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
21
+ if (staticProps) _defineProperties(Constructor, staticProps);
22
+ Object.defineProperty(Constructor, "prototype", {
23
+ writable: false
24
+ });
25
+ return Constructor;
26
26
  }
27
27
 
28
- function noop() {// intentional noop
28
+ var MockAbortController = /*#__PURE__*/function () {
29
+ function MockAbortController() {
30
+ this._signal = {
31
+ aborted: false
32
+ };
33
+ }
34
+
35
+ var _proto = MockAbortController.prototype;
36
+
37
+ _proto.abort = function abort() {
38
+ this._signal.aborted = true;
39
+ };
40
+
41
+ _createClass(MockAbortController, [{
42
+ key: "signal",
43
+ get: function get() {
44
+ return this._signal;
45
+ }
46
+ }]);
47
+
48
+ return MockAbortController;
49
+ }();
50
+
51
+ function getAborter() {
52
+ return typeof AbortController === 'undefined' ? new MockAbortController() : new AbortController();
29
53
  }
30
54
 
31
55
  function createCurrentUserHook(_ref) {
@@ -37,13 +61,11 @@ function createCurrentUserHook(_ref) {
37
61
  function getCurrentUser(projectId, abort) {
38
62
  return fetch("https://" + projectId + ".api.sanity.io/v1/users/me", {
39
63
  credentials: 'include',
40
- signal: abort == null ? void 0 : abort.signal
64
+ signal: abort.signal
41
65
  }).then(function (res) {
42
66
  return res.json();
43
67
  }).then(function (res) {
44
68
  return res != null && res.id ? res : null;
45
- }).catch(function (err) {
46
- return err.name === 'AbortError' ? null : Promise.reject(err);
47
69
  });
48
70
  }
49
71
 
@@ -58,9 +80,11 @@ function useCurrentUser(projectId) {
58
80
 
59
81
  useEffect(function () {
60
82
  var aborter = getAborter();
61
- getCurrentUser(projectId, aborter).then(setUser).catch(setError);
83
+ getCurrentUser(projectId, aborter).then(setUser).catch(function (err) {
84
+ return err.name !== 'AbortError' && setError(err);
85
+ });
62
86
  return function () {
63
- return aborter.abort();
87
+ aborter.abort();
64
88
  };
65
89
  }, [projectId]);
66
90
  return {
@@ -98,10 +122,19 @@ function createPreviewSubscriptionHook(_ref) {
98
122
  });
99
123
  };
100
124
 
101
- function getStore() {
125
+ function getStore(abort) {
102
126
  if (!store) {
103
127
  store = import('@sanity/groq-store').then(function (_ref2) {
104
128
  var groqStore = _ref2.groqStore;
129
+
130
+ // Skip creating the groq store if we've been unmounted to save memory and reduce gc pressure
131
+ if (abort.signal.aborted) {
132
+ var error = new Error('Cancelling groq store creation'); // This ensures we can skip it in the catch block same way
133
+
134
+ error.name = 'AbortError';
135
+ return Promise.reject(error);
136
+ }
137
+
105
138
  return groqStore({
106
139
  projectId: projectId,
107
140
  dataset: dataset,
@@ -121,7 +154,6 @@ function useQuerySubscription(options) {
121
154
  var getStore = options.getStore,
122
155
  projectId = options.projectId,
123
156
  query = options.query,
124
- params = options.params,
125
157
  initialData = options.initialData,
126
158
  _options$enabled = options.enabled,
127
159
  enabled = _options$enabled === void 0 ? false : _options$enabled;
@@ -136,15 +168,14 @@ function useQuerySubscription(options) {
136
168
 
137
169
  var _useState3 = useState(),
138
170
  data = _useState3[0],
139
- setData = _useState3[1]; // Use "deep" dependency comparison because params are often not _referentially_ equal,
140
- // but contains the same shallow properties, eg `{"slug": "some-slug"}`
171
+ setData = _useState3[1];
141
172
 
173
+ var params = useParams(options.params); // Use "deep" dependency comparison because params are often not _referentially_ equal,
174
+ // but contains the same shallow properties, eg `{"slug": "some-slug"}`
142
175
 
143
- useDeepCompareEffectNoCheck(function () {
176
+ useEffect(function () {
144
177
  if (!enabled) {
145
- return function () {
146
- /* intentional noop */
147
- };
178
+ return;
148
179
  }
149
180
 
150
181
  setLoading(true);
@@ -158,7 +189,9 @@ function useQuerySubscription(options) {
158
189
 
159
190
  console.warn('Not authenticated - preview not available');
160
191
  throw new Error('Not authenticated - preview not available');
161
- }).then(getStore).then(function (store) {
192
+ }).then(function () {
193
+ return getStore(aborter);
194
+ }).then(function (store) {
162
195
  subscription = store.subscribe(query, params, function (err, result) {
163
196
  if (err) {
164
197
  setError(err);
@@ -166,9 +199,12 @@ function useQuerySubscription(options) {
166
199
  setData(result);
167
200
  }
168
201
  });
169
- }).catch(setError).finally(function () {
202
+ }).catch(function (err) {
203
+ return err.name === 'AbortError' ? null : setError(err);
204
+ }).finally(function () {
170
205
  return setLoading(false);
171
- });
206
+ }); // eslint-disable-next-line consistent-return
207
+
172
208
  return function () {
173
209
  if (subscription) {
174
210
  subscription.unsubscribe();
@@ -182,20 +218,17 @@ function useQuerySubscription(options) {
182
218
  loading: loading,
183
219
  error: error
184
220
  };
185
- }
221
+ } // Return params that are stable with deep equal as long as the key order is the same
186
222
 
187
- function createPortableTextComponent(_ref) {
188
- var projectId = _ref.projectId,
189
- dataset = _ref.dataset,
190
- serializers = _ref.serializers;
191
- return function PortableText(props) {
192
- return React.createElement(SanityPortableText, Object.assign({
193
- projectId: projectId,
194
- dataset: dataset,
195
- serializers: serializers
196
- }, props));
197
- };
223
+
224
+ function useParams(params) {
225
+ var stringifiedParams = useMemo(function () {
226
+ return JSON.stringify(params);
227
+ }, [params]);
228
+ return useMemo(function () {
229
+ return JSON.parse(stringifiedParams);
230
+ }, [stringifiedParams]);
198
231
  }
199
232
 
200
- export { createClient, createCurrentUserHook, createImageUrlBuilder, createPortableTextComponent, createPreviewSubscriptionHook };
233
+ export { createClient, createCurrentUserHook, createPreviewSubscriptionHook };
201
234
  //# sourceMappingURL=next-sanity.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"next-sanity.esm.js","sources":["../src/client.ts","../src/imageUrlBuilder.ts","../src/aborter.ts","../src/currentUser.ts","../src/useSubscription.ts","../src/portableText.tsx"],"sourcesContent":["import sanityClient from '@sanity/client'\nimport {ClientConfig} from './types'\n\nexport function createClient(config: ClientConfig) {\n return sanityClient(config)\n}\n","import getImageUrlBuilder from '@sanity/image-url'\nimport {ProjectConfig} from './types'\n\nexport function createImageUrlBuilder({projectId, dataset}: ProjectConfig) {\n return getImageUrlBuilder({projectId, dataset})\n}\n","export interface Aborter {\n abort(): void\n signal?: AbortSignal\n}\n\nexport function getAborter(): Aborter {\n return typeof AbortController === 'undefined'\n ? {signal: undefined, abort: noop}\n : new AbortController()\n}\n\nfunction noop() {\n // intentional noop\n}\n","import {useEffect, useState} from 'react'\nimport {CurrentUser} from './types'\nimport {getAborter, Aborter} from './aborter'\n\nexport function createCurrentUserHook({projectId}: {projectId: string; dataset?: string}) {\n return () => useCurrentUser(projectId)\n}\n\nexport function getCurrentUser(projectId: string, abort?: Aborter): Promise<CurrentUser | null> {\n return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {\n credentials: 'include',\n signal: abort?.signal,\n })\n .then((res) => res.json())\n .then((res) => (res?.id ? res : null))\n .catch((err: Error) => (err.name === 'AbortError' ? null : Promise.reject(err)))\n}\n\nfunction useCurrentUser(projectId: string) {\n const [data, setUser] = useState<CurrentUser | null>()\n const [error, setError] = useState<Error>()\n\n useEffect(() => {\n const aborter = getAborter()\n getCurrentUser(projectId, aborter).then(setUser).catch(setError)\n return () => aborter.abort()\n }, [projectId])\n\n return {data, error, loading: data !== null || !error}\n}\n","import {useState} from 'react'\nimport {GroqStore, Subscription} from '@sanity/groq-store'\nimport {useDeepCompareEffectNoCheck as useDeepCompareEffect} from 'use-deep-compare-effect'\nimport {ProjectConfig} from './types'\nimport {getCurrentUser} from './currentUser'\nimport {getAborter} from './aborter'\n\nconst EMPTY_PARAMS = {}\n\ninterface SubscriptionOptions<R = any> {\n enabled?: boolean\n params?: Record<string, unknown>\n initialData?: R\n}\n\nexport function createPreviewSubscriptionHook({\n projectId,\n dataset,\n documentLimit = 3000,\n}: ProjectConfig & {documentLimit?: number}) {\n // Only construct/setup the store when `getStore()` is called\n let store: Promise<GroqStore>\n\n return function usePreviewSubscription<R = any>(\n query: string,\n options: SubscriptionOptions<R> = {}\n ) {\n const {params = EMPTY_PARAMS, initialData, enabled} = options\n return useQuerySubscription<R>({\n getStore,\n projectId,\n query,\n params,\n initialData: initialData as any,\n enabled: enabled ? typeof window !== 'undefined' : false,\n })\n }\n\n function getStore() {\n if (!store) {\n store = import('@sanity/groq-store').then(({groqStore}) =>\n groqStore({\n projectId,\n dataset,\n documentLimit,\n listen: true,\n overlayDrafts: true,\n subscriptionThrottleMs: 10,\n })\n )\n }\n return store\n }\n}\n\nfunction useQuerySubscription<R = any>(options: {\n getStore: () => Promise<GroqStore>\n projectId: string\n query: string\n params: Record<string, unknown>\n initialData: R\n enabled: boolean\n}) {\n const {getStore, projectId, query, params, initialData, enabled = false} = options\n const [error, setError] = useState<Error>()\n const [loading, setLoading] = useState(false)\n const [data, setData] = useState<R>()\n\n // Use \"deep\" dependency comparison because params are often not _referentially_ equal,\n // but contains the same shallow properties, eg `{\"slug\": \"some-slug\"}`\n useDeepCompareEffect(() => {\n if (!enabled) {\n return () => {\n /* intentional noop */\n }\n }\n\n setLoading(true)\n\n const aborter = getAborter()\n let subscription: Subscription | undefined\n getCurrentUser(projectId, aborter)\n .then((user) => {\n if (user) {\n return\n }\n\n // eslint-disable-next-line no-console\n console.warn('Not authenticated - preview not available')\n throw new Error('Not authenticated - preview not available')\n })\n .then(getStore)\n .then((store) => {\n subscription = store.subscribe(query, params, (err, result) => {\n if (err) {\n setError(err)\n } else {\n setData(result)\n }\n })\n })\n .catch(setError)\n .finally(() => setLoading(false))\n\n return () => {\n if (subscription) {\n subscription.unsubscribe()\n }\n\n aborter.abort()\n }\n }, [getStore, query, params, enabled])\n\n return {\n data: typeof data === 'undefined' ? initialData : data,\n loading,\n error,\n }\n}\n","import React from 'react'\nimport SanityPortableText, {\n PortableTextProps,\n PortableTextSerializers,\n} from '@sanity/block-content-to-react'\nimport {ProjectConfig} from './types'\n\nexport function createPortableTextComponent({\n projectId,\n dataset,\n serializers,\n}: ProjectConfig & {serializers?: PortableTextSerializers}) {\n return function PortableText(props: PortableTextProps) {\n return (\n <SanityPortableText\n projectId={projectId}\n dataset={dataset}\n serializers={serializers}\n {...props}\n />\n )\n }\n}\n"],"names":["createClient","config","sanityClient","createImageUrlBuilder","projectId","dataset","getImageUrlBuilder","getAborter","AbortController","signal","undefined","abort","noop","createCurrentUserHook","useCurrentUser","getCurrentUser","fetch","credentials","then","res","json","id","catch","err","name","Promise","reject","useState","data","setUser","error","setError","useEffect","aborter","loading","EMPTY_PARAMS","createPreviewSubscriptionHook","documentLimit","store","usePreviewSubscription","query","options","params","initialData","enabled","useQuerySubscription","getStore","window","groqStore","listen","overlayDrafts","subscriptionThrottleMs","setLoading","setData","useDeepCompareEffect","subscription","user","console","warn","Error","subscribe","result","finally","unsubscribe","createPortableTextComponent","serializers","PortableText","props","React","SanityPortableText"],"mappings":"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"}
1
+ {"version":3,"file":"next-sanity.esm.js","sources":["../src/client.ts","../src/aborter.ts","../src/currentUser.ts","../src/useSubscription.ts"],"sourcesContent":["import sanityClient from '@sanity/client'\nimport {ClientConfig} from './types'\n\nexport function createClient(config: ClientConfig) {\n return sanityClient(config)\n}\n","export interface Aborter {\n abort(): void\n signal: AbortSignal\n}\n\nclass MockAbortController {\n _signal = {aborted: false}\n get signal() {\n return this._signal as AbortSignal\n }\n abort() {\n this._signal.aborted = true\n }\n}\n\nexport function getAborter(): Aborter {\n return typeof AbortController === 'undefined'\n ? new MockAbortController()\n : new AbortController()\n}\n","import {useEffect, useState} from 'react'\nimport {CurrentUser} from './types'\nimport {getAborter, Aborter} from './aborter'\n\nexport function createCurrentUserHook({projectId}: {projectId: string; dataset?: string}) {\n return () => useCurrentUser(projectId)\n}\n\nexport function getCurrentUser(projectId: string, abort: Aborter): Promise<CurrentUser | null> {\n return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {\n credentials: 'include',\n signal: abort.signal,\n })\n .then((res) => res.json())\n .then((res) => (res?.id ? res : null))\n}\n\nfunction useCurrentUser(projectId: string) {\n const [data, setUser] = useState<CurrentUser | null>()\n const [error, setError] = useState<Error>()\n\n useEffect(() => {\n const aborter = getAborter()\n getCurrentUser(projectId, aborter)\n .then(setUser)\n .catch((err: Error) => err.name !== 'AbortError' && setError(err))\n\n return () => {\n aborter.abort()\n }\n }, [projectId])\n\n return {data, error, loading: data !== null || !error}\n}\n","import {useState, useEffect, useMemo} from 'react'\nimport {GroqStore, Subscription} from '@sanity/groq-store'\nimport {ProjectConfig} from './types'\nimport {getCurrentUser} from './currentUser'\nimport {getAborter, Aborter} from './aborter'\n\nconst EMPTY_PARAMS = {}\n\ntype Params = Record<string, unknown>\ninterface SubscriptionOptions<R = any> {\n enabled?: boolean\n params?: Params\n initialData?: R\n}\n\nexport function createPreviewSubscriptionHook({\n projectId,\n dataset,\n documentLimit = 3000,\n}: ProjectConfig & {documentLimit?: number}) {\n // Only construct/setup the store when `getStore()` is called\n let store: Promise<GroqStore>\n\n return function usePreviewSubscription<R = any>(\n query: string,\n options: SubscriptionOptions<R> = {}\n ) {\n const {params = EMPTY_PARAMS, initialData, enabled} = options\n return useQuerySubscription<R>({\n getStore,\n projectId,\n query,\n params,\n initialData: initialData as any,\n enabled: enabled ? typeof window !== 'undefined' : false,\n })\n }\n\n function getStore(abort: Aborter) {\n if (!store) {\n store = import('@sanity/groq-store').then(({groqStore}) => {\n // Skip creating the groq store if we've been unmounted to save memory and reduce gc pressure\n if (abort.signal.aborted) {\n const error = new Error('Cancelling groq store creation')\n // This ensures we can skip it in the catch block same way\n error.name = 'AbortError'\n return Promise.reject(error)\n }\n\n return groqStore({\n projectId,\n dataset,\n documentLimit,\n listen: true,\n overlayDrafts: true,\n subscriptionThrottleMs: 10,\n })\n })\n }\n return store\n }\n}\n\nfunction useQuerySubscription<R = any>(options: {\n getStore: (abort: Aborter) => Promise<GroqStore>\n projectId: string\n query: string\n params: Params\n initialData: R\n enabled: boolean\n}) {\n const {getStore, projectId, query, initialData, enabled = false} = options\n const [error, setError] = useState<Error>()\n const [loading, setLoading] = useState(false)\n const [data, setData] = useState<R>()\n const params = useParams(options.params)\n\n // Use \"deep\" dependency comparison because params are often not _referentially_ equal,\n // but contains the same shallow properties, eg `{\"slug\": \"some-slug\"}`\n useEffect(() => {\n if (!enabled) {\n return\n }\n\n setLoading(true)\n\n const aborter = getAborter()\n let subscription: Subscription | undefined\n getCurrentUser(projectId, aborter)\n .then((user) => {\n if (user) {\n return\n }\n\n // eslint-disable-next-line no-console\n console.warn('Not authenticated - preview not available')\n throw new Error('Not authenticated - preview not available')\n })\n .then(() => getStore(aborter))\n .then((store) => {\n subscription = store.subscribe(query, params, (err, result) => {\n if (err) {\n setError(err)\n } else {\n setData(result)\n }\n })\n })\n .catch((err: Error) => (err.name === 'AbortError' ? null : setError(err)))\n .finally(() => setLoading(false))\n\n // eslint-disable-next-line consistent-return\n return () => {\n if (subscription) {\n subscription.unsubscribe()\n }\n\n aborter.abort()\n }\n }, [getStore, query, params, enabled])\n\n return {\n data: typeof data === 'undefined' ? initialData : data,\n loading,\n error,\n }\n}\n\n// Return params that are stable with deep equal as long as the key order is the same\nfunction useParams(params: Params): Params {\n const stringifiedParams = useMemo(() => JSON.stringify(params), [params])\n return useMemo(() => JSON.parse(stringifiedParams), [stringifiedParams])\n}\n"],"names":["createClient","config","sanityClient","MockAbortController","aborted","abort","_signal","getAborter","AbortController","createCurrentUserHook","projectId","useCurrentUser","getCurrentUser","fetch","credentials","signal","then","res","json","id","useState","data","setUser","error","setError","useEffect","aborter","catch","err","name","loading","EMPTY_PARAMS","createPreviewSubscriptionHook","dataset","documentLimit","store","usePreviewSubscription","query","options","params","initialData","enabled","useQuerySubscription","getStore","window","groqStore","Error","Promise","reject","listen","overlayDrafts","subscriptionThrottleMs","setLoading","setData","useParams","subscription","user","console","warn","subscribe","result","finally","unsubscribe","stringifiedParams","useMemo","JSON","stringify","parse"],"mappings":";;;;SAGgBA,aAAaC;AAC3B,SAAOC,YAAY,CAACD,MAAD,CAAnB;AACD;;;;;;;;;;;;;;;;;;;;;ICAKE;AAAN;AACE,gBAAA,GAAU;AAACC,MAAAA,OAAO,EAAE;AAAV,KAAV;AAOD;;;;SAHCC,QAAA;AACE,SAAKC,OAAL,CAAaF,OAAb,GAAuB,IAAvB;AACD;;;;SALD;AACE,aAAO,KAAKE,OAAZ;AACD;;;;;;AAMH,SAAgBC;AACd,SAAO,OAAOC,eAAP,KAA2B,WAA3B,GACH,IAAIL,mBAAJ,EADG,GAEH,IAAIK,eAAJ,EAFJ;AAGD;;SCfeC;MAAuBC,iBAAAA;AACrC,SAAO;AAAA,WAAMC,cAAc,CAACD,SAAD,CAApB;AAAA,GAAP;AACD;AAED,SAAgBE,eAAeF,WAAmBL;AAChD,SAAOQ,KAAK,cAAYH,SAAZ,iCAAmD;AAC7DI,IAAAA,WAAW,EAAE,SADgD;AAE7DC,IAAAA,MAAM,EAAEV,KAAK,CAACU;AAF+C,GAAnD,CAAL,CAIJC,IAJI,CAIC,UAACC,GAAD;AAAA,WAASA,GAAG,CAACC,IAAJ,EAAT;AAAA,GAJD,EAKJF,IALI,CAKC,UAACC,GAAD;AAAA,WAAUA,GAAG,QAAH,IAAAA,GAAG,CAAEE,EAAL,GAAUF,GAAV,GAAgB,IAA1B;AAAA,GALD,CAAP;AAMD;;AAED,SAASN,cAAT,CAAwBD,SAAxB;AACE,kBAAwBU,QAAQ,EAAhC;AAAA,MAAOC,IAAP;AAAA,MAAaC,OAAb;;AACA,mBAA0BF,QAAQ,EAAlC;AAAA,MAAOG,KAAP;AAAA,MAAcC,QAAd;;AAEAC,EAAAA,SAAS,CAAC;AACR,QAAMC,OAAO,GAAGnB,UAAU,EAA1B;AACAK,IAAAA,cAAc,CAACF,SAAD,EAAYgB,OAAZ,CAAd,CACGV,IADH,CACQM,OADR,EAEGK,KAFH,CAES,UAACC,GAAD;AAAA,aAAgBA,GAAG,CAACC,IAAJ,KAAa,YAAb,IAA6BL,QAAQ,CAACI,GAAD,CAArD;AAAA,KAFT;AAIA,WAAO;AACLF,MAAAA,OAAO,CAACrB,KAAR;AACD,KAFD;AAGD,GATQ,EASN,CAACK,SAAD,CATM,CAAT;AAWA,SAAO;AAACW,IAAAA,IAAI,EAAJA,IAAD;AAAOE,IAAAA,KAAK,EAALA,KAAP;AAAcO,IAAAA,OAAO,EAAET,IAAI,KAAK,IAAT,IAAiB,CAACE;AAAzC,GAAP;AACD;;AC3BD,IAAMQ,YAAY,GAAG,EAArB;AASA,SAAgBC;MACdtB,iBAAAA;MACAuB,eAAAA;gCACAC;MAAAA,gDAAgB;AAEhB;AACA,MAAIC,KAAJ;AAEA,SAAO,SAASC,sBAAT,CACLC,KADK,EAELC,OAFK;QAELA;AAAAA,MAAAA,UAAkC;;;AAElC,mBAAsDA,OAAtD;AAAA,mCAAOC,MAAP;AAAA,QAAOA,MAAP,gCAAgBR,YAAhB;AAAA,QAA8BS,WAA9B,YAA8BA,WAA9B;AAAA,QAA2CC,OAA3C,YAA2CA,OAA3C;AACA,WAAOC,oBAAoB,CAAI;AAC7BC,MAAAA,QAAQ,EAARA,QAD6B;AAE7BjC,MAAAA,SAAS,EAATA,SAF6B;AAG7B2B,MAAAA,KAAK,EAALA,KAH6B;AAI7BE,MAAAA,MAAM,EAANA,MAJ6B;AAK7BC,MAAAA,WAAW,EAAEA,WALgB;AAM7BC,MAAAA,OAAO,EAAEA,OAAO,GAAG,OAAOG,MAAP,KAAkB,WAArB,GAAmC;AANtB,KAAJ,CAA3B;AAQD,GAbD;;AAeA,WAASD,QAAT,CAAkBtC,KAAlB;AACE,QAAI,CAAC8B,KAAL,EAAY;AACVA,MAAAA,KAAK,GAAG,OAAO,oBAAP,EAA6BnB,IAA7B,CAAkC;YAAE6B,kBAAAA;;AAC1C;AACA,YAAIxC,KAAK,CAACU,MAAN,CAAaX,OAAjB,EAA0B;AACxB,cAAMmB,KAAK,GAAG,IAAIuB,KAAJ,CAAU,gCAAV,CAAd,CADwB;;AAGxBvB,UAAAA,KAAK,CAACM,IAAN,GAAa,YAAb;AACA,iBAAOkB,OAAO,CAACC,MAAR,CAAezB,KAAf,CAAP;AACD;;AAED,eAAOsB,SAAS,CAAC;AACfnC,UAAAA,SAAS,EAATA,SADe;AAEfuB,UAAAA,OAAO,EAAPA,OAFe;AAGfC,UAAAA,aAAa,EAAbA,aAHe;AAIfe,UAAAA,MAAM,EAAE,IAJO;AAKfC,UAAAA,aAAa,EAAE,IALA;AAMfC,UAAAA,sBAAsB,EAAE;AANT,SAAD,CAAhB;AAQD,OAjBO,CAAR;AAkBD;;AACD,WAAOhB,KAAP;AACD;AACF;;AAED,SAASO,oBAAT,CAAuCJ,OAAvC;AAQE,MAAOK,QAAP,GAAmEL,OAAnE,CAAOK,QAAP;AAAA,MAAiBjC,SAAjB,GAAmE4B,OAAnE,CAAiB5B,SAAjB;AAAA,MAA4B2B,KAA5B,GAAmEC,OAAnE,CAA4BD,KAA5B;AAAA,MAAmCG,WAAnC,GAAmEF,OAAnE,CAAmCE,WAAnC;AAAA,yBAAmEF,OAAnE,CAAgDG,OAAhD;AAAA,MAAgDA,OAAhD,iCAA0D,KAA1D;;AACA,kBAA0BrB,QAAQ,EAAlC;AAAA,MAAOG,KAAP;AAAA,MAAcC,QAAd;;AACA,mBAA8BJ,QAAQ,CAAC,KAAD,CAAtC;AAAA,MAAOU,OAAP;AAAA,MAAgBsB,UAAhB;;AACA,mBAAwBhC,QAAQ,EAAhC;AAAA,MAAOC,IAAP;AAAA,MAAagC,OAAb;;AACA,MAAMd,MAAM,GAAGe,SAAS,CAAChB,OAAO,CAACC,MAAT,CAAxB;AAGA;;AACAd,EAAAA,SAAS,CAAC;AACR,QAAI,CAACgB,OAAL,EAAc;AACZ;AACD;;AAEDW,IAAAA,UAAU,CAAC,IAAD,CAAV;AAEA,QAAM1B,OAAO,GAAGnB,UAAU,EAA1B;AACA,QAAIgD,YAAJ;AACA3C,IAAAA,cAAc,CAACF,SAAD,EAAYgB,OAAZ,CAAd,CACGV,IADH,CACQ,UAACwC,IAAD;AACJ,UAAIA,IAAJ,EAAU;AACR;AACD;;;AAGDC,MAAAA,OAAO,CAACC,IAAR,CAAa,2CAAb;AACA,YAAM,IAAIZ,KAAJ,CAAU,2CAAV,CAAN;AACD,KATH,EAUG9B,IAVH,CAUQ;AAAA,aAAM2B,QAAQ,CAACjB,OAAD,CAAd;AAAA,KAVR,EAWGV,IAXH,CAWQ,UAACmB,KAAD;AACJoB,MAAAA,YAAY,GAAGpB,KAAK,CAACwB,SAAN,CAAgBtB,KAAhB,EAAuBE,MAAvB,EAA+B,UAACX,GAAD,EAAMgC,MAAN;AAC5C,YAAIhC,GAAJ,EAAS;AACPJ,UAAAA,QAAQ,CAACI,GAAD,CAAR;AACD,SAFD,MAEO;AACLyB,UAAAA,OAAO,CAACO,MAAD,CAAP;AACD;AACF,OANc,CAAf;AAOD,KAnBH,EAoBGjC,KApBH,CAoBS,UAACC,GAAD;AAAA,aAAiBA,GAAG,CAACC,IAAJ,KAAa,YAAb,GAA4B,IAA5B,GAAmCL,QAAQ,CAACI,GAAD,CAA5D;AAAA,KApBT,EAqBGiC,OArBH,CAqBW;AAAA,aAAMT,UAAU,CAAC,KAAD,CAAhB;AAAA,KArBX;;AAwBA,WAAO;AACL,UAAIG,YAAJ,EAAkB;AAChBA,QAAAA,YAAY,CAACO,WAAb;AACD;;AAEDpC,MAAAA,OAAO,CAACrB,KAAR;AACD,KAND;AAOD,GAxCQ,EAwCN,CAACsC,QAAD,EAAWN,KAAX,EAAkBE,MAAlB,EAA0BE,OAA1B,CAxCM,CAAT;AA0CA,SAAO;AACLpB,IAAAA,IAAI,EAAE,OAAOA,IAAP,KAAgB,WAAhB,GAA8BmB,WAA9B,GAA4CnB,IAD7C;AAELS,IAAAA,OAAO,EAAPA,OAFK;AAGLP,IAAAA,KAAK,EAALA;AAHK,GAAP;AAKD;;;AAGD,SAAS+B,SAAT,CAAmBf,MAAnB;AACE,MAAMwB,iBAAiB,GAAGC,OAAO,CAAC;AAAA,WAAMC,IAAI,CAACC,SAAL,CAAe3B,MAAf,CAAN;AAAA,GAAD,EAA+B,CAACA,MAAD,CAA/B,CAAjC;AACA,SAAOyB,OAAO,CAAC;AAAA,WAAMC,IAAI,CAACE,KAAL,CAAWJ,iBAAX,CAAN;AAAA,GAAD,EAAsC,CAACA,iBAAD,CAAtC,CAAd;AACD;;;;"}
@@ -1,7 +1,8 @@
1
1
  import { ProjectConfig } from './types';
2
+ declare type Params = Record<string, unknown>;
2
3
  interface SubscriptionOptions<R = any> {
3
4
  enabled?: boolean;
4
- params?: Record<string, unknown>;
5
+ params?: Params;
5
6
  initialData?: R;
6
7
  }
7
8
  export declare function createPreviewSubscriptionHook({ projectId, dataset, documentLimit, }: ProjectConfig & {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "next-sanity",
3
3
  "description": "Sanity.io toolkit for Next.js",
4
- "version": "0.2.0",
4
+ "version": "0.5.0",
5
5
  "author": "Sanity.io <hello@sanity.io>",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
@@ -25,29 +25,29 @@
25
25
  "coverage": "tsdx test --coverage"
26
26
  },
27
27
  "dependencies": {
28
- "@sanity/block-content-to-react": "^2.0.7",
29
- "@sanity/client": "^2.8.0",
30
- "@sanity/groq-store": "^0.1.3",
31
- "@sanity/image-url": "^0.140.22",
32
- "groq": "^2.2.6",
33
- "use-deep-compare-effect": "^1.6.1"
28
+ "@sanity/client": "^3.0.6",
29
+ "@sanity/groq-store": "^0.3.0",
30
+ "groq": "^2.15.0"
34
31
  },
35
32
  "devDependencies": {
36
- "@types/jest": "^26.0.20",
37
- "@types/react": "^17.0.2",
38
- "@types/react-dom": "^17.0.1",
39
- "@typescript-eslint/eslint-plugin": "^4.15.0",
40
- "@typescript-eslint/parser": "^4.15.0",
41
- "eslint": "^7.20.0",
42
- "eslint-config-prettier": "^7.2.0",
43
- "eslint-config-sanity": "^5.0.0",
44
- "eslint-plugin-prettier": "^3.3.1",
45
- "prettier": "^2.2.1",
46
- "react": "^17.0.0",
47
- "react-dom": "^17.0.0",
33
+ "@async-fn/jest": "^1.5.3",
34
+ "@testing-library/react-hooks": "^7.0.2",
35
+ "@types/jest": "^27.0.0",
36
+ "@types/react": "^17.0.17",
37
+ "@types/react-dom": "^17.0.9",
38
+ "@typescript-eslint/eslint-plugin": "^4.29.1",
39
+ "@typescript-eslint/parser": "^4.29.1",
40
+ "eslint": "^7.32.0",
41
+ "eslint-config-prettier": "^7.0.0",
42
+ "eslint-config-react-app": "^6.0.0",
43
+ "eslint-config-sanity": "^5.1.0",
44
+ "eslint-plugin-prettier": "^3.4.0",
45
+ "prettier": "^2.3.2",
46
+ "react": ">=17.0.2",
47
+ "react-dom": "^17.0.2",
48
48
  "tsdx": "^0.14.1",
49
- "tslib": "^2.1.0",
50
- "typescript": "^3.4.0"
49
+ "tslib": "^2.3.0",
50
+ "typescript": "^4.3.5"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "react": ">=16.3.0"
@@ -74,7 +74,6 @@
74
74
  "parser": "@typescript-eslint/parser",
75
75
  "extends": [
76
76
  "plugin:@typescript-eslint/recommended",
77
- "prettier/@typescript-eslint",
78
77
  "sanity",
79
78
  "sanity/react",
80
79
  "sanity/typescript",
package/src/aborter.ts CHANGED
@@ -1,14 +1,20 @@
1
1
  export interface Aborter {
2
2
  abort(): void
3
- signal?: AbortSignal
3
+ signal: AbortSignal
4
+ }
5
+
6
+ class MockAbortController {
7
+ _signal = {aborted: false}
8
+ get signal() {
9
+ return this._signal as AbortSignal
10
+ }
11
+ abort() {
12
+ this._signal.aborted = true
13
+ }
4
14
  }
5
15
 
6
16
  export function getAborter(): Aborter {
7
17
  return typeof AbortController === 'undefined'
8
- ? {signal: undefined, abort: noop}
18
+ ? new MockAbortController()
9
19
  : new AbortController()
10
20
  }
11
-
12
- function noop() {
13
- // intentional noop
14
- }
@@ -6,14 +6,13 @@ export function createCurrentUserHook({projectId}: {projectId: string; dataset?:
6
6
  return () => useCurrentUser(projectId)
7
7
  }
8
8
 
9
- export function getCurrentUser(projectId: string, abort?: Aborter): Promise<CurrentUser | null> {
9
+ export function getCurrentUser(projectId: string, abort: Aborter): Promise<CurrentUser | null> {
10
10
  return fetch(`https://${projectId}.api.sanity.io/v1/users/me`, {
11
11
  credentials: 'include',
12
- signal: abort?.signal,
12
+ signal: abort.signal,
13
13
  })
14
14
  .then((res) => res.json())
15
15
  .then((res) => (res?.id ? res : null))
16
- .catch((err: Error) => (err.name === 'AbortError' ? null : Promise.reject(err)))
17
16
  }
18
17
 
19
18
  function useCurrentUser(projectId: string) {
@@ -22,8 +21,13 @@ function useCurrentUser(projectId: string) {
22
21
 
23
22
  useEffect(() => {
24
23
  const aborter = getAborter()
25
- getCurrentUser(projectId, aborter).then(setUser).catch(setError)
26
- return () => aborter.abort()
24
+ getCurrentUser(projectId, aborter)
25
+ .then(setUser)
26
+ .catch((err: Error) => err.name !== 'AbortError' && setError(err))
27
+
28
+ return () => {
29
+ aborter.abort()
30
+ }
27
31
  }, [projectId])
28
32
 
29
33
  return {data, error, loading: data !== null || !error}
package/src/index.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export * from './types'
2
2
  export {createClient} from './client'
3
- export {createImageUrlBuilder} from './imageUrlBuilder'
4
3
  export {createCurrentUserHook} from './currentUser'
5
4
  export {createPreviewSubscriptionHook} from './useSubscription'
6
- export {createPortableTextComponent} from './portableText'
7
5
  export {default as groq} from 'groq'
@@ -1,15 +1,15 @@
1
- import {useState} from 'react'
1
+ import {useState, useEffect, useMemo} from 'react'
2
2
  import {GroqStore, Subscription} from '@sanity/groq-store'
3
- import {useDeepCompareEffectNoCheck as useDeepCompareEffect} from 'use-deep-compare-effect'
4
3
  import {ProjectConfig} from './types'
5
4
  import {getCurrentUser} from './currentUser'
6
- import {getAborter} from './aborter'
5
+ import {getAborter, Aborter} from './aborter'
7
6
 
8
7
  const EMPTY_PARAMS = {}
9
8
 
9
+ type Params = Record<string, unknown>
10
10
  interface SubscriptionOptions<R = any> {
11
11
  enabled?: boolean
12
- params?: Record<string, unknown>
12
+ params?: Params
13
13
  initialData?: R
14
14
  }
15
15
 
@@ -36,10 +36,18 @@ export function createPreviewSubscriptionHook({
36
36
  })
37
37
  }
38
38
 
39
- function getStore() {
39
+ function getStore(abort: Aborter) {
40
40
  if (!store) {
41
- store = import('@sanity/groq-store').then(({groqStore}) =>
42
- groqStore({
41
+ store = import('@sanity/groq-store').then(({groqStore}) => {
42
+ // Skip creating the groq store if we've been unmounted to save memory and reduce gc pressure
43
+ if (abort.signal.aborted) {
44
+ const error = new Error('Cancelling groq store creation')
45
+ // This ensures we can skip it in the catch block same way
46
+ error.name = 'AbortError'
47
+ return Promise.reject(error)
48
+ }
49
+
50
+ return groqStore({
43
51
  projectId,
44
52
  dataset,
45
53
  documentLimit,
@@ -47,32 +55,31 @@ export function createPreviewSubscriptionHook({
47
55
  overlayDrafts: true,
48
56
  subscriptionThrottleMs: 10,
49
57
  })
50
- )
58
+ })
51
59
  }
52
60
  return store
53
61
  }
54
62
  }
55
63
 
56
64
  function useQuerySubscription<R = any>(options: {
57
- getStore: () => Promise<GroqStore>
65
+ getStore: (abort: Aborter) => Promise<GroqStore>
58
66
  projectId: string
59
67
  query: string
60
- params: Record<string, unknown>
68
+ params: Params
61
69
  initialData: R
62
70
  enabled: boolean
63
71
  }) {
64
- const {getStore, projectId, query, params, initialData, enabled = false} = options
72
+ const {getStore, projectId, query, initialData, enabled = false} = options
65
73
  const [error, setError] = useState<Error>()
66
74
  const [loading, setLoading] = useState(false)
67
75
  const [data, setData] = useState<R>()
76
+ const params = useParams(options.params)
68
77
 
69
78
  // Use "deep" dependency comparison because params are often not _referentially_ equal,
70
79
  // but contains the same shallow properties, eg `{"slug": "some-slug"}`
71
- useDeepCompareEffect(() => {
80
+ useEffect(() => {
72
81
  if (!enabled) {
73
- return () => {
74
- /* intentional noop */
75
- }
82
+ return
76
83
  }
77
84
 
78
85
  setLoading(true)
@@ -89,7 +96,7 @@ function useQuerySubscription<R = any>(options: {
89
96
  console.warn('Not authenticated - preview not available')
90
97
  throw new Error('Not authenticated - preview not available')
91
98
  })
92
- .then(getStore)
99
+ .then(() => getStore(aborter))
93
100
  .then((store) => {
94
101
  subscription = store.subscribe(query, params, (err, result) => {
95
102
  if (err) {
@@ -99,9 +106,10 @@ function useQuerySubscription<R = any>(options: {
99
106
  }
100
107
  })
101
108
  })
102
- .catch(setError)
109
+ .catch((err: Error) => (err.name === 'AbortError' ? null : setError(err)))
103
110
  .finally(() => setLoading(false))
104
111
 
112
+ // eslint-disable-next-line consistent-return
105
113
  return () => {
106
114
  if (subscription) {
107
115
  subscription.unsubscribe()
@@ -117,3 +125,9 @@ function useQuerySubscription<R = any>(options: {
117
125
  error,
118
126
  }
119
127
  }
128
+
129
+ // Return params that are stable with deep equal as long as the key order is the same
130
+ function useParams(params: Params): Params {
131
+ const stringifiedParams = useMemo(() => JSON.stringify(params), [params])
132
+ return useMemo(() => JSON.parse(stringifiedParams), [stringifiedParams])
133
+ }
@@ -1,2 +0,0 @@
1
- import { ProjectConfig } from './types';
2
- export declare function createImageUrlBuilder({ projectId, dataset }: ProjectConfig): import("@sanity/image-url/lib/types/builder").ImageUrlBuilder;
@@ -1,6 +0,0 @@
1
- /// <reference types="react" />
2
- import { PortableTextProps, PortableTextSerializers } from '@sanity/block-content-to-react';
3
- import { ProjectConfig } from './types';
4
- export declare function createPortableTextComponent({ projectId, dataset, serializers, }: ProjectConfig & {
5
- serializers?: PortableTextSerializers;
6
- }): (props: PortableTextProps) => JSX.Element;
@@ -1,6 +0,0 @@
1
- import getImageUrlBuilder from '@sanity/image-url'
2
- import {ProjectConfig} from './types'
3
-
4
- export function createImageUrlBuilder({projectId, dataset}: ProjectConfig) {
5
- return getImageUrlBuilder({projectId, dataset})
6
- }
@@ -1,23 +0,0 @@
1
- import React from 'react'
2
- import SanityPortableText, {
3
- PortableTextProps,
4
- PortableTextSerializers,
5
- } from '@sanity/block-content-to-react'
6
- import {ProjectConfig} from './types'
7
-
8
- export function createPortableTextComponent({
9
- projectId,
10
- dataset,
11
- serializers,
12
- }: ProjectConfig & {serializers?: PortableTextSerializers}) {
13
- return function PortableText(props: PortableTextProps) {
14
- return (
15
- <SanityPortableText
16
- projectId={projectId}
17
- dataset={dataset}
18
- serializers={serializers}
19
- {...props}
20
- />
21
- )
22
- }
23
- }