Skip to content

Commit 53e7dd7

Browse files
authored
fix(presentation): support pt::text in live queries (#8380)
1 parent 6474dae commit 53e7dd7

File tree

6 files changed

+44
-23
lines changed

6 files changed

+44
-23
lines changed

dev/test-studio/preview/SimpleBlockPortableText.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ export function SimpleBlockPortableText(): React.JSX.Element {
2424
{
2525
_id: string
2626
title: string | null
27+
bodyString: string
2728
body: PortableTextBlock[]
2829
notes: {_key: string; title?: string; minutes?: number; notes?: PortableTextBlock[]}[]
2930
}[]
30-
>(/* groq */ `*[_type == "simpleBlock"]{_id,title,body,notes}`)
31+
>(/* groq */ `*[_type == "simpleBlock"]{_id,title,"bodyString":pt::text(body),body,notes}`)
3132

3233
if (error) {
3334
throw error
@@ -52,6 +53,7 @@ export function SimpleBlockPortableText(): React.JSX.Element {
5253
}}
5354
>
5455
<h1>{item.title || 'Untitled'}</h1>
56+
<p>{item.bodyString}</p>
5557
<PortableText components={components} value={item.body} />
5658
{item.notes?.map((note) => (
5759
<div key={note._key}>

packages/sanity/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
"@portabletext/block-tools": "^1.1.2",
157157
"@portabletext/editor": "^1.25.0",
158158
"@portabletext/react": "^3.0.0",
159+
"@portabletext/toolkit": "^2.0.16",
159160
"@rexxars/react-json-inspector": "^9.0.1",
160161
"@sanity/asset-utils": "^2.0.6",
161162
"@sanity/bifur-client": "^0.4.1",

packages/sanity/src/presentation/loader/LiveQueries.tsx

+2-11
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
type PresentationPerspective,
4242
} from '../types'
4343
import {type DocumentOnPage} from '../useDocumentsOnPage'
44-
import {useQueryParams, useRevalidate} from './utils'
44+
import {mapChangedValue, useQueryParams, useRevalidate} from './utils'
4545

4646
export interface LoaderQueriesProps {
4747
liveDocument: Partial<SanityDocument> | null | undefined
@@ -197,8 +197,6 @@ export default function LoaderQueries(props: LoaderQueriesProps): React.JSX.Elem
197197
if (comlink) {
198198
// eslint-disable-next-line @typescript-eslint/no-shadow
199199
const {projectId, dataset} = clientConfig
200-
// @todo - Can this be migrated/deprecated in favour of emitting
201-
// `presentation/perspective` at a higher level?
202200
comlink.post('loader/perspective', {
203201
projectId: projectId!,
204202
dataset: dataset!,
@@ -482,14 +480,7 @@ export function turboChargeResultIfSourceMap<T = unknown>(
482480
}
483481
return null
484482
},
485-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
486-
(changedValue: any, {previousValue}) => {
487-
if (typeof changedValue === 'number' && typeof previousValue === 'string') {
488-
// If the string() function was used in the query, we need to convert the source value to a string as well
489-
return `${changedValue}`
490-
}
491-
return changedValue
492-
},
483+
mapChangedValue,
493484
perspective,
494485
)
495486
}

packages/sanity/src/presentation/loader/LoaderQueries.tsx

+2-11
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
type PresentationPerspective,
4242
} from '../types'
4343
import {type DocumentOnPage} from '../useDocumentsOnPage'
44-
import {useQueryParams, useRevalidate} from './utils'
44+
import {mapChangedValue, useQueryParams, useRevalidate} from './utils'
4545

4646
export interface LoaderQueriesProps {
4747
liveDocument: Partial<SanityDocument> | null | undefined
@@ -174,8 +174,6 @@ export default function LoaderQueries(props: LoaderQueriesProps): React.JSX.Elem
174174
if (comlink) {
175175
// eslint-disable-next-line @typescript-eslint/no-shadow
176176
const {projectId, dataset} = clientConfig
177-
// @todo - Can this be migrated/deprecated in favour of emitting
178-
// `presentation/perspective` at a higher level?
179177
comlink.post('loader/perspective', {
180178
projectId: projectId!,
181179
dataset: dataset!,
@@ -556,14 +554,7 @@ export function turboChargeResultIfSourceMap<T = unknown>(
556554
// Fallback to general documents cache
557555
return cache.get(sourceDocument._id)
558556
},
559-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
560-
(changedValue: any, {previousValue}) => {
561-
if (typeof changedValue === 'number' && typeof previousValue === 'string') {
562-
// If the string() function was used in the query, we need to convert the source value to a string as well
563-
return `${changedValue}`
564-
}
565-
return changedValue
566-
},
557+
mapChangedValue,
567558
perspective,
568559
)
569560
}

packages/sanity/src/presentation/loader/utils.ts

+33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
1+
import {toPlainText} from '@portabletext/react'
2+
import {isPortableTextBlock} from '@portabletext/toolkit'
13
import {type ClientPerspective, type QueryParams} from '@sanity/client'
4+
import {type ApplySourceDocumentsUpdateFunction} from '@sanity/client/csm'
25
import {useCallback, useEffect, useMemo, useState, useSyncExternalStore} from 'react'
6+
import {type FIXME} from 'sanity'
7+
8+
/**
9+
* Used by `applySourceDocuments`
10+
* @internal
11+
*/
12+
export const mapChangedValue: ApplySourceDocumentsUpdateFunction = (
13+
changedValue: FIXME,
14+
{previousValue},
15+
) => {
16+
if (typeof previousValue === 'string') {
17+
if (typeof changedValue === 'number') {
18+
// If the string() function was used in the query, we need to convert the source value to a string as well
19+
return `${changedValue}`
20+
}
21+
// If it's an array in the source, but a string in the query response, it could be pt::text
22+
if (Array.isArray(changedValue)) {
23+
if (changedValue.length === 0) {
24+
// If it's empty assume it's PT and return an empty string
25+
return ''
26+
}
27+
// If the array contains any valid block type, assume the GROQ initially used pt::text on it and do the same conversion
28+
if (changedValue.some((node) => typeof node === 'object' && isPortableTextBlock(node))) {
29+
return toPlainText(changedValue)
30+
}
31+
}
32+
}
33+
34+
return changedValue
35+
}
336

437
/**
538
* @internal

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)