@nuxtjs/sanity
Version:
Sanity integration for Nuxt
123 lines (122 loc) • 4.38 kB
JavaScript
import { hash } from "ohash";
import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
import { useAsyncData } from "#imports";
import { reactive, ref, watch } from "vue";
import { useSanity } from "./useSanity.js";
import { useSanityConfig } from "./useSanityConfig.js";
import { useIsSanityPresentationTool } from "./useIsSanityPresentationTool.js";
import { useSanityPerspective } from "./useSanityPerspective.js";
import { useSanityVisualEditingState } from "./useSanityVisualEditingState.js";
import { createProxyClient } from "../util/createProxyClient.js";
import { useSanityTagRevalidation } from "./internal/useSanityTagRevalidation.js";
import { useSanityQueryFetcher } from "./internal/useSanityQueryFetcher.js";
const getToken = ({
config,
client,
perspective
}) => {
if (perspective === "published") {
return client.config().token || void 0;
}
if (config.liveContent?.serverToken) {
return config.liveContent.serverToken;
}
if (config.visualEditing) {
return config.visualEditing.token;
}
return void 0;
};
export function useSanityQuery(query, _params, _options = {}) {
const {
client: _client,
perspective: _perspective,
stega: _stega,
...options
} = _options;
const sanity = useSanity(_client);
const config = useSanityConfig();
const visualEditingState = useSanityVisualEditingState();
const clientConfig = sanity.client.config();
const params = _params ? reactive(_params) : void 0;
const queryKey = "sanity-" + hash(query + (params ? JSON.stringify(params) : ""));
const perspective = useSanityPerspective(_perspective);
const stega = _stega ?? (clientConfig.stega?.enabled && typeof clientConfig.stega.studioUrl !== "undefined" && visualEditingState?.enabled);
options.watch = options.watch || [];
options.watch.push(perspective);
if (params) {
options.watch.push(params);
}
const data = ref(null);
const sourceMap = ref(null);
const encodeDataAttribute = ref(() => {
});
const updateRefs = (newData, newSourceMap) => {
data.value = newData;
sourceMap.value = newSourceMap || null;
encodeDataAttribute.value = defineEncodeDataAttribute(
newData,
newSourceMap,
config.visualEditing?.studioUrl
);
};
const client = import.meta.server || perspective.value === "published" ? sanity.client : createProxyClient();
let tagRevalidation = void 0;
let queryFetcher = void 0;
const _inPresentation = useIsSanityPresentationTool();
watch(_inPresentation, (inPresentation, _wasInPresentation, onCleanup) => {
onCleanup(() => {
queryFetcher?.unsubscribe?.();
tagRevalidation?.unsubscribe();
});
const enableQueryFetcher = !!(visualEditingState?.enabled && config.visualEditing?.mode === "live-visual-editing" && inPresentation === true);
if (enableQueryFetcher) {
queryFetcher = useSanityQueryFetcher({
onSnapshot: updateRefs,
params,
query,
queryStore: sanity.queryStore
});
return;
}
if (config.liveContent && (import.meta.server || !enableQueryFetcher)) {
tagRevalidation = useSanityTagRevalidation({
client,
liveStore: sanity.liveStore,
queryKey
});
}
}, { immediate: true });
const result = useAsyncData(queryKey, async () => {
const useCdn = perspective.value === "published";
const token = getToken({
config,
client,
perspective: perspective.value
});
const options2 = {
cacheMode: useCdn ? "noStale" : void 0,
filterResponse: false,
lastLiveEventId: tagRevalidation?.getLastLiveEventId(),
perspective: perspective.value,
resultSourceMap: "withKeyArraySelector",
stega,
token,
useCdn
};
await tagRevalidation?.fetchTags(query, params, options2);
const { result: result2, resultSourceMap } = await client.fetch(query, params || {}, options2);
updateRefs(result2, resultSourceMap);
return { data: result2, sourceMap: resultSourceMap };
}, options);
return Object.assign(new Promise((resolve) => {
result.then((value) => {
updateRefs(value.data.value.data, value.data.value.sourceMap);
resolve({
...result,
data,
sourceMap,
encodeDataAttribute
});
});
}), { ...result, data, sourceMap, encodeDataAttribute });
}