@demokit-ai/trpc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/context.ts","../src/fixtures.ts","../src/provider.tsx","../src/hooks.ts","../src/matcher.ts","../src/link.ts"],"names":["createContext","useRef","useMemo","useContext","observable"],"mappings":"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","file":"react.cjs","sourcesContent":["import { createContext } from 'react'\nimport type { DemoTRPCState, FlatFixtureMap } from './types'\n\n/**\n * Default context value when no provider is present\n */\nconst defaultContextValue: DemoTRPCState = {\n isDemoMode: false,\n setFixture: () => {\n console.warn('[DemoKit/tRPC] setFixture called outside of DemoTRPCProvider')\n },\n removeFixture: () => {\n console.warn('[DemoKit/tRPC] removeFixture called outside of DemoTRPCProvider')\n },\n getFixtures: () => new Map(),\n}\n\n/**\n * React context for DemoKit tRPC integration\n */\nexport const DemoTRPCContext = createContext<DemoTRPCState>(defaultContextValue)\n","import type {\n AnyRouter,\n inferRouterInputs,\n inferRouterOutputs,\n} from '@trpc/server'\nimport type { TRPCFixtureHandler, TRPCFixtureContext, FlatFixtureMap } from './types'\n\n/**\n * Type helper to create fixture handlers with full type inference\n *\n * This helper infers input/output types from your router definition,\n * providing autocomplete and type checking for fixture definitions.\n *\n * @example\n * import { defineTRPCFixtures } from '@demokit-ai/trpc'\n * import type { AppRouter } from '../server/router'\n *\n * // Nested structure matching your router\n * const fixtures = defineTRPCFixtures<AppRouter>()({\n * user: {\n * list: () => [\n * { id: '1', name: 'Demo User', email: 'demo@example.com' }\n * ],\n * get: ({ input }) => ({\n * id: input.id,\n * name: 'Demo User',\n * email: 'demo@example.com',\n * }),\n * create: async ({ input }) => ({\n * id: crypto.randomUUID(),\n * ...input,\n * createdAt: new Date(),\n * }),\n * },\n * post: {\n * list: () => [],\n * },\n * })\n */\nexport function defineTRPCFixtures<TRouter extends AnyRouter>() {\n type RouterIn = inferRouterInputs<TRouter>\n type RouterOut = inferRouterOutputs<TRouter>\n\n /**\n * Helper type to build nested fixture structure\n */\n type BuildFixtureType<TIn, TOut> = {\n [K in keyof TIn & keyof TOut]?: TIn[K] extends object\n ? TOut[K] extends object\n ? // Check if this is a procedure (has no nested keys) or a namespace\n keyof TIn[K] extends never\n ? TRPCFixtureHandler<TIn[K], TOut[K]>\n : BuildFixtureType<TIn[K], TOut[K]>\n : TRPCFixtureHandler<TIn[K], TOut[K]>\n : TRPCFixtureHandler<TIn[K], TOut[K]>\n }\n\n return function <T extends BuildFixtureType<RouterIn, RouterOut>>(fixtures: T): T {\n return fixtures\n }\n}\n\n/**\n * Alternative: define fixtures using flat dot-notation paths\n *\n * Useful when you want to define fixtures independently of router structure.\n *\n * @example\n * const fixtures = defineFixtureMap<AppRouter>({\n * 'user.list': () => [{ id: '1', name: 'Demo' }],\n * 'user.get': ({ input }) => ({ id: input.id, name: 'Demo' }),\n * })\n */\nexport function defineFixtureMap<TRouter extends AnyRouter>(\n fixtures: FlatFixtureRecord<TRouter>\n): FlatFixtureMap {\n return new Map(Object.entries(fixtures))\n}\n\n/**\n * Type for flat fixture map with path-based keys\n */\ntype FlatFixtureRecord<TRouter extends AnyRouter> = {\n [K in ProcedurePaths<TRouter>]?: TRPCFixtureHandler<\n PathInput<TRouter, K>,\n PathOutput<TRouter, K>\n >\n}\n\n/**\n * Extract all procedure paths from a router using dot notation\n */\ntype ProcedurePaths<TRouter extends AnyRouter> = inferRouterInputs<TRouter> extends infer TIn\n ? TIn extends object\n ? FlattenPaths<TIn>\n : never\n : never\n\n/**\n * Flatten nested object keys to dot notation\n */\ntype FlattenPaths<T, Prefix extends string = ''> = T extends object\n ? {\n [K in keyof T]: K extends string\n ? T[K] extends object\n ? keyof T[K] extends never\n ? `${Prefix}${K}`\n : FlattenPaths<T[K], `${Prefix}${K}.`>\n : `${Prefix}${K}`\n : never\n }[keyof T]\n : never\n\n/**\n * Get input type for a specific procedure path\n */\ntype PathInput<TRouter extends AnyRouter, Path extends string> = Path extends `${infer First}.${infer Rest}`\n ? inferRouterInputs<TRouter>[First] extends object\n ? PathInput<inferRouterInputs<TRouter>[First] extends AnyRouter ? inferRouterInputs<TRouter>[First] : never, Rest>\n : never\n : inferRouterInputs<TRouter>[Path]\n\n/**\n * Get output type for a specific procedure path\n */\ntype PathOutput<TRouter extends AnyRouter, Path extends string> = Path extends `${infer First}.${infer Rest}`\n ? inferRouterOutputs<TRouter>[First] extends object\n ? PathOutput<inferRouterOutputs<TRouter>[First] extends AnyRouter ? inferRouterOutputs<TRouter>[First] : never, Rest>\n : never\n : inferRouterOutputs<TRouter>[Path]\n\n/**\n * Create a fixture handler with explicit types\n *\n * Useful when you need to define a fixture outside of the main fixture object.\n *\n * @example\n * const getUserFixture = createFixtureHandler<{ id: string }, User>(\n * ({ input }) => ({\n * id: input.id,\n * name: 'Demo User',\n * })\n * )\n */\nexport function createFixtureHandler<TInput, TOutput>(\n handler: TRPCFixtureHandler<TInput, TOutput>\n): TRPCFixtureHandler<TInput, TOutput> {\n return handler\n}\n\n/**\n * Normalize fixture definitions to a flat Map\n *\n * Converts nested fixture objects to a flat map with dot-notation paths.\n */\nexport function normalizeFixtures(\n fixtures: Record<string, unknown> | FlatFixtureMap | undefined\n): FlatFixtureMap {\n if (!fixtures) {\n return new Map()\n }\n\n if (fixtures instanceof Map) {\n return fixtures\n }\n\n const result: FlatFixtureMap = new Map()\n\n function flatten(obj: Record<string, unknown>, prefix = '') {\n for (const [key, value] of Object.entries(obj)) {\n const path = prefix ? `${prefix}.${key}` : key\n\n if (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n typeof value !== 'function'\n ) {\n // Check if this looks like a fixture handler or a namespace\n // Fixture handlers are either primitives, arrays, or functions\n // Namespaces are objects with nested procedures\n const hasNestedProcedures = Object.values(value).some(\n (v) => typeof v === 'function' || Array.isArray(v) || (typeof v === 'object' && v !== null)\n )\n\n if (hasNestedProcedures) {\n flatten(value as Record<string, unknown>, path)\n } else {\n // This is a static fixture value (an object)\n result.set(path, value as TRPCFixtureHandler)\n }\n } else {\n // This is a fixture handler (function, array, or primitive)\n result.set(path, value as TRPCFixtureHandler)\n }\n }\n }\n\n flatten(fixtures as Record<string, unknown>)\n return result\n}\n","'use client'\n\nimport { useMemo, useRef } from 'react'\nimport type { AnyRouter } from '@trpc/server'\nimport { DemoTRPCContext } from './context'\nimport type {\n DemoTRPCProviderProps,\n DemoTRPCState,\n TRPCFixtureHandler,\n FlatFixtureMap,\n} from './types'\nimport { normalizeFixtures } from './fixtures'\n\n/**\n * Provider component for DemoKit tRPC integration\n *\n * This provider enables demo mode state management and fixture controls\n * for tRPC procedures in your React app.\n *\n * Note: This provider manages state for React components. You still need to\n * use `createDemoLink` in your tRPC client configuration for actual interception.\n *\n * @example\n * // Basic usage\n * import { DemoTRPCProvider } from '@demokit-ai/trpc/react'\n * import { trpc } from './utils/trpc'\n *\n * const fixtures = {\n * user: {\n * list: () => [{ id: '1', name: 'Demo User' }],\n * },\n * }\n *\n * function App() {\n * return (\n * <DemoTRPCProvider fixtures={fixtures} enabled={true}>\n * <trpc.Provider client={trpcClient} queryClient={queryClient}>\n * <YourApp />\n * </trpc.Provider>\n * </DemoTRPCProvider>\n * )\n * }\n *\n * @example\n * // With DemoKitProvider for unified demo mode\n * import { DemoKitProvider } from '@demokit-ai/react'\n * import { DemoTRPCProvider } from '@demokit-ai/trpc/react'\n *\n * function App() {\n * const [isDemoMode, setIsDemoMode] = useState(false)\n *\n * return (\n * <DemoKitProvider enabled={isDemoMode}>\n * <DemoTRPCProvider fixtures={trpcFixtures}>\n * <YourApp />\n * </DemoTRPCProvider>\n * </DemoKitProvider>\n * )\n * }\n */\nexport function DemoTRPCProvider<TRouter extends AnyRouter = AnyRouter>({\n children,\n fixtures: rawFixtures,\n enabled = false,\n delay = 0,\n include,\n exclude,\n}: DemoTRPCProviderProps<TRouter>) {\n // Store fixtures in a ref so they persist across renders\n const fixturesRef = useRef<FlatFixtureMap>(\n normalizeFixtures(rawFixtures as Record<string, unknown>)\n )\n\n // Create context value\n const contextValue = useMemo<DemoTRPCState>(\n () => ({\n isDemoMode: enabled,\n\n setFixture: (path: string, handler: TRPCFixtureHandler) => {\n fixturesRef.current.set(path, handler)\n },\n\n removeFixture: (path: string) => {\n fixturesRef.current.delete(path)\n },\n\n getFixtures: () => fixturesRef.current,\n }),\n [enabled]\n )\n\n return (\n <DemoTRPCContext.Provider value={contextValue}>\n {children}\n </DemoTRPCContext.Provider>\n )\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { DemoTRPCContext } from './context'\nimport type { DemoTRPCState, TRPCFixtureHandler, FlatFixtureMap } from './types'\n\n/**\n * Hook to access demo tRPC state and controls\n *\n * @returns Demo tRPC state including enable/disable controls and fixture management\n *\n * @example\n * function MyComponent() {\n * const { isDemoMode, setFixture, removeFixture } = useDemoTRPC()\n *\n * const addCustomUser = () => {\n * setFixture('user.get', ({ input }) => ({\n * id: input.id,\n * name: 'Custom User',\n * }))\n * }\n *\n * return (\n * <div>\n * <p>Demo mode: {isDemoMode ? 'ON' : 'OFF'}</p>\n * <button onClick={addCustomUser}>Add Custom User Fixture</button>\n * </div>\n * )\n * }\n */\nexport function useDemoTRPC(): DemoTRPCState {\n return useContext(DemoTRPCContext)\n}\n\n/**\n * Hook to check if demo mode is enabled\n *\n * @returns Whether demo mode is currently enabled\n *\n * @example\n * function MyComponent() {\n * const isDemoMode = useIsDemoTRPCMode()\n *\n * return isDemoMode ? <DemoBanner /> : null\n * }\n */\nexport function useIsDemoTRPCMode(): boolean {\n const { isDemoMode } = useContext(DemoTRPCContext)\n return isDemoMode\n}\n\n/**\n * Hook to set fixtures dynamically\n *\n * @returns Function to set a fixture for a procedure path\n *\n * @example\n * function MyComponent() {\n * const setFixture = useSetTRPCFixture()\n *\n * useEffect(() => {\n * // Set custom fixture when component mounts\n * setFixture('analytics.dashboard', () => ({\n * visits: 1000,\n * conversions: 50,\n * }))\n * }, [])\n *\n * return <Dashboard />\n * }\n */\nexport function useSetTRPCFixture(): (path: string, handler: TRPCFixtureHandler) => void {\n const { setFixture } = useContext(DemoTRPCContext)\n return setFixture\n}\n\n/**\n * Hook to get all registered fixtures\n *\n * @returns The current fixture map\n *\n * @example\n * function FixtureDebugger() {\n * const getFixtures = useGetTRPCFixtures()\n * const fixtures = getFixtures()\n *\n * return (\n * <ul>\n * {Array.from(fixtures.keys()).map(path => (\n * <li key={path}>{path}</li>\n * ))}\n * </ul>\n * )\n * }\n */\nexport function useGetTRPCFixtures(): () => FlatFixtureMap {\n const { getFixtures } = useContext(DemoTRPCContext)\n return getFixtures\n}\n","import type { FlatFixtureMap, TRPCFixtureHandler, FixtureMatchResult } from './types'\n\n/**\n * Find a matching fixture for a procedure path\n *\n * @param fixtures - Map of procedure paths to fixture handlers\n * @param path - The procedure path to match (e.g., 'user.get', 'post.list')\n * @returns Match result with handler if found\n *\n * @example\n * const fixtures = new Map([\n * ['user.list', () => []],\n * ['user.get', ({ input }) => ({ id: input.id })],\n * ])\n *\n * findMatchingFixture(fixtures, 'user.get')\n * // { matched: true, handler: Function, path: 'user.get' }\n *\n * findMatchingFixture(fixtures, 'unknown.path')\n * // { matched: false, path: 'unknown.path' }\n */\nexport function findMatchingFixture<TOutput = unknown>(\n fixtures: FlatFixtureMap,\n path: string\n): FixtureMatchResult<TOutput> {\n const handler = fixtures.get(path)\n\n if (handler !== undefined) {\n return {\n matched: true,\n handler: handler as TRPCFixtureHandler<unknown, TOutput>,\n path,\n }\n }\n\n return {\n matched: false,\n path,\n }\n}\n\n/**\n * Check if a procedure path should be intercepted based on include/exclude rules\n *\n * @param path - The procedure path to check\n * @param include - Optional list of paths to include (if provided, only these are intercepted)\n * @param exclude - Optional list of paths to exclude (takes precedence over include)\n * @returns Whether the path should be intercepted\n *\n * @example\n * // Include only specific paths\n * shouldIntercept('user.get', ['user.get', 'user.list'], [])\n * // true\n *\n * shouldIntercept('post.list', ['user.get', 'user.list'], [])\n * // false\n *\n * // Exclude takes precedence\n * shouldIntercept('user.get', ['user.get'], ['user.get'])\n * // false\n */\nexport function shouldIntercept(\n path: string,\n include?: string[],\n exclude?: string[]\n): boolean {\n // Exclude takes precedence\n if (exclude?.includes(path)) {\n return false\n }\n\n // If include list is provided, only intercept those\n if (include && include.length > 0) {\n return include.includes(path)\n }\n\n // By default, intercept all\n return true\n}\n\n/**\n * Check if a procedure path matches a pattern with wildcards\n *\n * Supports:\n * - Exact match: 'user.get' matches 'user.get'\n * - Wildcard suffix: 'user.*' matches 'user.get', 'user.list', etc.\n * - Wildcard prefix: '*.get' matches 'user.get', 'post.get', etc.\n * - Full wildcard: '*' matches everything\n *\n * @param path - The procedure path to check\n * @param pattern - The pattern to match against\n * @returns Whether the path matches the pattern\n *\n * @example\n * matchPath('user.get', 'user.get') // true\n * matchPath('user.get', 'user.*') // true\n * matchPath('user.get', '*.get') // true\n * matchPath('user.get', '*') // true\n * matchPath('user.get', 'post.*') // false\n */\nexport function matchPath(path: string, pattern: string): boolean {\n if (pattern === '*') {\n return true\n }\n\n if (pattern === path) {\n return true\n }\n\n // Handle wildcard patterns\n if (pattern.includes('*')) {\n const regex = new RegExp(\n '^' +\n pattern\n .split('*')\n .map((s) => escapeRegex(s))\n .join('.*') +\n '$'\n )\n return regex.test(path)\n }\n\n return false\n}\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Filter fixtures based on include/exclude patterns\n *\n * @param fixtures - The fixture map to filter\n * @param include - Patterns to include (supports wildcards)\n * @param exclude - Patterns to exclude (takes precedence, supports wildcards)\n * @returns A new fixture map with only matching fixtures\n */\nexport function filterFixtures(\n fixtures: FlatFixtureMap,\n include?: string[],\n exclude?: string[]\n): FlatFixtureMap {\n const result: FlatFixtureMap = new Map()\n\n for (const [path, handler] of fixtures) {\n // Check if path should be included\n let shouldInclude = true\n\n if (include && include.length > 0) {\n shouldInclude = include.some((pattern) => matchPath(path, pattern))\n }\n\n // Check if path should be excluded\n if (exclude && exclude.length > 0) {\n if (exclude.some((pattern) => matchPath(path, pattern))) {\n shouldInclude = false\n }\n }\n\n if (shouldInclude) {\n result.set(path, handler)\n }\n }\n\n return result\n}\n\n/**\n * Get all procedure paths from a fixture map\n *\n * @param fixtures - The fixture map\n * @returns Array of all procedure paths\n */\nexport function getFixturePaths(fixtures: FlatFixtureMap): string[] {\n return Array.from(fixtures.keys())\n}\n\n/**\n * Merge multiple fixture maps\n *\n * Later maps take precedence over earlier ones for the same path.\n *\n * @param maps - Fixture maps to merge\n * @returns Merged fixture map\n */\nexport function mergeFixtures(...maps: FlatFixtureMap[]): FlatFixtureMap {\n const result: FlatFixtureMap = new Map()\n\n for (const map of maps) {\n for (const [path, handler] of map) {\n result.set(path, handler)\n }\n }\n\n return result\n}\n","import type { TRPCLink, Operation } from '@trpc/client'\nimport { observable } from '@trpc/server/observable'\nimport type { AnyRouter } from '@trpc/server'\nimport type {\n CreateDemoLinkOptions,\n TRPCFixtureContext,\n TRPCFixtureHandler,\n FlatFixtureMap,\n} from './types'\nimport { normalizeFixtures } from './fixtures'\nimport { findMatchingFixture, shouldIntercept } from './matcher'\n\n/**\n * Create a demo-aware tRPC link\n *\n * This link intercepts tRPC procedure calls when demo mode is enabled\n * and returns fixture data instead of making real API calls.\n *\n * The demo link should be placed before the terminating link (like httpBatchLink)\n * in your link chain.\n *\n * @example\n * import { createTRPCClient, httpBatchLink } from '@trpc/client'\n * import { createDemoLink } from '@demokit-ai/trpc'\n *\n * // Simple usage with fixtures\n * const client = createTRPCClient<AppRouter>({\n * links: [\n * createDemoLink({\n * fixtures: {\n * user: {\n * list: () => [{ id: '1', name: 'Demo User' }],\n * get: ({ input }) => ({ id: input.id, name: 'Demo User' }),\n * },\n * },\n * isEnabled: () => localStorage.getItem('demoMode') === 'true',\n * }),\n * httpBatchLink({ url: '/api/trpc' }),\n * ],\n * })\n *\n * @example\n * // With include/exclude filtering\n * createDemoLink({\n * fixtures: myFixtures,\n * include: ['user.*', 'post.list'], // Only intercept user.* and post.list\n * exclude: ['user.delete'], // Never intercept user.delete\n * delay: 200, // Simulate 200ms network latency\n * onMissing: (path, input) => {\n * console.warn(`No fixture for: ${path}`)\n * },\n * })\n */\nexport function createDemoLink<TRouter extends AnyRouter = AnyRouter>(\n options: CreateDemoLinkOptions<TRouter> = {}\n): TRPCLink<TRouter> {\n const {\n fixtures: rawFixtures,\n isEnabled = () => false,\n delay = 0,\n include,\n exclude,\n onMissing,\n } = options\n\n // Normalize fixtures to flat map on initialization\n const fixtures: FlatFixtureMap = normalizeFixtures(rawFixtures as Record<string, unknown>)\n\n // Return the link factory function\n return () => {\n // Return the link function that handles each operation\n return ({ next, op }) => {\n return observable((observer) => {\n // Check if demo mode is enabled\n if (!isEnabled()) {\n // Forward to next link\n const unsubscribe = next(op).subscribe({\n next(value) {\n observer.next(value)\n },\n error(err) {\n observer.error(err)\n },\n complete() {\n observer.complete()\n },\n })\n return unsubscribe\n }\n\n // Check if this procedure should be intercepted\n if (!shouldIntercept(op.path, include, exclude)) {\n // Forward to next link\n const unsubscribe = next(op).subscribe({\n next(value) {\n observer.next(value)\n },\n error(err) {\n observer.error(err)\n },\n complete() {\n observer.complete()\n },\n })\n return unsubscribe\n }\n\n // Find matching fixture\n const match = findMatchingFixture(fixtures, op.path)\n\n if (!match.matched || !match.handler) {\n // No fixture found\n onMissing?.(op.path, op.input)\n\n // Forward to next link as fallback\n const unsubscribe = next(op).subscribe({\n next(value) {\n observer.next(value)\n },\n error(err) {\n observer.error(err)\n },\n complete() {\n observer.complete()\n },\n })\n return unsubscribe\n }\n\n // Execute fixture handler\n const executeFixture = async () => {\n const context: TRPCFixtureContext = {\n path: op.path,\n input: op.input,\n type: op.type,\n }\n\n // Apply delay if configured\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay))\n }\n\n // Execute handler\n const handler = match.handler as TRPCFixtureHandler\n const result = typeof handler === 'function' ? await handler(context) : handler\n\n return result\n }\n\n // Handle async execution\n executeFixture()\n .then((data) => {\n observer.next({\n result: { data },\n })\n observer.complete()\n })\n .catch((err) => {\n observer.error(err)\n })\n\n // Return cleanup function (no-op for demo fixtures)\n return () => {}\n })\n }\n }\n}\n\n/**\n * Create a demo link with state management\n *\n * Returns the link along with controls to enable/disable demo mode\n * and manage fixtures at runtime.\n *\n * @example\n * const { link, enable, disable, isEnabled, setFixture, removeFixture } =\n * createDemoLinkWithState({\n * fixtures: myFixtures,\n * })\n *\n * const client = createTRPCClient<AppRouter>({\n * links: [link, httpBatchLink({ url: '/api/trpc' })],\n * })\n *\n * // Later...\n * enable() // Turn on demo mode\n * disable() // Turn off demo mode\n *\n * // Add fixture at runtime\n * setFixture('user.get', ({ input }) => ({ id: input.id, name: 'Runtime User' }))\n */\nexport function createDemoLinkWithState<TRouter extends AnyRouter = AnyRouter>(\n options: Omit<CreateDemoLinkOptions<TRouter>, 'isEnabled'> & {\n /**\n * Initial enabled state\n * @default false\n */\n enabled?: boolean\n } = {}\n) {\n const { fixtures: rawFixtures, enabled: initialEnabled = false, ...rest } = options\n\n let enabled = initialEnabled\n const fixtures: FlatFixtureMap = normalizeFixtures(rawFixtures as Record<string, unknown>)\n\n const link = createDemoLink<TRouter>({\n ...rest,\n fixtures,\n isEnabled: () => enabled,\n })\n\n return {\n /**\n * The tRPC link to use in your client\n */\n link,\n\n /**\n * Enable demo mode\n */\n enable: () => {\n enabled = true\n },\n\n /**\n * Disable demo mode\n */\n disable: () => {\n enabled = false\n },\n\n /**\n * Check if demo mode is enabled\n */\n isEnabled: () => enabled,\n\n /**\n * Toggle demo mode\n */\n toggle: () => {\n enabled = !enabled\n return enabled\n },\n\n /**\n * Set or update a fixture\n */\n setFixture: (path: string, handler: TRPCFixtureHandler) => {\n fixtures.set(path, handler)\n },\n\n /**\n * Remove a fixture\n */\n removeFixture: (path: string) => {\n fixtures.delete(path)\n },\n\n /**\n * Get all fixtures\n */\n getFixtures: () => fixtures,\n\n /**\n * Clear all fixtures\n */\n clearFixtures: () => {\n fixtures.clear()\n },\n }\n}\n\nexport type DemoLinkWithState<TRouter extends AnyRouter = AnyRouter> = ReturnType<\n typeof createDemoLinkWithState<TRouter>\n>\n"]}
@@ -0,0 +1,143 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { AnyRouter } from '@trpc/server';
3
+ import { k as DemoTRPCProviderProps, l as DemoTRPCState, g as TRPCFixtureHandler, F as FlatFixtureMap } from './fixtures-BV-EUS_X.cjs';
4
+ export { j as DemoTRPCProviderConfig, c as createDemoLink, b as createDemoLinkWithState, e as defineFixtureMap, d as defineTRPCFixtures } from './fixtures-BV-EUS_X.cjs';
5
+ import * as react from 'react';
6
+ import '@trpc/client';
7
+ import '@trpc/server/unstable-core-do-not-import';
8
+
9
+ /**
10
+ * Provider component for DemoKit tRPC integration
11
+ *
12
+ * This provider enables demo mode state management and fixture controls
13
+ * for tRPC procedures in your React app.
14
+ *
15
+ * Note: This provider manages state for React components. You still need to
16
+ * use `createDemoLink` in your tRPC client configuration for actual interception.
17
+ *
18
+ * @example
19
+ * // Basic usage
20
+ * import { DemoTRPCProvider } from '@demokit-ai/trpc/react'
21
+ * import { trpc } from './utils/trpc'
22
+ *
23
+ * const fixtures = {
24
+ * user: {
25
+ * list: () => [{ id: '1', name: 'Demo User' }],
26
+ * },
27
+ * }
28
+ *
29
+ * function App() {
30
+ * return (
31
+ * <DemoTRPCProvider fixtures={fixtures} enabled={true}>
32
+ * <trpc.Provider client={trpcClient} queryClient={queryClient}>
33
+ * <YourApp />
34
+ * </trpc.Provider>
35
+ * </DemoTRPCProvider>
36
+ * )
37
+ * }
38
+ *
39
+ * @example
40
+ * // With DemoKitProvider for unified demo mode
41
+ * import { DemoKitProvider } from '@demokit-ai/react'
42
+ * import { DemoTRPCProvider } from '@demokit-ai/trpc/react'
43
+ *
44
+ * function App() {
45
+ * const [isDemoMode, setIsDemoMode] = useState(false)
46
+ *
47
+ * return (
48
+ * <DemoKitProvider enabled={isDemoMode}>
49
+ * <DemoTRPCProvider fixtures={trpcFixtures}>
50
+ * <YourApp />
51
+ * </DemoTRPCProvider>
52
+ * </DemoKitProvider>
53
+ * )
54
+ * }
55
+ */
56
+ declare function DemoTRPCProvider<TRouter extends AnyRouter = AnyRouter>({ children, fixtures: rawFixtures, enabled, delay, include, exclude, }: DemoTRPCProviderProps<TRouter>): react_jsx_runtime.JSX.Element;
57
+
58
+ /**
59
+ * Hook to access demo tRPC state and controls
60
+ *
61
+ * @returns Demo tRPC state including enable/disable controls and fixture management
62
+ *
63
+ * @example
64
+ * function MyComponent() {
65
+ * const { isDemoMode, setFixture, removeFixture } = useDemoTRPC()
66
+ *
67
+ * const addCustomUser = () => {
68
+ * setFixture('user.get', ({ input }) => ({
69
+ * id: input.id,
70
+ * name: 'Custom User',
71
+ * }))
72
+ * }
73
+ *
74
+ * return (
75
+ * <div>
76
+ * <p>Demo mode: {isDemoMode ? 'ON' : 'OFF'}</p>
77
+ * <button onClick={addCustomUser}>Add Custom User Fixture</button>
78
+ * </div>
79
+ * )
80
+ * }
81
+ */
82
+ declare function useDemoTRPC(): DemoTRPCState;
83
+ /**
84
+ * Hook to check if demo mode is enabled
85
+ *
86
+ * @returns Whether demo mode is currently enabled
87
+ *
88
+ * @example
89
+ * function MyComponent() {
90
+ * const isDemoMode = useIsDemoTRPCMode()
91
+ *
92
+ * return isDemoMode ? <DemoBanner /> : null
93
+ * }
94
+ */
95
+ declare function useIsDemoTRPCMode(): boolean;
96
+ /**
97
+ * Hook to set fixtures dynamically
98
+ *
99
+ * @returns Function to set a fixture for a procedure path
100
+ *
101
+ * @example
102
+ * function MyComponent() {
103
+ * const setFixture = useSetTRPCFixture()
104
+ *
105
+ * useEffect(() => {
106
+ * // Set custom fixture when component mounts
107
+ * setFixture('analytics.dashboard', () => ({
108
+ * visits: 1000,
109
+ * conversions: 50,
110
+ * }))
111
+ * }, [])
112
+ *
113
+ * return <Dashboard />
114
+ * }
115
+ */
116
+ declare function useSetTRPCFixture(): (path: string, handler: TRPCFixtureHandler) => void;
117
+ /**
118
+ * Hook to get all registered fixtures
119
+ *
120
+ * @returns The current fixture map
121
+ *
122
+ * @example
123
+ * function FixtureDebugger() {
124
+ * const getFixtures = useGetTRPCFixtures()
125
+ * const fixtures = getFixtures()
126
+ *
127
+ * return (
128
+ * <ul>
129
+ * {Array.from(fixtures.keys()).map(path => (
130
+ * <li key={path}>{path}</li>
131
+ * ))}
132
+ * </ul>
133
+ * )
134
+ * }
135
+ */
136
+ declare function useGetTRPCFixtures(): () => FlatFixtureMap;
137
+
138
+ /**
139
+ * React context for DemoKit tRPC integration
140
+ */
141
+ declare const DemoTRPCContext: react.Context<DemoTRPCState>;
142
+
143
+ export { DemoTRPCContext, DemoTRPCProvider, DemoTRPCProviderProps, DemoTRPCState, FlatFixtureMap, TRPCFixtureHandler, useDemoTRPC, useGetTRPCFixtures, useIsDemoTRPCMode, useSetTRPCFixture };
@@ -0,0 +1,143 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { AnyRouter } from '@trpc/server';
3
+ import { k as DemoTRPCProviderProps, l as DemoTRPCState, g as TRPCFixtureHandler, F as FlatFixtureMap } from './fixtures-BV-EUS_X.js';
4
+ export { j as DemoTRPCProviderConfig, c as createDemoLink, b as createDemoLinkWithState, e as defineFixtureMap, d as defineTRPCFixtures } from './fixtures-BV-EUS_X.js';
5
+ import * as react from 'react';
6
+ import '@trpc/client';
7
+ import '@trpc/server/unstable-core-do-not-import';
8
+
9
+ /**
10
+ * Provider component for DemoKit tRPC integration
11
+ *
12
+ * This provider enables demo mode state management and fixture controls
13
+ * for tRPC procedures in your React app.
14
+ *
15
+ * Note: This provider manages state for React components. You still need to
16
+ * use `createDemoLink` in your tRPC client configuration for actual interception.
17
+ *
18
+ * @example
19
+ * // Basic usage
20
+ * import { DemoTRPCProvider } from '@demokit-ai/trpc/react'
21
+ * import { trpc } from './utils/trpc'
22
+ *
23
+ * const fixtures = {
24
+ * user: {
25
+ * list: () => [{ id: '1', name: 'Demo User' }],
26
+ * },
27
+ * }
28
+ *
29
+ * function App() {
30
+ * return (
31
+ * <DemoTRPCProvider fixtures={fixtures} enabled={true}>
32
+ * <trpc.Provider client={trpcClient} queryClient={queryClient}>
33
+ * <YourApp />
34
+ * </trpc.Provider>
35
+ * </DemoTRPCProvider>
36
+ * )
37
+ * }
38
+ *
39
+ * @example
40
+ * // With DemoKitProvider for unified demo mode
41
+ * import { DemoKitProvider } from '@demokit-ai/react'
42
+ * import { DemoTRPCProvider } from '@demokit-ai/trpc/react'
43
+ *
44
+ * function App() {
45
+ * const [isDemoMode, setIsDemoMode] = useState(false)
46
+ *
47
+ * return (
48
+ * <DemoKitProvider enabled={isDemoMode}>
49
+ * <DemoTRPCProvider fixtures={trpcFixtures}>
50
+ * <YourApp />
51
+ * </DemoTRPCProvider>
52
+ * </DemoKitProvider>
53
+ * )
54
+ * }
55
+ */
56
+ declare function DemoTRPCProvider<TRouter extends AnyRouter = AnyRouter>({ children, fixtures: rawFixtures, enabled, delay, include, exclude, }: DemoTRPCProviderProps<TRouter>): react_jsx_runtime.JSX.Element;
57
+
58
+ /**
59
+ * Hook to access demo tRPC state and controls
60
+ *
61
+ * @returns Demo tRPC state including enable/disable controls and fixture management
62
+ *
63
+ * @example
64
+ * function MyComponent() {
65
+ * const { isDemoMode, setFixture, removeFixture } = useDemoTRPC()
66
+ *
67
+ * const addCustomUser = () => {
68
+ * setFixture('user.get', ({ input }) => ({
69
+ * id: input.id,
70
+ * name: 'Custom User',
71
+ * }))
72
+ * }
73
+ *
74
+ * return (
75
+ * <div>
76
+ * <p>Demo mode: {isDemoMode ? 'ON' : 'OFF'}</p>
77
+ * <button onClick={addCustomUser}>Add Custom User Fixture</button>
78
+ * </div>
79
+ * )
80
+ * }
81
+ */
82
+ declare function useDemoTRPC(): DemoTRPCState;
83
+ /**
84
+ * Hook to check if demo mode is enabled
85
+ *
86
+ * @returns Whether demo mode is currently enabled
87
+ *
88
+ * @example
89
+ * function MyComponent() {
90
+ * const isDemoMode = useIsDemoTRPCMode()
91
+ *
92
+ * return isDemoMode ? <DemoBanner /> : null
93
+ * }
94
+ */
95
+ declare function useIsDemoTRPCMode(): boolean;
96
+ /**
97
+ * Hook to set fixtures dynamically
98
+ *
99
+ * @returns Function to set a fixture for a procedure path
100
+ *
101
+ * @example
102
+ * function MyComponent() {
103
+ * const setFixture = useSetTRPCFixture()
104
+ *
105
+ * useEffect(() => {
106
+ * // Set custom fixture when component mounts
107
+ * setFixture('analytics.dashboard', () => ({
108
+ * visits: 1000,
109
+ * conversions: 50,
110
+ * }))
111
+ * }, [])
112
+ *
113
+ * return <Dashboard />
114
+ * }
115
+ */
116
+ declare function useSetTRPCFixture(): (path: string, handler: TRPCFixtureHandler) => void;
117
+ /**
118
+ * Hook to get all registered fixtures
119
+ *
120
+ * @returns The current fixture map
121
+ *
122
+ * @example
123
+ * function FixtureDebugger() {
124
+ * const getFixtures = useGetTRPCFixtures()
125
+ * const fixtures = getFixtures()
126
+ *
127
+ * return (
128
+ * <ul>
129
+ * {Array.from(fixtures.keys()).map(path => (
130
+ * <li key={path}>{path}</li>
131
+ * ))}
132
+ * </ul>
133
+ * )
134
+ * }
135
+ */
136
+ declare function useGetTRPCFixtures(): () => FlatFixtureMap;
137
+
138
+ /**
139
+ * React context for DemoKit tRPC integration
140
+ */
141
+ declare const DemoTRPCContext: react.Context<DemoTRPCState>;
142
+
143
+ export { DemoTRPCContext, DemoTRPCProvider, DemoTRPCProviderProps, DemoTRPCState, FlatFixtureMap, TRPCFixtureHandler, useDemoTRPC, useGetTRPCFixtures, useIsDemoTRPCMode, useSetTRPCFixture };
package/dist/react.js ADDED
@@ -0,0 +1,271 @@
1
+ import { createContext, useRef, useMemo, useContext } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { observable } from '@trpc/server/observable';
4
+
5
+ // src/provider.tsx
6
+ var defaultContextValue = {
7
+ isDemoMode: false,
8
+ setFixture: () => {
9
+ console.warn("[DemoKit/tRPC] setFixture called outside of DemoTRPCProvider");
10
+ },
11
+ removeFixture: () => {
12
+ console.warn("[DemoKit/tRPC] removeFixture called outside of DemoTRPCProvider");
13
+ },
14
+ getFixtures: () => /* @__PURE__ */ new Map()
15
+ };
16
+ var DemoTRPCContext = createContext(defaultContextValue);
17
+
18
+ // src/fixtures.ts
19
+ function defineTRPCFixtures() {
20
+ return function(fixtures) {
21
+ return fixtures;
22
+ };
23
+ }
24
+ function defineFixtureMap(fixtures) {
25
+ return new Map(Object.entries(fixtures));
26
+ }
27
+ function normalizeFixtures(fixtures) {
28
+ if (!fixtures) {
29
+ return /* @__PURE__ */ new Map();
30
+ }
31
+ if (fixtures instanceof Map) {
32
+ return fixtures;
33
+ }
34
+ const result = /* @__PURE__ */ new Map();
35
+ function flatten(obj, prefix = "") {
36
+ for (const [key, value] of Object.entries(obj)) {
37
+ const path = prefix ? `${prefix}.${key}` : key;
38
+ if (value !== null && typeof value === "object" && !Array.isArray(value) && typeof value !== "function") {
39
+ const hasNestedProcedures = Object.values(value).some(
40
+ (v) => typeof v === "function" || Array.isArray(v) || typeof v === "object" && v !== null
41
+ );
42
+ if (hasNestedProcedures) {
43
+ flatten(value, path);
44
+ } else {
45
+ result.set(path, value);
46
+ }
47
+ } else {
48
+ result.set(path, value);
49
+ }
50
+ }
51
+ }
52
+ flatten(fixtures);
53
+ return result;
54
+ }
55
+ function DemoTRPCProvider({
56
+ children,
57
+ fixtures: rawFixtures,
58
+ enabled = false,
59
+ delay = 0,
60
+ include,
61
+ exclude
62
+ }) {
63
+ const fixturesRef = useRef(
64
+ normalizeFixtures(rawFixtures)
65
+ );
66
+ const contextValue = useMemo(
67
+ () => ({
68
+ isDemoMode: enabled,
69
+ setFixture: (path, handler) => {
70
+ fixturesRef.current.set(path, handler);
71
+ },
72
+ removeFixture: (path) => {
73
+ fixturesRef.current.delete(path);
74
+ },
75
+ getFixtures: () => fixturesRef.current
76
+ }),
77
+ [enabled]
78
+ );
79
+ return /* @__PURE__ */ jsx(DemoTRPCContext.Provider, { value: contextValue, children });
80
+ }
81
+ function useDemoTRPC() {
82
+ return useContext(DemoTRPCContext);
83
+ }
84
+ function useIsDemoTRPCMode() {
85
+ const { isDemoMode } = useContext(DemoTRPCContext);
86
+ return isDemoMode;
87
+ }
88
+ function useSetTRPCFixture() {
89
+ const { setFixture } = useContext(DemoTRPCContext);
90
+ return setFixture;
91
+ }
92
+ function useGetTRPCFixtures() {
93
+ const { getFixtures } = useContext(DemoTRPCContext);
94
+ return getFixtures;
95
+ }
96
+
97
+ // src/matcher.ts
98
+ function findMatchingFixture(fixtures, path) {
99
+ const handler = fixtures.get(path);
100
+ if (handler !== void 0) {
101
+ return {
102
+ matched: true,
103
+ handler,
104
+ path
105
+ };
106
+ }
107
+ return {
108
+ matched: false,
109
+ path
110
+ };
111
+ }
112
+ function shouldIntercept(path, include, exclude) {
113
+ if (exclude?.includes(path)) {
114
+ return false;
115
+ }
116
+ if (include && include.length > 0) {
117
+ return include.includes(path);
118
+ }
119
+ return true;
120
+ }
121
+
122
+ // src/link.ts
123
+ function createDemoLink(options = {}) {
124
+ const {
125
+ fixtures: rawFixtures,
126
+ isEnabled = () => false,
127
+ delay = 0,
128
+ include,
129
+ exclude,
130
+ onMissing
131
+ } = options;
132
+ const fixtures = normalizeFixtures(rawFixtures);
133
+ return () => {
134
+ return ({ next, op }) => {
135
+ return observable((observer) => {
136
+ if (!isEnabled()) {
137
+ const unsubscribe = next(op).subscribe({
138
+ next(value) {
139
+ observer.next(value);
140
+ },
141
+ error(err) {
142
+ observer.error(err);
143
+ },
144
+ complete() {
145
+ observer.complete();
146
+ }
147
+ });
148
+ return unsubscribe;
149
+ }
150
+ if (!shouldIntercept(op.path, include, exclude)) {
151
+ const unsubscribe = next(op).subscribe({
152
+ next(value) {
153
+ observer.next(value);
154
+ },
155
+ error(err) {
156
+ observer.error(err);
157
+ },
158
+ complete() {
159
+ observer.complete();
160
+ }
161
+ });
162
+ return unsubscribe;
163
+ }
164
+ const match = findMatchingFixture(fixtures, op.path);
165
+ if (!match.matched || !match.handler) {
166
+ onMissing?.(op.path, op.input);
167
+ const unsubscribe = next(op).subscribe({
168
+ next(value) {
169
+ observer.next(value);
170
+ },
171
+ error(err) {
172
+ observer.error(err);
173
+ },
174
+ complete() {
175
+ observer.complete();
176
+ }
177
+ });
178
+ return unsubscribe;
179
+ }
180
+ const executeFixture = async () => {
181
+ const context = {
182
+ path: op.path,
183
+ input: op.input,
184
+ type: op.type
185
+ };
186
+ if (delay > 0) {
187
+ await new Promise((resolve) => setTimeout(resolve, delay));
188
+ }
189
+ const handler = match.handler;
190
+ const result = typeof handler === "function" ? await handler(context) : handler;
191
+ return result;
192
+ };
193
+ executeFixture().then((data) => {
194
+ observer.next({
195
+ result: { data }
196
+ });
197
+ observer.complete();
198
+ }).catch((err) => {
199
+ observer.error(err);
200
+ });
201
+ return () => {
202
+ };
203
+ });
204
+ };
205
+ };
206
+ }
207
+ function createDemoLinkWithState(options = {}) {
208
+ const { fixtures: rawFixtures, enabled: initialEnabled = false, ...rest } = options;
209
+ let enabled = initialEnabled;
210
+ const fixtures = normalizeFixtures(rawFixtures);
211
+ const link = createDemoLink({
212
+ ...rest,
213
+ fixtures,
214
+ isEnabled: () => enabled
215
+ });
216
+ return {
217
+ /**
218
+ * The tRPC link to use in your client
219
+ */
220
+ link,
221
+ /**
222
+ * Enable demo mode
223
+ */
224
+ enable: () => {
225
+ enabled = true;
226
+ },
227
+ /**
228
+ * Disable demo mode
229
+ */
230
+ disable: () => {
231
+ enabled = false;
232
+ },
233
+ /**
234
+ * Check if demo mode is enabled
235
+ */
236
+ isEnabled: () => enabled,
237
+ /**
238
+ * Toggle demo mode
239
+ */
240
+ toggle: () => {
241
+ enabled = !enabled;
242
+ return enabled;
243
+ },
244
+ /**
245
+ * Set or update a fixture
246
+ */
247
+ setFixture: (path, handler) => {
248
+ fixtures.set(path, handler);
249
+ },
250
+ /**
251
+ * Remove a fixture
252
+ */
253
+ removeFixture: (path) => {
254
+ fixtures.delete(path);
255
+ },
256
+ /**
257
+ * Get all fixtures
258
+ */
259
+ getFixtures: () => fixtures,
260
+ /**
261
+ * Clear all fixtures
262
+ */
263
+ clearFixtures: () => {
264
+ fixtures.clear();
265
+ }
266
+ };
267
+ }
268
+
269
+ export { DemoTRPCContext, DemoTRPCProvider, createDemoLink, createDemoLinkWithState, defineFixtureMap, defineTRPCFixtures, useDemoTRPC, useGetTRPCFixtures, useIsDemoTRPCMode, useSetTRPCFixture };
270
+ //# sourceMappingURL=react.js.map
271
+ //# sourceMappingURL=react.js.map