@sanity/client 6.26.1 → 6.27.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/client",
3
- "version": "6.26.1",
3
+ "version": "6.27.0",
4
4
  "description": "Client for retrieving, creating and patching data from Sanity.io",
5
5
  "keywords": [
6
6
  "sanity",
@@ -1,4 +1,4 @@
1
- import {getDraftId, getPublishedId, isDraftId} from './draftUtils'
1
+ import {createSourceDocumentResolver} from './createSourceDocumentResolver'
2
2
  import {parseJsonPath} from './jsonPath'
3
3
  import {resolveMapping} from './resolveMapping'
4
4
  import * as paths from './studioPath'
@@ -13,8 +13,6 @@ import type {
13
13
  } from './types'
14
14
  import {walkMap} from './walkMap'
15
15
 
16
- const defaultUpdateFunction = <T = unknown>(changed: T): T => changed
17
-
18
16
  /**
19
17
  * Optimistically applies source documents to a result, using the content source map to trace fields.
20
18
  * Can be used to apply mutations to documents being edited in a Studio, or any mutation on Content Lake, to a result with extremely low latency.
@@ -25,20 +23,21 @@ export function applySourceDocuments<Result = unknown>(
25
23
  resultSourceMap: ContentSourceMap | undefined,
26
24
  getCachedDocument: (
27
25
  sourceDocument: ContentSourceMapDocuments[number],
28
- ) => Partial<SanityDocument> | null | undefined,
29
- updateFn: ApplySourceDocumentsUpdateFunction = defaultUpdateFunction,
30
- perspective: ClientPerspective = 'raw',
26
+ ) =>
27
+ | (Partial<SanityDocument> & Required<Pick<SanityDocument, '_id' | '_type'>>)
28
+ | null
29
+ | undefined,
30
+ updateFn: ApplySourceDocumentsUpdateFunction,
31
+ perspective: Exclude<ClientPerspective, 'raw'>,
31
32
  ): Result {
32
33
  if (!resultSourceMap) return result
33
34
 
34
- if (perspective !== 'published' && perspective !== 'raw' && perspective !== 'previewDrafts') {
35
- throw new Error(`Unknown perspective "${perspective}"`)
36
- }
35
+ const resolveDocument = createSourceDocumentResolver(getCachedDocument, perspective)
36
+ const cachedDocuments = resultSourceMap.documents.map(resolveDocument)
37
37
 
38
38
  return walkMap(JSON.parse(JSON.stringify(result)), (value, path) => {
39
39
  const resolveMappingResult = resolveMapping(path, resultSourceMap)
40
40
  if (!resolveMappingResult) {
41
- // console.warn('no mapping for path', path)
42
41
  return value
43
42
  }
44
43
 
@@ -57,36 +56,7 @@ export function applySourceDocuments<Result = unknown>(
57
56
  if (sourceDocument) {
58
57
  const parsedPath = parseJsonPath(sourcePath + pathSuffix)
59
58
  const stringifiedPath = paths.toString(parsedPath as Path)
60
-
61
- // The _id is sometimes used used as `key` in lists, and should not be changed optimistically
62
- if (stringifiedPath === '_id') {
63
- return value
64
- }
65
-
66
- let cachedDocument: Partial<SanityDocument> | null | undefined
67
- if (perspective === 'previewDrafts') {
68
- cachedDocument = getCachedDocument(
69
- isDraftId(sourceDocument._id)
70
- ? sourceDocument
71
- : {...sourceDocument, _id: getDraftId(sourceDocument._id)},
72
- )
73
- if (!cachedDocument) {
74
- cachedDocument = getCachedDocument(
75
- isDraftId(sourceDocument._id)
76
- ? {...sourceDocument, _id: getPublishedId(sourceDocument._id)}
77
- : sourceDocument,
78
- )
79
- }
80
- if (cachedDocument) {
81
- cachedDocument = {
82
- ...cachedDocument,
83
- _id: getPublishedId(sourceDocument._id),
84
- _originalId: sourceDocument._id,
85
- }
86
- }
87
- } else {
88
- cachedDocument = getCachedDocument(sourceDocument)
89
- }
59
+ const cachedDocument = cachedDocuments[mapping.source.document]
90
60
 
91
61
  if (!cachedDocument) {
92
62
  return value
@@ -0,0 +1,54 @@
1
+ import {getDraftId, getPublishedId, getVersionId} from './draftUtils'
2
+ import {resolvePerspectives} from './resolvePerspectives'
3
+ import type {ClientPerspective, ContentSourceMapDocuments, SanityDocument} from './types'
4
+
5
+ /** @internal */
6
+ export type ResolvedDocument = Partial<SanityDocument> &
7
+ Required<Pick<SanityDocument, '_id' | '_type'>>
8
+
9
+ /** @internal */
10
+ export type MatchedDocument = Partial<SanityDocument> &
11
+ Required<Pick<SanityDocument, '_id' | '_type' | '_originalId'>>
12
+
13
+ /** @internal */
14
+ export function createSourceDocumentResolver(
15
+ getCachedDocument: (
16
+ sourceDocument: ContentSourceMapDocuments[number],
17
+ ) => ResolvedDocument | null | undefined,
18
+ _perspective: Exclude<ClientPerspective, 'raw'>,
19
+ ) {
20
+ const perspectives = resolvePerspectives(_perspective)
21
+ function findDocument(sourceDocument: ContentSourceMapDocuments[number]) {
22
+ for (const perspective of perspectives) {
23
+ let match: ReturnType<typeof getCachedDocument> = null
24
+ if (perspective.startsWith('r')) {
25
+ match = getCachedDocument({
26
+ ...sourceDocument,
27
+ _id: getVersionId(sourceDocument._id, perspective),
28
+ })
29
+ }
30
+ if (perspective === 'drafts') {
31
+ match = getCachedDocument({
32
+ ...sourceDocument,
33
+ _id: getDraftId(sourceDocument._id),
34
+ })
35
+ }
36
+ if (perspective === 'published') {
37
+ match = getCachedDocument({
38
+ ...sourceDocument,
39
+ _id: getPublishedId(sourceDocument._id),
40
+ })
41
+ }
42
+ if (match) {
43
+ return {...match, _id: getPublishedId(match._id), _originalId: match._id}
44
+ }
45
+ }
46
+ return null
47
+ }
48
+ // define resolver that loops over source documents and perspectives
49
+ return function resolveSourceDocument(
50
+ sourceDocument: ContentSourceMapDocuments[number],
51
+ ): MatchedDocument | null {
52
+ return findDocument(sourceDocument)
53
+ }
54
+ }
@@ -0,0 +1,29 @@
1
+ import {validateApiPerspective} from '../config'
2
+ import type {ReleaseId} from '../types'
3
+ import type {ClientPerspective} from './types'
4
+
5
+ /**
6
+ * This resolves the perspectives to how documents should be resolved when applying optimistic updates,
7
+ * like in `applySourceDocuments`.
8
+ * @internal
9
+ */
10
+ export function resolvePerspectives(
11
+ perspective: Exclude<ClientPerspective, 'raw'>,
12
+ ): ('published' | 'drafts' | ReleaseId)[] {
13
+ validateApiPerspective(perspective)
14
+
15
+ if (Array.isArray(perspective)) {
16
+ if (!perspective.includes('published')) {
17
+ return [...perspective, 'published']
18
+ }
19
+ return perspective
20
+ }
21
+ switch (perspective) {
22
+ case 'previewDrafts':
23
+ case 'drafts':
24
+ return ['drafts', 'published']
25
+ case 'published':
26
+ default:
27
+ return ['published']
28
+ }
29
+ }