@demokit-ai/swr 0.3.0 → 0.4.0
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/dist/index.cjs +12 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
DemoSWRProvider: () => DemoSWRProvider,
|
|
34
34
|
createDemoFetcher: () => createDemoFetcher,
|
|
35
35
|
createDemoMiddleware: () => createDemoMiddleware,
|
|
36
|
+
createRemoteSource: () => createRemoteSource,
|
|
36
37
|
defaultFetcher: () => defaultFetcher,
|
|
37
38
|
findMatchingFixture: () => findMatchingFixture,
|
|
38
39
|
matchQueryKey: () => import_core.matchQueryKey,
|
|
@@ -268,6 +269,16 @@ function DemoSWRProvider({
|
|
|
268
269
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DemoSWRContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_swr.SWRConfig, { value: config, children }) });
|
|
269
270
|
}
|
|
270
271
|
|
|
272
|
+
// src/config.ts
|
|
273
|
+
function createRemoteSource(config) {
|
|
274
|
+
return {
|
|
275
|
+
timeout: 1e4,
|
|
276
|
+
retry: true,
|
|
277
|
+
maxRetries: 3,
|
|
278
|
+
...config
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
271
282
|
// src/hooks.ts
|
|
272
283
|
var import_react3 = require("react");
|
|
273
284
|
var import_mutation = __toESM(require("swr/mutation"), 1);
|
|
@@ -329,6 +340,7 @@ function useDemoSWRMutation(key, options) {
|
|
|
329
340
|
DemoSWRProvider,
|
|
330
341
|
createDemoFetcher,
|
|
331
342
|
createDemoMiddleware,
|
|
343
|
+
createRemoteSource,
|
|
332
344
|
defaultFetcher,
|
|
333
345
|
findMatchingFixture,
|
|
334
346
|
matchQueryKey,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/context.ts","../src/matcher.ts","../src/fetcher.ts","../src/middleware.ts","../src/hooks.ts"],"sourcesContent":["/**\n * @demokit-ai/swr\n *\n * SWR adapter for DemoKit.\n * Mock fetches and mutations when demo mode is enabled using SWR's middleware pattern.\n *\n * @example\n * import { DemoSWRProvider } from '@demokit-ai/swr'\n *\n * // Define fixtures\n * const fixtures = {\n * '/api/users': [\n * { id: '1', name: 'Demo User' },\n * { id: '2', name: 'Another User' },\n * ],\n * '[\"/api/users\", \":id\"]': ({ params }) => ({\n * id: params.id,\n * name: `User ${params.id}`,\n * }),\n * '[\"/api/projects\", { status: \":status\" }]': ({ params }) => [\n * { id: '1', name: 'Project', status: params.status },\n * ],\n * }\n *\n * // Wrap your app\n * <DemoSWRProvider fixtures={fixtures} enabled={true}>\n * <App />\n * </DemoSWRProvider>\n *\n * @packageDocumentation\n */\n\n// Provider\nexport { DemoSWRProvider } from './provider'\n\n// Hooks\nexport { useDemoSWR, useIsDemoSWRMode, useDemoSWRMutation } from './hooks'\nexport type { UseDemoSWRMutationOptions } from './hooks'\n\n// Fetcher utilities\nexport { createDemoFetcher, defaultFetcher } from './fetcher'\nexport type { CreateDemoFetcherOptions } from './fetcher'\n\n// Middleware\nexport { createDemoMiddleware } from './middleware'\nexport type { CreateDemoMiddlewareOptions } from './middleware'\n\n// Matcher utilities\nexport {\n findMatchingFixture,\n normalizeKey,\n normalizeFixtureMap,\n parsePatternString,\n matchQueryKey,\n} from './matcher'\n\n// Types\nexport type {\n SWRFixtureContext,\n SWRFixtureHandler,\n SWRFixtureMap,\n SWRFixtureMapObject,\n SWRMutationFixtureContext,\n SWRMutationFixtureHandler,\n SWRMutationFixtureMap,\n SWRMutationFixtureMapObject,\n DemoSWRProviderConfig,\n DemoSWRProviderProps,\n DemoSWRState,\n} from './types'\n","'use client'\n\nimport { useMemo, useRef, useCallback } from 'react'\nimport { SWRConfig } from 'swr'\nimport type { QueryKey } from '@demokit-ai/core'\nimport { DemoSWRContext } from './context'\nimport { createDemoFetcher, defaultFetcher } from './fetcher'\nimport { createDemoMiddleware } from './middleware'\nimport { normalizeFixtureMap } from './matcher'\nimport type {\n DemoSWRProviderProps,\n SWRFixtureHandler,\n SWRFixtureMap,\n SWRMutationFixtureHandler,\n SWRMutationFixtureMap,\n DemoSWRState,\n} from './types'\n\n/**\n * Provider component for DemoKit SWR integration\n *\n * Wraps SWRConfig and intercepts fetches when demo mode is enabled.\n * Uses SWR's middleware pattern for maximum flexibility.\n *\n * @example\n * // With object-based fixtures\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={{\n * '/api/users': [{ id: '1', name: 'Demo User' }],\n * '[\"/api/users\", \":id\"]': ({ params }) => ({ id: params.id, name: 'Demo User' }),\n * '[\"/api/projects\", { status: \":status\" }]': ({ params }) => [\n * { id: '1', name: 'Project', status: params.status },\n * ],\n * }}\n * delay={100}\n * >\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With Map-based fixtures\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'Demo User' })],\n * ])\n *\n * <DemoSWRProvider enabled={true} fixtures={fixtures}>\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With cache seeding via fallback\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={fixtures}\n * fallback={{\n * '/api/users': [{ id: '1', name: 'Pre-loaded User' }],\n * }}\n * >\n * <App />\n * </DemoSWRProvider>\n */\nexport function DemoSWRProvider({\n children,\n fixtures = new Map(),\n mutations = new Map(),\n enabled = false,\n delay = 0,\n fallback = {},\n swrConfig = {},\n}: DemoSWRProviderProps) {\n // Normalize fixtures\n const fixturesRef = useRef<SWRFixtureMap>(normalizeFixtureMap(fixtures))\n const mutationFixturesRef = useRef<SWRMutationFixtureMap>(\n mutations instanceof Map ? mutations : new Map(Object.entries(mutations))\n )\n\n const isDemoMode = enabled\n\n // Create demo middleware\n const demoMiddleware = useMemo(\n () =>\n createDemoMiddleware({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n }),\n [isDemoMode, delay]\n )\n\n // Create demo fetcher (for direct use)\n const demoFetcher = useMemo(\n () =>\n createDemoFetcher({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n fallbackFetcher: defaultFetcher,\n }),\n [isDemoMode, delay]\n )\n\n // Build fallback data from static fixtures + provided fallback\n const combinedFallback = useMemo(() => {\n if (!isDemoMode) return swrConfig.fallback || {}\n\n const staticFixtures: Record<string, unknown> = {}\n\n // Add static fixture values to fallback\n for (const [pattern, handler] of fixturesRef.current) {\n if (typeof handler !== 'function') {\n // Use the pattern as key for static fixtures\n const key = pattern.length === 1 ? String(pattern[0]) : JSON.stringify(pattern)\n staticFixtures[key] = handler\n }\n }\n\n return {\n ...staticFixtures,\n ...fallback,\n ...(swrConfig.fallback || {}),\n }\n }, [isDemoMode, fallback, swrConfig.fallback])\n\n // Build SWR config\n const config = useMemo(\n () => ({\n ...swrConfig,\n use: [...(swrConfig.use || []), demoMiddleware],\n fallback: combinedFallback,\n // In demo mode, don't retry and keep data fresh longer\n ...(isDemoMode\n ? {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n }\n : {}),\n }),\n [swrConfig, demoMiddleware, combinedFallback, isDemoMode]\n )\n\n // Context value with manipulation methods\n const getFetcher = useCallback(() => demoFetcher, [demoFetcher])\n const getMiddleware = useCallback(() => demoMiddleware, [demoMiddleware])\n\n const contextValue = useMemo<DemoSWRState>(\n () => ({\n isDemoMode,\n\n setFixture: (pattern: QueryKey, handler: SWRFixtureHandler) => {\n fixturesRef.current.set(pattern, handler)\n },\n\n removeFixture: (pattern: QueryKey) => {\n fixturesRef.current.delete(pattern)\n },\n\n setMutationFixture: (name: string, handler: SWRMutationFixtureHandler) => {\n mutationFixturesRef.current.set(name, handler)\n },\n\n removeMutationFixture: (name: string) => {\n mutationFixturesRef.current.delete(name)\n },\n\n getFetcher,\n getMiddleware,\n }),\n [isDemoMode, getFetcher, getMiddleware]\n )\n\n return (\n <DemoSWRContext.Provider value={contextValue}>\n <SWRConfig value={config}>{children}</SWRConfig>\n </DemoSWRContext.Provider>\n )\n}\n","'use client'\n\nimport { createContext } from 'react'\nimport type { DemoSWRState } from './types'\n\n/**\n * Context for DemoSWR state\n * @internal\n */\nexport const DemoSWRContext = createContext<DemoSWRState | undefined>(undefined)\n\nDemoSWRContext.displayName = 'DemoSWRContext'\n","import { matchQueryKey, findMatchingQueryKeyPattern } from '@demokit-ai/core'\nimport type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureHandler, SWRFixtureMap, SWRFixtureMapObject } from './types'\n\n/**\n * Normalize an SWR key to a QueryKey for matching\n *\n * SWR keys can be:\n * - Strings: '/api/users' -> ['/api/users']\n * - Arrays: ['/api/users', id] -> ['/api/users', id]\n * - Functions that return keys (not handled here)\n */\nexport function normalizeKey(key: string | unknown[]): QueryKey {\n if (typeof key === 'string') {\n return [key]\n }\n\n return key.map((element) => {\n if (element === null || element === undefined) {\n return element\n }\n if (typeof element === 'object') {\n return element as Record<string, unknown>\n }\n return element as string | number | boolean\n })\n}\n\n/**\n * Parse a JSON string pattern into a QueryKey\n * Handles both array notation and simple string patterns\n *\n * @example\n * parsePatternString('[\"/api/users\"]') // ['/api/users']\n * parsePatternString('[\"/api/users\", \":id\"]') // ['/api/users', ':id']\n * parsePatternString('/api/users') // ['/api/users']\n */\nexport function parsePatternString(pattern: string): QueryKey {\n // Try to parse as JSON array\n if (pattern.startsWith('[')) {\n try {\n return JSON.parse(pattern) as QueryKey\n } catch {\n // Fall through to simple string\n }\n }\n\n // Simple string becomes single-element array\n return [pattern]\n}\n\n/**\n * Convert object-based fixture map to Map-based fixture map\n */\nexport function normalizeFixtureMap(fixtures: SWRFixtureMapObject | SWRFixtureMap): SWRFixtureMap {\n if (fixtures instanceof Map) {\n return fixtures\n }\n\n const map = new Map<QueryKey, SWRFixtureHandler>()\n for (const [pattern, handler] of Object.entries(fixtures)) {\n map.set(parsePatternString(pattern), handler)\n }\n return map\n}\n\n/**\n * Find a matching fixture for an SWR key\n *\n * @param fixtures - Map of key patterns to handlers\n * @param key - The SWR key to match\n * @returns Tuple of [handler, match result] or null if no match\n */\nexport function findMatchingFixture(\n fixtures: SWRFixtureMap,\n key: string | unknown[]\n): [SWRFixtureHandler, { params: Record<string, unknown>; normalizedKey: QueryKey }] | null {\n const normalizedKey = normalizeKey(key)\n const result = findMatchingQueryKeyPattern(fixtures, normalizedKey)\n\n if (result) {\n const [, handler, matchResult] = result\n return [handler, { params: matchResult.params, normalizedKey }]\n }\n\n return null\n}\n\n/**\n * Re-export the matchQueryKey function for direct use\n */\nexport { matchQueryKey }","import type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture, normalizeKey } from './matcher'\n\n/**\n * Options for creating a demo-aware fetcher\n */\nexport interface CreateDemoFetcherOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n\n /**\n * Fallback fetcher to use when demo mode is disabled\n * or no fixture matches\n */\n fallbackFetcher?: <T>(key: string | unknown[]) => Promise<T>\n}\n\n/**\n * Create a demo-aware fetcher function for SWR\n *\n * This fetcher intercepts requests when demo mode is enabled\n * and returns fixture data instead of making real API calls.\n *\n * @example\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const fetcher = createDemoFetcher({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * // Use with SWR\n * const { data } = useSWR('/api/users', fetcher)\n */\nexport function createDemoFetcher(options: CreateDemoFetcherOptions) {\n const { fixtures, isEnabled, delay = 0, fallbackFetcher } = options\n\n return async function demoFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n // If demo mode is not enabled, use fallback\n if (!isEnabled()) {\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(\n `[DemoKit SWR] No fallback fetcher provided and demo mode is disabled. ` +\n `Key: ${JSON.stringify(key)}`\n )\n }\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, key)\n\n if (!match) {\n // No fixture found, try fallback\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(`[DemoKit SWR] No fixture found for key: ${JSON.stringify(key)}`)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context) as TData\n }\n\n // Return static value\n return handler as TData\n }\n}\n\n/**\n * Default fetcher that uses fetch API\n * Used as fallback when demo mode is disabled\n */\nexport async function defaultFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n const url = typeof key === 'string' ? key : String(key[0])\n const response = await fetch(url)\n\n if (!response.ok) {\n const error = new Error('An error occurred while fetching the data.')\n throw error\n }\n\n return response.json()\n}\n","import type { Middleware } from 'swr'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture } from './matcher'\n\n/**\n * Options for creating the demo middleware\n */\nexport interface CreateDemoMiddlewareOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n}\n\n/**\n * Create a demo-aware SWR middleware\n *\n * This middleware intercepts SWR requests when demo mode is enabled\n * and returns fixture data instead of using the original fetcher.\n *\n * @example\n * import { SWRConfig } from 'swr'\n * import { createDemoMiddleware } from '@demokit-ai/swr'\n *\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const demoMiddleware = createDemoMiddleware({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * function App() {\n * return (\n * <SWRConfig value={{ use: [demoMiddleware] }}>\n * <YourApp />\n * </SWRConfig>\n * )\n * }\n */\nexport function createDemoMiddleware(options: CreateDemoMiddlewareOptions): Middleware {\n const { fixtures, isEnabled, delay = 0 } = options\n\n // Use the simpler middleware pattern that SWR expects\n const middleware: Middleware = (useSWRNext) => (key, fetcher, config) => {\n // Create an extended fetcher that checks for demo mode\n const extendedFetcher =\n fetcher === null\n ? null\n : async (...args: Parameters<typeof fetcher>) => {\n // Resolve the key if it's a function\n const resolvedKey = typeof key === 'function' ? key() : key\n\n // If no key, let SWR handle it\n if (resolvedKey === null || resolvedKey === undefined) {\n return fetcher(...args)\n }\n\n // If demo mode is not enabled, use original fetcher\n if (!isEnabled()) {\n return fetcher(...args)\n }\n\n // Normalize key for matching\n const keyToMatch =\n typeof resolvedKey === 'string' ? resolvedKey : (resolvedKey as unknown[])\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, keyToMatch)\n\n if (!match) {\n // No fixture found, use original fetcher\n return fetcher(...args)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key: resolvedKey,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context)\n }\n\n // Return static value\n return handler\n }\n\n return useSWRNext(key, extendedFetcher, config)\n }\n\n return middleware\n}\n","'use client'\n\nimport { useContext, useCallback } from 'react'\nimport useSWRMutation, { type SWRMutationConfiguration, type SWRMutationResponse } from 'swr/mutation'\nimport { useSWRConfig } from 'swr'\nimport { DemoSWRContext } from './context'\nimport type { DemoSWRState, SWRMutationFixtureContext, SWRMutationFixtureHandler } from './types'\n\n/**\n * Hook to access DemoSWR state and controls\n *\n * @returns DemoSWR context value\n * @throws Error if used outside of DemoSWRProvider\n *\n * @example\n * function MyComponent() {\n * const { isDemoMode, setFixture } = useDemoSWR()\n *\n * // Dynamically add a fixture\n * const handleAddFixture = () => {\n * setFixture(['/api/users', 'custom'], { id: 'custom', name: 'Custom User' })\n * }\n *\n * return (\n * <button onClick={handleAddFixture}>Add Custom Fixture</button>\n * )\n * }\n */\nexport function useDemoSWR(): DemoSWRState {\n const context = useContext(DemoSWRContext)\n\n if (context === undefined) {\n throw new Error(\n 'useDemoSWR must be used within a DemoSWRProvider. ' +\n 'Make sure to wrap your app with <DemoSWRProvider>.'\n )\n }\n\n return context\n}\n\n/**\n * Hook to check if demo mode is enabled\n * Shorthand for useDemoSWR().isDemoMode\n *\n * @example\n * function MyComponent() {\n * const isDemoMode = useIsDemoSWRMode()\n *\n * return isDemoMode ? <DemoBadge /> : null\n * }\n */\nexport function useIsDemoSWRMode(): boolean {\n return useDemoSWR().isDemoMode\n}\n\n/**\n * Options for useDemoSWRMutation hook\n */\nexport interface UseDemoSWRMutationOptions<TData, TError, TArg>\n extends Omit<SWRMutationConfiguration<TData, TError, string, TArg>, 'fetcher'> {\n /**\n * The real mutation function to use when demo mode is disabled\n */\n fetcher: (key: string, options: { arg: TArg }) => Promise<TData>\n\n /**\n * Demo fixture handler for this mutation\n */\n demoFixture?: SWRMutationFixtureHandler<TData, TArg>\n\n /**\n * Delay in ms before returning demo data\n * @default 0\n */\n demoDelay?: number\n}\n\n/**\n * A mutation hook that automatically uses demo fixtures when demo mode is enabled\n *\n * Works with useSWRMutation from swr/mutation.\n *\n * @example\n * const { trigger: createUser, isMutating } = useDemoSWRMutation('/api/users', {\n * fetcher: async (key, { arg }) => api.createUser(arg),\n * demoFixture: ({ arg, mutate }) => {\n * // Create demo user\n * const newUser = { id: crypto.randomUUID(), ...arg }\n *\n * // Update the users cache\n * mutate('/api/users', (current: User[] = []) => [...current, newUser])\n *\n * return newUser\n * },\n * onSuccess: (data) => {\n * console.log('Created user:', data)\n * },\n * })\n *\n * // Use like normal useSWRMutation\n * createUser({ name: 'New User', email: 'user@example.com' })\n */\nexport function useDemoSWRMutation<TData = unknown, TError = unknown, TArg = unknown>(\n key: string,\n options: UseDemoSWRMutationOptions<TData, TError, TArg>\n): SWRMutationResponse<TData, TError, string, TArg> {\n const { fetcher, demoFixture, demoDelay = 0, ...mutationOptions } = options\n\n const { mutate } = useSWRConfig()\n\n // Try to get demo state - may not be in DemoSWRProvider context\n let isDemoMode = false\n try {\n const demoState = useDemoSWR()\n isDemoMode = demoState.isDemoMode\n } catch {\n // Not in DemoSWRProvider context, use real mutation\n }\n\n // Create the demo-aware mutation function\n const demoAwareFetcher = useCallback(\n async (mutationKey: string, { arg }: { arg: TArg }): Promise<TData> => {\n // If not in demo mode, use real mutation\n if (!isDemoMode) {\n return fetcher(mutationKey, { arg })\n }\n\n // Apply delay if configured\n if (demoDelay > 0) {\n await new Promise((resolve) => setTimeout(resolve, demoDelay))\n }\n\n // If a demo fixture is provided, use it\n if (demoFixture !== undefined) {\n const context: SWRMutationFixtureContext<TData, TArg> = {\n key: mutationKey,\n arg,\n currentData: undefined, // SWR mutation doesn't have direct access to current data\n mutate: mutate as SWRMutationFixtureContext<TData, TArg>['mutate'],\n }\n\n if (typeof demoFixture === 'function') {\n const fixtureFn = demoFixture as (\n context: SWRMutationFixtureContext<TData, TArg>\n ) => TData | Promise<TData>\n return fixtureFn(context)\n }\n return demoFixture as TData\n }\n\n // No fixture found, fall back to real mutation\n console.warn(\n `[DemoKit SWR] No mutation fixture found for \"${key}\". Using real mutation function.`\n )\n return fetcher(mutationKey, { arg })\n },\n [isDemoMode, fetcher, demoFixture, demoDelay, key, mutate]\n )\n\n return useSWRMutation(key, demoAwareFetcher, mutationOptions)\n}\n"],"mappings":"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","names":["import_react","import_react","import_swr","useSWRMutation"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/context.ts","../src/matcher.ts","../src/fetcher.ts","../src/middleware.ts","../src/config.ts","../src/hooks.ts"],"sourcesContent":["/**\n * @demokit-ai/swr\n *\n * SWR adapter for DemoKit.\n * Mock fetches and mutations when demo mode is enabled using SWR's middleware pattern.\n *\n * @example\n * import { DemoSWRProvider } from '@demokit-ai/swr'\n *\n * // Define fixtures\n * const fixtures = {\n * '/api/users': [\n * { id: '1', name: 'Demo User' },\n * { id: '2', name: 'Another User' },\n * ],\n * '[\"/api/users\", \":id\"]': ({ params }) => ({\n * id: params.id,\n * name: `User ${params.id}`,\n * }),\n * '[\"/api/projects\", { status: \":status\" }]': ({ params }) => [\n * { id: '1', name: 'Project', status: params.status },\n * ],\n * }\n *\n * // Wrap your app\n * <DemoSWRProvider fixtures={fixtures} enabled={true}>\n * <App />\n * </DemoSWRProvider>\n *\n * @packageDocumentation\n */\n\n// Provider\nexport { DemoSWRProvider } from './provider'\n\n// Config helpers\nexport { createRemoteSource } from './config'\n\n// Hooks\nexport { useDemoSWR, useIsDemoSWRMode, useDemoSWRMutation } from './hooks'\nexport type { UseDemoSWRMutationOptions } from './hooks'\n\n// Fetcher utilities\nexport { createDemoFetcher, defaultFetcher } from './fetcher'\nexport type { CreateDemoFetcherOptions } from './fetcher'\n\n// Middleware\nexport { createDemoMiddleware } from './middleware'\nexport type { CreateDemoMiddlewareOptions } from './middleware'\n\n// Matcher utilities\nexport {\n findMatchingFixture,\n normalizeKey,\n normalizeFixtureMap,\n parsePatternString,\n matchQueryKey,\n} from './matcher'\n\n// Types\nexport type {\n SWRFixtureContext,\n SWRFixtureHandler,\n SWRFixtureMap,\n SWRFixtureMapObject,\n SWRMutationFixtureContext,\n SWRMutationFixtureHandler,\n SWRMutationFixtureMap,\n SWRMutationFixtureMapObject,\n DemoSWRProviderConfig,\n DemoSWRProviderProps,\n DemoSWRState,\n RemoteSourceConfig,\n} from './types'\n","'use client'\n\nimport { useMemo, useRef, useCallback } from 'react'\nimport { SWRConfig } from 'swr'\nimport type { QueryKey } from '@demokit-ai/core'\nimport { DemoSWRContext } from './context'\nimport { createDemoFetcher, defaultFetcher } from './fetcher'\nimport { createDemoMiddleware } from './middleware'\nimport { normalizeFixtureMap } from './matcher'\nimport type {\n DemoSWRProviderProps,\n SWRFixtureHandler,\n SWRFixtureMap,\n SWRMutationFixtureHandler,\n SWRMutationFixtureMap,\n DemoSWRState,\n} from './types'\n\n/**\n * Provider component for DemoKit SWR integration\n *\n * Wraps SWRConfig and intercepts fetches when demo mode is enabled.\n * Uses SWR's middleware pattern for maximum flexibility.\n *\n * @example\n * // With object-based fixtures\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={{\n * '/api/users': [{ id: '1', name: 'Demo User' }],\n * '[\"/api/users\", \":id\"]': ({ params }) => ({ id: params.id, name: 'Demo User' }),\n * '[\"/api/projects\", { status: \":status\" }]': ({ params }) => [\n * { id: '1', name: 'Project', status: params.status },\n * ],\n * }}\n * delay={100}\n * >\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With Map-based fixtures\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'Demo User' })],\n * ])\n *\n * <DemoSWRProvider enabled={true} fixtures={fixtures}>\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With cache seeding via fallback\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={fixtures}\n * fallback={{\n * '/api/users': [{ id: '1', name: 'Pre-loaded User' }],\n * }}\n * >\n * <App />\n * </DemoSWRProvider>\n */\nexport function DemoSWRProvider({\n children,\n fixtures = new Map(),\n mutations = new Map(),\n enabled = false,\n delay = 0,\n fallback = {},\n swrConfig = {},\n}: DemoSWRProviderProps) {\n // Normalize fixtures\n const fixturesRef = useRef<SWRFixtureMap>(normalizeFixtureMap(fixtures))\n const mutationFixturesRef = useRef<SWRMutationFixtureMap>(\n mutations instanceof Map ? mutations : new Map(Object.entries(mutations))\n )\n\n const isDemoMode = enabled\n\n // Create demo middleware\n const demoMiddleware = useMemo(\n () =>\n createDemoMiddleware({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n }),\n [isDemoMode, delay]\n )\n\n // Create demo fetcher (for direct use)\n const demoFetcher = useMemo(\n () =>\n createDemoFetcher({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n fallbackFetcher: defaultFetcher,\n }),\n [isDemoMode, delay]\n )\n\n // Build fallback data from static fixtures + provided fallback\n const combinedFallback = useMemo(() => {\n if (!isDemoMode) return swrConfig.fallback || {}\n\n const staticFixtures: Record<string, unknown> = {}\n\n // Add static fixture values to fallback\n for (const [pattern, handler] of fixturesRef.current) {\n if (typeof handler !== 'function') {\n // Use the pattern as key for static fixtures\n const key = pattern.length === 1 ? String(pattern[0]) : JSON.stringify(pattern)\n staticFixtures[key] = handler\n }\n }\n\n return {\n ...staticFixtures,\n ...fallback,\n ...(swrConfig.fallback || {}),\n }\n }, [isDemoMode, fallback, swrConfig.fallback])\n\n // Build SWR config\n const config = useMemo(\n () => ({\n ...swrConfig,\n use: [...(swrConfig.use || []), demoMiddleware],\n fallback: combinedFallback,\n // In demo mode, don't retry and keep data fresh longer\n ...(isDemoMode\n ? {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n }\n : {}),\n }),\n [swrConfig, demoMiddleware, combinedFallback, isDemoMode]\n )\n\n // Context value with manipulation methods\n const getFetcher = useCallback(() => demoFetcher, [demoFetcher])\n const getMiddleware = useCallback(() => demoMiddleware, [demoMiddleware])\n\n const contextValue = useMemo<DemoSWRState>(\n () => ({\n isDemoMode,\n\n setFixture: (pattern: QueryKey, handler: SWRFixtureHandler) => {\n fixturesRef.current.set(pattern, handler)\n },\n\n removeFixture: (pattern: QueryKey) => {\n fixturesRef.current.delete(pattern)\n },\n\n setMutationFixture: (name: string, handler: SWRMutationFixtureHandler) => {\n mutationFixturesRef.current.set(name, handler)\n },\n\n removeMutationFixture: (name: string) => {\n mutationFixturesRef.current.delete(name)\n },\n\n getFetcher,\n getMiddleware,\n }),\n [isDemoMode, getFetcher, getMiddleware]\n )\n\n return (\n <DemoSWRContext.Provider value={contextValue}>\n <SWRConfig value={config}>{children}</SWRConfig>\n </DemoSWRContext.Provider>\n )\n}\n","'use client'\n\nimport { createContext } from 'react'\nimport type { DemoSWRState } from './types'\n\n/**\n * Context for DemoSWR state\n * @internal\n */\nexport const DemoSWRContext = createContext<DemoSWRState | undefined>(undefined)\n\nDemoSWRContext.displayName = 'DemoSWRContext'\n","import { matchQueryKey, findMatchingQueryKeyPattern } from '@demokit-ai/core'\nimport type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureHandler, SWRFixtureMap, SWRFixtureMapObject } from './types'\n\n/**\n * Normalize an SWR key to a QueryKey for matching\n *\n * SWR keys can be:\n * - Strings: '/api/users' -> ['/api/users']\n * - Arrays: ['/api/users', id] -> ['/api/users', id]\n * - Functions that return keys (not handled here)\n */\nexport function normalizeKey(key: string | unknown[]): QueryKey {\n if (typeof key === 'string') {\n return [key]\n }\n\n return key.map((element) => {\n if (element === null || element === undefined) {\n return element\n }\n if (typeof element === 'object') {\n return element as Record<string, unknown>\n }\n return element as string | number | boolean\n })\n}\n\n/**\n * Parse a JSON string pattern into a QueryKey\n * Handles both array notation and simple string patterns\n *\n * @example\n * parsePatternString('[\"/api/users\"]') // ['/api/users']\n * parsePatternString('[\"/api/users\", \":id\"]') // ['/api/users', ':id']\n * parsePatternString('/api/users') // ['/api/users']\n */\nexport function parsePatternString(pattern: string): QueryKey {\n // Try to parse as JSON array\n if (pattern.startsWith('[')) {\n try {\n return JSON.parse(pattern) as QueryKey\n } catch {\n // Fall through to simple string\n }\n }\n\n // Simple string becomes single-element array\n return [pattern]\n}\n\n/**\n * Convert object-based fixture map to Map-based fixture map\n */\nexport function normalizeFixtureMap(fixtures: SWRFixtureMapObject | SWRFixtureMap): SWRFixtureMap {\n if (fixtures instanceof Map) {\n return fixtures\n }\n\n const map = new Map<QueryKey, SWRFixtureHandler>()\n for (const [pattern, handler] of Object.entries(fixtures)) {\n map.set(parsePatternString(pattern), handler)\n }\n return map\n}\n\n/**\n * Find a matching fixture for an SWR key\n *\n * @param fixtures - Map of key patterns to handlers\n * @param key - The SWR key to match\n * @returns Tuple of [handler, match result] or null if no match\n */\nexport function findMatchingFixture(\n fixtures: SWRFixtureMap,\n key: string | unknown[]\n): [SWRFixtureHandler, { params: Record<string, unknown>; normalizedKey: QueryKey }] | null {\n const normalizedKey = normalizeKey(key)\n const result = findMatchingQueryKeyPattern(fixtures, normalizedKey)\n\n if (result) {\n const [, handler, matchResult] = result\n return [handler, { params: matchResult.params, normalizedKey }]\n }\n\n return null\n}\n\n/**\n * Re-export the matchQueryKey function for direct use\n */\nexport { matchQueryKey }","import type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture, normalizeKey } from './matcher'\n\n/**\n * Options for creating a demo-aware fetcher\n */\nexport interface CreateDemoFetcherOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n\n /**\n * Fallback fetcher to use when demo mode is disabled\n * or no fixture matches\n */\n fallbackFetcher?: <T>(key: string | unknown[]) => Promise<T>\n}\n\n/**\n * Create a demo-aware fetcher function for SWR\n *\n * This fetcher intercepts requests when demo mode is enabled\n * and returns fixture data instead of making real API calls.\n *\n * @example\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const fetcher = createDemoFetcher({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * // Use with SWR\n * const { data } = useSWR('/api/users', fetcher)\n */\nexport function createDemoFetcher(options: CreateDemoFetcherOptions) {\n const { fixtures, isEnabled, delay = 0, fallbackFetcher } = options\n\n return async function demoFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n // If demo mode is not enabled, use fallback\n if (!isEnabled()) {\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(\n `[DemoKit SWR] No fallback fetcher provided and demo mode is disabled. ` +\n `Key: ${JSON.stringify(key)}`\n )\n }\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, key)\n\n if (!match) {\n // No fixture found, try fallback\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(`[DemoKit SWR] No fixture found for key: ${JSON.stringify(key)}`)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context) as TData\n }\n\n // Return static value\n return handler as TData\n }\n}\n\n/**\n * Default fetcher that uses fetch API\n * Used as fallback when demo mode is disabled\n */\nexport async function defaultFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n const url = typeof key === 'string' ? key : String(key[0])\n const response = await fetch(url)\n\n if (!response.ok) {\n const error = new Error('An error occurred while fetching the data.')\n throw error\n }\n\n return response.json()\n}\n","import type { Middleware } from 'swr'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture } from './matcher'\n\n/**\n * Options for creating the demo middleware\n */\nexport interface CreateDemoMiddlewareOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n}\n\n/**\n * Create a demo-aware SWR middleware\n *\n * This middleware intercepts SWR requests when demo mode is enabled\n * and returns fixture data instead of using the original fetcher.\n *\n * @example\n * import { SWRConfig } from 'swr'\n * import { createDemoMiddleware } from '@demokit-ai/swr'\n *\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const demoMiddleware = createDemoMiddleware({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * function App() {\n * return (\n * <SWRConfig value={{ use: [demoMiddleware] }}>\n * <YourApp />\n * </SWRConfig>\n * )\n * }\n */\nexport function createDemoMiddleware(options: CreateDemoMiddlewareOptions): Middleware {\n const { fixtures, isEnabled, delay = 0 } = options\n\n // Use the simpler middleware pattern that SWR expects\n const middleware: Middleware = (useSWRNext) => (key, fetcher, config) => {\n // Create an extended fetcher that checks for demo mode\n const extendedFetcher =\n fetcher === null\n ? null\n : async (...args: Parameters<typeof fetcher>) => {\n // Resolve the key if it's a function\n const resolvedKey = typeof key === 'function' ? key() : key\n\n // If no key, let SWR handle it\n if (resolvedKey === null || resolvedKey === undefined) {\n return fetcher(...args)\n }\n\n // If demo mode is not enabled, use original fetcher\n if (!isEnabled()) {\n return fetcher(...args)\n }\n\n // Normalize key for matching\n const keyToMatch =\n typeof resolvedKey === 'string' ? resolvedKey : (resolvedKey as unknown[])\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, keyToMatch)\n\n if (!match) {\n // No fixture found, use original fetcher\n return fetcher(...args)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key: resolvedKey,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context)\n }\n\n // Return static value\n return handler\n }\n\n return useSWRNext(key, extendedFetcher, config)\n }\n\n return middleware\n}\n","import type { RemoteSourceConfig } from './types'\n\n/**\n * Create a remote source configuration for fetching fixtures from DemoKit Cloud\n *\n * The SDK appends `/fixtures` to your apiUrl, so provide the versioned base URL.\n *\n * @example\n * ```typescript\n * // lib/demokit-config.ts\n * import { createRemoteSource } from '@demokit-ai/swr'\n *\n * // .env:\n * // VITE_DEMOKIT_API_URL=https://demokit-cloud.kasava.dev/api\n * // VITE_DEMOKIT_API_KEY=dk_live_xxxx\n *\n * export const demokitSource = createRemoteSource({\n * apiUrl: import.meta.env.VITE_DEMOKIT_API_URL,\n * apiKey: import.meta.env.VITE_DEMOKIT_API_KEY,\n * })\n *\n * // Then in your app:\n * import { demokitSource } from './lib/demokit-config'\n *\n * <DemoSWRProvider source={demokitSource}>\n * <SWRConfig>\n * <App />\n * </SWRConfig>\n * </DemoSWRProvider>\n * ```\n */\nexport function createRemoteSource(config: RemoteSourceConfig): RemoteSourceConfig {\n return {\n timeout: 10000,\n retry: true,\n maxRetries: 3,\n ...config,\n }\n}\n","'use client'\n\nimport { useContext, useCallback } from 'react'\nimport useSWRMutation, { type SWRMutationConfiguration, type SWRMutationResponse } from 'swr/mutation'\nimport { useSWRConfig } from 'swr'\nimport { DemoSWRContext } from './context'\nimport type { DemoSWRState, SWRMutationFixtureContext, SWRMutationFixtureHandler } from './types'\n\n/**\n * Hook to access DemoSWR state and controls\n *\n * @returns DemoSWR context value\n * @throws Error if used outside of DemoSWRProvider\n *\n * @example\n * function MyComponent() {\n * const { isDemoMode, setFixture } = useDemoSWR()\n *\n * // Dynamically add a fixture\n * const handleAddFixture = () => {\n * setFixture(['/api/users', 'custom'], { id: 'custom', name: 'Custom User' })\n * }\n *\n * return (\n * <button onClick={handleAddFixture}>Add Custom Fixture</button>\n * )\n * }\n */\nexport function useDemoSWR(): DemoSWRState {\n const context = useContext(DemoSWRContext)\n\n if (context === undefined) {\n throw new Error(\n 'useDemoSWR must be used within a DemoSWRProvider. ' +\n 'Make sure to wrap your app with <DemoSWRProvider>.'\n )\n }\n\n return context\n}\n\n/**\n * Hook to check if demo mode is enabled\n * Shorthand for useDemoSWR().isDemoMode\n *\n * @example\n * function MyComponent() {\n * const isDemoMode = useIsDemoSWRMode()\n *\n * return isDemoMode ? <DemoBadge /> : null\n * }\n */\nexport function useIsDemoSWRMode(): boolean {\n return useDemoSWR().isDemoMode\n}\n\n/**\n * Options for useDemoSWRMutation hook\n */\nexport interface UseDemoSWRMutationOptions<TData, TError, TArg>\n extends Omit<SWRMutationConfiguration<TData, TError, string, TArg>, 'fetcher'> {\n /**\n * The real mutation function to use when demo mode is disabled\n */\n fetcher: (key: string, options: { arg: TArg }) => Promise<TData>\n\n /**\n * Demo fixture handler for this mutation\n */\n demoFixture?: SWRMutationFixtureHandler<TData, TArg>\n\n /**\n * Delay in ms before returning demo data\n * @default 0\n */\n demoDelay?: number\n}\n\n/**\n * A mutation hook that automatically uses demo fixtures when demo mode is enabled\n *\n * Works with useSWRMutation from swr/mutation.\n *\n * @example\n * const { trigger: createUser, isMutating } = useDemoSWRMutation('/api/users', {\n * fetcher: async (key, { arg }) => api.createUser(arg),\n * demoFixture: ({ arg, mutate }) => {\n * // Create demo user\n * const newUser = { id: crypto.randomUUID(), ...arg }\n *\n * // Update the users cache\n * mutate('/api/users', (current: User[] = []) => [...current, newUser])\n *\n * return newUser\n * },\n * onSuccess: (data) => {\n * console.log('Created user:', data)\n * },\n * })\n *\n * // Use like normal useSWRMutation\n * createUser({ name: 'New User', email: 'user@example.com' })\n */\nexport function useDemoSWRMutation<TData = unknown, TError = unknown, TArg = unknown>(\n key: string,\n options: UseDemoSWRMutationOptions<TData, TError, TArg>\n): SWRMutationResponse<TData, TError, string, TArg> {\n const { fetcher, demoFixture, demoDelay = 0, ...mutationOptions } = options\n\n const { mutate } = useSWRConfig()\n\n // Try to get demo state - may not be in DemoSWRProvider context\n let isDemoMode = false\n try {\n const demoState = useDemoSWR()\n isDemoMode = demoState.isDemoMode\n } catch {\n // Not in DemoSWRProvider context, use real mutation\n }\n\n // Create the demo-aware mutation function\n const demoAwareFetcher = useCallback(\n async (mutationKey: string, { arg }: { arg: TArg }): Promise<TData> => {\n // If not in demo mode, use real mutation\n if (!isDemoMode) {\n return fetcher(mutationKey, { arg })\n }\n\n // Apply delay if configured\n if (demoDelay > 0) {\n await new Promise((resolve) => setTimeout(resolve, demoDelay))\n }\n\n // If a demo fixture is provided, use it\n if (demoFixture !== undefined) {\n const context: SWRMutationFixtureContext<TData, TArg> = {\n key: mutationKey,\n arg,\n currentData: undefined, // SWR mutation doesn't have direct access to current data\n mutate: mutate as SWRMutationFixtureContext<TData, TArg>['mutate'],\n }\n\n if (typeof demoFixture === 'function') {\n const fixtureFn = demoFixture as (\n context: SWRMutationFixtureContext<TData, TArg>\n ) => TData | Promise<TData>\n return fixtureFn(context)\n }\n return demoFixture as TData\n }\n\n // No fixture found, fall back to real mutation\n console.warn(\n `[DemoKit SWR] No mutation fixture found for \"${key}\". Using real mutation function.`\n )\n return fetcher(mutationKey, { arg })\n },\n [isDemoMode, fetcher, demoFixture, demoDelay, key, mutate]\n )\n\n return useSWRMutation(key, demoAwareFetcher, mutationOptions)\n}\n"],"mappings":"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","names":["import_react","import_react","import_swr","useSWRMutation"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -149,6 +149,38 @@ interface DemoSWRState {
|
|
|
149
149
|
*/
|
|
150
150
|
getMiddleware: () => Middleware;
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Configuration for remote fixture source (DemoKit Cloud)
|
|
154
|
+
*/
|
|
155
|
+
interface RemoteSourceConfig {
|
|
156
|
+
/**
|
|
157
|
+
* DemoKit Cloud API URL (versioned base URL)
|
|
158
|
+
* The SDK will append `/fixtures` to this URL.
|
|
159
|
+
* @example 'https://demokit-cloud.kasava.dev/api'
|
|
160
|
+
* @default 'https://api.demokit.cloud/api'
|
|
161
|
+
*/
|
|
162
|
+
apiUrl: string;
|
|
163
|
+
/**
|
|
164
|
+
* DemoKit Cloud API key
|
|
165
|
+
* Format: dk_live_xxx
|
|
166
|
+
*/
|
|
167
|
+
apiKey: string;
|
|
168
|
+
/**
|
|
169
|
+
* Request timeout in milliseconds
|
|
170
|
+
* @default 10000
|
|
171
|
+
*/
|
|
172
|
+
timeout?: number;
|
|
173
|
+
/**
|
|
174
|
+
* Whether to retry failed requests
|
|
175
|
+
* @default true
|
|
176
|
+
*/
|
|
177
|
+
retry?: boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Maximum number of retries
|
|
180
|
+
* @default 3
|
|
181
|
+
*/
|
|
182
|
+
maxRetries?: number;
|
|
183
|
+
}
|
|
152
184
|
|
|
153
185
|
/**
|
|
154
186
|
* Provider component for DemoKit SWR integration
|
|
@@ -197,6 +229,37 @@ interface DemoSWRState {
|
|
|
197
229
|
*/
|
|
198
230
|
declare function DemoSWRProvider({ children, fixtures, mutations, enabled, delay, fallback, swrConfig, }: DemoSWRProviderProps): react_jsx_runtime.JSX.Element;
|
|
199
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Create a remote source configuration for fetching fixtures from DemoKit Cloud
|
|
234
|
+
*
|
|
235
|
+
* The SDK appends `/fixtures` to your apiUrl, so provide the versioned base URL.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* // lib/demokit-config.ts
|
|
240
|
+
* import { createRemoteSource } from '@demokit-ai/swr'
|
|
241
|
+
*
|
|
242
|
+
* // .env:
|
|
243
|
+
* // VITE_DEMOKIT_API_URL=https://demokit-cloud.kasava.dev/api
|
|
244
|
+
* // VITE_DEMOKIT_API_KEY=dk_live_xxxx
|
|
245
|
+
*
|
|
246
|
+
* export const demokitSource = createRemoteSource({
|
|
247
|
+
* apiUrl: import.meta.env.VITE_DEMOKIT_API_URL,
|
|
248
|
+
* apiKey: import.meta.env.VITE_DEMOKIT_API_KEY,
|
|
249
|
+
* })
|
|
250
|
+
*
|
|
251
|
+
* // Then in your app:
|
|
252
|
+
* import { demokitSource } from './lib/demokit-config'
|
|
253
|
+
*
|
|
254
|
+
* <DemoSWRProvider source={demokitSource}>
|
|
255
|
+
* <SWRConfig>
|
|
256
|
+
* <App />
|
|
257
|
+
* </SWRConfig>
|
|
258
|
+
* </DemoSWRProvider>
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
declare function createRemoteSource(config: RemoteSourceConfig): RemoteSourceConfig;
|
|
262
|
+
|
|
200
263
|
/**
|
|
201
264
|
* Hook to access DemoSWR state and controls
|
|
202
265
|
*
|
|
@@ -412,4 +475,4 @@ declare function findMatchingFixture(fixtures: SWRFixtureMap, key: string | unkn
|
|
|
412
475
|
normalizedKey: QueryKey;
|
|
413
476
|
}] | null;
|
|
414
477
|
|
|
415
|
-
export { type CreateDemoFetcherOptions, type CreateDemoMiddlewareOptions, DemoSWRProvider, type DemoSWRProviderConfig, type DemoSWRProviderProps, type DemoSWRState, type SWRFixtureContext, type SWRFixtureHandler, type SWRFixtureMap, type SWRFixtureMapObject, type SWRMutationFixtureContext, type SWRMutationFixtureHandler, type SWRMutationFixtureMap, type SWRMutationFixtureMapObject, type UseDemoSWRMutationOptions, createDemoFetcher, createDemoMiddleware, defaultFetcher, findMatchingFixture, normalizeFixtureMap, normalizeKey, parsePatternString, useDemoSWR, useDemoSWRMutation, useIsDemoSWRMode };
|
|
478
|
+
export { type CreateDemoFetcherOptions, type CreateDemoMiddlewareOptions, DemoSWRProvider, type DemoSWRProviderConfig, type DemoSWRProviderProps, type DemoSWRState, type RemoteSourceConfig, type SWRFixtureContext, type SWRFixtureHandler, type SWRFixtureMap, type SWRFixtureMapObject, type SWRMutationFixtureContext, type SWRMutationFixtureHandler, type SWRMutationFixtureMap, type SWRMutationFixtureMapObject, type UseDemoSWRMutationOptions, createDemoFetcher, createDemoMiddleware, createRemoteSource, defaultFetcher, findMatchingFixture, normalizeFixtureMap, normalizeKey, parsePatternString, useDemoSWR, useDemoSWRMutation, useIsDemoSWRMode };
|
package/dist/index.d.ts
CHANGED
|
@@ -149,6 +149,38 @@ interface DemoSWRState {
|
|
|
149
149
|
*/
|
|
150
150
|
getMiddleware: () => Middleware;
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Configuration for remote fixture source (DemoKit Cloud)
|
|
154
|
+
*/
|
|
155
|
+
interface RemoteSourceConfig {
|
|
156
|
+
/**
|
|
157
|
+
* DemoKit Cloud API URL (versioned base URL)
|
|
158
|
+
* The SDK will append `/fixtures` to this URL.
|
|
159
|
+
* @example 'https://demokit-cloud.kasava.dev/api'
|
|
160
|
+
* @default 'https://api.demokit.cloud/api'
|
|
161
|
+
*/
|
|
162
|
+
apiUrl: string;
|
|
163
|
+
/**
|
|
164
|
+
* DemoKit Cloud API key
|
|
165
|
+
* Format: dk_live_xxx
|
|
166
|
+
*/
|
|
167
|
+
apiKey: string;
|
|
168
|
+
/**
|
|
169
|
+
* Request timeout in milliseconds
|
|
170
|
+
* @default 10000
|
|
171
|
+
*/
|
|
172
|
+
timeout?: number;
|
|
173
|
+
/**
|
|
174
|
+
* Whether to retry failed requests
|
|
175
|
+
* @default true
|
|
176
|
+
*/
|
|
177
|
+
retry?: boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Maximum number of retries
|
|
180
|
+
* @default 3
|
|
181
|
+
*/
|
|
182
|
+
maxRetries?: number;
|
|
183
|
+
}
|
|
152
184
|
|
|
153
185
|
/**
|
|
154
186
|
* Provider component for DemoKit SWR integration
|
|
@@ -197,6 +229,37 @@ interface DemoSWRState {
|
|
|
197
229
|
*/
|
|
198
230
|
declare function DemoSWRProvider({ children, fixtures, mutations, enabled, delay, fallback, swrConfig, }: DemoSWRProviderProps): react_jsx_runtime.JSX.Element;
|
|
199
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Create a remote source configuration for fetching fixtures from DemoKit Cloud
|
|
234
|
+
*
|
|
235
|
+
* The SDK appends `/fixtures` to your apiUrl, so provide the versioned base URL.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* // lib/demokit-config.ts
|
|
240
|
+
* import { createRemoteSource } from '@demokit-ai/swr'
|
|
241
|
+
*
|
|
242
|
+
* // .env:
|
|
243
|
+
* // VITE_DEMOKIT_API_URL=https://demokit-cloud.kasava.dev/api
|
|
244
|
+
* // VITE_DEMOKIT_API_KEY=dk_live_xxxx
|
|
245
|
+
*
|
|
246
|
+
* export const demokitSource = createRemoteSource({
|
|
247
|
+
* apiUrl: import.meta.env.VITE_DEMOKIT_API_URL,
|
|
248
|
+
* apiKey: import.meta.env.VITE_DEMOKIT_API_KEY,
|
|
249
|
+
* })
|
|
250
|
+
*
|
|
251
|
+
* // Then in your app:
|
|
252
|
+
* import { demokitSource } from './lib/demokit-config'
|
|
253
|
+
*
|
|
254
|
+
* <DemoSWRProvider source={demokitSource}>
|
|
255
|
+
* <SWRConfig>
|
|
256
|
+
* <App />
|
|
257
|
+
* </SWRConfig>
|
|
258
|
+
* </DemoSWRProvider>
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
declare function createRemoteSource(config: RemoteSourceConfig): RemoteSourceConfig;
|
|
262
|
+
|
|
200
263
|
/**
|
|
201
264
|
* Hook to access DemoSWR state and controls
|
|
202
265
|
*
|
|
@@ -412,4 +475,4 @@ declare function findMatchingFixture(fixtures: SWRFixtureMap, key: string | unkn
|
|
|
412
475
|
normalizedKey: QueryKey;
|
|
413
476
|
}] | null;
|
|
414
477
|
|
|
415
|
-
export { type CreateDemoFetcherOptions, type CreateDemoMiddlewareOptions, DemoSWRProvider, type DemoSWRProviderConfig, type DemoSWRProviderProps, type DemoSWRState, type SWRFixtureContext, type SWRFixtureHandler, type SWRFixtureMap, type SWRFixtureMapObject, type SWRMutationFixtureContext, type SWRMutationFixtureHandler, type SWRMutationFixtureMap, type SWRMutationFixtureMapObject, type UseDemoSWRMutationOptions, createDemoFetcher, createDemoMiddleware, defaultFetcher, findMatchingFixture, normalizeFixtureMap, normalizeKey, parsePatternString, useDemoSWR, useDemoSWRMutation, useIsDemoSWRMode };
|
|
478
|
+
export { type CreateDemoFetcherOptions, type CreateDemoMiddlewareOptions, DemoSWRProvider, type DemoSWRProviderConfig, type DemoSWRProviderProps, type DemoSWRState, type RemoteSourceConfig, type SWRFixtureContext, type SWRFixtureHandler, type SWRFixtureMap, type SWRFixtureMapObject, type SWRMutationFixtureContext, type SWRMutationFixtureHandler, type SWRMutationFixtureMap, type SWRMutationFixtureMapObject, type UseDemoSWRMutationOptions, createDemoFetcher, createDemoMiddleware, createRemoteSource, defaultFetcher, findMatchingFixture, normalizeFixtureMap, normalizeKey, parsePatternString, useDemoSWR, useDemoSWRMutation, useIsDemoSWRMode };
|
package/dist/index.js
CHANGED
|
@@ -221,6 +221,16 @@ function DemoSWRProvider({
|
|
|
221
221
|
return /* @__PURE__ */ jsx(DemoSWRContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(SWRConfig, { value: config, children }) });
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
// src/config.ts
|
|
225
|
+
function createRemoteSource(config) {
|
|
226
|
+
return {
|
|
227
|
+
timeout: 1e4,
|
|
228
|
+
retry: true,
|
|
229
|
+
maxRetries: 3,
|
|
230
|
+
...config
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
224
234
|
// src/hooks.ts
|
|
225
235
|
import { useContext, useCallback as useCallback2 } from "react";
|
|
226
236
|
import useSWRMutation from "swr/mutation";
|
|
@@ -281,6 +291,7 @@ export {
|
|
|
281
291
|
DemoSWRProvider,
|
|
282
292
|
createDemoFetcher,
|
|
283
293
|
createDemoMiddleware,
|
|
294
|
+
createRemoteSource,
|
|
284
295
|
defaultFetcher,
|
|
285
296
|
findMatchingFixture,
|
|
286
297
|
matchQueryKey,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx","../src/context.ts","../src/matcher.ts","../src/fetcher.ts","../src/middleware.ts","../src/hooks.ts"],"sourcesContent":["'use client'\n\nimport { useMemo, useRef, useCallback } from 'react'\nimport { SWRConfig } from 'swr'\nimport type { QueryKey } from '@demokit-ai/core'\nimport { DemoSWRContext } from './context'\nimport { createDemoFetcher, defaultFetcher } from './fetcher'\nimport { createDemoMiddleware } from './middleware'\nimport { normalizeFixtureMap } from './matcher'\nimport type {\n DemoSWRProviderProps,\n SWRFixtureHandler,\n SWRFixtureMap,\n SWRMutationFixtureHandler,\n SWRMutationFixtureMap,\n DemoSWRState,\n} from './types'\n\n/**\n * Provider component for DemoKit SWR integration\n *\n * Wraps SWRConfig and intercepts fetches when demo mode is enabled.\n * Uses SWR's middleware pattern for maximum flexibility.\n *\n * @example\n * // With object-based fixtures\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={{\n * '/api/users': [{ id: '1', name: 'Demo User' }],\n * '[\"/api/users\", \":id\"]': ({ params }) => ({ id: params.id, name: 'Demo User' }),\n * '[\"/api/projects\", { status: \":status\" }]': ({ params }) => [\n * { id: '1', name: 'Project', status: params.status },\n * ],\n * }}\n * delay={100}\n * >\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With Map-based fixtures\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'Demo User' })],\n * ])\n *\n * <DemoSWRProvider enabled={true} fixtures={fixtures}>\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With cache seeding via fallback\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={fixtures}\n * fallback={{\n * '/api/users': [{ id: '1', name: 'Pre-loaded User' }],\n * }}\n * >\n * <App />\n * </DemoSWRProvider>\n */\nexport function DemoSWRProvider({\n children,\n fixtures = new Map(),\n mutations = new Map(),\n enabled = false,\n delay = 0,\n fallback = {},\n swrConfig = {},\n}: DemoSWRProviderProps) {\n // Normalize fixtures\n const fixturesRef = useRef<SWRFixtureMap>(normalizeFixtureMap(fixtures))\n const mutationFixturesRef = useRef<SWRMutationFixtureMap>(\n mutations instanceof Map ? mutations : new Map(Object.entries(mutations))\n )\n\n const isDemoMode = enabled\n\n // Create demo middleware\n const demoMiddleware = useMemo(\n () =>\n createDemoMiddleware({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n }),\n [isDemoMode, delay]\n )\n\n // Create demo fetcher (for direct use)\n const demoFetcher = useMemo(\n () =>\n createDemoFetcher({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n fallbackFetcher: defaultFetcher,\n }),\n [isDemoMode, delay]\n )\n\n // Build fallback data from static fixtures + provided fallback\n const combinedFallback = useMemo(() => {\n if (!isDemoMode) return swrConfig.fallback || {}\n\n const staticFixtures: Record<string, unknown> = {}\n\n // Add static fixture values to fallback\n for (const [pattern, handler] of fixturesRef.current) {\n if (typeof handler !== 'function') {\n // Use the pattern as key for static fixtures\n const key = pattern.length === 1 ? String(pattern[0]) : JSON.stringify(pattern)\n staticFixtures[key] = handler\n }\n }\n\n return {\n ...staticFixtures,\n ...fallback,\n ...(swrConfig.fallback || {}),\n }\n }, [isDemoMode, fallback, swrConfig.fallback])\n\n // Build SWR config\n const config = useMemo(\n () => ({\n ...swrConfig,\n use: [...(swrConfig.use || []), demoMiddleware],\n fallback: combinedFallback,\n // In demo mode, don't retry and keep data fresh longer\n ...(isDemoMode\n ? {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n }\n : {}),\n }),\n [swrConfig, demoMiddleware, combinedFallback, isDemoMode]\n )\n\n // Context value with manipulation methods\n const getFetcher = useCallback(() => demoFetcher, [demoFetcher])\n const getMiddleware = useCallback(() => demoMiddleware, [demoMiddleware])\n\n const contextValue = useMemo<DemoSWRState>(\n () => ({\n isDemoMode,\n\n setFixture: (pattern: QueryKey, handler: SWRFixtureHandler) => {\n fixturesRef.current.set(pattern, handler)\n },\n\n removeFixture: (pattern: QueryKey) => {\n fixturesRef.current.delete(pattern)\n },\n\n setMutationFixture: (name: string, handler: SWRMutationFixtureHandler) => {\n mutationFixturesRef.current.set(name, handler)\n },\n\n removeMutationFixture: (name: string) => {\n mutationFixturesRef.current.delete(name)\n },\n\n getFetcher,\n getMiddleware,\n }),\n [isDemoMode, getFetcher, getMiddleware]\n )\n\n return (\n <DemoSWRContext.Provider value={contextValue}>\n <SWRConfig value={config}>{children}</SWRConfig>\n </DemoSWRContext.Provider>\n )\n}\n","'use client'\n\nimport { createContext } from 'react'\nimport type { DemoSWRState } from './types'\n\n/**\n * Context for DemoSWR state\n * @internal\n */\nexport const DemoSWRContext = createContext<DemoSWRState | undefined>(undefined)\n\nDemoSWRContext.displayName = 'DemoSWRContext'\n","import { matchQueryKey, findMatchingQueryKeyPattern } from '@demokit-ai/core'\nimport type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureHandler, SWRFixtureMap, SWRFixtureMapObject } from './types'\n\n/**\n * Normalize an SWR key to a QueryKey for matching\n *\n * SWR keys can be:\n * - Strings: '/api/users' -> ['/api/users']\n * - Arrays: ['/api/users', id] -> ['/api/users', id]\n * - Functions that return keys (not handled here)\n */\nexport function normalizeKey(key: string | unknown[]): QueryKey {\n if (typeof key === 'string') {\n return [key]\n }\n\n return key.map((element) => {\n if (element === null || element === undefined) {\n return element\n }\n if (typeof element === 'object') {\n return element as Record<string, unknown>\n }\n return element as string | number | boolean\n })\n}\n\n/**\n * Parse a JSON string pattern into a QueryKey\n * Handles both array notation and simple string patterns\n *\n * @example\n * parsePatternString('[\"/api/users\"]') // ['/api/users']\n * parsePatternString('[\"/api/users\", \":id\"]') // ['/api/users', ':id']\n * parsePatternString('/api/users') // ['/api/users']\n */\nexport function parsePatternString(pattern: string): QueryKey {\n // Try to parse as JSON array\n if (pattern.startsWith('[')) {\n try {\n return JSON.parse(pattern) as QueryKey\n } catch {\n // Fall through to simple string\n }\n }\n\n // Simple string becomes single-element array\n return [pattern]\n}\n\n/**\n * Convert object-based fixture map to Map-based fixture map\n */\nexport function normalizeFixtureMap(fixtures: SWRFixtureMapObject | SWRFixtureMap): SWRFixtureMap {\n if (fixtures instanceof Map) {\n return fixtures\n }\n\n const map = new Map<QueryKey, SWRFixtureHandler>()\n for (const [pattern, handler] of Object.entries(fixtures)) {\n map.set(parsePatternString(pattern), handler)\n }\n return map\n}\n\n/**\n * Find a matching fixture for an SWR key\n *\n * @param fixtures - Map of key patterns to handlers\n * @param key - The SWR key to match\n * @returns Tuple of [handler, match result] or null if no match\n */\nexport function findMatchingFixture(\n fixtures: SWRFixtureMap,\n key: string | unknown[]\n): [SWRFixtureHandler, { params: Record<string, unknown>; normalizedKey: QueryKey }] | null {\n const normalizedKey = normalizeKey(key)\n const result = findMatchingQueryKeyPattern(fixtures, normalizedKey)\n\n if (result) {\n const [, handler, matchResult] = result\n return [handler, { params: matchResult.params, normalizedKey }]\n }\n\n return null\n}\n\n/**\n * Re-export the matchQueryKey function for direct use\n */\nexport { matchQueryKey }","import type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture, normalizeKey } from './matcher'\n\n/**\n * Options for creating a demo-aware fetcher\n */\nexport interface CreateDemoFetcherOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n\n /**\n * Fallback fetcher to use when demo mode is disabled\n * or no fixture matches\n */\n fallbackFetcher?: <T>(key: string | unknown[]) => Promise<T>\n}\n\n/**\n * Create a demo-aware fetcher function for SWR\n *\n * This fetcher intercepts requests when demo mode is enabled\n * and returns fixture data instead of making real API calls.\n *\n * @example\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const fetcher = createDemoFetcher({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * // Use with SWR\n * const { data } = useSWR('/api/users', fetcher)\n */\nexport function createDemoFetcher(options: CreateDemoFetcherOptions) {\n const { fixtures, isEnabled, delay = 0, fallbackFetcher } = options\n\n return async function demoFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n // If demo mode is not enabled, use fallback\n if (!isEnabled()) {\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(\n `[DemoKit SWR] No fallback fetcher provided and demo mode is disabled. ` +\n `Key: ${JSON.stringify(key)}`\n )\n }\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, key)\n\n if (!match) {\n // No fixture found, try fallback\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(`[DemoKit SWR] No fixture found for key: ${JSON.stringify(key)}`)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context) as TData\n }\n\n // Return static value\n return handler as TData\n }\n}\n\n/**\n * Default fetcher that uses fetch API\n * Used as fallback when demo mode is disabled\n */\nexport async function defaultFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n const url = typeof key === 'string' ? key : String(key[0])\n const response = await fetch(url)\n\n if (!response.ok) {\n const error = new Error('An error occurred while fetching the data.')\n throw error\n }\n\n return response.json()\n}\n","import type { Middleware } from 'swr'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture } from './matcher'\n\n/**\n * Options for creating the demo middleware\n */\nexport interface CreateDemoMiddlewareOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n}\n\n/**\n * Create a demo-aware SWR middleware\n *\n * This middleware intercepts SWR requests when demo mode is enabled\n * and returns fixture data instead of using the original fetcher.\n *\n * @example\n * import { SWRConfig } from 'swr'\n * import { createDemoMiddleware } from '@demokit-ai/swr'\n *\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const demoMiddleware = createDemoMiddleware({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * function App() {\n * return (\n * <SWRConfig value={{ use: [demoMiddleware] }}>\n * <YourApp />\n * </SWRConfig>\n * )\n * }\n */\nexport function createDemoMiddleware(options: CreateDemoMiddlewareOptions): Middleware {\n const { fixtures, isEnabled, delay = 0 } = options\n\n // Use the simpler middleware pattern that SWR expects\n const middleware: Middleware = (useSWRNext) => (key, fetcher, config) => {\n // Create an extended fetcher that checks for demo mode\n const extendedFetcher =\n fetcher === null\n ? null\n : async (...args: Parameters<typeof fetcher>) => {\n // Resolve the key if it's a function\n const resolvedKey = typeof key === 'function' ? key() : key\n\n // If no key, let SWR handle it\n if (resolvedKey === null || resolvedKey === undefined) {\n return fetcher(...args)\n }\n\n // If demo mode is not enabled, use original fetcher\n if (!isEnabled()) {\n return fetcher(...args)\n }\n\n // Normalize key for matching\n const keyToMatch =\n typeof resolvedKey === 'string' ? resolvedKey : (resolvedKey as unknown[])\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, keyToMatch)\n\n if (!match) {\n // No fixture found, use original fetcher\n return fetcher(...args)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key: resolvedKey,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context)\n }\n\n // Return static value\n return handler\n }\n\n return useSWRNext(key, extendedFetcher, config)\n }\n\n return middleware\n}\n","'use client'\n\nimport { useContext, useCallback } from 'react'\nimport useSWRMutation, { type SWRMutationConfiguration, type SWRMutationResponse } from 'swr/mutation'\nimport { useSWRConfig } from 'swr'\nimport { DemoSWRContext } from './context'\nimport type { DemoSWRState, SWRMutationFixtureContext, SWRMutationFixtureHandler } from './types'\n\n/**\n * Hook to access DemoSWR state and controls\n *\n * @returns DemoSWR context value\n * @throws Error if used outside of DemoSWRProvider\n *\n * @example\n * function MyComponent() {\n * const { isDemoMode, setFixture } = useDemoSWR()\n *\n * // Dynamically add a fixture\n * const handleAddFixture = () => {\n * setFixture(['/api/users', 'custom'], { id: 'custom', name: 'Custom User' })\n * }\n *\n * return (\n * <button onClick={handleAddFixture}>Add Custom Fixture</button>\n * )\n * }\n */\nexport function useDemoSWR(): DemoSWRState {\n const context = useContext(DemoSWRContext)\n\n if (context === undefined) {\n throw new Error(\n 'useDemoSWR must be used within a DemoSWRProvider. ' +\n 'Make sure to wrap your app with <DemoSWRProvider>.'\n )\n }\n\n return context\n}\n\n/**\n * Hook to check if demo mode is enabled\n * Shorthand for useDemoSWR().isDemoMode\n *\n * @example\n * function MyComponent() {\n * const isDemoMode = useIsDemoSWRMode()\n *\n * return isDemoMode ? <DemoBadge /> : null\n * }\n */\nexport function useIsDemoSWRMode(): boolean {\n return useDemoSWR().isDemoMode\n}\n\n/**\n * Options for useDemoSWRMutation hook\n */\nexport interface UseDemoSWRMutationOptions<TData, TError, TArg>\n extends Omit<SWRMutationConfiguration<TData, TError, string, TArg>, 'fetcher'> {\n /**\n * The real mutation function to use when demo mode is disabled\n */\n fetcher: (key: string, options: { arg: TArg }) => Promise<TData>\n\n /**\n * Demo fixture handler for this mutation\n */\n demoFixture?: SWRMutationFixtureHandler<TData, TArg>\n\n /**\n * Delay in ms before returning demo data\n * @default 0\n */\n demoDelay?: number\n}\n\n/**\n * A mutation hook that automatically uses demo fixtures when demo mode is enabled\n *\n * Works with useSWRMutation from swr/mutation.\n *\n * @example\n * const { trigger: createUser, isMutating } = useDemoSWRMutation('/api/users', {\n * fetcher: async (key, { arg }) => api.createUser(arg),\n * demoFixture: ({ arg, mutate }) => {\n * // Create demo user\n * const newUser = { id: crypto.randomUUID(), ...arg }\n *\n * // Update the users cache\n * mutate('/api/users', (current: User[] = []) => [...current, newUser])\n *\n * return newUser\n * },\n * onSuccess: (data) => {\n * console.log('Created user:', data)\n * },\n * })\n *\n * // Use like normal useSWRMutation\n * createUser({ name: 'New User', email: 'user@example.com' })\n */\nexport function useDemoSWRMutation<TData = unknown, TError = unknown, TArg = unknown>(\n key: string,\n options: UseDemoSWRMutationOptions<TData, TError, TArg>\n): SWRMutationResponse<TData, TError, string, TArg> {\n const { fetcher, demoFixture, demoDelay = 0, ...mutationOptions } = options\n\n const { mutate } = useSWRConfig()\n\n // Try to get demo state - may not be in DemoSWRProvider context\n let isDemoMode = false\n try {\n const demoState = useDemoSWR()\n isDemoMode = demoState.isDemoMode\n } catch {\n // Not in DemoSWRProvider context, use real mutation\n }\n\n // Create the demo-aware mutation function\n const demoAwareFetcher = useCallback(\n async (mutationKey: string, { arg }: { arg: TArg }): Promise<TData> => {\n // If not in demo mode, use real mutation\n if (!isDemoMode) {\n return fetcher(mutationKey, { arg })\n }\n\n // Apply delay if configured\n if (demoDelay > 0) {\n await new Promise((resolve) => setTimeout(resolve, demoDelay))\n }\n\n // If a demo fixture is provided, use it\n if (demoFixture !== undefined) {\n const context: SWRMutationFixtureContext<TData, TArg> = {\n key: mutationKey,\n arg,\n currentData: undefined, // SWR mutation doesn't have direct access to current data\n mutate: mutate as SWRMutationFixtureContext<TData, TArg>['mutate'],\n }\n\n if (typeof demoFixture === 'function') {\n const fixtureFn = demoFixture as (\n context: SWRMutationFixtureContext<TData, TArg>\n ) => TData | Promise<TData>\n return fixtureFn(context)\n }\n return demoFixture as TData\n }\n\n // No fixture found, fall back to real mutation\n console.warn(\n `[DemoKit SWR] No mutation fixture found for \"${key}\". Using real mutation function.`\n )\n return fetcher(mutationKey, { arg })\n },\n [isDemoMode, fetcher, demoFixture, demoDelay, key, mutate]\n )\n\n return useSWRMutation(key, demoAwareFetcher, mutationOptions)\n}\n"],"mappings":"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","names":["useCallback","useCallback"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx","../src/context.ts","../src/matcher.ts","../src/fetcher.ts","../src/middleware.ts","../src/config.ts","../src/hooks.ts"],"sourcesContent":["'use client'\n\nimport { useMemo, useRef, useCallback } from 'react'\nimport { SWRConfig } from 'swr'\nimport type { QueryKey } from '@demokit-ai/core'\nimport { DemoSWRContext } from './context'\nimport { createDemoFetcher, defaultFetcher } from './fetcher'\nimport { createDemoMiddleware } from './middleware'\nimport { normalizeFixtureMap } from './matcher'\nimport type {\n DemoSWRProviderProps,\n SWRFixtureHandler,\n SWRFixtureMap,\n SWRMutationFixtureHandler,\n SWRMutationFixtureMap,\n DemoSWRState,\n} from './types'\n\n/**\n * Provider component for DemoKit SWR integration\n *\n * Wraps SWRConfig and intercepts fetches when demo mode is enabled.\n * Uses SWR's middleware pattern for maximum flexibility.\n *\n * @example\n * // With object-based fixtures\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={{\n * '/api/users': [{ id: '1', name: 'Demo User' }],\n * '[\"/api/users\", \":id\"]': ({ params }) => ({ id: params.id, name: 'Demo User' }),\n * '[\"/api/projects\", { status: \":status\" }]': ({ params }) => [\n * { id: '1', name: 'Project', status: params.status },\n * ],\n * }}\n * delay={100}\n * >\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With Map-based fixtures\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'Demo User' })],\n * ])\n *\n * <DemoSWRProvider enabled={true} fixtures={fixtures}>\n * <App />\n * </DemoSWRProvider>\n *\n * @example\n * // With cache seeding via fallback\n * <DemoSWRProvider\n * enabled={true}\n * fixtures={fixtures}\n * fallback={{\n * '/api/users': [{ id: '1', name: 'Pre-loaded User' }],\n * }}\n * >\n * <App />\n * </DemoSWRProvider>\n */\nexport function DemoSWRProvider({\n children,\n fixtures = new Map(),\n mutations = new Map(),\n enabled = false,\n delay = 0,\n fallback = {},\n swrConfig = {},\n}: DemoSWRProviderProps) {\n // Normalize fixtures\n const fixturesRef = useRef<SWRFixtureMap>(normalizeFixtureMap(fixtures))\n const mutationFixturesRef = useRef<SWRMutationFixtureMap>(\n mutations instanceof Map ? mutations : new Map(Object.entries(mutations))\n )\n\n const isDemoMode = enabled\n\n // Create demo middleware\n const demoMiddleware = useMemo(\n () =>\n createDemoMiddleware({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n }),\n [isDemoMode, delay]\n )\n\n // Create demo fetcher (for direct use)\n const demoFetcher = useMemo(\n () =>\n createDemoFetcher({\n fixtures: fixturesRef.current,\n isEnabled: () => isDemoMode,\n delay,\n fallbackFetcher: defaultFetcher,\n }),\n [isDemoMode, delay]\n )\n\n // Build fallback data from static fixtures + provided fallback\n const combinedFallback = useMemo(() => {\n if (!isDemoMode) return swrConfig.fallback || {}\n\n const staticFixtures: Record<string, unknown> = {}\n\n // Add static fixture values to fallback\n for (const [pattern, handler] of fixturesRef.current) {\n if (typeof handler !== 'function') {\n // Use the pattern as key for static fixtures\n const key = pattern.length === 1 ? String(pattern[0]) : JSON.stringify(pattern)\n staticFixtures[key] = handler\n }\n }\n\n return {\n ...staticFixtures,\n ...fallback,\n ...(swrConfig.fallback || {}),\n }\n }, [isDemoMode, fallback, swrConfig.fallback])\n\n // Build SWR config\n const config = useMemo(\n () => ({\n ...swrConfig,\n use: [...(swrConfig.use || []), demoMiddleware],\n fallback: combinedFallback,\n // In demo mode, don't retry and keep data fresh longer\n ...(isDemoMode\n ? {\n revalidateOnFocus: false,\n revalidateOnReconnect: false,\n shouldRetryOnError: false,\n }\n : {}),\n }),\n [swrConfig, demoMiddleware, combinedFallback, isDemoMode]\n )\n\n // Context value with manipulation methods\n const getFetcher = useCallback(() => demoFetcher, [demoFetcher])\n const getMiddleware = useCallback(() => demoMiddleware, [demoMiddleware])\n\n const contextValue = useMemo<DemoSWRState>(\n () => ({\n isDemoMode,\n\n setFixture: (pattern: QueryKey, handler: SWRFixtureHandler) => {\n fixturesRef.current.set(pattern, handler)\n },\n\n removeFixture: (pattern: QueryKey) => {\n fixturesRef.current.delete(pattern)\n },\n\n setMutationFixture: (name: string, handler: SWRMutationFixtureHandler) => {\n mutationFixturesRef.current.set(name, handler)\n },\n\n removeMutationFixture: (name: string) => {\n mutationFixturesRef.current.delete(name)\n },\n\n getFetcher,\n getMiddleware,\n }),\n [isDemoMode, getFetcher, getMiddleware]\n )\n\n return (\n <DemoSWRContext.Provider value={contextValue}>\n <SWRConfig value={config}>{children}</SWRConfig>\n </DemoSWRContext.Provider>\n )\n}\n","'use client'\n\nimport { createContext } from 'react'\nimport type { DemoSWRState } from './types'\n\n/**\n * Context for DemoSWR state\n * @internal\n */\nexport const DemoSWRContext = createContext<DemoSWRState | undefined>(undefined)\n\nDemoSWRContext.displayName = 'DemoSWRContext'\n","import { matchQueryKey, findMatchingQueryKeyPattern } from '@demokit-ai/core'\nimport type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureHandler, SWRFixtureMap, SWRFixtureMapObject } from './types'\n\n/**\n * Normalize an SWR key to a QueryKey for matching\n *\n * SWR keys can be:\n * - Strings: '/api/users' -> ['/api/users']\n * - Arrays: ['/api/users', id] -> ['/api/users', id]\n * - Functions that return keys (not handled here)\n */\nexport function normalizeKey(key: string | unknown[]): QueryKey {\n if (typeof key === 'string') {\n return [key]\n }\n\n return key.map((element) => {\n if (element === null || element === undefined) {\n return element\n }\n if (typeof element === 'object') {\n return element as Record<string, unknown>\n }\n return element as string | number | boolean\n })\n}\n\n/**\n * Parse a JSON string pattern into a QueryKey\n * Handles both array notation and simple string patterns\n *\n * @example\n * parsePatternString('[\"/api/users\"]') // ['/api/users']\n * parsePatternString('[\"/api/users\", \":id\"]') // ['/api/users', ':id']\n * parsePatternString('/api/users') // ['/api/users']\n */\nexport function parsePatternString(pattern: string): QueryKey {\n // Try to parse as JSON array\n if (pattern.startsWith('[')) {\n try {\n return JSON.parse(pattern) as QueryKey\n } catch {\n // Fall through to simple string\n }\n }\n\n // Simple string becomes single-element array\n return [pattern]\n}\n\n/**\n * Convert object-based fixture map to Map-based fixture map\n */\nexport function normalizeFixtureMap(fixtures: SWRFixtureMapObject | SWRFixtureMap): SWRFixtureMap {\n if (fixtures instanceof Map) {\n return fixtures\n }\n\n const map = new Map<QueryKey, SWRFixtureHandler>()\n for (const [pattern, handler] of Object.entries(fixtures)) {\n map.set(parsePatternString(pattern), handler)\n }\n return map\n}\n\n/**\n * Find a matching fixture for an SWR key\n *\n * @param fixtures - Map of key patterns to handlers\n * @param key - The SWR key to match\n * @returns Tuple of [handler, match result] or null if no match\n */\nexport function findMatchingFixture(\n fixtures: SWRFixtureMap,\n key: string | unknown[]\n): [SWRFixtureHandler, { params: Record<string, unknown>; normalizedKey: QueryKey }] | null {\n const normalizedKey = normalizeKey(key)\n const result = findMatchingQueryKeyPattern(fixtures, normalizedKey)\n\n if (result) {\n const [, handler, matchResult] = result\n return [handler, { params: matchResult.params, normalizedKey }]\n }\n\n return null\n}\n\n/**\n * Re-export the matchQueryKey function for direct use\n */\nexport { matchQueryKey }","import type { QueryKey } from '@demokit-ai/core'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture, normalizeKey } from './matcher'\n\n/**\n * Options for creating a demo-aware fetcher\n */\nexport interface CreateDemoFetcherOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n\n /**\n * Fallback fetcher to use when demo mode is disabled\n * or no fixture matches\n */\n fallbackFetcher?: <T>(key: string | unknown[]) => Promise<T>\n}\n\n/**\n * Create a demo-aware fetcher function for SWR\n *\n * This fetcher intercepts requests when demo mode is enabled\n * and returns fixture data instead of making real API calls.\n *\n * @example\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const fetcher = createDemoFetcher({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * // Use with SWR\n * const { data } = useSWR('/api/users', fetcher)\n */\nexport function createDemoFetcher(options: CreateDemoFetcherOptions) {\n const { fixtures, isEnabled, delay = 0, fallbackFetcher } = options\n\n return async function demoFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n // If demo mode is not enabled, use fallback\n if (!isEnabled()) {\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(\n `[DemoKit SWR] No fallback fetcher provided and demo mode is disabled. ` +\n `Key: ${JSON.stringify(key)}`\n )\n }\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, key)\n\n if (!match) {\n // No fixture found, try fallback\n if (fallbackFetcher) {\n return fallbackFetcher<TData>(key)\n }\n throw new Error(`[DemoKit SWR] No fixture found for key: ${JSON.stringify(key)}`)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context) as TData\n }\n\n // Return static value\n return handler as TData\n }\n}\n\n/**\n * Default fetcher that uses fetch API\n * Used as fallback when demo mode is disabled\n */\nexport async function defaultFetcher<TData = unknown>(key: string | unknown[]): Promise<TData> {\n const url = typeof key === 'string' ? key : String(key[0])\n const response = await fetch(url)\n\n if (!response.ok) {\n const error = new Error('An error occurred while fetching the data.')\n throw error\n }\n\n return response.json()\n}\n","import type { Middleware } from 'swr'\nimport type { SWRFixtureMap, SWRFixtureContext } from './types'\nimport { findMatchingFixture } from './matcher'\n\n/**\n * Options for creating the demo middleware\n */\nexport interface CreateDemoMiddlewareOptions {\n /**\n * Map of key patterns to fixture handlers\n */\n fixtures: SWRFixtureMap\n\n /**\n * Function to check if demo mode is enabled\n */\n isEnabled: () => boolean\n\n /**\n * Delay in ms before returning fixture data\n * @default 0\n */\n delay?: number\n}\n\n/**\n * Create a demo-aware SWR middleware\n *\n * This middleware intercepts SWR requests when demo mode is enabled\n * and returns fixture data instead of using the original fetcher.\n *\n * @example\n * import { SWRConfig } from 'swr'\n * import { createDemoMiddleware } from '@demokit-ai/swr'\n *\n * const fixtures = new Map([\n * [['/api/users'], [{ id: '1', name: 'Demo User' }]],\n * [['/api/users', ':id'], ({ params }) => ({ id: params.id, name: 'User' })],\n * ])\n *\n * const demoMiddleware = createDemoMiddleware({\n * fixtures,\n * isEnabled: () => isDemoMode,\n * delay: 100,\n * })\n *\n * function App() {\n * return (\n * <SWRConfig value={{ use: [demoMiddleware] }}>\n * <YourApp />\n * </SWRConfig>\n * )\n * }\n */\nexport function createDemoMiddleware(options: CreateDemoMiddlewareOptions): Middleware {\n const { fixtures, isEnabled, delay = 0 } = options\n\n // Use the simpler middleware pattern that SWR expects\n const middleware: Middleware = (useSWRNext) => (key, fetcher, config) => {\n // Create an extended fetcher that checks for demo mode\n const extendedFetcher =\n fetcher === null\n ? null\n : async (...args: Parameters<typeof fetcher>) => {\n // Resolve the key if it's a function\n const resolvedKey = typeof key === 'function' ? key() : key\n\n // If no key, let SWR handle it\n if (resolvedKey === null || resolvedKey === undefined) {\n return fetcher(...args)\n }\n\n // If demo mode is not enabled, use original fetcher\n if (!isEnabled()) {\n return fetcher(...args)\n }\n\n // Normalize key for matching\n const keyToMatch =\n typeof resolvedKey === 'string' ? resolvedKey : (resolvedKey as unknown[])\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, keyToMatch)\n\n if (!match) {\n // No fixture found, use original fetcher\n return fetcher(...args)\n }\n\n const [handler, { params, normalizedKey }] = match\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Build context\n const context: SWRFixtureContext = {\n key: resolvedKey,\n normalizedKey,\n params,\n match: { matched: true, params },\n }\n\n // Execute handler\n if (typeof handler === 'function') {\n return handler(context)\n }\n\n // Return static value\n return handler\n }\n\n return useSWRNext(key, extendedFetcher, config)\n }\n\n return middleware\n}\n","import type { RemoteSourceConfig } from './types'\n\n/**\n * Create a remote source configuration for fetching fixtures from DemoKit Cloud\n *\n * The SDK appends `/fixtures` to your apiUrl, so provide the versioned base URL.\n *\n * @example\n * ```typescript\n * // lib/demokit-config.ts\n * import { createRemoteSource } from '@demokit-ai/swr'\n *\n * // .env:\n * // VITE_DEMOKIT_API_URL=https://demokit-cloud.kasava.dev/api\n * // VITE_DEMOKIT_API_KEY=dk_live_xxxx\n *\n * export const demokitSource = createRemoteSource({\n * apiUrl: import.meta.env.VITE_DEMOKIT_API_URL,\n * apiKey: import.meta.env.VITE_DEMOKIT_API_KEY,\n * })\n *\n * // Then in your app:\n * import { demokitSource } from './lib/demokit-config'\n *\n * <DemoSWRProvider source={demokitSource}>\n * <SWRConfig>\n * <App />\n * </SWRConfig>\n * </DemoSWRProvider>\n * ```\n */\nexport function createRemoteSource(config: RemoteSourceConfig): RemoteSourceConfig {\n return {\n timeout: 10000,\n retry: true,\n maxRetries: 3,\n ...config,\n }\n}\n","'use client'\n\nimport { useContext, useCallback } from 'react'\nimport useSWRMutation, { type SWRMutationConfiguration, type SWRMutationResponse } from 'swr/mutation'\nimport { useSWRConfig } from 'swr'\nimport { DemoSWRContext } from './context'\nimport type { DemoSWRState, SWRMutationFixtureContext, SWRMutationFixtureHandler } from './types'\n\n/**\n * Hook to access DemoSWR state and controls\n *\n * @returns DemoSWR context value\n * @throws Error if used outside of DemoSWRProvider\n *\n * @example\n * function MyComponent() {\n * const { isDemoMode, setFixture } = useDemoSWR()\n *\n * // Dynamically add a fixture\n * const handleAddFixture = () => {\n * setFixture(['/api/users', 'custom'], { id: 'custom', name: 'Custom User' })\n * }\n *\n * return (\n * <button onClick={handleAddFixture}>Add Custom Fixture</button>\n * )\n * }\n */\nexport function useDemoSWR(): DemoSWRState {\n const context = useContext(DemoSWRContext)\n\n if (context === undefined) {\n throw new Error(\n 'useDemoSWR must be used within a DemoSWRProvider. ' +\n 'Make sure to wrap your app with <DemoSWRProvider>.'\n )\n }\n\n return context\n}\n\n/**\n * Hook to check if demo mode is enabled\n * Shorthand for useDemoSWR().isDemoMode\n *\n * @example\n * function MyComponent() {\n * const isDemoMode = useIsDemoSWRMode()\n *\n * return isDemoMode ? <DemoBadge /> : null\n * }\n */\nexport function useIsDemoSWRMode(): boolean {\n return useDemoSWR().isDemoMode\n}\n\n/**\n * Options for useDemoSWRMutation hook\n */\nexport interface UseDemoSWRMutationOptions<TData, TError, TArg>\n extends Omit<SWRMutationConfiguration<TData, TError, string, TArg>, 'fetcher'> {\n /**\n * The real mutation function to use when demo mode is disabled\n */\n fetcher: (key: string, options: { arg: TArg }) => Promise<TData>\n\n /**\n * Demo fixture handler for this mutation\n */\n demoFixture?: SWRMutationFixtureHandler<TData, TArg>\n\n /**\n * Delay in ms before returning demo data\n * @default 0\n */\n demoDelay?: number\n}\n\n/**\n * A mutation hook that automatically uses demo fixtures when demo mode is enabled\n *\n * Works with useSWRMutation from swr/mutation.\n *\n * @example\n * const { trigger: createUser, isMutating } = useDemoSWRMutation('/api/users', {\n * fetcher: async (key, { arg }) => api.createUser(arg),\n * demoFixture: ({ arg, mutate }) => {\n * // Create demo user\n * const newUser = { id: crypto.randomUUID(), ...arg }\n *\n * // Update the users cache\n * mutate('/api/users', (current: User[] = []) => [...current, newUser])\n *\n * return newUser\n * },\n * onSuccess: (data) => {\n * console.log('Created user:', data)\n * },\n * })\n *\n * // Use like normal useSWRMutation\n * createUser({ name: 'New User', email: 'user@example.com' })\n */\nexport function useDemoSWRMutation<TData = unknown, TError = unknown, TArg = unknown>(\n key: string,\n options: UseDemoSWRMutationOptions<TData, TError, TArg>\n): SWRMutationResponse<TData, TError, string, TArg> {\n const { fetcher, demoFixture, demoDelay = 0, ...mutationOptions } = options\n\n const { mutate } = useSWRConfig()\n\n // Try to get demo state - may not be in DemoSWRProvider context\n let isDemoMode = false\n try {\n const demoState = useDemoSWR()\n isDemoMode = demoState.isDemoMode\n } catch {\n // Not in DemoSWRProvider context, use real mutation\n }\n\n // Create the demo-aware mutation function\n const demoAwareFetcher = useCallback(\n async (mutationKey: string, { arg }: { arg: TArg }): Promise<TData> => {\n // If not in demo mode, use real mutation\n if (!isDemoMode) {\n return fetcher(mutationKey, { arg })\n }\n\n // Apply delay if configured\n if (demoDelay > 0) {\n await new Promise((resolve) => setTimeout(resolve, demoDelay))\n }\n\n // If a demo fixture is provided, use it\n if (demoFixture !== undefined) {\n const context: SWRMutationFixtureContext<TData, TArg> = {\n key: mutationKey,\n arg,\n currentData: undefined, // SWR mutation doesn't have direct access to current data\n mutate: mutate as SWRMutationFixtureContext<TData, TArg>['mutate'],\n }\n\n if (typeof demoFixture === 'function') {\n const fixtureFn = demoFixture as (\n context: SWRMutationFixtureContext<TData, TArg>\n ) => TData | Promise<TData>\n return fixtureFn(context)\n }\n return demoFixture as TData\n }\n\n // No fixture found, fall back to real mutation\n console.warn(\n `[DemoKit SWR] No mutation fixture found for \"${key}\". Using real mutation function.`\n )\n return fetcher(mutationKey, { arg })\n },\n [isDemoMode, fetcher, demoFixture, demoDelay, key, mutate]\n )\n\n return useSWRMutation(key, demoAwareFetcher, mutationOptions)\n}\n"],"mappings":"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","names":["useCallback","useCallback"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@demokit-ai/swr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "SWR integration for DemoKit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@demokit-ai/core": "0.
|
|
26
|
-
"@demokit-ai/react": "0.
|
|
25
|
+
"@demokit-ai/core": "0.4.0",
|
|
26
|
+
"@demokit-ai/react": "0.4.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
+
"@types/node": "^22.0.0",
|
|
29
30
|
"@types/react": "^19.0.0",
|
|
30
31
|
"swr": "^2.2.5",
|
|
31
32
|
"tsup": "^8.3.5",
|