@sanity/preview-kit
Advanced tools
Comparing version 2.3.0-perspective.4 to 2.3.1
@@ -25,5 +25,7 @@ import type { ClientConfig } from '@sanity/client' | ||
| typeof console | ||
| Pick< | ||
typeof console, | ||
'debug' | 'error' | 'groupCollapsed' | 'groupEnd' | 'log' | 'table' | ||
| Partial< | ||
Pick< | ||
typeof console, | ||
'debug' | 'error' | 'groupCollapsed' | 'groupEnd' | 'log' | 'table' | ||
> | ||
> | ||
@@ -69,3 +71,3 @@ | ||
*/ | ||
encodeSourceMap?: 'auto' | true | false | ||
encodeSourceMap?: 'auto' | string | true | false | ||
/** | ||
@@ -111,3 +113,3 @@ * Where the Studio is hosted. | ||
*/ | ||
studioUrl: StudioUrl | ||
studioUrl?: StudioUrl | ||
/** | ||
@@ -114,0 +116,0 @@ * Specify a `console.log` compatible logger to see debug logs, which keys are encoded and which are not. |
@@ -5,3 +5,3 @@ import { requester, SanityClient, createClient as createClient$1 } from '@sanity/client'; | ||
import { vercelStegaCombine } from '@vercel/stega'; | ||
import { parseNormalisedJsonPath, encode, encodeIntoResult } from './_chunks/sourcemap-0a868d9e.js'; | ||
import { parseNormalisedJsonPath, encode, encodeIntoResult } from './_chunks/sourcemap-6c156d38.js'; | ||
function defineEditLink(_studioUrl) { | ||
@@ -99,2 +99,3 @@ const studioUrl = _studioUrl.replace(/\/$/, ""); | ||
onResponse: response => { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if (!isBodyResponse(response)) { | ||
@@ -106,3 +107,3 @@ return response; | ||
if (logger) { | ||
logger == null ? void 0 : logger.error("[@sanity/preview-kit]: Missing Content Source Map from response body", response.body); | ||
(_a = logger == null ? void 0 : logger.error) == null ? void 0 : _a.call(logger, "[@sanity/preview-kit]: Missing Content Source Map from response body", response.body); | ||
} | ||
@@ -116,8 +117,8 @@ return response; | ||
if (isSkipping || isEncoding) { | ||
logger == null ? void 0 : logger.groupCollapsed("[@sanity/preview-kit]: Stega encoding source map into result"); | ||
logger == null ? void 0 : logger.log("[@sanity/preview-kit]: Paths encoded: ".concat(transcoder.report.encoded.length, ", skipped: ").concat(transcoder.report.skipped.length)); | ||
(_b = (logger == null ? void 0 : logger.groupCollapsed) || logger.log) == null ? void 0 : _b("[@sanity/preview-kit]: Stega encoding source map into result"); | ||
(_c = logger.log) == null ? void 0 : _c.call(logger, "[@sanity/preview-kit]: Paths encoded: ".concat(transcoder.report.encoded.length, ", skipped: ").concat(transcoder.report.skipped.length)); | ||
} | ||
if (transcoder.report.encoded.length > 0) { | ||
logger == null ? void 0 : logger.log("[@sanity/preview-kit]: Table of encoded paths"); | ||
logger == null ? void 0 : logger.table(transcoder.report.encoded); | ||
(_d = logger == null ? void 0 : logger.log) == null ? void 0 : _d.call(logger, "[@sanity/preview-kit]: Table of encoded paths"); | ||
(_e = (logger == null ? void 0 : logger.table) || logger.log) == null ? void 0 : _e(transcoder.report.encoded); | ||
} | ||
@@ -131,6 +132,6 @@ if (transcoder.report.skipped.length > 0) { | ||
} | ||
logger == null ? void 0 : logger.log("[@sanity/preview-kit]: List of skipped paths", [...skipped.values()]); | ||
(_f = logger == null ? void 0 : logger.log) == null ? void 0 : _f.call(logger, "[@sanity/preview-kit]: List of skipped paths", [...skipped.values()]); | ||
} | ||
if (isSkipping || isEncoding) { | ||
logger == null ? void 0 : logger.groupEnd(); | ||
(_g = logger == null ? void 0 : logger.groupEnd) == null ? void 0 : _g.call(logger); | ||
} | ||
@@ -183,6 +184,9 @@ } | ||
const createClient = config => { | ||
var _a; | ||
const { | ||
encodeSourceMap = detectEnableSourceMap(), | ||
encodeSourceMapAtPath, | ||
studioUrl = detectStudioUrl(), | ||
logger | ||
logger, | ||
...options | ||
} = config; | ||
@@ -193,11 +197,15 @@ let shouldEncodeSourceMap = encodeSourceMap === true; | ||
} | ||
if (typeof encodeSourceMap === "string" && encodeSourceMap !== "auto") { | ||
throw new Error("Invalid value for encodeSourceMap: ".concat(encodeSourceMap, ". Did you mean 'auto'?")); | ||
} | ||
try { | ||
if (shouldEncodeSourceMap && config.resultSourceMap !== false) { | ||
logger == null ? void 0 : logger.debug("[@sanity/preview-kit]: Creating source map enabled client"); | ||
(_a = logger == null ? void 0 : logger.debug) == null ? void 0 : _a.call(logger, "[@sanity/preview-kit]: Creating source map enabled client"); | ||
const httpRequest = createHttpRequest({ | ||
...config, | ||
studioUrl | ||
encodeSourceMapAtPath, | ||
studioUrl, | ||
logger | ||
}); | ||
return new SanityClient(httpRequest, { | ||
...config, | ||
...options, | ||
// Source maps by Content Lake are required in order to know where to insert the encoded source maps into strings | ||
@@ -210,3 +218,3 @@ resultSourceMap: true | ||
} | ||
return createClient$1(config); | ||
return createClient$1(options); | ||
}; | ||
@@ -213,0 +221,0 @@ function isVercelPreviewEnvironment() { |
@@ -1,4 +0,4 @@ | ||
import { GroqStoreProvider as GroqStoreProvider$1 } from './_chunks/GroqStoreProvider-31b1f04b.js'; | ||
import { GroqStoreProvider as GroqStoreProvider$1 } from './_chunks/GroqStoreProvider-91f41b8b.js'; | ||
const GroqStoreProvider = GroqStoreProvider$1; | ||
export { GroqStoreProvider }; | ||
//# sourceMappingURL=groq-store.js.map |
import { useContext, useMemo, useState, useCallback, lazy, memo, Suspense, useEffect } from 'react'; | ||
import isFastEqual from 'react-fast-compare'; | ||
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector'; | ||
import { defineListenerContext, LoadedListenersContext, getQueryCacheKey, DEFAULT_MAX_DOCUMENTS } from './_chunks/context-13c019e1.js'; | ||
import { defineListenerContext, LoadedListenersContext, getQueryCacheKey, DEFAULT_TAG, DEFAULT_MAX_DOCUMENTS } from './_chunks/context-a9a2d4a8.js'; | ||
import { jsx } from 'react/jsx-runtime'; | ||
@@ -56,4 +56,4 @@ function useLiveQuery(initialData, query, queryParams, options) { | ||
} | ||
const LazyGroqStoreProvider = lazy(() => import('./_chunks/index-55699f1a.js')); | ||
const LiveStoreProvider = lazy(() => import('./_chunks/index-f9874699.js')); | ||
const LazyGroqStoreProvider = lazy(() => import('./_chunks/index-b4747685.js')); | ||
const LiveStoreProvider = lazy(() => import('./_chunks/index-682ca163.js')); | ||
const LiveQueryProvider = memo(function LiveQueryProvider2(props) { | ||
@@ -64,3 +64,8 @@ const { | ||
} = props; | ||
const [client] = useState(() => props.client); | ||
if (!props.client) { | ||
throw new Error("Missing a `client` prop with a configured Sanity client instance"); | ||
} | ||
const [client] = useState(() => props.client.withConfig({ | ||
requestTagPrefix: props.client.config().requestTagPrefix || DEFAULT_TAG | ||
})); | ||
const [cache] = useState(() => props.cache); | ||
@@ -172,3 +177,4 @@ const [logger] = useState(() => props.logger); | ||
token, | ||
perspective = "previewDrafts" | ||
perspective = "previewDrafts", | ||
requestTagPrefix | ||
} = useMemo(() => client.config(), [client]); | ||
@@ -184,2 +190,3 @@ return /* @__PURE__ */jsx(LazyGroqStoreProvider, { | ||
includeTypes: cache == null ? void 0 : cache.includeTypes, | ||
requestTagPrefix, | ||
children | ||
@@ -186,0 +193,0 @@ }); |
{ | ||
"name": "@sanity/preview-kit", | ||
"version": "2.3.0-perspective.4", | ||
"version": "2.3.1", | ||
"description": "General purpose utils for live content and visual editing", | ||
@@ -107,3 +107,3 @@ "keywords": [ | ||
"@sanity/eventsource": "^5.0.0", | ||
"@sanity/groq-store": "2.2.0", | ||
"@sanity/groq-store": "2.3.0", | ||
"@vercel/stega": "0.0.5", | ||
@@ -119,2 +119,3 @@ "lodash.get": "4.4.2", | ||
"devDependencies": { | ||
"@sanity/client": "^6.1.4", | ||
"@sanity/pkg-utils": "2.3.3", | ||
@@ -140,4 +141,4 @@ "@sanity/semantic-release-preset": "4.1.1", | ||
"rimraf": "5.0.1", | ||
"semantic-release": "21.0.5", | ||
"typescript": "5.1.5", | ||
"semantic-release": "21.0.6", | ||
"typescript": "^5.1.6", | ||
"vitest": "0.32.2", | ||
@@ -147,3 +148,3 @@ "vitest-github-actions-reporter": "0.10.0" | ||
"peerDependencies": { | ||
"@sanity/client": "^6.1.3", | ||
"@sanity/client": "^6.1.4", | ||
"react": "^18.0.0" | ||
@@ -150,0 +151,0 @@ }, |
@@ -6,5 +6,24 @@ # @sanity/preview-kit<!-- omit in toc --> | ||
- [Installation](#installation) | ||
- [`@sanity/preview-kit/client` Visual Editing with Content Source Maps](#sanitypreview-kitclient) | ||
- [`@sanity/preview-kit` Live real-time preview for React](#sanitypreview-kit-1) | ||
- [Release new version](#release-new-version) | ||
- [`@sanity/preview-kit/client`](#sanitypreview-kitclient) | ||
- [Visual Editing with Content Source Maps](#visual-editing-with-content-source-maps) | ||
- [Enhanced Sanity client with `createClient`](#enhanced-sanity-client-with-createclient) | ||
- [`studioUrl`](#studiourl) | ||
- [`encodeSourceMap`](#encodesourcemap) | ||
- [`encodeSourceMapAtPath`](#encodesourcemapatpath) | ||
- [`logger`](#logger) | ||
- [`resultSourceMap`](#resultsourcemap) | ||
- [Using the Content Source Map with custom logic](#using-the-content-source-map-with-custom-logic) | ||
- [Using Perspectives](#using-perspectives) | ||
- [`@sanity/preview-kit`](#sanitypreview-kit-1) | ||
- [Live real-time preview for React](#live-real-time-preview-for-react) | ||
- [1. Create a `getClient` utility](#1-create-a-getclient-utility) | ||
- [2. Define a `<LiveQueryProvider />` component](#2-define-a-livequeryprovider--component) | ||
- [3. Making a Remix route conditionally preview draft](#3-making-a-remix-route-conditionally-preview-draft) | ||
- [4. Adding the `useLiveQuery` hook to components that need to re-render in real-time](#4-adding-the-uselivequery-hook-to-components-that-need-to-re-render-in-real-time) | ||
- [Implementing a Loading UI with `useLiveQuery`](#implementing-a-loading-ui-with-uselivequery) | ||
- [Optimizing performance](#optimizing-performance) | ||
- [Advanced usage](#advanced-usage) | ||
- [Fine-tuning `cache`](#fine-tuning-cache) | ||
- [Content Source Map features](#content-source-map-features) | ||
- [Release new version](#release-new-version) | ||
- [License](#license) | ||
@@ -34,25 +53,25 @@ | ||
You can use [visual editing][visual-editing-intro] with any framework, not just React. [Read our guide for how to get started.][visual-editing] | ||
You can use [Visual Editing][visual-editing-intro] with any framework, not just React. [Read our guide for how to get started.][visual-editing] | ||
### `createClient` | ||
### Enhanced Sanity client with `createClient` | ||
The Preview Kit client is built on top of `@sanity/client` and is designed to be a drop-in replacement. It extends the client configuration with options for customizing visual editing experiences. | ||
Preview Kit's enhanced Sanity client is built on top of `@sanity/client` and is designed to be a drop-in replacement. It extends the client configuration with options for returning encoded metadata from Content Source Maps. | ||
```diff | ||
-import {createClient, type ClientConfig} from '@sanity/client' | ||
+import { createClient, type ClientConfig } from '@sanity/preview-kit/client' | ||
```ts | ||
// Remove your vanilla `@sanity/client` import | ||
// import {createClient, type ClientConfig} from '@sanity/client' | ||
// Use the enhanced client instead | ||
import { createClient, type ClientConfig } from '@sanity/preview-kit/client' | ||
const config: ClientConfig = { | ||
projectId: 'your-project-id', | ||
dataset: 'your-dataset-name', | ||
useCdn: true, // set to `false` to bypass the edge cache | ||
apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version | ||
// ...base config options | ||
- // enable content source map in the response | ||
- resultSourceMap: true, | ||
+ // Required, set it to the URL of your Sanity Studio | ||
+ studioUrl: 'https://your-project-name.sanity.studio', | ||
+ // enable content source map in the response, and encode it into strings | ||
+ // 'auto' is the default, you can also use `true` or `false` | ||
+ encodeSourceMap: 'auto', | ||
// Required: when "encodeSourceMap" is enabled | ||
// Set it to relative or absolute URL of your Sanity Studio | ||
studioUrl: '/studio', // or 'https://your-project-name.sanity.studio' | ||
// Required: for encoded metadata from Content Source Maps | ||
// 'auto' is the default, you can also use `true` or `false` | ||
encodeSourceMap: 'auto', | ||
} | ||
@@ -65,3 +84,3 @@ | ||
It's **required**, and can either be an absolute URL: | ||
**Required** when `encodeSourceMap` is active, and can either be an absolute URL: | ||
@@ -90,3 +109,3 @@ ```ts | ||
Accepts `"auto"`, the default, or a `boolean`. Controls when to encode the content source map into strings using `@vercel/stega` encoding. When `"auto"` is used a best-effort environment detection is used to see if the environment is a Vercel Preview deployment. Most of the time it works out of the box, but in some scenarios and some frameworks it might be necessary to run custom logic, equivalent to: | ||
Accepts `"auto"`, the default, or a `boolean`. Controls when to encode the content source map into strings using `@vercel/stega` encoding. When `"auto"` is used a best-effort environment detection is used to see if the environment is a Vercel Preview deployment. On a different hosting provider, or in local development, configure this option to make sure it is only enabled in non-production deployments. | ||
@@ -207,2 +226,9 @@ ```tsx | ||
## Using Perspectives | ||
The `perspective` option can be used to specify special filtering behavior for queries. The default value is `raw`, which means no special filtering is applied, while [`published`](#published) and [`previewDrafts`](#previewdrafts) can be used to optimize for specific use cases. Read more about this option: | ||
- [Perspectives in Sanity docs][perspectives-docs] | ||
- [Perspectives in @sanity/client README][perspectives-readme] | ||
# `@sanity/preview-kit` | ||
@@ -735,1 +761,3 @@ | ||
[migration]: https://github.com/sanity-io/preview-kit/blob/main/MIGRATION.md | ||
[perspectives-docs]: https://www.sanity.io/docs/perspectives | ||
[perspectives-readme]: https://github.com/sanity-io/client/#performing-queries |
@@ -17,4 +17,6 @@ import { createClient as _createClient, SanityClient } from '@sanity/client' | ||
encodeSourceMap = detectEnableSourceMap(), | ||
encodeSourceMapAtPath, | ||
studioUrl = detectStudioUrl(), | ||
logger, | ||
...options | ||
} = config | ||
@@ -29,8 +31,20 @@ | ||
if (typeof encodeSourceMap === 'string' && encodeSourceMap !== 'auto') { | ||
throw new Error( | ||
`Invalid value for encodeSourceMap: ${encodeSourceMap}. Did you mean 'auto'?` | ||
) | ||
} | ||
try { | ||
if (shouldEncodeSourceMap && config.resultSourceMap !== false) { | ||
logger?.debug('[@sanity/preview-kit]: Creating source map enabled client') | ||
const httpRequest = createHttpRequest({ ...config, studioUrl }) | ||
logger?.debug?.( | ||
'[@sanity/preview-kit]: Creating source map enabled client' | ||
) | ||
const httpRequest = createHttpRequest({ | ||
encodeSourceMapAtPath, | ||
studioUrl, | ||
logger, | ||
}) | ||
return new SanityClient(httpRequest, { | ||
...config, | ||
...options, | ||
// Source maps by Content Lake are required in order to know where to insert the encoded source maps into strings | ||
@@ -48,3 +62,3 @@ resultSourceMap: true, | ||
} | ||
return _createClient(config) | ||
return _createClient(options) | ||
} | ||
@@ -51,0 +65,0 @@ |
@@ -44,3 +44,3 @@ /** | ||
if (logger) { | ||
logger?.error( | ||
logger?.error?.( | ||
'[@sanity/preview-kit]: Missing Content Source Map from response body', | ||
@@ -59,6 +59,7 @@ response.body | ||
if (isSkipping || isEncoding) { | ||
logger?.groupCollapsed( | ||
// eslint-disable-next-line @typescript-eslint/no-extra-semi | ||
;(logger?.groupCollapsed || logger.log)?.( | ||
'[@sanity/preview-kit]: Stega encoding source map into result' | ||
) | ||
logger?.log( | ||
logger.log?.( | ||
`[@sanity/preview-kit]: Paths encoded: ${transcoder.report.encoded.length}, skipped: ${transcoder.report.skipped.length}` | ||
@@ -68,4 +69,4 @@ ) | ||
if (transcoder.report.encoded.length > 0) { | ||
logger?.log(`[@sanity/preview-kit]: Table of encoded paths`) | ||
logger?.table(transcoder.report.encoded) | ||
logger?.log?.(`[@sanity/preview-kit]: Table of encoded paths`) | ||
;(logger?.table || logger.log)?.(transcoder.report.encoded) | ||
} | ||
@@ -77,3 +78,3 @@ if (transcoder.report.skipped.length > 0) { | ||
} | ||
logger?.log(`[@sanity/preview-kit]: List of skipped paths`, [ | ||
logger?.log?.(`[@sanity/preview-kit]: List of skipped paths`, [ | ||
...skipped.values(), | ||
@@ -84,3 +85,3 @@ ]) | ||
if (isSkipping || isEncoding) { | ||
logger?.groupEnd() | ||
logger?.groupEnd?.() | ||
} | ||
@@ -102,3 +103,6 @@ } | ||
logger, | ||
}: PreviewKitClientConfig): HttpRequest { | ||
}: Pick< | ||
PreviewKitClientConfig, | ||
'studioUrl' | 'encodeSourceMapAtPath' | 'logger' | ||
>): HttpRequest { | ||
invariant(studioUrl, 'Missing studioUrl in client config') | ||
@@ -105,0 +109,0 @@ const superRequester = originalRequester.clone() |
@@ -111,3 +111,5 @@ /* eslint-disable no-nested-ternary */ | ||
if (!csm.mappings) { | ||
logger?.error('Missing resultSourceMap.mappings', { resultSourceMap: csm }) | ||
logger?.error?.('Missing resultSourceMap.mappings', { | ||
resultSourceMap: csm, | ||
}) | ||
return undefined | ||
@@ -114,0 +116,0 @@ } |
@@ -86,3 +86,4 @@ /* eslint-disable no-nested-ternary */ | ||
} { | ||
const createEditLink = defineEditLink(studioUrl) | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const createEditLink = defineEditLink(studioUrl!) | ||
const report: Record< | ||
@@ -89,0 +90,0 @@ 'encoded' | 'skipped', |
@@ -22,5 +22,7 @@ import type { ClientConfig } from '@sanity/client' | ||
| typeof console | ||
| Pick< | ||
typeof console, | ||
'debug' | 'error' | 'groupCollapsed' | 'groupEnd' | 'log' | 'table' | ||
| Partial< | ||
Pick< | ||
typeof console, | ||
'debug' | 'error' | 'groupCollapsed' | 'groupEnd' | 'log' | 'table' | ||
> | ||
> | ||
@@ -62,3 +64,3 @@ | ||
*/ | ||
encodeSourceMap?: 'auto' | true | false | ||
encodeSourceMap?: 'auto' | string | true | false | ||
/** | ||
@@ -104,3 +106,3 @@ * Where the Studio is hosted. | ||
*/ | ||
studioUrl: StudioUrl | ||
studioUrl?: StudioUrl | ||
/** | ||
@@ -107,0 +109,0 @@ * Specify a `console.log` compatible logger to see debug logs, which keys are encoded and which are not. |
@@ -54,1 +54,2 @@ import type { QueryParams } from '@sanity/client' | ||
export const DEFAULT_MAX_DOCUMENTS = 3000 | ||
export const DEFAULT_TAG = 'sanity.preview-kit' |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
409892
5013
0
758
25
+ Added@sanity/groq-store@2.3.0(transitive)
- Removed@sanity/groq-store@2.2.0(transitive)
Updated@sanity/groq-store@2.3.0