@invisiblecities/sanity-edge-fetcher
Version:
Lightweight, Edge Runtime-compatible Sanity client for Next.js and Vercel Edge Functions
349 lines (346 loc) • 10.9 kB
text/typescript
import { Q as QueryParams } from './core-zsRjuWVw.cjs';
/**
* @file config.ts
* @description Centralized configuration for Sanity Edge Fetcher
* @author Invisible Cities Agency
* @license MIT
*/
/**
* Sanity configuration from environment variables
*/
declare const sanityConfig: {
readonly projectId: string;
readonly apiVersion: string;
readonly dataset: string;
readonly token: string | undefined;
readonly useCdn: boolean;
};
/**
* Cache configuration
*/
declare const cacheConfig: {
readonly ttl: {
readonly default: 60;
readonly static: 3600;
readonly dynamic: 30;
readonly long: 86400;
};
readonly prefixes: {
readonly page: "page:";
readonly post: "post:";
readonly author: "author:";
readonly category: "cat:";
readonly section: "section:";
readonly global: "global:";
};
readonly layers: {
readonly memory: {
readonly enabled: true;
readonly maxSize: 100;
};
readonly redis: {
readonly enabled: boolean;
readonly url: string | undefined;
readonly token: string | undefined;
readonly readOnlyToken: string | undefined;
};
readonly nextCache: {
readonly enabled: boolean;
};
};
};
/**
* Rate limiting configuration
*/
declare const rateLimitConfig: {
readonly minInterval: 100;
readonly maxRequestsPerSecond: 10;
};
/**
* Retry configuration (if p-retry is available)
*/
declare const retryConfig: {
readonly retries: 3;
readonly minTimeout: 100;
readonly maxTimeout: 2000;
readonly factor: 2;
};
/**
* Real-time configuration
*/
declare const realtimeConfig: {
readonly sse: {
readonly endpoint: "/api/sanity-updates";
readonly pollInterval: 5000;
readonly heartbeatInterval: 30000;
};
readonly websocket: {
readonly endpoint: string;
readonly reconnectDelay: 1000;
readonly maxReconnectAttempts: 5;
};
};
/**
* Pre-configured fetchers for common use cases
* NOTE: For Next.js apps, use the smart fetchers from the main export instead:
* - sanityFetch() - Auto-detects draft mode
* - sanityFetchWithFallback() - Smart fallback to drafts
* - sanityFetchStatic() - Always CDN
* - sanityFetchAuthenticated() - Always authenticated
*
* These are lower-level fetchers for advanced use cases:
*/
declare const fetchers: {
/**
* Basic fetcher - no caching, no retry
* Use for: One-off queries, testing
*/
readonly basic: <T>(query: string, params?: QueryParams) => Promise<T>;
/**
* Authenticated fetcher - includes token for draft preview
* Use for: Preview mode, draft content
*/
readonly authenticated: <T>(query: string, params?: QueryParams) => Promise<T>;
/**
* Cached fetcher - multi-layer caching with default TTL
* Use for: Most production queries
*/
readonly cached: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Static content fetcher - long cache TTL
* Use for: Global settings, rarely changing content
*/
readonly static: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Dynamic content fetcher - short cache TTL with retry
* Use for: Frequently updated content, user-specific data
*/
readonly dynamic: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Page fetcher - optimized for page data
* Use for: Full page queries
*/
readonly page: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Section fetcher - for page sections/components
* Use for: Individual page sections
*/
readonly section: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
};
/**
* Helper to create a custom fetcher with merged config
*/
declare function createCustomFetcher(options: {
dataset?: string;
ttl?: number;
prefix?: string;
useAuth?: boolean;
useCache?: boolean;
useRetry?: boolean;
}): <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Queries that should be warmed on startup
*/
declare const warmupQueries: readonly [{
readonly query: "*[_type == \"siteSettings\"][0]";
readonly ttl: 86400;
readonly fetcher: "static";
}, {
readonly query: "*[_type == \"navigation\"][0]";
readonly ttl: 86400;
readonly fetcher: "static";
}, {
readonly query: "*[_type == \"post\"] | order(_createdAt desc)[0..10]";
readonly ttl: 60;
readonly fetcher: "cached";
}, {
readonly query: "*[_type == \"page\" && slug.current == \"home\"][0]";
readonly ttl: 3600;
readonly fetcher: "page";
}];
/**
* Export all configurations for easy access
*/
declare const config: {
readonly sanity: {
readonly projectId: string;
readonly apiVersion: string;
readonly dataset: string;
readonly token: string | undefined;
readonly useCdn: boolean;
};
readonly cache: {
readonly ttl: {
readonly default: 60;
readonly static: 3600;
readonly dynamic: 30;
readonly long: 86400;
};
readonly prefixes: {
readonly page: "page:";
readonly post: "post:";
readonly author: "author:";
readonly category: "cat:";
readonly section: "section:";
readonly global: "global:";
};
readonly layers: {
readonly memory: {
readonly enabled: true;
readonly maxSize: 100;
};
readonly redis: {
readonly enabled: boolean;
readonly url: string | undefined;
readonly token: string | undefined;
readonly readOnlyToken: string | undefined;
};
readonly nextCache: {
readonly enabled: boolean;
};
};
};
readonly rateLimit: {
readonly minInterval: 100;
readonly maxRequestsPerSecond: 10;
};
readonly retry: {
readonly retries: 3;
readonly minTimeout: 100;
readonly maxTimeout: 2000;
readonly factor: 2;
};
readonly realtime: {
readonly sse: {
readonly endpoint: "/api/sanity-updates";
readonly pollInterval: 5000;
readonly heartbeatInterval: 30000;
};
readonly websocket: {
readonly endpoint: string;
readonly reconnectDelay: 1000;
readonly maxReconnectAttempts: 5;
};
};
readonly fetchers: {
/**
* Basic fetcher - no caching, no retry
* Use for: One-off queries, testing
*/
readonly basic: <T>(query: string, params?: QueryParams) => Promise<T>;
/**
* Authenticated fetcher - includes token for draft preview
* Use for: Preview mode, draft content
*/
readonly authenticated: <T>(query: string, params?: QueryParams) => Promise<T>;
/**
* Cached fetcher - multi-layer caching with default TTL
* Use for: Most production queries
*/
readonly cached: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Static content fetcher - long cache TTL
* Use for: Global settings, rarely changing content
*/
readonly static: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Dynamic content fetcher - short cache TTL with retry
* Use for: Frequently updated content, user-specific data
*/
readonly dynamic: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Page fetcher - optimized for page data
* Use for: Full page queries
*/
readonly page: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
/**
* Section fetcher - for page sections/components
* Use for: Individual page sections
*/
readonly section: <T>(query: string, params?: QueryParams, cacheOverrides?: {
ttl?: number;
prefix?: string;
force?: boolean;
useRedis?: boolean;
useNextCache?: boolean;
} | undefined) => Promise<T>;
};
readonly warmupQueries: readonly [{
readonly query: "*[_type == \"siteSettings\"][0]";
readonly ttl: 86400;
readonly fetcher: "static";
}, {
readonly query: "*[_type == \"navigation\"][0]";
readonly ttl: 86400;
readonly fetcher: "static";
}, {
readonly query: "*[_type == \"post\"] | order(_createdAt desc)[0..10]";
readonly ttl: 60;
readonly fetcher: "cached";
}, {
readonly query: "*[_type == \"page\" && slug.current == \"home\"][0]";
readonly ttl: 3600;
readonly fetcher: "page";
}];
};
export { cacheConfig, config, createCustomFetcher, config as default, fetchers, rateLimitConfig, realtimeConfig, retryConfig, sanityConfig, warmupQueries };