@devite/nuxt-sanity 2.4.3 → 2.5.1

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.
Files changed (35) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +3 -3
  3. package/dist/runtime/client/DefaultSanityClient.d.ts +2 -2
  4. package/dist/runtime/client/DefaultSanityClient.js +6 -1
  5. package/dist/runtime/client/MinimalSanityClient.d.ts +1 -1
  6. package/dist/runtime/client/MinimalSanityClient.js +10 -5
  7. package/dist/runtime/client/SanityClient.d.ts +3 -2
  8. package/dist/runtime/components/SanityPage.vue +1 -2
  9. package/dist/runtime/composables/{useSanityQuery.d.ts → query.d.ts} +8 -7
  10. package/dist/runtime/composables/query.js +56 -0
  11. package/dist/runtime/composables/useSanityLiveMode.d.ts +1 -1
  12. package/dist/runtime/composables/useSanityLiveMode.js +6 -10
  13. package/dist/runtime/plugins/visual-editing.js +2 -2
  14. package/dist/runtime/server/routes/cache/asset.js +1 -1
  15. package/dist/runtime/server/routes/cache/query.d.ts +1 -1
  16. package/dist/runtime/server/routes/cache/query.js +3 -2
  17. package/dist/runtime/server/routes/cache/webhook.js +3 -2
  18. package/dist/runtime/server/utils/useSanityClient.d.ts +3 -2
  19. package/dist/runtime/server/utils/useSanityClient.js +16 -13
  20. package/dist/runtime/utils/default/fetchSanityData.d.ts +5 -0
  21. package/dist/runtime/utils/default/fetchSanityData.js +5 -0
  22. package/dist/runtime/utils/resolveImageAssetById.js +5 -2
  23. package/dist/runtime/utils/resolveInternalLink.js +5 -2
  24. package/dist/runtime/utils/useSanityClient.d.ts +3 -1
  25. package/dist/runtime/utils/useSanityClient.js +12 -7
  26. package/dist/runtime/utils/visualEditing/fetchSanityData.d.ts +5 -0
  27. package/dist/runtime/utils/visualEditing/fetchSanityData.js +21 -0
  28. package/dist/runtime/utils/visualEditing/subscribeToChanges.d.ts +5 -0
  29. package/dist/runtime/utils/visualEditing/subscribeToChanges.js +19 -0
  30. package/package.json +4 -1
  31. package/dist/runtime/composables/useLazySanityQuery.d.ts +0 -4
  32. package/dist/runtime/composables/useLazySanityQuery.js +0 -4
  33. package/dist/runtime/composables/useSanityQuery.js +0 -69
  34. package/dist/runtime/utils/getOrCreateSanityClient.d.ts +0 -4
  35. package/dist/runtime/utils/getOrCreateSanityClient.js +0 -15
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devite/nuxt-sanity",
3
- "version": "2.4.3",
3
+ "version": "2.5.1",
4
4
  "configKey": "sanity",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
package/dist/module.mjs CHANGED
@@ -3,7 +3,7 @@ import { defineNuxtModule, createResolver, addPlugin, addServerHandler, addImpor
3
3
  import defu from 'defu';
4
4
 
5
5
  const name = "@devite/nuxt-sanity";
6
- const version = "2.4.3";
6
+ const version = "2.5.1";
7
7
 
8
8
  const CONFIG_KEY = "sanity";
9
9
  const module = defineNuxtModule({
@@ -141,8 +141,8 @@ const module = defineNuxtModule({
141
141
  addImports(
142
142
  [
143
143
  // composables
144
- { name: "useSanityQuery", from: resolve("runtime/composables/useSanityQuery") },
145
- { name: "useLazySanityQuery", from: resolve("runtime/composables/useLazySanityQuery") },
144
+ { name: "useSanityQuery", from: resolve("runtime/composables/query") },
145
+ { name: "useLazySanityQuery", from: resolve("runtime/composables/query") },
146
146
  // helper methods
147
147
  { name: "groq", from: resolve("runtime/utils/groq") },
148
148
  { name: "resolveImageAssetById", from: resolve("runtime/utils/resolveImageAssetById") },
@@ -6,9 +6,9 @@ declare class DefaultSanityClient extends SanityClient {
6
6
  readonly client: SanityClientType;
7
7
  queryStore: QueryStore | null;
8
8
  constructor(config: ModuleOptions);
9
- fetch<T = unknown>(query: string, params: QueryParams, options?: {
9
+ fetch<T>(query: string, params: QueryParams, options?: {
10
10
  perspective?: ClientPerspective;
11
- }): Promise<T>;
11
+ }): Promise<T | null>;
12
12
  createQueryStore(tag?: string): void;
13
13
  clone(): DefaultSanityClient;
14
14
  }
@@ -11,7 +11,12 @@ class DefaultSanityClient extends SanityClient {
11
11
  this.client = createClient(config);
12
12
  }
13
13
  async fetch(query, params, options) {
14
- return await this.client.fetch(query, params, options);
14
+ try {
15
+ return await this.client.fetch(query, params, options);
16
+ } catch (error) {
17
+ console.error("Failed to fetch data from Sanity:", error);
18
+ return null;
19
+ }
15
20
  }
16
21
  createQueryStore(tag) {
17
22
  const queryStore = createCoreQueryStore({
@@ -9,7 +9,7 @@ declare class MinimalSanityClient extends SanityClient {
9
9
  private toQueryString;
10
10
  fetch<T>(query: string, params: QueryParams, _options?: {
11
11
  perspective?: ClientPerspective;
12
- }): Promise<T>;
12
+ }): Promise<T | null>;
13
13
  clone(): MinimalSanityClient;
14
14
  }
15
15
  export default MinimalSanityClient;
@@ -41,11 +41,16 @@ class MinimalSanityClient extends SanityClient {
41
41
  const useCache = minimalClientConfig.cachingEnabled && isEligibleForGetRequest;
42
42
  const cacheBaseUrl = import.meta.client ? minimalClientConfig.cacheClientBaseUrl : minimalClientConfig.cacheServerBaseUrl;
43
43
  const requestUrl = useCache && cacheBaseUrl ? cacheBaseUrl + minimalClientConfig.queryEndpoint : `https://${this.config.projectId}.${this.config.useCdn && isEligibleForGetRequest ? API_CDN_HOST : API_HOST}${this.queryPath}`;
44
- return (await $fetch(requestUrl + queryString, {
45
- ...this.fetchOptions,
46
- method: isEligibleForGetRequest ? "GET" : "POST",
47
- body: !isEligibleForGetRequest ? { query, params } : void 0
48
- })).result;
44
+ try {
45
+ return (await $fetch(requestUrl + queryString, {
46
+ ...this.fetchOptions,
47
+ method: isEligibleForGetRequest ? "GET" : "POST",
48
+ body: !isEligibleForGetRequest ? { query, params } : void 0
49
+ })).result;
50
+ } catch (error) {
51
+ console.error("Failed to fetch data from Sanity:", error);
52
+ return null;
53
+ }
49
54
  }
50
55
  clone() {
51
56
  return new MinimalSanityClient({
@@ -1,10 +1,11 @@
1
1
  import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
2
2
  import type { ModuleOptions } from '@devite/nuxt-sanity';
3
+ export type SanityClientType = 'minimal' | 'default';
3
4
  export default abstract class SanityClient {
4
5
  config: ModuleOptions;
5
6
  sourceMap: ContentSourceMap | undefined;
6
7
  protected constructor(config: ModuleOptions);
7
- abstract fetch<T = unknown>(query: string, params: QueryParams, options?: {
8
+ abstract fetch<T>(query: string, params: QueryParams, options?: {
8
9
  perspective?: ClientPerspective;
9
- }): Promise<T>;
10
+ }): Promise<T | null>;
10
11
  }
@@ -14,9 +14,8 @@ import type { ImageAsset } from '@sanity/types'
14
14
  import type { GlobalSEO, Home, NotFound, Page } from '@devite/nuxt-sanity'
15
15
  import { setResponseStatus } from 'h3'
16
16
  import { IMAGE_WITHOUT_PREVIEW_PROJECTION } from '../utils/projections'
17
- import { useSanityQuery } from '../composables/useSanityQuery'
18
17
  import { groq } from '../utils/groq'
19
- import { useHead, useRoute, useRuntimeConfig, useSeoMeta, useRequestEvent } from '#imports'
18
+ import { useHead, useRequestEvent, useRoute, useRuntimeConfig, useSanityQuery, useSeoMeta } from '#imports'
20
19
 
21
20
  const path = useRoute().path
22
21
  const groqFilter = path === '/' ? '_type == "home"' : `_type == "page" && slug.current == $slug`
@@ -1,12 +1,17 @@
1
+ import type { AsyncDataOptions, AsyncDataRequestStatus } from 'nuxt/app';
1
2
  import type { ContentSourceMap, QueryParams } from '@sanity/client';
2
3
  import type { EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
3
- import type { AsyncDataOptions, AsyncDataRequestStatus } from 'nuxt/app';
4
4
  import { type Ref } from 'vue';
5
+ export interface UseSanityQueryOptions<T> extends AsyncDataOptions<T> {
6
+ client?: 'default' | 'minimal';
7
+ perspective?: 'previewDrafts' | 'published' | 'raw';
8
+ }
5
9
  export interface SanityQueryResponse<T> {
6
10
  data: T;
7
11
  sourceMap?: ContentSourceMap;
8
12
  encodeDataAttribute?: EncodeDataAttributeFunction;
9
13
  }
14
+ export type AsyncSanityData<T, E> = _AsyncSanityData<T, E> & Promise<_AsyncSanityData<T, E>>;
10
15
  interface AsyncDataExecuteOptions {
11
16
  _initial?: boolean;
12
17
  dedupe?: boolean;
@@ -21,10 +26,6 @@ export interface _AsyncSanityData<T, E> {
21
26
  error: Ref<E | null>;
22
27
  status: Ref<AsyncDataRequestStatus>;
23
28
  }
24
- export type AsyncSanityData<T, E> = _AsyncSanityData<T, E> & Promise<_AsyncSanityData<T, E>>;
25
- export interface UseSanityQueryOptions<T> extends AsyncDataOptions<T> {
26
- client?: 'default' | 'minimal';
27
- perspective?: 'previewDrafts' | 'published' | 'raw';
28
- }
29
- export declare const useSanityQuery: <T = unknown, E = Error>(query: string, _params?: QueryParams, _options?: UseSanityQueryOptions<SanityQueryResponse<T | null>>, lazy?: boolean) => AsyncSanityData<T | null, E>;
29
+ export declare function useLazySanityQuery<T = unknown, E = Error>(query: string, params?: QueryParams, options?: UseSanityQueryOptions<SanityQueryResponse<T | null>>): AsyncSanityData<T | null, E>;
30
+ export declare function useSanityQuery<T = unknown, E = Error>(query: string, _params?: QueryParams, options?: UseSanityQueryOptions<SanityQueryResponse<T | null>>, lazy?: boolean): AsyncSanityData<T | null, E>;
30
31
  export {};
@@ -0,0 +1,56 @@
1
+ import { hash } from "ohash";
2
+ import { useAsyncData, useLazyAsyncData } from "nuxt/app";
3
+ import { reactive, ref } from "vue";
4
+ import defu from "defu";
5
+ import useSanityClient from "../utils/useSanityClient.js";
6
+ import useServerSanityClient from "../server/utils/useSanityClient.js";
7
+ import { useSanityVisualEditingState } from "./useSanityVisualEditingState.js";
8
+ import { useRuntimeConfig } from "#imports";
9
+ export function useLazySanityQuery(query, params = {}, options = {}) {
10
+ return useSanityQuery(query, params, options, true);
11
+ }
12
+ export function useSanityQuery(query, _params = {}, options = {}, lazy = false) {
13
+ const $config = useRuntimeConfig();
14
+ const sanityConfig = defu(import.meta.server ? $config.sanity : {}, $config.public.sanity);
15
+ const visualEditingEnabled = useSanityVisualEditingState().enabled;
16
+ const clientType = visualEditingEnabled ? "default" : options.client || (sanityConfig.minimalClient ? "minimal" : "default");
17
+ const perspective = options.perspective || (visualEditingEnabled ? "previewDrafts" : "published");
18
+ const reactiveParams = _params ? reactive(_params) : void 0;
19
+ if (reactiveParams) {
20
+ options.watch ||= [];
21
+ options.watch.push(reactiveParams);
22
+ }
23
+ const data = ref(null);
24
+ const sourceMap = ref(null);
25
+ const encodeDataAttribute = ref(() => {
26
+ });
27
+ function updateRefs(resultData, resultSourceMap, resultEncodeDataAttribute) {
28
+ data.value = resultData;
29
+ sourceMap.value = resultSourceMap || null;
30
+ if (resultEncodeDataAttribute) encodeDataAttribute.value = resultEncodeDataAttribute;
31
+ }
32
+ const fetchFunc = () => new Promise((resolve) => {
33
+ (visualEditingEnabled ? import("../utils/visualEditing/fetchSanityData") : import("../utils/default/fetchSanityData")).then(async ({ fetchSanityData }) => {
34
+ const client = import.meta.server ? useServerSanityClient(clientType, sanityConfig) : await useSanityClient(visualEditingEnabled, clientType, sanityConfig);
35
+ function onDataUpdate(resultData, resultSourceMap, resultEncodeDataAttribute) {
36
+ if (resultEncodeDataAttribute)
37
+ encodeDataAttribute.value = resultEncodeDataAttribute;
38
+ resolve({ data: resultData, sourceMap: resultSourceMap });
39
+ }
40
+ const fetchSanityDataFunc = fetchSanityData;
41
+ fetchSanityDataFunc(query, reactiveParams, client, perspective, onDataUpdate);
42
+ });
43
+ });
44
+ const key = "sanity-" + hash(query + (reactiveParams ? JSON.stringify(reactiveParams) : ""));
45
+ const pendingData = lazy ? useLazyAsyncData(key, fetchFunc, options) : useAsyncData(key, fetchFunc, options);
46
+ if (visualEditingEnabled && import.meta.client) {
47
+ import("../utils/visualEditing/subscribeToChanges.js").then(async ({ subscribeToChanges }) => {
48
+ const client = await useSanityClient(visualEditingEnabled, clientType, sanityConfig);
49
+ subscribeToChanges(query, reactiveParams, client, updateRefs);
50
+ });
51
+ }
52
+ return Object.assign(new Promise((resolve) => pendingData.then(({ data: { value } }) => {
53
+ updateRefs(value.data, value.sourceMap);
54
+ resolve({ ...pendingData, data, sourceMap, encodeDataAttribute });
55
+ })), { ...pendingData, data, sourceMap, encodeDataAttribute });
56
+ }
@@ -1 +1 @@
1
- export declare const useSanityLiveMode: () => () => void;
1
+ export declare const useSanityLiveMode: () => Promise<() => void>;
@@ -1,16 +1,12 @@
1
- import { onScopeDispose } from "vue";
2
1
  import useSanityClient from "../utils/useSanityClient.js";
3
- export const useSanityLiveMode = () => {
4
- let disable = () => {
5
- };
2
+ import { useRuntimeConfig } from "#imports";
3
+ export const useSanityLiveMode = async () => {
6
4
  if (import.meta.client) {
7
- const client = useSanityClient("default");
5
+ const client = await useSanityClient(true, "default", useRuntimeConfig().public.sanity);
8
6
  if (client.queryStore) {
9
- disable = client.queryStore.enableLiveMode({
10
- client: client.client
11
- });
7
+ return client.queryStore.enableLiveMode({ client: client.client });
12
8
  }
13
9
  }
14
- onScopeDispose(disable);
15
- return disable;
10
+ return () => {
11
+ };
16
12
  };
@@ -6,7 +6,7 @@ import {
6
6
  useCookie,
7
7
  useRuntimeConfig
8
8
  } from "#imports";
9
- export default defineNuxtPlugin(() => {
9
+ export default defineNuxtPlugin(async () => {
10
10
  const visualEditingState = useSanityVisualEditingState();
11
11
  const $config = useRuntimeConfig();
12
12
  const { visualEditing } = $config.public.sanity;
@@ -24,7 +24,7 @@ export default defineNuxtPlugin(() => {
24
24
  refresh: visualEditing?.refresh,
25
25
  zIndex: visualEditing?.zIndex
26
26
  });
27
- if (visualEditing?.mode === "live-visual-editing") useSanityLiveMode();
27
+ if (visualEditing?.mode === "live-visual-editing") await useSanityLiveMode();
28
28
  break;
29
29
  }
30
30
  }
@@ -1,7 +1,7 @@
1
1
  import { createError, defineEventHandler, getRequestURL } from "h3";
2
2
  import { hash } from "ohash";
3
+ import { useStorage } from "nitropack/runtime/internal/storage";
3
4
  import resolveSanityImageUrl from "../../utils/resolveSanityImageUrl.js";
4
- import { useStorage } from "#imports";
5
5
  const TTL = 60 * 60 * 24 * 365;
6
6
  export default defineEventHandler(async (event) => {
7
7
  const queryParams = getRequestURL(event).searchParams;
@@ -1,5 +1,5 @@
1
1
  declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
2
- result: any;
2
+ result: string | number | true | object;
3
3
  } | {
4
4
  result?: undefined;
5
5
  }>>;
@@ -5,8 +5,9 @@ import {
5
5
  setResponseHeader
6
6
  } from "h3";
7
7
  import { hash } from "ohash";
8
+ import { useStorage } from "nitropack/runtime/internal/storage";
8
9
  import useSanityClient from "../../utils/useSanityClient.js";
9
- import { useRuntimeConfig, useStorage } from "#imports";
10
+ import { useRuntimeConfig } from "#imports";
10
11
  const TTL = 60 * 60 * 8;
11
12
  export default defineEventHandler(async (event) => {
12
13
  const url = getRequestURL(event);
@@ -38,7 +39,7 @@ export default defineEventHandler(async (event) => {
38
39
  { perspective }
39
40
  );
40
41
  if (!result)
41
- throw createError({ statusCode: 400, statusMessage: "Invalid query" });
42
+ throw createError({ statusCode: 404, statusMessage: "No results" });
42
43
  setResponseHeader(event, "Content-Type", "application/json");
43
44
  if (Object.keys(result).length === 0)
44
45
  return {};
@@ -1,6 +1,7 @@
1
1
  import { createHmac } from "node:crypto";
2
- import { defineEventHandler, readRawBody, setResponseStatus, getRequestHeader } from "h3";
3
- import { useRuntimeConfig, useStorage } from "#imports";
2
+ import { defineEventHandler, getRequestHeader, readRawBody, setResponseStatus } from "h3";
3
+ import { useStorage } from "nitropack/runtime/internal/storage";
4
+ import { useRuntimeConfig } from "#imports";
4
5
  export default defineEventHandler(async (event) => {
5
6
  const body = await readRawBody(event);
6
7
  const signatureHeader = getRequestHeader(event, "sanity-webhook-signature");
@@ -1,3 +1,4 @@
1
+ import type { ModuleOptions } from '@devite/nuxt-sanity';
1
2
  import type SanityClient from '../../client/SanityClient.js';
2
- import type { SanityClientType } from '../../utils/getOrCreateSanityClient.js';
3
- export default function useSanityClient(type?: SanityClientType): SanityClient;
3
+ import type { SanityClientType } from '../../client/SanityClient.js';
4
+ export default function useSanityClient(type?: SanityClientType, config?: ModuleOptions): SanityClient;
@@ -1,17 +1,20 @@
1
1
  import defu from "defu";
2
- import getOrCreateSanityClient from "../../utils/getOrCreateSanityClient.js";
2
+ import DefaultSanityClient from "../../client/DefaultSanityClient.js";
3
+ import MinimalSanityClient from "../../client/MinimalSanityClient.js";
3
4
  import { useRuntimeConfig } from "#imports";
4
- export default function useSanityClient(type) {
5
- const $config = useRuntimeConfig();
6
- const sanityConfig = defu($config.sanity, $config.public.sanity || {});
5
+ const clients = {};
6
+ export default function useSanityClient(type, config) {
7
+ const sanityConfig = config || defu(useRuntimeConfig().sanity, useRuntimeConfig().public.sanity || {});
7
8
  const visualEditingEnabled = type !== "minimal" && sanityConfig.visualEditing && sanityConfig.visualEditing.previewMode !== false;
8
- return getOrCreateSanityClient(
9
- visualEditingEnabled || false,
10
- visualEditingEnabled ? {
11
- ...sanityConfig,
12
- token: sanityConfig.visualEditing?.token,
13
- useCdn: false
14
- } : sanityConfig,
15
- type
16
- );
9
+ const clientType = (type || (sanityConfig.minimalClient ? "minimal" : "default")) + (visualEditingEnabled ? "-visual-editing" : "");
10
+ if (clientType in clients) return clients[clientType];
11
+ const clientConfig = visualEditingEnabled ? {
12
+ ...sanityConfig,
13
+ token: sanityConfig.visualEditing?.token,
14
+ useCdn: false
15
+ } : sanityConfig;
16
+ const client = new (clientType === "minimal" ? MinimalSanityClient : DefaultSanityClient)(clientConfig);
17
+ if (visualEditingEnabled) client.createQueryStore();
18
+ clients[clientType] = client;
19
+ return client;
17
20
  }
@@ -0,0 +1,5 @@
1
+ import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
2
+ import type { Reactive } from 'vue';
3
+ import type { EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
4
+ import type SanityClient from '../../client/SanityClient.js';
5
+ export declare function fetchSanityData<T>(query: string, params: Reactive<QueryParams> | undefined, client: SanityClient, perspective: ClientPerspective, callback: (data: T | null, sourceMap?: ContentSourceMap, encodeDataAttribute?: EncodeDataAttributeFunction) => void): Promise<void>;
@@ -0,0 +1,5 @@
1
+ export async function fetchSanityData(query, params, client, perspective, callback) {
2
+ client.fetch(query, params || {}, { perspective }).then((fetchResult) => {
3
+ callback(fetchResult);
4
+ });
5
+ }
@@ -1,5 +1,8 @@
1
- import { useSanityQuery } from "../composables/useSanityQuery.js";
2
1
  import { IMAGE_ASSET_PROJECTION } from "./projections.js";
2
+ import { useSanityQuery } from "#imports";
3
3
  export const resolveImageAssetById = async (id) => {
4
- return useSanityQuery(`*[_type == "sanity.imageAsset" && _id == $assetId][0] ${IMAGE_ASSET_PROJECTION}`, { assetId: id }).data;
4
+ return (await useSanityQuery(
5
+ `*[_type == "sanity.imageAsset" && _id == $assetId][0] ${IMAGE_ASSET_PROJECTION}`,
6
+ { assetId: id }
7
+ )).data;
5
8
  };
@@ -1,4 +1,7 @@
1
- import { useSanityQuery } from "../composables/useSanityQuery.js";
1
+ import { useSanityQuery } from "#imports";
2
2
  export const resolveInternalLink = async (reference) => {
3
- return useSanityQuery(`*[_id == $documentId][0] { '_type': 'linkInternal', 'slug': coalesce(slug.current, '/') }`, { documentId: reference._ref }).data;
3
+ return (await useSanityQuery(
4
+ `*[_id == $documentId][0] { '_type': 'linkInternal', 'slug': coalesce(slug.current, '/') }`,
5
+ { documentId: reference._ref }
6
+ )).data;
4
7
  };
@@ -1,2 +1,4 @@
1
+ import type { ModuleOptions } from '@devite/nuxt-sanity';
1
2
  import type SanityClient from '../client/SanityClient.js';
2
- export default function useSanityClient(type?: 'minimal' | 'default'): SanityClient;
3
+ import type { SanityClientType } from '../client/SanityClient.js';
4
+ export default function useSanityClient(visualEditing: boolean, type: SanityClientType, config: ModuleOptions): Promise<SanityClient>;
@@ -1,8 +1,13 @@
1
- import { useSanityVisualEditingState } from "../composables/useSanityVisualEditingState.js";
2
- import getOrCreateSanityClient from "./getOrCreateSanityClient.js";
3
- import { useRuntimeConfig } from "#imports";
4
- export default function useSanityClient(type) {
5
- const $config = useRuntimeConfig();
6
- const sanityConfig = $config.public.sanity;
7
- return getOrCreateSanityClient(useSanityVisualEditingState().enabled, sanityConfig, type);
1
+ const clients = {};
2
+ export default async function useSanityClient(visualEditing, type, config) {
3
+ const clientType = visualEditing ? "default" : type;
4
+ if (clientType in clients) return clients[clientType];
5
+ const clientConfig = {
6
+ ...config,
7
+ stega: visualEditing && config.stega
8
+ };
9
+ const client = new (await (clientType === "minimal" ? import("../client/MinimalSanityClient") : import("../client/DefaultSanityClient"))).default(clientConfig);
10
+ if (visualEditing) client.createQueryStore();
11
+ clients[clientType] = client;
12
+ return client;
8
13
  }
@@ -0,0 +1,5 @@
1
+ import type { ClientPerspective, ContentSourceMap, QueryParams } from '@sanity/client';
2
+ import type { Reactive } from 'vue';
3
+ import { type EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
4
+ import type SanityClient from '../../client/SanityClient.js';
5
+ export declare function fetchSanityData<T>(query: string, params: Reactive<QueryParams> | undefined, client: SanityClient, perspective: ClientPerspective, callback: (data: T | null, sourceMap?: ContentSourceMap, encodeDataAttribute?: EncodeDataAttributeFunction) => void): Promise<void>;
@@ -0,0 +1,21 @@
1
+ import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
2
+ export async function fetchSanityData(query, params, client, perspective, callback) {
3
+ function updateResult(data2, sourceMap2) {
4
+ const encodeDataAttribute = sourceMap2 ? defineEncodeDataAttribute(data2, sourceMap2, client.config.visualEditing?.studioUrl) : void 0;
5
+ callback(data2, sourceMap2, encodeDataAttribute);
6
+ }
7
+ const defaultClient = client;
8
+ const proxyClient = {
9
+ fetch: (query2, params2, options) => $fetch(client.config.visualEditing.proxyEndpoint || "/_sanity/fetch", {
10
+ method: "POST",
11
+ body: { query: query2, params: params2, options }
12
+ })
13
+ };
14
+ const currentClient = import.meta.server ? defaultClient.queryStore.unstable__serverClient.instance || defaultClient.client : proxyClient;
15
+ const { result: data, resultSourceMap: sourceMap } = await currentClient.fetch(query, params || {}, {
16
+ perspective,
17
+ filterResponse: false,
18
+ resultSourceMap: "withKeyArraySelector"
19
+ });
20
+ updateResult(data, sourceMap);
21
+ }
@@ -0,0 +1,5 @@
1
+ import { type Reactive } from 'vue';
2
+ import type { ContentSourceMap, QueryParams } from '@sanity/client';
3
+ import type { EncodeDataAttributeFunction } from '@sanity/core-loader/encode-data-attribute';
4
+ import type SanityClient from '../../client/SanityClient.js';
5
+ export declare const subscribeToChanges: <T, E>(query: string, params: Reactive<QueryParams> | undefined, client: SanityClient, updateData: (data: T, sourceMap?: ContentSourceMap, encodeDataAttribute?: EncodeDataAttributeFunction) => void) => void;
@@ -0,0 +1,19 @@
1
+ import { toRaw } from "vue";
2
+ import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
3
+ export const subscribeToChanges = (query, params, client, updateData) => {
4
+ let unsubscribe = () => {
5
+ };
6
+ function setupFetcher(cb) {
7
+ unsubscribe();
8
+ const deepClonedParams = params ? JSON.parse(JSON.stringify(toRaw(params))) : void 0;
9
+ const fetcher = client.queryStore.createFetcherStore(query, deepClonedParams, void 0);
10
+ unsubscribe = fetcher.subscribe((newSnapshot) => {
11
+ if (newSnapshot.data) {
12
+ const encodeDataAttribute = newSnapshot.sourceMap ? defineEncodeDataAttribute(newSnapshot.data, newSnapshot.sourceMap, client.config.visualEditing?.studioUrl) : void 0;
13
+ updateData(newSnapshot.data, newSnapshot.sourceMap, encodeDataAttribute);
14
+ cb?.(newSnapshot);
15
+ }
16
+ });
17
+ }
18
+ setupFetcher();
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devite/nuxt-sanity",
3
- "version": "2.4.3",
3
+ "version": "2.5.1",
4
4
  "description": "Advanced Sanity integration for Nuxt.js.",
5
5
  "repository": "devite-io/nuxt-sanity",
6
6
  "license": "MIT",
@@ -52,6 +52,9 @@
52
52
  "vue-router": "^4.5.0",
53
53
  "vue-tsc": "^2.1.10"
54
54
  },
55
+ "overrides": {
56
+ "react": "18.3.1"
57
+ },
55
58
  "resolutions": {
56
59
  "@devite/nuxt-sanity": "link:."
57
60
  },
@@ -1,4 +0,0 @@
1
- import type { AsyncDataOptions } from 'nuxt/app';
2
- import type { QueryParams } from '@sanity/client';
3
- import { type AsyncSanityData, type SanityQueryResponse } from './useSanityQuery.js';
4
- export declare const useLazySanityQuery: <T = unknown, E = Error>(query: string, _params?: QueryParams, options?: AsyncDataOptions<SanityQueryResponse<T | null>>) => AsyncSanityData<T | null, E>;
@@ -1,4 +0,0 @@
1
- import { useSanityQuery } from "./useSanityQuery.js";
2
- export const useLazySanityQuery = (query, _params = {}, options = {}) => {
3
- return useSanityQuery(query, _params, options, true);
4
- };
@@ -1,69 +0,0 @@
1
- import { hash } from "ohash";
2
- import { defineEncodeDataAttribute } from "@sanity/core-loader/encode-data-attribute";
3
- import { onScopeDispose, reactive, ref } from "vue";
4
- import useSanityClient from "../utils/useSanityClient.js";
5
- import { useAsyncData, useLazyAsyncData } from "#imports";
6
- export const useSanityQuery = (query, _params = {}, _options = {}, lazy = false) => {
7
- const { client: clientType, perspective: _perspective, ...options } = _options;
8
- const client = clientType ? useSanityClient(clientType) : useSanityClient();
9
- const hasQueryStore = "queryStore" in client && client.queryStore !== null;
10
- const perspective = _perspective || (hasQueryStore ? "previewDrafts" : "published");
11
- const reactiveParams = _params ? reactive(_params) : void 0;
12
- if (reactiveParams) {
13
- options.watch ||= [];
14
- options.watch.push(reactiveParams);
15
- }
16
- const key = "sanity-" + hash(query + (reactiveParams ? JSON.stringify(reactiveParams) : ""));
17
- const data = ref(null);
18
- const sourceMap = ref(null);
19
- const encodeDataAttribute = ref(() => {
20
- });
21
- function updateResult(newData, newSourceMap) {
22
- data.value = newData;
23
- sourceMap.value = newSourceMap || null;
24
- if (client.config.visualEditing) {
25
- encodeDataAttribute.value = defineEncodeDataAttribute(newData, newSourceMap, client.config.visualEditing?.studioUrl);
26
- }
27
- }
28
- let fetchFunc = async () => {
29
- return { data: await client.fetch(query, reactiveParams || {}, { perspective }) };
30
- };
31
- if (hasQueryStore) {
32
- let setupFetcher = function(cb) {
33
- unsubscribe();
34
- const deepClonedParams = _params ? JSON.parse(JSON.stringify(_params)) : void 0;
35
- const fetcher = defaultClient.queryStore.createFetcherStore(query, deepClonedParams, void 0);
36
- unsubscribe = fetcher.subscribe((newSnapshot) => {
37
- if (newSnapshot.data) {
38
- updateResult(newSnapshot.data, newSnapshot.sourceMap);
39
- cb?.(newSnapshot);
40
- }
41
- });
42
- };
43
- const defaultClient = client;
44
- let unsubscribe = () => {
45
- };
46
- const proxyClient = {
47
- fetch: (query2, params, options2) => $fetch(defaultClient.config.visualEditing.proxyEndpoint || "/_sanity/fetch", {
48
- method: "POST",
49
- body: { query: query2, params, options: options2 }
50
- })
51
- };
52
- fetchFunc = async () => {
53
- const currentClient = import.meta.server ? defaultClient.queryStore.unstable__serverClient.instance || defaultClient.client : proxyClient;
54
- const { result: fetchData, resultSourceMap: sourceMap2 } = await currentClient.fetch(query, reactiveParams || {}, {
55
- perspective,
56
- filterResponse: false,
57
- resultSourceMap: "withKeyArraySelector"
58
- });
59
- return sourceMap2 ? { data: fetchData, sourceMap: sourceMap2 } : { data: fetchData };
60
- };
61
- if (import.meta.client) setupFetcher();
62
- onScopeDispose(unsubscribe);
63
- }
64
- const pendingData = lazy ? useLazyAsyncData(key, fetchFunc, options) : useAsyncData(key, fetchFunc, options);
65
- return Object.assign(new Promise((resolve) => pendingData.then(({ data: { value } }) => {
66
- updateResult(value.data, value.sourceMap);
67
- resolve({ ...pendingData, data, sourceMap, encodeDataAttribute });
68
- })), { ...pendingData, data, sourceMap, encodeDataAttribute });
69
- };
@@ -1,4 +0,0 @@
1
- import type { ModuleOptions } from '@devite/nuxt-sanity';
2
- import type SanityClient from '../client/SanityClient.js';
3
- export type SanityClientType = 'minimal' | 'default';
4
- export default function getOrCreateSanityClient(visualEditing: boolean, config: ModuleOptions, type?: SanityClientType): SanityClient;
@@ -1,15 +0,0 @@
1
- import MinimalSanityClient from "../client/MinimalSanityClient.js";
2
- import DefaultSanityClient from "../client/DefaultSanityClient.js";
3
- const clients = {};
4
- export default function getOrCreateSanityClient(visualEditing, config, type) {
5
- const clientType = visualEditing ? "default" : type || (config.minimalClient ? "minimal" : "default");
6
- if (clientType in clients) return clients[clientType];
7
- const clientConfig = {
8
- ...config,
9
- stega: visualEditing && config.stega
10
- };
11
- const client = clientType === "minimal" ? new MinimalSanityClient(clientConfig) : new DefaultSanityClient(clientConfig);
12
- if (visualEditing && import.meta.client) client.createQueryStore();
13
- clients[clientType] = client;
14
- return client;
15
- }