Skip to content

Commit fac01df

Browse files
committed
feat(views): support dev mode (emulate) on views client
when overrrides are set switch to the emulate endpoint
1 parent fb7f914 commit fac01df

File tree

11 files changed

+415
-100
lines changed

11 files changed

+415
-100
lines changed

src/SanityClient.ts

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,13 @@ export class ObservableSanityClient {
318318
): Observable<
319319
SanityDocument<R> | SanityDocument<R>[] | SingleMutationResult | MultipleMutationResult
320320
> {
321-
return dataMethods._create<R>(this.#clientConfig, this.#httpRequest, document, 'create', options)
321+
return dataMethods._create<R>(
322+
this.#clientConfig,
323+
this.#httpRequest,
324+
document,
325+
'create',
326+
options,
327+
)
322328
}
323329

324330
/**
@@ -387,7 +393,12 @@ export class ObservableSanityClient {
387393
): Observable<
388394
SanityDocument<R> | SanityDocument<R>[] | SingleMutationResult | MultipleMutationResult
389395
> {
390-
return dataMethods._createIfNotExists<R>(this.#clientConfig, this.#httpRequest, document, options)
396+
return dataMethods._createIfNotExists<R>(
397+
this.#clientConfig,
398+
this.#httpRequest,
399+
document,
400+
options,
401+
)
391402
}
392403

393404
/**
@@ -726,7 +737,13 @@ export class ObservableSanityClient {
726737
): Observable<SingleActionResult | MultipleActionResult> {
727738
const documentVersionId = getDocumentVersionId(publishedId, releaseId)
728739

729-
return dataMethods._discardVersion(this.config(), this.#httpRequest, documentVersionId, purge, options)
740+
return dataMethods._discardVersion(
741+
this.config(),
742+
this.#httpRequest,
743+
documentVersionId,
744+
purge,
745+
options,
746+
)
730747
}
731748

732749
/**
@@ -830,7 +847,12 @@ export class ObservableSanityClient {
830847

831848
const documentVersion = {...document, _id: documentVersionId}
832849

833-
return dataMethods._replaceVersion<R>(this.config(), this.#httpRequest, documentVersion, options)
850+
return dataMethods._replaceVersion<R>(
851+
this.config(),
852+
this.#httpRequest,
853+
documentVersion,
854+
options,
855+
)
834856
}
835857

836858
/**
@@ -860,7 +882,13 @@ export class ObservableSanityClient {
860882
): Observable<SingleActionResult | MultipleActionResult> {
861883
const versionId = getVersionId(publishedId, releaseId)
862884

863-
return dataMethods._unpublishVersion(this.config(), this.#httpRequest, versionId, publishedId, options)
885+
return dataMethods._unpublishVersion(
886+
this.config(),
887+
this.#httpRequest,
888+
versionId,
889+
publishedId,
890+
options,
891+
)
864892
}
865893

866894
/**
@@ -1208,7 +1236,9 @@ export class SanityClient {
12081236
id: string,
12091237
options?: {signal?: AbortSignal; tag?: string; releaseId?: string},
12101238
): Promise<SanityDocument<R> | undefined> {
1211-
return lastValueFrom(dataMethods._getDocument<R>(this.#clientConfig, this.#httpRequest, id, options))
1239+
return lastValueFrom(
1240+
dataMethods._getDocument<R>(this.#clientConfig, this.#httpRequest, id, options),
1241+
)
12121242
}
12131243

12141244
/**
@@ -1224,7 +1254,9 @@ export class SanityClient {
12241254
ids: string[],
12251255
options?: {signal?: AbortSignal; tag?: string},
12261256
): Promise<(SanityDocument<R> | null)[]> {
1227-
return lastValueFrom(dataMethods._getDocuments<R>(this.#clientConfig, this.#httpRequest, ids, options))
1257+
return lastValueFrom(
1258+
dataMethods._getDocuments<R>(this.#clientConfig, this.#httpRequest, ids, options),
1259+
)
12281260
}
12291261

12301262
/**
@@ -1671,7 +1703,9 @@ export class SanityClient {
16711703
): Promise<
16721704
SanityDocument<R> | SanityDocument<R>[] | SingleMutationResult | MultipleMutationResult
16731705
> {
1674-
return lastValueFrom(dataMethods._delete<R>(this.#clientConfig, this.#httpRequest, selection, options))
1706+
return lastValueFrom(
1707+
dataMethods._delete<R>(this.#clientConfig, this.#httpRequest, selection, options),
1708+
)
16751709
}
16761710

16771711
/**
@@ -1710,7 +1744,13 @@ export class SanityClient {
17101744
const documentVersionId = getDocumentVersionId(publishedId, releaseId)
17111745

17121746
return lastValueFrom(
1713-
dataMethods._discardVersion(this.config(), this.#httpRequest, documentVersionId, purge, options),
1747+
dataMethods._discardVersion(
1748+
this.config(),
1749+
this.#httpRequest,
1750+
documentVersionId,
1751+
purge,
1752+
options,
1753+
),
17141754
)
17151755
}
17161756

@@ -1849,7 +1889,13 @@ export class SanityClient {
18491889
const versionId = getVersionId(publishedId, releaseId)
18501890

18511891
return lastValueFrom(
1852-
dataMethods._unpublishVersion(this.config(), this.#httpRequest, versionId, publishedId, options),
1892+
dataMethods._unpublishVersion(
1893+
this.config(),
1894+
this.#httpRequest,
1895+
versionId,
1896+
publishedId,
1897+
options,
1898+
),
18531899
)
18541900
}
18551901

@@ -1919,7 +1965,9 @@ export class SanityClient {
19191965
): Promise<
19201966
SanityDocument<R> | SanityDocument<R>[] | SingleMutationResult | MultipleMutationResult
19211967
> {
1922-
return lastValueFrom(dataMethods._mutate<R>(this.#clientConfig, this.#httpRequest, operations, options))
1968+
return lastValueFrom(
1969+
dataMethods._mutate<R>(this.#clientConfig, this.#httpRequest, operations, options),
1970+
)
19231971
}
19241972

19251973
/**
@@ -1982,7 +2030,9 @@ export class SanityClient {
19822030
operations: Action | Action[],
19832031
options?: BaseActionOptions,
19842032
): Promise<SingleActionResult | MultipleActionResult> {
1985-
return lastValueFrom(dataMethods._action(this.#clientConfig, this.#httpRequest, operations, options))
2033+
return lastValueFrom(
2034+
dataMethods._action(this.#clientConfig, this.#httpRequest, operations, options),
2035+
)
19862036
}
19872037

19882038
/**
@@ -2007,7 +2057,9 @@ export class SanityClient {
20072057
* @internal
20082058
*/
20092059
dataRequest(endpoint: string, body: unknown, options?: BaseMutationOptions): Promise<Any> {
2010-
return lastValueFrom(dataMethods._dataRequest(this.#clientConfig, this.#httpRequest, endpoint, body, options))
2060+
return lastValueFrom(
2061+
dataMethods._dataRequest(this.#clientConfig, this.#httpRequest, endpoint, body, options),
2062+
)
20112063
}
20122064

20132065
/**

src/config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ export const initConfig = (
154154
const protocol = hostParts[0]
155155
const host = hostParts[1]
156156

157-
const cdnURL = newConfig.isDefaultApi ? `https://${defaultCdnHost}` : newConfig.apiCdnHost || newConfig.apiHost
157+
const cdnURL = newConfig.isDefaultApi
158+
? `https://${defaultCdnHost}`
159+
: newConfig.apiCdnHost || newConfig.apiHost
158160
const cdnURLParts = cdnURL.split('://', 2)
159161
const cdnProtocol = cdnURLParts[0]
160162
const cdnHost = cdnURLParts[1]

src/data/dataMethods.ts

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,19 @@ export function _fetch<R, Q>(
9090
const mapResponse =
9191
options.filterResponse === false ? (res: Any) => res : (res: Any) => res.result
9292

93-
const {cache, next, ...opts} = {
93+
const {cache, next, useEmulate, connections, ...opts} = {
9494
// Opt out of setting a `signal` on an internal `fetch` if one isn't provided.
9595
// This is necessary in React Server Components to avoid opting out of Request Memoization.
9696
useAbortSignal: typeof options.signal !== 'undefined',
9797
// Set `resultSourceMap' when stega is enabled, as it's required for encoding.
9898
resultSourceMap: stega.enabled ? 'withKeyArraySelector' : options.resultSourceMap,
99+
100+
// Only use emulate if explicitly asked for
101+
useEmulate: false,
102+
103+
// Having connections is a special case for views
104+
connections: undefined,
105+
99106
...options,
100107
// Default to not returning the query, unless `filterResponse` is `false`,
101108
// or `returnQuery` is explicitly set. `true` is the default in Content Lake, so skip if truthy
@@ -106,7 +113,17 @@ export function _fetch<R, Q>(
106113
? {...opts, fetch: {cache, next}}
107114
: opts
108115

109-
const $request = _dataRequest(config, httpRequest, 'query', {query, params}, reqOpts)
116+
// Use 'emulate' endpoint for view emulation, otherwise use 'query'
117+
const endpoint = useEmulate ? 'emulate' : 'query'
118+
const requestBody = useEmulate
119+
? {
120+
query,
121+
params,
122+
connections: connections,
123+
}
124+
: {query, params}
125+
126+
const $request = _dataRequest(config, httpRequest, endpoint, requestBody, reqOpts)
110127
return stega.enabled
111128
? $request.pipe(
112129
combineLatestWith(
@@ -413,11 +430,13 @@ export function _dataRequest(
413430
const isMutation = endpoint === 'mutate'
414431
const isAction = endpoint === 'actions'
415432
const isQuery = endpoint === 'query'
433+
const isEmulate = endpoint === 'emulate'
416434

417435
// Check if the query string is within a configured threshold,
418436
// in which case we can use GET. Otherwise, use POST.
419-
const strQuery = isMutation || isAction ? '' : encodeQueryString(body)
420-
const useGet = !isMutation && !isAction && strQuery.length < getQuerySizeLimit
437+
// Emulate endpoint always uses POST
438+
const strQuery = isMutation || isAction || isEmulate ? '' : encodeQueryString(body)
439+
const useGet = !isMutation && !isAction && !isEmulate && strQuery.length < getQuerySizeLimit
421440
const stringQuery = useGet ? strQuery : ''
422441
const returnFirst = options.returnFirst
423442
const {timeout, token, tag, headers, returnQuery, lastLiveEventId, cacheMode} = options
@@ -439,7 +458,7 @@ export function _dataRequest(
439458
resultSourceMap: options.resultSourceMap,
440459
lastLiveEventId: Array.isArray(lastLiveEventId) ? lastLiveEventId[0] : lastLiveEventId,
441460
cacheMode: cacheMode,
442-
canUseCdn: isQuery,
461+
canUseCdn: isQuery || isEmulate,
443462
signal: options.signal,
444463
fetch: options.fetch,
445464
useAbortSignal: options.useAbortSignal,
@@ -501,6 +520,9 @@ const isQuery = (config: InitializedClientConfig, uri: string) =>
501520
const isViewQuery = (config: InitializedClientConfig, uri: string) =>
502521
hasDataConfig(config) && uri.startsWith(_getDataUrl(config, 'views'))
503522

523+
const isEmulate = (config: InitializedClientConfig, uri: string) =>
524+
hasDataConfig(config) && uri.startsWith(_getDataUrl(config, 'emulate'))
525+
504526
const isMutate = (config: InitializedClientConfig, uri: string) =>
505527
hasDataConfig(config) && uri.startsWith(_getDataUrl(config, 'mutate'))
506528

@@ -520,7 +542,8 @@ const isData = (config: InitializedClientConfig, uri: string) =>
520542
isDoc(config, uri) ||
521543
isListener(config, uri) ||
522544
isHistory(config, uri) ||
523-
isViewQuery(config, uri)
545+
isViewQuery(config, uri) ||
546+
isEmulate(config, uri)
524547

525548
/**
526549
* @internal
@@ -549,8 +572,11 @@ export function _requestObservable<R>(
549572
options.query = {tag: validate.requestTag(tag), ...options.query}
550573
}
551574

552-
// GROQ query-only parameters
553-
if (['GET', 'HEAD', 'POST'].indexOf(options.method || 'GET') >= 0 && isQuery(config, uri)) {
575+
// GROQ query-only parameters (applies to both query and emulate endpoints)
576+
if (
577+
['GET', 'HEAD', 'POST'].indexOf(options.method || 'GET') >= 0 &&
578+
(isQuery(config, uri) || isEmulate(config, uri))
579+
) {
554580
const resultSourceMap = options.resultSourceMap ?? config.resultSourceMap
555581
if (resultSourceMap !== undefined && resultSourceMap !== false) {
556582
options.query = {resultSourceMap, ...options.query}
@@ -610,7 +636,11 @@ export function _requestObservable<R>(
610636
/**
611637
* @internal
612638
*/
613-
export function _request<R>(config: InitializedClientConfig, httpRequest: HttpRequest, options: Any): Observable<R> {
639+
export function _request<R>(
640+
config: InitializedClientConfig,
641+
httpRequest: HttpRequest,
642+
options: Any,
643+
): Observable<R> {
614644
const observable = _requestObservable<R>(config, httpRequest, options).pipe(
615645
filter((event: Any) => event.type === 'response'),
616646
map((event: Any) => event.body),
@@ -622,7 +652,11 @@ export function _request<R>(config: InitializedClientConfig, httpRequest: HttpRe
622652
/**
623653
* @internal
624654
*/
625-
export function _getDataUrl(config: InitializedClientConfig, operation: string, path?: string): string {
655+
export function _getDataUrl(
656+
config: InitializedClientConfig,
657+
operation: string,
658+
path?: string,
659+
): string {
626660
if (config['~experimental_resource']) {
627661
validators.resourceConfig(config)
628662
const resourceBase = resourceDataBase(config)
@@ -638,7 +672,7 @@ export function _getDataUrl(config: InitializedClientConfig, operation: string,
638672
/**
639673
* @internal
640674
*/
641-
export function _getUrl(config: InitializedClientConfig, uri: string, canUseCdn = false, options: {forceApiUrl?: boolean} = {}): string {
675+
export function _getUrl(config: InitializedClientConfig, uri: string, canUseCdn = false): string {
642676
const {url, cdnUrl} = config
643677
const base = canUseCdn ? cdnUrl : url
644678
return `${base}/${uri.replace(/^\//, '')}`

src/datasets/DatasetsClient.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ export class DatasetsClient {
105105
list(): Promise<DatasetsResponse> {
106106
validate.resourceGuard('dataset', this.#client.config())
107107
return lastValueFrom(
108-
_request<DatasetsResponse>(this.#client.config(), this.#httpRequest, {uri: '/datasets', tag: null}),
108+
_request<DatasetsResponse>(this.#client.config(), this.#httpRequest, {
109+
uri: '/datasets',
110+
tag: null,
111+
}),
109112
)
110113
}
111114
}

src/projects/ProjectsClient.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ export class ObservableProjectsClient {
3737
*/
3838
getById(projectId: string): Observable<SanityProject> {
3939
validate.resourceGuard('projects', this.#client.config())
40-
return _request<SanityProject>(this.#client.config(), this.#httpRequest, {uri: `/projects/${projectId}`})
40+
return _request<SanityProject>(this.#client.config(), this.#httpRequest, {
41+
uri: `/projects/${projectId}`,
42+
})
4143
}
4244
}
4345

@@ -72,7 +74,9 @@ export class ProjectsClient {
7274
getById(projectId: string): Promise<SanityProject> {
7375
validate.resourceGuard('projects', this.#client.config())
7476
return lastValueFrom(
75-
_request<SanityProject>(this.#client.config(), this.#httpRequest, {uri: `/projects/${projectId}`}),
77+
_request<SanityProject>(this.#client.config(), this.#httpRequest, {
78+
uri: `/projects/${projectId}`,
79+
}),
7680
)
7781
}
7882
}

src/releases/ReleasesClient.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,9 @@ export class ReleasesClient {
582582
releaseId,
583583
}
584584

585-
return lastValueFrom(_action(this.#client.config(), this.#httpRequest, unarchiveAction, options))
585+
return lastValueFrom(
586+
_action(this.#client.config(), this.#httpRequest, unarchiveAction, options),
587+
)
586588
}
587589

588590
/**
@@ -638,7 +640,9 @@ export class ReleasesClient {
638640
releaseId,
639641
}
640642

641-
return lastValueFrom(_action(this.#client.config(), this.#httpRequest, unscheduleAction, options))
643+
return lastValueFrom(
644+
_action(this.#client.config(), this.#httpRequest, unscheduleAction, options),
645+
)
642646
}
643647

644648
/**
@@ -682,6 +686,8 @@ export class ReleasesClient {
682686
{releaseId}: {releaseId: string},
683687
options?: BaseMutationOptions,
684688
): Promise<RawQueryResponse<SanityDocument[]>> {
685-
return lastValueFrom(_getReleaseDocuments(this.#client.config(), this.#httpRequest, releaseId, options))
689+
return lastValueFrom(
690+
_getReleaseDocuments(this.#client.config(), this.#httpRequest, releaseId, options),
691+
)
686692
}
687693
}

0 commit comments

Comments
 (0)