sanity 3.72.1 → 3.72.2-use-live-content-api.9
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/lib/_chunks-cjs/LiveQueries.js +236 -163
- package/lib/_chunks-cjs/LiveQueries.js.map +1 -1
- package/lib/_chunks-cjs/PresentationToolGrantsCheck.js +3 -7
- package/lib/_chunks-cjs/PresentationToolGrantsCheck.js.map +1 -1
- package/lib/_chunks-cjs/buildAction.js +3 -0
- package/lib/_chunks-cjs/buildAction.js.map +1 -1
- package/lib/_chunks-cjs/presentation.js +3 -4
- package/lib/_chunks-cjs/presentation.js.map +1 -1
- package/lib/_chunks-cjs/version.js +1 -1
- package/lib/_chunks-es/LiveQueries.mjs +235 -162
- package/lib/_chunks-es/LiveQueries.mjs.map +1 -1
- package/lib/_chunks-es/PresentationToolGrantsCheck.mjs +2 -4
- package/lib/_chunks-es/PresentationToolGrantsCheck.mjs.map +1 -1
- package/lib/_chunks-es/presentation.mjs +3 -3
- package/lib/_chunks-es/presentation.mjs.map +1 -1
- package/lib/_chunks-es/version.mjs +1 -1
- package/lib/_internal/cli/threads/validateDocuments.js +1 -1
- package/lib/_internal/cli/threads/validateDocuments.js.map +1 -1
- package/lib/_legacy/LiveQueries.esm.js +235 -162
- package/lib/_legacy/LiveQueries.esm.js.map +1 -1
- package/lib/_legacy/PresentationToolGrantsCheck.esm.js +2 -4
- package/lib/_legacy/PresentationToolGrantsCheck.esm.js.map +1 -1
- package/lib/_legacy/presentation.esm.js +3 -3
- package/lib/_legacy/presentation.esm.js.map +1 -1
- package/lib/_legacy/version.esm.js +1 -1
- package/package.json +13 -14
- package/src/_internal/cli/server/buildVendorDependencies.ts +1 -0
- package/src/_internal/cli/threads/validateDocuments.ts +2 -2
- package/src/presentation/PresentationTool.tsx +10 -21
- package/src/presentation/constants.ts +4 -16
- package/src/presentation/loader/LiveQueries.tsx +79 -234
- package/src/presentation/loader/useLiveEvents.ts +75 -0
- package/src/presentation/loader/useLiveQueries.ts +127 -0
- package/src/presentation/loader/utils.ts +2 -125
- package/src/presentation/types.ts +1 -18
- package/lib/_chunks-cjs/LoaderQueries.js +0 -281
- package/lib/_chunks-cjs/LoaderQueries.js.map +0 -1
- package/lib/_chunks-cjs/utils.js +0 -70
- package/lib/_chunks-cjs/utils.js.map +0 -1
- package/lib/_chunks-es/LoaderQueries.mjs +0 -288
- package/lib/_chunks-es/LoaderQueries.mjs.map +0 -1
- package/lib/_chunks-es/utils.mjs +0 -74
- package/lib/_chunks-es/utils.mjs.map +0 -1
- package/lib/_legacy/LoaderQueries.esm.js +0 -288
- package/lib/_legacy/LoaderQueries.esm.js.map +0 -1
- package/lib/_legacy/utils.esm.js +0 -74
- package/lib/_legacy/utils.esm.js.map +0 -1
- package/src/presentation/loader/LoaderQueries.tsx +0 -564
@@ -2,7 +2,6 @@ import {toPlainText} from '@portabletext/react'
|
|
2
2
|
import {isPortableTextBlock} from '@portabletext/toolkit'
|
3
3
|
import {type ClientPerspective, type QueryParams} from '@sanity/client'
|
4
4
|
import {type ApplySourceDocumentsUpdateFunction} from '@sanity/client/csm'
|
5
|
-
import {useCallback, useEffect, useMemo, useState, useSyncExternalStore} from 'react'
|
6
5
|
import {type FIXME} from 'sanity'
|
7
6
|
|
8
7
|
/**
|
@@ -37,7 +36,7 @@ export const mapChangedValue: ApplySourceDocumentsUpdateFunction = (
|
|
37
36
|
/**
|
38
37
|
* @internal
|
39
38
|
*/
|
40
|
-
export type QueryCacheKey = `${string}
|
39
|
+
export type QueryCacheKey = `${string}:${string}:${string}`
|
41
40
|
/**
|
42
41
|
* @internal
|
43
42
|
*/
|
@@ -46,127 +45,5 @@ export function getQueryCacheKey(
|
|
46
45
|
query: string,
|
47
46
|
params: QueryParams,
|
48
47
|
): QueryCacheKey {
|
49
|
-
return `${perspective}
|
50
|
-
}
|
51
|
-
|
52
|
-
/**
|
53
|
-
* Return params that are stable with deep equal as long as the key order is the same
|
54
|
-
* @internal
|
55
|
-
*/
|
56
|
-
export function useQueryParams(params?: undefined | null | QueryParams): QueryParams {
|
57
|
-
const stringifiedParams = useMemo(() => JSON.stringify(params || {}), [params])
|
58
|
-
return useMemo(() => JSON.parse(stringifiedParams) as QueryParams, [stringifiedParams])
|
59
|
-
}
|
60
|
-
|
61
|
-
/**
|
62
|
-
* 'hit' - the cache is fresh and valid
|
63
|
-
* 'stale' - the cache should revalidate, but can't/shouldn't yet (offline, visibility = hidden)
|
64
|
-
* 'refresh' - stale cache, and now is a great time to start refreshing
|
65
|
-
* 'inflight' - refreshing cache, revalidate events should be ignored
|
66
|
-
*/
|
67
|
-
export type RevalidateState = 'hit' | 'stale' | 'refresh' | 'inflight'
|
68
|
-
/**
|
69
|
-
* Keeps track of when queries should revalidate
|
70
|
-
*/
|
71
|
-
export function useRevalidate(props: {
|
72
|
-
/**
|
73
|
-
* How frequently queries should be refetched in the background to refresh the parts of queries that can't be source mapped.
|
74
|
-
* Setting it to `0` will disable background refresh.
|
75
|
-
*/
|
76
|
-
refreshInterval: number
|
77
|
-
}): [RevalidateState, () => () => void] {
|
78
|
-
const {refreshInterval} = props
|
79
|
-
|
80
|
-
const shouldPause = useShouldPause()
|
81
|
-
const [state, setState] = useState<RevalidateState>('hit')
|
82
|
-
|
83
|
-
// Keep track of indicators for when revalidation should be 'paused'
|
84
|
-
// Like if we're currently offline, or the document isn't visible
|
85
|
-
// Basically if 'stale' and all good we return 'refresh'
|
86
|
-
|
87
|
-
// Next keep track of staleness itself. If we come back online, on a windows focus event
|
88
|
-
// or on a refreshInterval timeout
|
89
|
-
// Basically it controls if cache should be 'hit' or 'stale'
|
90
|
-
|
91
|
-
// How to handle refresh to inflight?
|
92
|
-
|
93
|
-
const startRefresh = useCallback(() => {
|
94
|
-
setState('inflight')
|
95
|
-
return () => setState('hit')
|
96
|
-
}, [])
|
97
|
-
|
98
|
-
// Revalidate on refreshInterval
|
99
|
-
useEffect(() => {
|
100
|
-
// If refreshInterval is nullish then we don't want to refresh.
|
101
|
-
// Inflight means it's already refreshing and we pause the countdown.
|
102
|
-
// It's only necessary to start the countdown if the cache isn't already stale
|
103
|
-
if (!refreshInterval || state !== 'hit') {
|
104
|
-
return undefined
|
105
|
-
}
|
106
|
-
const timeout = setTimeout(() => setState('stale'), refreshInterval)
|
107
|
-
return () => clearTimeout(timeout)
|
108
|
-
}, [refreshInterval, state])
|
109
|
-
// Revalidate on windows focus
|
110
|
-
useEffect(() => {
|
111
|
-
if (state !== 'hit') {
|
112
|
-
return undefined
|
113
|
-
}
|
114
|
-
const onFocus = () => setState('stale')
|
115
|
-
window.addEventListener('focus', onFocus)
|
116
|
-
return () => window.removeEventListener('focus', onFocus)
|
117
|
-
}, [refreshInterval, state])
|
118
|
-
// Revalidate on changes to shouldPause
|
119
|
-
useEffect(() => {
|
120
|
-
// Mark as stale pre-emptively if we're offline or the document isn't visible
|
121
|
-
if (shouldPause && state === 'hit') {
|
122
|
-
setState('stale')
|
123
|
-
}
|
124
|
-
// If not paused we can mark stale as ready for refresh
|
125
|
-
if (!shouldPause && state === 'stale') {
|
126
|
-
setState('refresh')
|
127
|
-
}
|
128
|
-
}, [shouldPause, state])
|
129
|
-
|
130
|
-
return [state, startRefresh]
|
131
|
-
}
|
132
|
-
|
133
|
-
/**
|
134
|
-
* Keeps track of when revalidation and activities should be paused
|
135
|
-
*/
|
136
|
-
function useShouldPause(): boolean {
|
137
|
-
const [online, setOnline] = useState(false)
|
138
|
-
useEffect(() => {
|
139
|
-
setOnline(navigator.onLine)
|
140
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
141
|
-
const online = () => setOnline(true)
|
142
|
-
const offline = () => setOnline(false)
|
143
|
-
window.addEventListener('online', online)
|
144
|
-
window.addEventListener('offline', offline)
|
145
|
-
return () => {
|
146
|
-
window.removeEventListener('online', online)
|
147
|
-
window.removeEventListener('offline', offline)
|
148
|
-
}
|
149
|
-
}, [])
|
150
|
-
const visibilityState = useSyncExternalStore(
|
151
|
-
onVisibilityChange,
|
152
|
-
() => document.visibilityState,
|
153
|
-
() => 'hidden' satisfies DocumentVisibilityState,
|
154
|
-
)
|
155
|
-
|
156
|
-
// Should pause activity when offline
|
157
|
-
if (!online) {
|
158
|
-
return true
|
159
|
-
}
|
160
|
-
|
161
|
-
// Should pause when the document isn't visible, as it's likely the user isn't looking at the page
|
162
|
-
if (visibilityState === 'hidden') {
|
163
|
-
return true
|
164
|
-
}
|
165
|
-
|
166
|
-
return false
|
167
|
-
}
|
168
|
-
|
169
|
-
function onVisibilityChange(onStoreChange: () => void): () => void {
|
170
|
-
document.addEventListener('visibilitychange', onStoreChange)
|
171
|
-
return () => document.removeEventListener('visibilitychange', onStoreChange)
|
48
|
+
return `${perspective}:${query}:${JSON.stringify(params)}`
|
172
49
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {type ClientPerspective
|
1
|
+
import {type ClientPerspective} from '@sanity/client'
|
2
2
|
import {type ChannelInstance} from '@sanity/comlink'
|
3
3
|
import {
|
4
4
|
type LoaderControllerMsg,
|
@@ -257,23 +257,6 @@ export type PresentationPerspective = Extract<'published' | 'previewDrafts', Cli
|
|
257
257
|
/** @public */
|
258
258
|
export type PresentationViewport = 'desktop' | 'mobile'
|
259
259
|
|
260
|
-
/** @internal */
|
261
|
-
export type LiveQueriesState = Record<string, LiveQueriesStateValue>
|
262
|
-
|
263
|
-
/** @internal */
|
264
|
-
export interface LiveQueriesStateValue {
|
265
|
-
query: string
|
266
|
-
params: QueryParams
|
267
|
-
perspective: ClientPerspective
|
268
|
-
receivedAt: number
|
269
|
-
/**
|
270
|
-
* If false it means the query can't safely be garbage collected,
|
271
|
-
* as older versions of \@sanity/core-loader doesn't fire listen events
|
272
|
-
* on an interval.
|
273
|
-
*/
|
274
|
-
heartbeat: number | false
|
275
|
-
}
|
276
|
-
|
277
260
|
/** @internal */
|
278
261
|
export interface FrameState {
|
279
262
|
title: string | undefined
|
@@ -1,281 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var jsxRuntime = require("react/jsx-runtime"), reactCompilerRuntime = require("react-compiler-runtime"), csm = require("@sanity/client/csm"), comlink = require("@sanity/comlink"), presentationComlink = require("@sanity/presentation-comlink"), mendoza = require("mendoza"), LRUCache = require("mnemonist/lru-cache-with-delete"), React = require("react"), sanity = require("sanity"), presentation = require("./presentation.js"), utils = require("./utils.js");
|
3
|
-
function _interopDefaultCompat(e) {
|
4
|
-
return e && typeof e == "object" && "default" in e ? e : { default: e };
|
5
|
-
}
|
6
|
-
var LRUCache__default = /* @__PURE__ */ _interopDefaultCompat(LRUCache);
|
7
|
-
function LoaderQueries(props) {
|
8
|
-
const {
|
9
|
-
liveDocument,
|
10
|
-
controller,
|
11
|
-
perspective: activePerspective,
|
12
|
-
documentsOnPage,
|
13
|
-
onLoadersConnection,
|
14
|
-
onDocumentsOnPage
|
15
|
-
} = props, [comlink$1, setComlink] = React.useState(), [liveQueries, setLiveQueries] = React.useState({}), projectId = sanity.useProjectId(), dataset = sanity.useDataset();
|
16
|
-
React.useEffect(() => {
|
17
|
-
const interval = setInterval(() => (
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
19
|
-
setLiveQueries((liveQueries_0) => {
|
20
|
-
if (Object.keys(liveQueries_0).length < 1)
|
21
|
-
return liveQueries_0;
|
22
|
-
const now = Date.now();
|
23
|
-
if (!Object.values(liveQueries_0).some(
|
24
|
-
// eslint-disable-next-line max-nested-callbacks
|
25
|
-
(liveQuery) => liveQuery.heartbeat !== !1 && now > liveQuery.receivedAt + liveQuery.heartbeat
|
26
|
-
))
|
27
|
-
return liveQueries_0;
|
28
|
-
const next = {};
|
29
|
-
for (const [key, value] of Object.entries(liveQueries_0))
|
30
|
-
value.heartbeat !== !1 && now > value.receivedAt + value.heartbeat || (next[key] = value);
|
31
|
-
return next;
|
32
|
-
})
|
33
|
-
), presentation.MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL);
|
34
|
-
return () => clearInterval(interval);
|
35
|
-
}, []), React.useEffect(() => {
|
36
|
-
if (controller) {
|
37
|
-
const comlink_0 = controller.createChannel({
|
38
|
-
name: "presentation",
|
39
|
-
connectTo: "loaders",
|
40
|
-
heartbeat: !0
|
41
|
-
}, comlink.createConnectionMachine().provide({
|
42
|
-
actors: presentationComlink.createCompatibilityActors()
|
43
|
-
}));
|
44
|
-
return setComlink(comlink_0), comlink_0.onStatus(onLoadersConnection), comlink_0.on("loader/documents", (data) => {
|
45
|
-
data.projectId === projectId && data.dataset === dataset && onDocumentsOnPage(
|
46
|
-
"loaders",
|
47
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
48
|
-
data.perspective,
|
49
|
-
data.documents
|
50
|
-
);
|
51
|
-
}), comlink_0.on("loader/query-listen", (data_0) => {
|
52
|
-
if (data_0.projectId === projectId && data_0.dataset === dataset) {
|
53
|
-
if (typeof data_0.heartbeat == "number" && data_0.heartbeat < presentation.MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL)
|
54
|
-
throw new Error(`Loader query listen heartbeat interval must be at least ${presentation.MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL}ms`);
|
55
|
-
setLiveQueries((prev) => ({
|
56
|
-
...prev,
|
57
|
-
[getQueryCacheKey(data_0.query, data_0.params)]: {
|
58
|
-
perspective: data_0.perspective,
|
59
|
-
query: data_0.query,
|
60
|
-
params: data_0.params,
|
61
|
-
receivedAt: Date.now(),
|
62
|
-
heartbeat: data_0.heartbeat ?? !1
|
63
|
-
}
|
64
|
-
}));
|
65
|
-
}
|
66
|
-
}), comlink_0.start();
|
67
|
-
}
|
68
|
-
}, [controller, dataset, onDocumentsOnPage, onLoadersConnection, projectId]);
|
69
|
-
const [cache] = React.useState(() => new LRUCache__default.default(presentation.LIVE_QUERY_CACHE_SIZE)), studioClient = sanity.useClient({
|
70
|
-
apiVersion: "2023-10-16"
|
71
|
-
}), clientConfig = React.useMemo(() => studioClient.config(), [studioClient]), client = React.useMemo(() => studioClient.withConfig({
|
72
|
-
resultSourceMap: "withKeyArraySelector"
|
73
|
-
}), [studioClient]);
|
74
|
-
React.useEffect(() => {
|
75
|
-
if (comlink$1) {
|
76
|
-
const {
|
77
|
-
projectId: projectId_0,
|
78
|
-
dataset: dataset_0
|
79
|
-
} = clientConfig;
|
80
|
-
comlink$1.post("loader/perspective", {
|
81
|
-
projectId: projectId_0,
|
82
|
-
dataset: dataset_0,
|
83
|
-
perspective: activePerspective
|
84
|
-
});
|
85
|
-
}
|
86
|
-
}, [comlink$1, clientConfig, activePerspective]);
|
87
|
-
const turboIds = React.useMemo(() => {
|
88
|
-
const documentsActuallyInUse = documentsOnPage.map(({
|
89
|
-
_id
|
90
|
-
}) => _id), ids = [...new Set(documentsActuallyInUse)], max = cache.capacity;
|
91
|
-
return ids.length >= max && (ids.length = max), ids;
|
92
|
-
}, [cache.capacity, documentsOnPage]), [documentsCacheLastUpdated, setDocumentsCacheLastUpdated] = React.useState(0);
|
93
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
94
|
-
/* @__PURE__ */ jsxRuntime.jsx(Turbo, { cache, client, turboIds, setDocumentsCacheLastUpdated }),
|
95
|
-
Object.entries(liveQueries).map(([key_0, {
|
96
|
-
query,
|
97
|
-
params,
|
98
|
-
perspective
|
99
|
-
}]) => /* @__PURE__ */ jsxRuntime.jsx(QuerySubscription, { cache, projectId: clientConfig.projectId, dataset: clientConfig.dataset, perspective, query, params, comlink: comlink$1, client, refreshInterval: activePerspective ? 2e3 : 0, liveDocument, documentsCacheLastUpdated }, `${key_0}${perspective}`))
|
100
|
-
] });
|
101
|
-
}
|
102
|
-
const Turbo = React.memo(function(props) {
|
103
|
-
const {
|
104
|
-
cache,
|
105
|
-
client,
|
106
|
-
turboIds,
|
107
|
-
setDocumentsCacheLastUpdated
|
108
|
-
} = props, [batch, setBatch] = React.useState([]);
|
109
|
-
return React.useEffect(() => {
|
110
|
-
const batchSet = new Set(batch.flat()), nextBatch = /* @__PURE__ */ new Set();
|
111
|
-
for (const turboId of turboIds)
|
112
|
-
!batchSet.has(turboId) && !cache.has(turboId) && nextBatch.add(turboId);
|
113
|
-
const nextBatchSlice = [...nextBatch].slice(0, presentation.LIVE_QUERY_CACHE_BATCH_SIZE);
|
114
|
-
if (nextBatchSlice.length === 0) return;
|
115
|
-
const raf = requestAnimationFrame(() => (
|
116
|
-
// eslint-disable-next-line max-nested-callbacks
|
117
|
-
setBatch((prevBatch) => [...prevBatch.slice(-100), nextBatchSlice])
|
118
|
-
));
|
119
|
-
return () => cancelAnimationFrame(raf);
|
120
|
-
}, [batch, cache, turboIds]), React.useEffect(() => {
|
121
|
-
const subscription = client.listen("*", {}, {
|
122
|
-
events: ["mutation"],
|
123
|
-
effectFormat: "mendoza",
|
124
|
-
includePreviousRevision: !1,
|
125
|
-
includeResult: !1,
|
126
|
-
tag: "presentation-loader"
|
127
|
-
}).subscribe((update) => {
|
128
|
-
if (update.type === "mutation" && update.transition === "disappear" && cache.delete(update.documentId) && setDocumentsCacheLastUpdated(Date.now()), update.type !== "mutation" || !update.effects?.apply?.length) return;
|
129
|
-
const cachedDocument = cache.peek(update.documentId);
|
130
|
-
if (cachedDocument) {
|
131
|
-
const patchDoc = {
|
132
|
-
...cachedDocument
|
133
|
-
};
|
134
|
-
delete patchDoc._rev;
|
135
|
-
const patchedDocument = mendoza.applyPatch(patchDoc, update.effects.apply);
|
136
|
-
cache.set(update.documentId, patchedDocument), setDocumentsCacheLastUpdated(Date.now());
|
137
|
-
}
|
138
|
-
});
|
139
|
-
return () => subscription.unsubscribe();
|
140
|
-
}, [cache, client, setDocumentsCacheLastUpdated]), /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: batch.map((ids) => /* @__PURE__ */ jsxRuntime.jsx(GetDocuments, { cache, client, ids, setDocumentsCacheLastUpdated }, JSON.stringify(ids))) });
|
141
|
-
}), GetDocuments = React.memo(function(props) {
|
142
|
-
const {
|
143
|
-
client,
|
144
|
-
cache,
|
145
|
-
ids,
|
146
|
-
setDocumentsCacheLastUpdated
|
147
|
-
} = props;
|
148
|
-
return React.useEffect(() => {
|
149
|
-
const missingIds = ids.filter((id) => !cache.has(id));
|
150
|
-
missingIds.length !== 0 && client.getDocuments(missingIds).then((documents) => {
|
151
|
-
for (const doc of documents)
|
152
|
-
doc && doc?._id && (cache.set(doc._id, doc), setDocumentsCacheLastUpdated(Date.now()));
|
153
|
-
}, console.error);
|
154
|
-
}, [cache, client, ids, setDocumentsCacheLastUpdated]), null;
|
155
|
-
});
|
156
|
-
GetDocuments.displayName = "GetDocuments";
|
157
|
-
function QuerySubscription(props) {
|
158
|
-
const $ = reactCompilerRuntime.c(20), {
|
159
|
-
cache,
|
160
|
-
projectId,
|
161
|
-
dataset,
|
162
|
-
perspective,
|
163
|
-
query,
|
164
|
-
client,
|
165
|
-
refreshInterval,
|
166
|
-
liveDocument,
|
167
|
-
comlink: comlink2,
|
168
|
-
documentsCacheLastUpdated
|
169
|
-
} = props, params = utils.useQueryParams(props.params);
|
170
|
-
let t0;
|
171
|
-
$[0] !== cache || $[1] !== client || $[2] !== documentsCacheLastUpdated || $[3] !== liveDocument || $[4] !== params || $[5] !== perspective || $[6] !== query || $[7] !== refreshInterval ? (t0 = {
|
172
|
-
cache,
|
173
|
-
client,
|
174
|
-
liveDocument,
|
175
|
-
params,
|
176
|
-
perspective,
|
177
|
-
query,
|
178
|
-
refreshInterval,
|
179
|
-
documentsCacheLastUpdated
|
180
|
-
}, $[0] = cache, $[1] = client, $[2] = documentsCacheLastUpdated, $[3] = liveDocument, $[4] = params, $[5] = perspective, $[6] = query, $[7] = refreshInterval, $[8] = t0) : t0 = $[8];
|
181
|
-
const data = useQuerySubscription(t0), result = data?.result, resultSourceMap = data?.resultSourceMap, tags = data?.tags;
|
182
|
-
let t1, t2;
|
183
|
-
return $[9] !== comlink2 || $[10] !== dataset || $[11] !== params || $[12] !== perspective || $[13] !== projectId || $[14] !== query || $[15] !== result || $[16] !== resultSourceMap || $[17] !== tags ? (t1 = () => {
|
184
|
-
resultSourceMap && comlink2?.post("loader/query-change", {
|
185
|
-
projectId,
|
186
|
-
dataset,
|
187
|
-
perspective,
|
188
|
-
query,
|
189
|
-
params,
|
190
|
-
result,
|
191
|
-
resultSourceMap,
|
192
|
-
tags
|
193
|
-
});
|
194
|
-
}, t2 = [comlink2, dataset, params, perspective, projectId, query, result, resultSourceMap, tags], $[9] = comlink2, $[10] = dataset, $[11] = params, $[12] = perspective, $[13] = projectId, $[14] = query, $[15] = result, $[16] = resultSourceMap, $[17] = tags, $[18] = t1, $[19] = t2) : (t1 = $[18], t2 = $[19]), React.useEffect(t1, t2), null;
|
195
|
-
}
|
196
|
-
function useQuerySubscription(props) {
|
197
|
-
const {
|
198
|
-
cache,
|
199
|
-
liveDocument,
|
200
|
-
client,
|
201
|
-
refreshInterval,
|
202
|
-
query,
|
203
|
-
params,
|
204
|
-
perspective,
|
205
|
-
documentsCacheLastUpdated
|
206
|
-
} = props, [snapshot, setSnapshot] = React.useState(null), {
|
207
|
-
projectId: projectId_0,
|
208
|
-
dataset: dataset_0
|
209
|
-
} = React.useMemo(() => {
|
210
|
-
const {
|
211
|
-
projectId,
|
212
|
-
dataset
|
213
|
-
} = client.config();
|
214
|
-
return {
|
215
|
-
projectId,
|
216
|
-
dataset
|
217
|
-
};
|
218
|
-
}, [client]), [error, setError] = React.useState(null);
|
219
|
-
if (error) throw error;
|
220
|
-
const [revalidate, startRefresh] = utils.useRevalidate({
|
221
|
-
refreshInterval
|
222
|
-
}), shouldRefetch = revalidate === "refresh" || revalidate === "inflight";
|
223
|
-
return React.useEffect(() => {
|
224
|
-
if (!shouldRefetch)
|
225
|
-
return;
|
226
|
-
let fulfilled = !1, fetching = !1;
|
227
|
-
const controller = new AbortController();
|
228
|
-
async function effect() {
|
229
|
-
const {
|
230
|
-
signal
|
231
|
-
} = controller;
|
232
|
-
fetching = !0;
|
233
|
-
const {
|
234
|
-
result,
|
235
|
-
resultSourceMap,
|
236
|
-
syncTags
|
237
|
-
} = await client.fetch(query, params, {
|
238
|
-
tag: "presentation-loader",
|
239
|
-
signal,
|
240
|
-
perspective,
|
241
|
-
filterResponse: !1
|
242
|
-
});
|
243
|
-
fetching = !1, signal.aborted || (setSnapshot({
|
244
|
-
result,
|
245
|
-
resultSourceMap,
|
246
|
-
tags: syncTags
|
247
|
-
}), fulfilled = !0);
|
248
|
-
}
|
249
|
-
const onFinally = startRefresh();
|
250
|
-
return effect().catch((error_0) => {
|
251
|
-
fetching = !1, error_0.name !== "AbortError" && setError(error_0);
|
252
|
-
}).finally(onFinally), () => {
|
253
|
-
!fulfilled && !fetching && controller.abort();
|
254
|
-
};
|
255
|
-
}, [client, dataset_0, liveDocument, params, perspective, projectId_0, query, shouldRefetch, startRefresh]), React.useMemo(() => documentsCacheLastUpdated && snapshot?.resultSourceMap ? {
|
256
|
-
result: turboChargeResultIfSourceMap(cache, liveDocument, snapshot.result, perspective, snapshot.resultSourceMap),
|
257
|
-
resultSourceMap: snapshot.resultSourceMap
|
258
|
-
} : snapshot, [cache, documentsCacheLastUpdated, liveDocument, perspective, snapshot]);
|
259
|
-
}
|
260
|
-
let warnedAboutCrossDatasetReference = !1;
|
261
|
-
function turboChargeResultIfSourceMap(cache, liveDocument, result, perspective, resultSourceMap) {
|
262
|
-
if (perspective === "raw")
|
263
|
-
throw new Error("turboChargeResultIfSourceMap does not support raw perspective");
|
264
|
-
return csm.applySourceDocuments(result, resultSourceMap, (sourceDocument) => {
|
265
|
-
if (sourceDocument._projectId) {
|
266
|
-
warnedAboutCrossDatasetReference || (console.warn("Cross dataset references are not supported yet, ignoring source document", sourceDocument), warnedAboutCrossDatasetReference = !0);
|
267
|
-
return;
|
268
|
-
}
|
269
|
-
return liveDocument?._id && csm.getPublishedId(liveDocument._id) === csm.getPublishedId(sourceDocument._id) ? typeof liveDocument._id == "string" && typeof sourceDocument._type == "string" ? liveDocument : {
|
270
|
-
...liveDocument,
|
271
|
-
_id: liveDocument._id || sourceDocument._id,
|
272
|
-
_type: liveDocument._type || sourceDocument._type
|
273
|
-
} : cache.get(sourceDocument._id);
|
274
|
-
}, utils.mapChangedValue, perspective);
|
275
|
-
}
|
276
|
-
function getQueryCacheKey(query, params) {
|
277
|
-
return `${query}-${typeof params == "string" ? params : JSON.stringify(params)}`;
|
278
|
-
}
|
279
|
-
exports.default = LoaderQueries;
|
280
|
-
exports.turboChargeResultIfSourceMap = turboChargeResultIfSourceMap;
|
281
|
-
//# sourceMappingURL=LoaderQueries.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"LoaderQueries.js","sources":["../../src/presentation/loader/LoaderQueries.tsx"],"sourcesContent":["import {\n type ClientConfig,\n type ClientPerspective,\n type ContentSourceMap,\n type QueryParams,\n type SyncTag,\n} from '@sanity/client'\nimport {applySourceDocuments, getPublishedId} from '@sanity/client/csm'\nimport {\n type ChannelInstance,\n type Controller,\n createConnectionMachine,\n type StatusEvent,\n} from '@sanity/comlink'\nimport {\n createCompatibilityActors,\n type LoaderControllerMsg,\n type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {applyPatch} from 'mendoza'\nimport LRUCache from 'mnemonist/lru-cache-with-delete'\nimport {memo, useEffect, useMemo, useState} from 'react'\nimport {\n type SanityClient,\n type SanityDocument,\n useClient,\n // useCurrentUser,\n useDataset,\n useProjectId,\n} from 'sanity'\n\nimport {\n LIVE_QUERY_CACHE_BATCH_SIZE,\n LIVE_QUERY_CACHE_SIZE,\n MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL,\n} from '../constants'\nimport {\n type LiveQueriesState,\n type LiveQueriesStateValue,\n type LoaderConnection,\n type PresentationPerspective,\n} from '../types'\nimport {type DocumentOnPage} from '../useDocumentsOnPage'\nimport {mapChangedValue, useQueryParams, useRevalidate} from './utils'\n\nexport interface LoaderQueriesProps {\n liveDocument: Partial<SanityDocument> | null | undefined\n controller: Controller | undefined\n perspective: ClientPerspective\n documentsOnPage: {_id: string; _type: string}[]\n onLoadersConnection: (event: StatusEvent) => void\n onDocumentsOnPage: (\n key: string,\n perspective: PresentationPerspective,\n state: DocumentOnPage[],\n ) => void\n}\n\nexport default function LoaderQueries(props: LoaderQueriesProps): React.JSX.Element {\n const {\n liveDocument,\n controller,\n perspective: activePerspective,\n documentsOnPage,\n onLoadersConnection,\n onDocumentsOnPage,\n } = props\n\n const [comlink, setComlink] = useState<ChannelInstance<LoaderControllerMsg, LoaderNodeMsg>>()\n const [liveQueries, setLiveQueries] = useState<LiveQueriesState>({})\n\n const projectId = useProjectId()\n const dataset = useDataset()\n\n useEffect(() => {\n const interval = setInterval(\n () =>\n // eslint-disable-next-line @typescript-eslint/no-shadow\n setLiveQueries((liveQueries) => {\n if (Object.keys(liveQueries).length < 1) {\n return liveQueries\n }\n\n const now = Date.now()\n const hasAnyExpired = Object.values(liveQueries).some(\n // eslint-disable-next-line max-nested-callbacks\n (liveQuery) =>\n liveQuery.heartbeat !== false && now > liveQuery.receivedAt + liveQuery.heartbeat,\n )\n if (!hasAnyExpired) {\n return liveQueries\n }\n const next = {} as LiveQueriesState\n for (const [key, value] of Object.entries(liveQueries)) {\n if (value.heartbeat !== false && now > value.receivedAt + value.heartbeat) {\n continue\n }\n next[key] = value\n }\n return next\n }),\n MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL,\n )\n return () => clearInterval(interval)\n }, [])\n\n useEffect(() => {\n if (controller) {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const comlink = controller.createChannel<LoaderControllerMsg, LoaderNodeMsg>(\n {\n name: 'presentation',\n connectTo: 'loaders',\n heartbeat: true,\n },\n createConnectionMachine<LoaderControllerMsg, LoaderNodeMsg>().provide({\n actors: createCompatibilityActors<LoaderControllerMsg>(),\n }),\n )\n setComlink(comlink)\n\n comlink.onStatus(onLoadersConnection)\n\n comlink.on('loader/documents', (data) => {\n if (data.projectId === projectId && data.dataset === dataset) {\n onDocumentsOnPage(\n 'loaders',\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data.perspective as unknown as any,\n data.documents,\n )\n }\n })\n\n comlink.on('loader/query-listen', (data) => {\n if (data.projectId === projectId && data.dataset === dataset) {\n if (\n typeof data.heartbeat === 'number' &&\n data.heartbeat < MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL\n ) {\n throw new Error(\n `Loader query listen heartbeat interval must be at least ${MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL}ms`,\n )\n }\n setLiveQueries((prev) => ({\n ...prev,\n [getQueryCacheKey(data.query, data.params)]: {\n perspective: data.perspective,\n query: data.query,\n params: data.params,\n receivedAt: Date.now(),\n heartbeat: data.heartbeat ?? false,\n } satisfies LiveQueriesStateValue,\n }))\n }\n })\n\n return comlink.start()\n }\n return undefined\n }, [controller, dataset, onDocumentsOnPage, onLoadersConnection, projectId])\n\n const [cache] = useState(() => new LRUCache<string, SanityDocument>(LIVE_QUERY_CACHE_SIZE))\n const studioClient = useClient({apiVersion: '2023-10-16'})\n const clientConfig = useMemo(() => studioClient.config(), [studioClient])\n const client = useMemo(\n () =>\n studioClient.withConfig({\n resultSourceMap: 'withKeyArraySelector',\n }),\n [studioClient],\n )\n useEffect(() => {\n if (comlink) {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const {projectId, dataset} = clientConfig\n comlink.post('loader/perspective', {\n projectId: projectId!,\n dataset: dataset!,\n perspective: activePerspective,\n })\n }\n }, [comlink, clientConfig, activePerspective])\n\n const turboIds = useMemo(() => {\n const documentsActuallyInUse = documentsOnPage.map(({_id}) => _id)\n const set = new Set(documentsActuallyInUse)\n const ids = [...set]\n const max = cache.capacity\n if (ids.length >= max) {\n ids.length = max\n }\n return ids\n }, [cache.capacity, documentsOnPage])\n\n const [documentsCacheLastUpdated, setDocumentsCacheLastUpdated] = useState(0)\n\n return (\n <>\n <Turbo\n cache={cache}\n client={client}\n turboIds={turboIds}\n setDocumentsCacheLastUpdated={setDocumentsCacheLastUpdated}\n />\n {Object.entries(liveQueries).map(([key, {query, params, perspective}]) => (\n <QuerySubscription\n key={`${key}${perspective}`}\n cache={cache}\n projectId={clientConfig.projectId!}\n dataset={clientConfig.dataset!}\n perspective={perspective}\n query={query}\n params={params}\n comlink={comlink}\n client={client}\n refreshInterval={activePerspective ? 2000 : 0}\n liveDocument={liveDocument}\n documentsCacheLastUpdated={documentsCacheLastUpdated}\n />\n ))}\n </>\n )\n}\n\ninterface SharedProps {\n /**\n * The Sanity client to use for fetching data and listening to mutations.\n */\n client: SanityClient\n /**\n * How frequently queries should be refetched in the background to refresh the parts of queries that can't be source mapped.\n * Setting it to `0` will disable background refresh.\n * @defaultValue 10000\n */\n refreshInterval?: number\n /**\n * The documents cache to use for turbo-charging queries.\n */\n cache: LRUCache<string, SanityDocument>\n}\n\ninterface TurboProps extends Pick<SharedProps, 'client' | 'cache'> {\n turboIds: string[]\n setDocumentsCacheLastUpdated: (timestamp: number) => void\n}\n/**\n * A turbo-charged mutation observer that uses Content Source Maps to apply mendoza patches on your queries\n */\nconst Turbo = memo(function Turbo(props: TurboProps) {\n const {cache, client, turboIds, setDocumentsCacheLastUpdated} = props\n // Figure out which documents are missing from the cache\n const [batch, setBatch] = useState<string[][]>([])\n useEffect(() => {\n const batchSet = new Set(batch.flat())\n const nextBatch = new Set<string>()\n for (const turboId of turboIds) {\n if (!batchSet.has(turboId) && !cache.has(turboId)) {\n nextBatch.add(turboId)\n }\n }\n const nextBatchSlice = [...nextBatch].slice(0, LIVE_QUERY_CACHE_BATCH_SIZE)\n if (nextBatchSlice.length === 0) return undefined\n const raf = requestAnimationFrame(() =>\n // eslint-disable-next-line max-nested-callbacks\n setBatch((prevBatch) => [...prevBatch.slice(-LIVE_QUERY_CACHE_BATCH_SIZE), nextBatchSlice]),\n )\n return () => cancelAnimationFrame(raf)\n }, [batch, cache, turboIds])\n\n // Use the same listen instance and patch documents as they come in\n useEffect(() => {\n const subscription = client\n .listen(\n '*',\n {},\n {\n events: ['mutation'],\n effectFormat: 'mendoza',\n includePreviousRevision: false,\n includeResult: false,\n tag: 'presentation-loader',\n },\n )\n .subscribe((update) => {\n if (update.type === 'mutation' && update.transition === 'disappear') {\n if (cache.delete(update.documentId)) {\n setDocumentsCacheLastUpdated(Date.now())\n }\n }\n\n if (update.type !== 'mutation' || !update.effects?.apply?.length) return\n // Schedule a reach state update with the ID of the document that were mutated\n // This react handler will apply the document to related source map snapshots\n const cachedDocument = cache.peek(update.documentId)\n if (cachedDocument as SanityDocument) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const patchDoc = {...cachedDocument} as any\n delete patchDoc._rev\n const patchedDocument = applyPatch(patchDoc, update.effects.apply)\n cache.set(update.documentId, patchedDocument)\n setDocumentsCacheLastUpdated(Date.now())\n }\n })\n return () => subscription.unsubscribe()\n }, [cache, client, setDocumentsCacheLastUpdated])\n\n return (\n <>\n {batch.map((ids) => (\n <GetDocuments\n key={JSON.stringify(ids)}\n cache={cache}\n client={client}\n ids={ids}\n setDocumentsCacheLastUpdated={setDocumentsCacheLastUpdated}\n />\n ))}\n </>\n )\n})\n\ninterface GetDocumentsProps extends Pick<SharedProps, 'client' | 'cache'> {\n ids: string[]\n setDocumentsCacheLastUpdated: (timestamp: number) => void\n}\nconst GetDocuments = memo(function GetDocuments(props: GetDocumentsProps) {\n const {client, cache, ids, setDocumentsCacheLastUpdated} = props\n\n useEffect(() => {\n const missingIds = ids.filter((id) => !cache.has(id))\n if (missingIds.length === 0) return\n client.getDocuments(missingIds).then((documents) => {\n for (const doc of documents) {\n if (doc && doc?._id) {\n cache.set(doc._id, doc)\n setDocumentsCacheLastUpdated(Date.now())\n }\n }\n // eslint-disable-next-line no-console\n }, console.error)\n }, [cache, client, ids, setDocumentsCacheLastUpdated])\n\n return null\n})\nGetDocuments.displayName = 'GetDocuments'\n\ninterface QuerySubscriptionProps\n extends Pick<\n UseQuerySubscriptionProps,\n 'client' | 'cache' | 'refreshInterval' | 'liveDocument' | 'documentsCacheLastUpdated'\n > {\n projectId: string\n dataset: string\n perspective: ClientPerspective\n query: string\n params: QueryParams\n comlink: LoaderConnection | undefined\n}\nfunction QuerySubscription(props: QuerySubscriptionProps) {\n const {\n cache,\n projectId,\n dataset,\n perspective,\n query,\n client,\n refreshInterval,\n liveDocument,\n comlink,\n documentsCacheLastUpdated,\n } = props\n\n const params = useQueryParams(props.params)\n const data = useQuerySubscription({\n cache,\n client,\n liveDocument,\n params,\n perspective,\n query,\n refreshInterval,\n documentsCacheLastUpdated,\n })\n const result = data?.result\n const resultSourceMap = data?.resultSourceMap\n const tags = data?.tags\n\n useEffect(() => {\n if (resultSourceMap) {\n comlink?.post('loader/query-change', {\n projectId,\n dataset,\n perspective,\n query,\n params,\n result,\n resultSourceMap,\n tags,\n })\n }\n }, [comlink, dataset, params, perspective, projectId, query, result, resultSourceMap, tags])\n\n return null\n}\n\ninterface UseQuerySubscriptionProps\n extends Required<Pick<SharedProps, 'client' | 'refreshInterval' | 'cache'>> {\n liveDocument: Partial<SanityDocument> | null | undefined\n query: string\n params: QueryParams\n perspective: ClientPerspective\n documentsCacheLastUpdated: number\n}\nfunction useQuerySubscription(props: UseQuerySubscriptionProps) {\n const {\n cache,\n liveDocument,\n client,\n refreshInterval,\n query,\n params,\n perspective,\n documentsCacheLastUpdated,\n } = props\n const [snapshot, setSnapshot] = useState<{\n result: unknown\n resultSourceMap?: ContentSourceMap\n tags?: SyncTag[]\n } | null>(null)\n const {projectId, dataset} = useMemo(() => {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const {projectId, dataset} = client.config()\n return {projectId, dataset} as Required<Pick<ClientConfig, 'projectId' | 'dataset'>>\n }, [client])\n\n // Make sure any async errors bubble up to the nearest error boundary\n const [error, setError] = useState<unknown>(null)\n if (error) throw error\n\n const [revalidate, startRefresh] = useRevalidate({refreshInterval})\n const shouldRefetch = revalidate === 'refresh' || revalidate === 'inflight'\n useEffect(() => {\n if (!shouldRefetch) {\n return undefined\n }\n\n let fulfilled = false\n let fetching = false\n const controller = new AbortController()\n // eslint-disable-next-line no-inner-declarations\n async function effect() {\n const {signal} = controller\n fetching = true\n const {result, resultSourceMap, syncTags} = await client.fetch(query, params, {\n tag: 'presentation-loader',\n signal,\n perspective,\n filterResponse: false,\n })\n fetching = false\n\n if (!signal.aborted) {\n setSnapshot({result, resultSourceMap, tags: syncTags})\n\n fulfilled = true\n }\n }\n const onFinally = startRefresh()\n effect()\n // eslint-disable-next-line @typescript-eslint/no-shadow\n .catch((error) => {\n fetching = false\n if (error.name !== 'AbortError') {\n setError(error)\n }\n })\n .finally(onFinally)\n return () => {\n if (!fulfilled && !fetching) {\n controller.abort()\n }\n }\n }, [\n client,\n dataset,\n liveDocument,\n params,\n perspective,\n projectId,\n query,\n shouldRefetch,\n startRefresh,\n ])\n\n return useMemo(() => {\n if (documentsCacheLastUpdated && snapshot?.resultSourceMap) {\n return {\n result: turboChargeResultIfSourceMap(\n cache,\n liveDocument,\n snapshot.result,\n perspective,\n snapshot.resultSourceMap,\n ),\n resultSourceMap: snapshot.resultSourceMap,\n }\n }\n return snapshot\n }, [cache, documentsCacheLastUpdated, liveDocument, perspective, snapshot])\n}\n\nlet warnedAboutCrossDatasetReference = false\nexport function turboChargeResultIfSourceMap<T = unknown>(\n cache: SharedProps['cache'],\n liveDocument: Partial<SanityDocument> | null | undefined,\n result: T,\n perspective: ClientPerspective,\n resultSourceMap?: ContentSourceMap,\n): T {\n if (perspective === 'raw') {\n throw new Error('turboChargeResultIfSourceMap does not support raw perspective')\n }\n return applySourceDocuments(\n result,\n resultSourceMap,\n (sourceDocument) => {\n if (sourceDocument._projectId) {\n // @TODO Handle cross dataset references\n if (!warnedAboutCrossDatasetReference) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Cross dataset references are not supported yet, ignoring source document',\n sourceDocument,\n )\n warnedAboutCrossDatasetReference = true\n }\n return undefined\n }\n // If there's a displayed document, always prefer it\n if (\n liveDocument?._id &&\n getPublishedId(liveDocument._id) === getPublishedId(sourceDocument._id)\n ) {\n if (typeof liveDocument._id === 'string' && typeof sourceDocument._type === 'string') {\n return liveDocument as unknown as Required<Pick<SanityDocument, '_id' | '_type'>>\n }\n return {\n ...liveDocument,\n _id: liveDocument._id || sourceDocument._id,\n _type: liveDocument._type || sourceDocument._type,\n }\n }\n // Fallback to general documents cache\n return cache.get(sourceDocument._id)\n },\n mapChangedValue,\n perspective,\n )\n}\n\nfunction getQueryCacheKey(query: string, params: QueryParams | string): `${string}-${string}` {\n return `${query}-${typeof params === 'string' ? params : JSON.stringify(params)}`\n}\n"],"names":["LoaderQueries","props","liveDocument","controller","perspective","activePerspective","documentsOnPage","onLoadersConnection","onDocumentsOnPage","comlink","setComlink","useState","liveQueries","setLiveQueries","projectId","useProjectId","dataset","useDataset","useEffect","interval","setInterval","Object","keys","length","now","Date","values","some","liveQuery","heartbeat","receivedAt","next","key","value","entries","MIN_LOADER_QUERY_LISTEN_HEARTBEAT_INTERVAL","clearInterval","createChannel","name","connectTo","createConnectionMachine","provide","actors","createCompatibilityActors","onStatus","on","data","documents","Error","prev","getQueryCacheKey","query","params","start","cache","LRUCache","LIVE_QUERY_CACHE_SIZE","studioClient","useClient","apiVersion","clientConfig","useMemo","config","client","withConfig","resultSourceMap","post","turboIds","documentsActuallyInUse","map","_id","ids","Set","max","capacity","documentsCacheLastUpdated","setDocumentsCacheLastUpdated","jsxs","Fragment","jsx","Turbo","memo","batch","setBatch","batchSet","flat","nextBatch","turboId","has","add","nextBatchSlice","slice","LIVE_QUERY_CACHE_BATCH_SIZE","raf","requestAnimationFrame","prevBatch","cancelAnimationFrame","subscription","listen","events","effectFormat","includePreviousRevision","includeResult","tag","subscribe","update","type","transition","delete","documentId","effects","apply","cachedDocument","peek","patchDoc","_rev","patchedDocument","applyPatch","set","unsubscribe","JSON","stringify","GetDocuments","missingIds","filter","id","getDocuments","then","doc","console","error","displayName","QuerySubscription","$","_c","refreshInterval","useQueryParams","t0","useQuerySubscription","result","tags","t1","t2","snapshot","setSnapshot","setError","revalidate","startRefresh","useRevalidate","shouldRefetch","fulfilled","fetching","AbortController","effect","signal","syncTags","fetch","filterResponse","aborted","onFinally","catch","finally","abort","turboChargeResultIfSourceMap","warnedAboutCrossDatasetReference","applySourceDocuments","sourceDocument","_projectId","warn","getPublishedId","_type","get","mapChangedValue"],"mappings":"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"}
|
package/lib/_chunks-cjs/utils.js
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var reactCompilerRuntime = require("react-compiler-runtime"), react = require("@portabletext/react"), toolkit = require("@portabletext/toolkit"), React = require("react");
|
3
|
-
const mapChangedValue = (changedValue, {
|
4
|
-
previousValue
|
5
|
-
}) => {
|
6
|
-
if (typeof previousValue == "string") {
|
7
|
-
if (typeof changedValue == "number")
|
8
|
-
return `${changedValue}`;
|
9
|
-
if (Array.isArray(changedValue)) {
|
10
|
-
if (changedValue.length === 0)
|
11
|
-
return "";
|
12
|
-
if (changedValue.some((node) => typeof node == "object" && toolkit.isPortableTextBlock(node)))
|
13
|
-
return react.toPlainText(changedValue);
|
14
|
-
}
|
15
|
-
}
|
16
|
-
return changedValue;
|
17
|
-
};
|
18
|
-
function useQueryParams(params) {
|
19
|
-
const stringifiedParams = React.useMemo(() => JSON.stringify(params || {}), [params]);
|
20
|
-
return React.useMemo(() => JSON.parse(stringifiedParams), [stringifiedParams]);
|
21
|
-
}
|
22
|
-
function useRevalidate(props) {
|
23
|
-
const $ = reactCompilerRuntime.c(16), {
|
24
|
-
refreshInterval
|
25
|
-
} = props, shouldPause = useShouldPause(), [state, setState] = React.useState("hit");
|
26
|
-
let t0;
|
27
|
-
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => (setState("inflight"), () => setState("hit")), $[0] = t0) : t0 = $[0];
|
28
|
-
const startRefresh = t0;
|
29
|
-
let t1, t2;
|
30
|
-
$[1] !== refreshInterval || $[2] !== state ? (t1 = () => {
|
31
|
-
if (!refreshInterval || state !== "hit")
|
32
|
-
return;
|
33
|
-
const timeout = setTimeout(() => setState("stale"), refreshInterval);
|
34
|
-
return () => clearTimeout(timeout);
|
35
|
-
}, t2 = [refreshInterval, state], $[1] = refreshInterval, $[2] = state, $[3] = t1, $[4] = t2) : (t1 = $[3], t2 = $[4]), React.useEffect(t1, t2);
|
36
|
-
let t3;
|
37
|
-
$[5] !== state ? (t3 = () => {
|
38
|
-
if (state !== "hit")
|
39
|
-
return;
|
40
|
-
const onFocus = () => setState("stale");
|
41
|
-
return window.addEventListener("focus", onFocus), () => window.removeEventListener("focus", onFocus);
|
42
|
-
}, $[5] = state, $[6] = t3) : t3 = $[6];
|
43
|
-
let t4;
|
44
|
-
$[7] !== refreshInterval || $[8] !== state ? (t4 = [refreshInterval, state], $[7] = refreshInterval, $[8] = state, $[9] = t4) : t4 = $[9], React.useEffect(t3, t4);
|
45
|
-
let t5, t6;
|
46
|
-
$[10] !== shouldPause || $[11] !== state ? (t5 = () => {
|
47
|
-
shouldPause && state === "hit" && setState("stale"), !shouldPause && state === "stale" && setState("refresh");
|
48
|
-
}, t6 = [shouldPause, state], $[10] = shouldPause, $[11] = state, $[12] = t5, $[13] = t6) : (t5 = $[12], t6 = $[13]), React.useEffect(t5, t6);
|
49
|
-
let t7;
|
50
|
-
return $[14] !== state ? (t7 = [state, startRefresh], $[14] = state, $[15] = t7) : t7 = $[15], t7;
|
51
|
-
}
|
52
|
-
function useShouldPause() {
|
53
|
-
const [online, setOnline] = React.useState(!1);
|
54
|
-
React.useEffect(() => {
|
55
|
-
setOnline(navigator.onLine);
|
56
|
-
const online_0 = () => setOnline(!0), offline = () => setOnline(!1);
|
57
|
-
return window.addEventListener("online", online_0), window.addEventListener("offline", offline), () => {
|
58
|
-
window.removeEventListener("online", online_0), window.removeEventListener("offline", offline);
|
59
|
-
};
|
60
|
-
}, []);
|
61
|
-
const visibilityState = React.useSyncExternalStore(onVisibilityChange, () => document.visibilityState, () => "hidden");
|
62
|
-
return !online || visibilityState === "hidden";
|
63
|
-
}
|
64
|
-
function onVisibilityChange(onStoreChange) {
|
65
|
-
return document.addEventListener("visibilitychange", onStoreChange), () => document.removeEventListener("visibilitychange", onStoreChange);
|
66
|
-
}
|
67
|
-
exports.mapChangedValue = mapChangedValue;
|
68
|
-
exports.useQueryParams = useQueryParams;
|
69
|
-
exports.useRevalidate = useRevalidate;
|
70
|
-
//# sourceMappingURL=utils.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../src/presentation/loader/utils.ts"],"sourcesContent":["import {toPlainText} from '@portabletext/react'\nimport {isPortableTextBlock} from '@portabletext/toolkit'\nimport {type ClientPerspective, type QueryParams} from '@sanity/client'\nimport {type ApplySourceDocumentsUpdateFunction} from '@sanity/client/csm'\nimport {useCallback, useEffect, useMemo, useState, useSyncExternalStore} from 'react'\nimport {type FIXME} from 'sanity'\n\n/**\n * Used by `applySourceDocuments`\n * @internal\n */\nexport const mapChangedValue: ApplySourceDocumentsUpdateFunction = (\n changedValue: FIXME,\n {previousValue},\n) => {\n if (typeof previousValue === 'string') {\n if (typeof changedValue === 'number') {\n // If the string() function was used in the query, we need to convert the source value to a string as well\n return `${changedValue}`\n }\n // If it's an array in the source, but a string in the query response, it could be pt::text\n if (Array.isArray(changedValue)) {\n if (changedValue.length === 0) {\n // If it's empty assume it's PT and return an empty string\n return ''\n }\n // If the array contains any valid block type, assume the GROQ initially used pt::text on it and do the same conversion\n if (changedValue.some((node) => typeof node === 'object' && isPortableTextBlock(node))) {\n return toPlainText(changedValue)\n }\n }\n }\n\n return changedValue\n}\n\n/**\n * @internal\n */\nexport type QueryCacheKey = `${string}-${string}-${string}`\n/**\n * @internal\n */\nexport function getQueryCacheKey(\n perspective: ClientPerspective,\n query: string,\n params: QueryParams,\n): QueryCacheKey {\n return `${perspective}-${query}-${JSON.stringify(params)}`\n}\n\n/**\n * Return params that are stable with deep equal as long as the key order is the same\n * @internal\n */\nexport function useQueryParams(params?: undefined | null | QueryParams): QueryParams {\n const stringifiedParams = useMemo(() => JSON.stringify(params || {}), [params])\n return useMemo(() => JSON.parse(stringifiedParams) as QueryParams, [stringifiedParams])\n}\n\n/**\n * 'hit' - the cache is fresh and valid\n * 'stale' - the cache should revalidate, but can't/shouldn't yet (offline, visibility = hidden)\n * 'refresh' - stale cache, and now is a great time to start refreshing\n * 'inflight' - refreshing cache, revalidate events should be ignored\n */\nexport type RevalidateState = 'hit' | 'stale' | 'refresh' | 'inflight'\n/**\n * Keeps track of when queries should revalidate\n */\nexport function useRevalidate(props: {\n /**\n * How frequently queries should be refetched in the background to refresh the parts of queries that can't be source mapped.\n * Setting it to `0` will disable background refresh.\n */\n refreshInterval: number\n}): [RevalidateState, () => () => void] {\n const {refreshInterval} = props\n\n const shouldPause = useShouldPause()\n const [state, setState] = useState<RevalidateState>('hit')\n\n // Keep track of indicators for when revalidation should be 'paused'\n // Like if we're currently offline, or the document isn't visible\n // Basically if 'stale' and all good we return 'refresh'\n\n // Next keep track of staleness itself. If we come back online, on a windows focus event\n // or on a refreshInterval timeout\n // Basically it controls if cache should be 'hit' or 'stale'\n\n // How to handle refresh to inflight?\n\n const startRefresh = useCallback(() => {\n setState('inflight')\n return () => setState('hit')\n }, [])\n\n // Revalidate on refreshInterval\n useEffect(() => {\n // If refreshInterval is nullish then we don't want to refresh.\n // Inflight means it's already refreshing and we pause the countdown.\n // It's only necessary to start the countdown if the cache isn't already stale\n if (!refreshInterval || state !== 'hit') {\n return undefined\n }\n const timeout = setTimeout(() => setState('stale'), refreshInterval)\n return () => clearTimeout(timeout)\n }, [refreshInterval, state])\n // Revalidate on windows focus\n useEffect(() => {\n if (state !== 'hit') {\n return undefined\n }\n const onFocus = () => setState('stale')\n window.addEventListener('focus', onFocus)\n return () => window.removeEventListener('focus', onFocus)\n }, [refreshInterval, state])\n // Revalidate on changes to shouldPause\n useEffect(() => {\n // Mark as stale pre-emptively if we're offline or the document isn't visible\n if (shouldPause && state === 'hit') {\n setState('stale')\n }\n // If not paused we can mark stale as ready for refresh\n if (!shouldPause && state === 'stale') {\n setState('refresh')\n }\n }, [shouldPause, state])\n\n return [state, startRefresh]\n}\n\n/**\n * Keeps track of when revalidation and activities should be paused\n */\nfunction useShouldPause(): boolean {\n const [online, setOnline] = useState(false)\n useEffect(() => {\n setOnline(navigator.onLine)\n // eslint-disable-next-line @typescript-eslint/no-shadow\n const online = () => setOnline(true)\n const offline = () => setOnline(false)\n window.addEventListener('online', online)\n window.addEventListener('offline', offline)\n return () => {\n window.removeEventListener('online', online)\n window.removeEventListener('offline', offline)\n }\n }, [])\n const visibilityState = useSyncExternalStore(\n onVisibilityChange,\n () => document.visibilityState,\n () => 'hidden' satisfies DocumentVisibilityState,\n )\n\n // Should pause activity when offline\n if (!online) {\n return true\n }\n\n // Should pause when the document isn't visible, as it's likely the user isn't looking at the page\n if (visibilityState === 'hidden') {\n return true\n }\n\n return false\n}\n\nfunction onVisibilityChange(onStoreChange: () => void): () => void {\n document.addEventListener('visibilitychange', onStoreChange)\n return () => document.removeEventListener('visibilitychange', onStoreChange)\n}\n"],"names":["mapChangedValue","changedValue","previousValue","Array","isArray","length","some","node","isPortableTextBlock","toPlainText","useQueryParams","params","stringifiedParams","useMemo","JSON","stringify","parse","useRevalidate","props","$","_c","refreshInterval","shouldPause","useShouldPause","state","setState","useState","t0","Symbol","for","startRefresh","t1","t2","timeout","setTimeout","clearTimeout","useEffect","t3","onFocus","addEventListener","window","removeEventListener","t4","t5","t6","t7","online","setOnline","navigator","onLine","offline","visibilityState","useSyncExternalStore","onVisibilityChange","document","onStoreChange"],"mappings":"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"}
|