ws-dottie
Version:
Your friendly TypeScript companion for Washington State transportation APIs - WSDOT and WSF data with smart caching and React Query integration
1 lines • 24.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/apis/wsf-fares/apiMeta.ts","../src/apis/wsf-schedule/apiMeta.ts","../src/apis/wsf-terminals/apiMeta.ts","../src/apis/wsf-vessels/apiMeta.ts","../src/shared/factories/buildFetchEndpoint.ts","../src/shared/factories/createFetchFunction.ts","../src/shared/cache/cacheFlushDate.ts","../src/shared/cache/index.ts","../src/shared/factories/strategies.ts","../src/shared/factories/createHook.ts","../src/shared/factories/createFetchAndHook.ts","../src/shared/factories/index.ts"],"names":["wsfFaresApiMeta","init_apiMeta","__esmMin","wsfScheduleApiMeta","wsfTerminalsApiMeta","wsfVesselsApiMeta","buildFetchEndpoint","api","endpoint","init_buildFetchEndpoint","createFetchFunction","params","fetchEndpoint","fetchDottie","init_createFetchFunction","init_fetching","CACHE_FLUSH_API_NAMES","CACHE_FLUSH_BASE_URLS","createCacheFlushEndpoint","fetchCacheFlushDate","getEndpointId","normalizeFlushDate","useCacheFlushDate","useInvalidateOnFlushChange","init_cacheFlushDate","baseUrl","cacheFlushDateInputSchema","cacheFlushDateOutputSchema","apiName","fetchMode","result","functionName","s","value","isCacheFlushApi","endpointId","useQuery","flushDateQuery","queryClient","useQueryClient","previousFlushDateRef","React","useEffect","currentFlushDate","init_cache","cacheStrategies","init_strategies","createHook","endpointName","fetchFn","cacheStrategy","options","init_createHook","createFetchAndHook","getCacheStrategy","fetch","init_createFetchAndHook","init_factories"],"mappings":"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","file":"chunk-DOBO2Q4R.mjs","sourcesContent":["import type { ApiMeta } from \"@/apis/types\";\n\n/**\n * API metadata for WSF Fares API\n */\nexport const wsfFaresApiMeta: ApiMeta = {\n name: \"wsf-fares\",\n baseUrl: \"https://www.wsdot.wa.gov/ferries/api/fares/rest\",\n};\n","import type { ApiMeta } from \"@/apis/types\";\n\n/**\n * API metadata for WSF Schedule API\n */\nexport const wsfScheduleApiMeta: ApiMeta = {\n name: \"wsf-schedule\",\n baseUrl: \"https://www.wsdot.wa.gov/ferries/api/schedule/rest\",\n};\n","import type { ApiMeta } from \"@/apis/types\";\n\n/**\n * API metadata for WSF Terminals API\n */\nexport const wsfTerminalsApiMeta: ApiMeta = {\n name: \"wsf-terminals\",\n baseUrl: \"https://www.wsdot.wa.gov/ferries/api/terminals/rest\",\n};\n","import type { ApiMeta } from \"@/apis/types\";\n\n/**\n * API metadata for WSF Vessels API\n */\nexport const wsfVesselsApiMeta: ApiMeta = {\n name: \"wsf-vessels\",\n baseUrl: \"https://www.wsdot.wa.gov/ferries/api/vessels/rest\",\n};\n","/**\n * @fileoverview Fetch Endpoint Builder\n *\n * Builds minimal fetch endpoint objects from metadata objects.\n * Only includes fields necessary for fetching operations.\n */\n\nimport type { ApiMeta, EndpointMeta } from \"@/apis/types\";\nimport type { FetchEndpoint } from \"@/shared/types\";\n\n/**\n * Builds a minimal fetch endpoint from metadata objects\n *\n * Returns only the fields necessary for fetching operations,\n * excluding housekeeping metadata used by hooks and other system components.\n *\n * @template I - The input parameters type\n * @template O - The output response type\n * @param api - API metadata containing base URL\n * @param endpoint - Endpoint metadata containing path and schemas\n * @returns A FetchEndpoint object with urlTemplate, endpoint path, and optional schemas\n */\nexport function buildFetchEndpoint<I, O>(\n api: ApiMeta,\n endpoint: EndpointMeta<I, O>\n): FetchEndpoint<I, O> {\n return {\n urlTemplate: `${api.baseUrl}${endpoint.endpoint}`,\n endpoint: endpoint.endpoint,\n inputSchema: endpoint.inputSchema,\n outputSchema: endpoint.outputSchema,\n };\n}\n","/**\n * @fileoverview Fetch Function Factory\n *\n * Creates strongly-typed fetch functions from metadata objects.\n * This is a pure factory with no React Query dependencies.\n */\n\nimport type { ApiMeta, EndpointMeta } from \"@/apis/types\";\nimport { fetchDottie } from \"@/shared/fetching\";\nimport { buildFetchEndpoint } from \"./buildFetchEndpoint\";\nimport type { FetchFactory, FetchFunctionParams } from \"./types\";\n\n/**\n * Creates a strongly-typed fetch function from metadata objects\n *\n * @template I - The input parameters type\n * @template O - The output response type\n * @param params - Configuration object containing API and endpoint metadata\n * @param params.api - API metadata containing base URL and configuration\n * @param params.endpoint - Endpoint metadata containing path, schemas, and function name\n * @returns A fetch function that accepts optional parameters and returns a Promise resolving to the output type\n */\nexport function createFetchFunction<I, O>(params: {\n api: ApiMeta;\n endpoint: EndpointMeta<I, O>;\n}): FetchFactory<I, O> {\n const fetchEndpoint = buildFetchEndpoint(params.api, params.endpoint);\n\n return (params?: FetchFunctionParams<I>): Promise<O> =>\n fetchDottie<I, O>({\n endpoint: fetchEndpoint,\n ...params,\n });\n}\n","/**\n * @fileoverview Cache Flush Date Hooks for WS-Dottie\n *\n * Provides React Query hooks for polling cache flush dates and invalidating\n * queries when flush dates change. This is specifically for WSF APIs that\n * use cache flush dates to indicate when static data has been updated.\n *\n * Uses simple fetch functions that directly call fetchDottie with minimal\n * endpoint descriptors, avoiding circular dependencies.\n */\n\nimport type { UseQueryResult } from \"@tanstack/react-query\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport React, { useEffect } from \"react\";\nimport type { CacheFlushDateOutput } from \"@/apis/shared/cacheFlushDate\";\nimport {\n cacheFlushDateInputSchema,\n cacheFlushDateOutputSchema,\n} from \"@/apis/shared/cacheFlushDate\";\nimport { wsfFaresApiMeta } from \"@/apis/wsf-fares/apiMeta\";\nimport { wsfScheduleApiMeta } from \"@/apis/wsf-schedule/apiMeta\";\nimport { wsfTerminalsApiMeta } from \"@/apis/wsf-terminals/apiMeta\";\nimport { wsfVesselsApiMeta } from \"@/apis/wsf-vessels/apiMeta\";\nimport { fetchDottie } from \"@/shared/fetching\";\nimport type { FetchEndpoint } from \"@/shared/types\";\n\ntype CacheFlushApiName =\n | \"wsf-fares\"\n | \"wsf-schedule\"\n | \"wsf-terminals\"\n | \"wsf-vessels\";\n\nconst CACHE_FLUSH_API_NAMES = new Set<CacheFlushApiName>([\n \"wsf-fares\",\n \"wsf-schedule\",\n \"wsf-terminals\",\n \"wsf-vessels\",\n]);\n\n// Map API names to their base URLs\nconst CACHE_FLUSH_BASE_URLS: Record<CacheFlushApiName, string> = {\n \"wsf-fares\": wsfFaresApiMeta.baseUrl,\n \"wsf-schedule\": wsfScheduleApiMeta.baseUrl,\n \"wsf-terminals\": wsfTerminalsApiMeta.baseUrl,\n \"wsf-vessels\": wsfVesselsApiMeta.baseUrl,\n} as const;\n\n/**\n * Creates a minimal FetchEndpoint for cache flush date endpoints\n *\n * These are simple GET requests with no parameters.\n *\n * @param baseUrl - The base URL for the API (e.g., \"https://www.wsdot.wa.gov/ferries/api/vessels/rest\")\n * @returns A FetchEndpoint object configured for the cache flush date endpoint\n */\nconst createCacheFlushEndpoint = (\n baseUrl: string\n): FetchEndpoint<Record<string, never>, CacheFlushDateOutput> => ({\n urlTemplate: `${baseUrl}/cacheflushdate`,\n endpoint: \"/cacheflushdate\",\n inputSchema: cacheFlushDateInputSchema,\n outputSchema: cacheFlushDateOutputSchema,\n});\n\n/**\n * Fetches and normalizes cache flush date for a given API\n *\n * @param apiName - The name of the API (must be one of the WSF APIs with cache flush support)\n * @param fetchMode - Optional fetch mode to use (default: \"native\")\n * @returns Promise resolving to the normalized cache flush date as an ISO string\n * @throws Error if the API name is not found in the base URL mapping\n */\nconst fetchCacheFlushDate = async (\n apiName: CacheFlushApiName,\n fetchMode: \"native\" | \"jsonp\" = \"native\"\n): Promise<string> => {\n const baseUrl = CACHE_FLUSH_BASE_URLS[apiName];\n if (!baseUrl) {\n throw new Error(`No base URL found for API: ${apiName}`);\n }\n\n const result = await fetchDottie({\n endpoint: createCacheFlushEndpoint(baseUrl),\n fetchMode,\n validate: false,\n logMode: \"none\",\n });\n\n return normalizeFlushDate(result);\n};\n\n/**\n * Generates endpoint ID in format \"api-name:fetchCacheFlushDateApiName\"\n *\n * Converts API names like \"wsf-vessels\" to function names like \"fetchCacheFlushDateVessels\".\n *\n * @param apiName - The name of the API (e.g., \"wsf-vessels\")\n * @returns Endpoint ID string in format \"api-name:functionName\"\n */\nconst getEndpointId = (apiName: CacheFlushApiName): string => {\n const functionName = `fetchCacheFlushDate${apiName\n .replace(\"wsf-\", \"\")\n .split(\"-\")\n .map((s) => s[0].toUpperCase() + s.slice(1))\n .join(\"\")}`;\n return `${apiName}:${functionName}`;\n};\n\n/**\n * Normalizes cache flush date value to a consistent string format\n *\n * Converts Date objects to ISO strings, other values to strings.\n * Returns empty string for falsy values.\n *\n * @param value - The cache flush date value (can be Date, string, or other)\n * @returns Normalized date string (ISO format for Dates, empty string for falsy values)\n */\nconst normalizeFlushDate = (value: CacheFlushDateOutput): string => {\n if (!value) {\n return \"\";\n }\n return value instanceof Date ? value.toISOString() : String(value);\n};\n\n/**\n * Hook to poll cache flush date endpoint\n *\n * Automatically polls the cache flush date endpoint every 5 minutes for WSF APIs\n * with cache flush support. Returns an empty string for APIs without cache flush support.\n *\n * @param apiName - The name of the API (e.g., \"wsf-vessels\")\n * @param fetchMode - Optional fetch mode to use (default: \"native\"). Should match the fetchMode used by the underlying hook to ensure consistent behavior\n * @returns UseQueryResult containing the cache flush date as an ISO string, or empty string for unsupported APIs\n */\nexport const useCacheFlushDate = (\n apiName: string,\n fetchMode: \"native\" | \"jsonp\" = \"native\"\n): UseQueryResult<string, Error> => {\n const isCacheFlushApi = CACHE_FLUSH_API_NAMES.has(\n apiName as CacheFlushApiName\n );\n const endpointId = isCacheFlushApi\n ? getEndpointId(apiName as CacheFlushApiName)\n : \"no-cache-flush\";\n\n return useQuery({\n queryKey: [endpointId, fetchMode],\n queryFn: isCacheFlushApi\n ? () => fetchCacheFlushDate(apiName as CacheFlushApiName, fetchMode)\n : () => Promise.resolve(\"\"),\n refetchInterval: isCacheFlushApi ? 5 * 60 * 1000 : undefined,\n staleTime: isCacheFlushApi ? 5 * 60 * 1000 : undefined,\n refetchOnWindowFocus: false,\n });\n};\n\n/**\n * Hook to handle cache invalidation when flush date changes\n *\n * Monitors the cache flush date query and invalidates the specified endpoint's\n * queries when the flush date changes, ensuring fresh data is fetched.\n *\n * @param endpointId - The endpoint ID to invalidate when flush date changes\n * @param flushDateQuery - Optional React Query result from useCacheFlushDate hook\n * @returns void\n */\nexport const useInvalidateOnFlushChange = (\n endpointId: string,\n flushDateQuery?: UseQueryResult<string, Error>\n): void => {\n const queryClient = useQueryClient();\n const previousFlushDateRef = React.useRef<string | null>(null);\n\n useEffect(() => {\n if (!flushDateQuery?.data) {\n return;\n }\n\n const currentFlushDate = flushDateQuery.data;\n if (\n previousFlushDateRef.current !== null &&\n previousFlushDateRef.current !== currentFlushDate\n ) {\n queryClient.invalidateQueries({ queryKey: [endpointId] });\n }\n previousFlushDateRef.current = currentFlushDate;\n }, [flushDateQuery?.data, queryClient, endpointId]);\n};\n","/**\n * @fileoverview Cache Management Exports\n */\n\nexport {\n useCacheFlushDate,\n useInvalidateOnFlushChange,\n} from \"./cacheFlushDate\";\n","/**\n * @fileoverview Cache Strategy Configurations\n *\n * Cache strategy configurations for different data update frequencies.\n * These are used by React Query hooks to determine caching behavior.\n */\n\nexport const cacheStrategies = {\n REALTIME: {\n staleTime: 5 * 1000, // 5 seconds\n gcTime: 60 * 60 * 1000, // 1 hour\n refetchInterval: 5 * 1000, // 5 seconds\n retry: 2,\n retryDelay: 5 * 1000, // 5 seconds\n },\n FREQUENT: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 60 * 60 * 1000, // 1 hour\n refetchInterval: 5 * 60 * 1000, // 5 minutes\n retry: 3,\n retryDelay: 5 * 1000, // 5 seconds\n },\n MODERATE: {\n staleTime: 60 * 60 * 1000, // 1 hour\n gcTime: 2 * 24 * 60 * 60 * 1000, // 2 days\n refetchInterval: 60 * 60 * 1000, // 1 hour\n retry: 3,\n retryDelay: 60 * 1000, // 1 minute\n },\n STATIC: {\n staleTime: 24 * 60 * 60 * 1000, // 1 day\n gcTime: 2 * 24 * 60 * 60 * 1000, // 2 days\n refetchInterval: 24 * 60 * 60 * 1000, // 1 day\n retry: 2,\n retryDelay: 5 * 1000, // 5 seconds\n },\n} as const;\n","/**\n * @fileoverview React Query Hook Factory\n *\n * Creates strongly-typed React Query hooks from metadata objects.\n * Handles both regular hooks and cache-flush-date-aware hooks.\n */\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useCacheFlushDate, useInvalidateOnFlushChange } from \"@/shared/cache\";\nimport type { CacheStrategy } from \"@/shared/types\";\nimport { cacheStrategies } from \"./strategies\";\nimport type {\n FetchFunctionParams,\n HookFactory,\n QueryHookOptions,\n} from \"./types\";\n\n/**\n * Creates a strongly-typed React Query hook from parameter objects\n *\n * Automatically handles cache flush date polling and invalidation for WSF APIs\n * with STATIC cache strategy. For other APIs or strategies, creates a standard\n * React Query hook with the specified cache strategy.\n *\n * @template I - The input parameters type\n * @template O - The output response type\n * @param params - Configuration object for hook creation\n * @param params.apiName - The name of the API (e.g., \"wsf-vessels\")\n * @param params.endpointName - The function name of the endpoint (e.g., \"vesselBasics\")\n * @param params.fetchFn - The fetch function created by createFetchFunction\n * @param params.cacheStrategy - The cache strategy to use (REALTIME, FREQUENT, MODERATE, STATIC)\n * @returns A React Query hook function that accepts optional parameters and query options, returning UseQueryResult\n */\nexport function createHook<I, O>(params: {\n apiName: string;\n endpointName: string;\n fetchFn: (params?: FetchFunctionParams<I>) => Promise<O>;\n cacheStrategy: CacheStrategy;\n}): HookFactory<I, O> {\n const { apiName, endpointName, fetchFn, cacheStrategy } = params;\n const useCacheFlush =\n apiName.startsWith(\"wsf-\") && cacheStrategy === \"STATIC\";\n\n if (useCacheFlush) {\n return (params?: FetchFunctionParams<I>, options?: QueryHookOptions<O>) => {\n const flushDateQuery = useCacheFlushDate(apiName, params?.fetchMode);\n useInvalidateOnFlushChange(endpointName, flushDateQuery);\n\n return useQuery({\n queryKey: [endpointName, params?.params ?? null],\n queryFn: () => fetchFn(params),\n ...cacheStrategies.STATIC,\n refetchOnWindowFocus: false,\n ...options,\n });\n };\n }\n\n return (params?: FetchFunctionParams<I>, options?: QueryHookOptions<O>) =>\n useQuery({\n queryKey: [endpointName, params?.params ?? null],\n queryFn: () => fetchFn(params),\n ...cacheStrategies[cacheStrategy],\n refetchOnWindowFocus: false,\n ...options,\n });\n}\n","/**\n * @fileoverview Combined Fetch and Hook Factory\n *\n * Creates both strongly-typed fetch functions and React Query hooks from\n * metadata objects. Uses lazy loading for cache strategy to avoid circular\n * dependency issues.\n */\n\nimport type { ApiMeta, EndpointMeta } from \"@/apis/types\";\nimport type { CacheStrategy } from \"@/shared/types\";\nimport { createFetchFunction } from \"./createFetchFunction\";\nimport { createHook } from \"./createHook\";\nimport type { FetchFactory, HookFactory } from \"./types\";\n\n/**\n * Creates both a fetch function and a React Query hook from metadata objects\n *\n * This factory combines createFetchFunction and createHook into a single call,\n * using lazy loading for the cache strategy to avoid circular dependency issues\n * when endpoint files need to reference their group's cache strategy.\n *\n * @template I - The input parameters type\n * @template O - The output response type\n * @param params - Configuration object containing API, endpoint, and cache strategy getter\n * @param params.api - API metadata containing base URL and configuration\n * @param params.endpoint - Endpoint metadata containing path, schemas, and function name\n * @param params.getCacheStrategy - Function that lazily returns the cache strategy (called on each hook invocation)\n * @returns Object containing both fetch function and hook function\n */\nexport function createFetchAndHook<I, O>(params: {\n api: ApiMeta;\n endpoint: EndpointMeta<I, O>;\n getCacheStrategy: () => CacheStrategy;\n}): {\n fetch: FetchFactory<I, O>;\n useHook: HookFactory<I, O>;\n} {\n const { api, endpoint, getCacheStrategy } = params;\n\n // Create the fetch function using the existing factory\n const fetch = createFetchFunction({\n api,\n endpoint,\n });\n\n // Create a hook factory that lazily gets the cache strategy on each call\n const useHook: HookFactory<I, O> = (params, options) => {\n const cacheStrategy = getCacheStrategy();\n const hook = createHook({\n apiName: api.name,\n endpointName: endpoint.functionName,\n fetchFn: fetch,\n cacheStrategy,\n });\n return hook(params, options);\n };\n\n return { fetch, useHook };\n}\n","/**\n * @fileoverview Factory Functions for WS-Dottie\n *\n * This module provides factory functions for creating typed fetch functions\n * and React Query hooks using a metadata-driven approach.\n */\n\n// Export combined fetch and hook factory\nexport { createFetchAndHook } from \"./createFetchAndHook\";\n// Export fetch function factory\nexport { createFetchFunction } from \"./createFetchFunction\";\n// Export hook factory\nexport { createHook } from \"./createHook\";\n// Export cache strategies\nexport { cacheStrategies } from \"./strategies\";\n// Export types\nexport type {\n FetchFactory,\n FetchFunctionParams,\n HookFactory,\n QueryHookOptions,\n} from \"./types\";\n"]}