convex 1.42.1 → 1.42.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/browser.bundle.js +1 -1
  3. package/dist/browser.bundle.js.map +2 -2
  4. package/dist/cjs/browser/simple_client.js +2 -2
  5. package/dist/cjs/browser/simple_client.js.map +2 -2
  6. package/dist/cjs/cli/codegen_templates/common.js +6 -0
  7. package/dist/cjs/cli/codegen_templates/common.js.map +2 -2
  8. package/dist/cjs/cli/dev.js +1 -0
  9. package/dist/cjs/cli/dev.js.map +2 -2
  10. package/dist/cjs/cli/generatedApi.js.map +1 -1
  11. package/dist/cjs/cli/lib/api.js.map +2 -2
  12. package/dist/cjs/cli/lib/codegen.js +2 -1
  13. package/dist/cjs/cli/lib/codegen.js.map +2 -2
  14. package/dist/cjs/cli/lib/utils/utils.js +4 -12
  15. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  16. package/dist/cjs/index.js +1 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/react/client.js +1 -1
  19. package/dist/cjs/react/client.js.map +2 -2
  20. package/dist/cjs/react-clerk/ConvexProviderWithClerk.js +2 -1
  21. package/dist/cjs/react-clerk/ConvexProviderWithClerk.js.map +2 -2
  22. package/dist/cjs/server/database.js.map +1 -1
  23. package/dist/cjs/server/impl/meta_impl.js +2 -2
  24. package/dist/cjs/server/impl/meta_impl.js.map +2 -2
  25. package/dist/cjs/server/impl/query_impl.js.map +2 -2
  26. package/dist/cjs/server/meta.js.map +1 -1
  27. package/dist/cjs/server/query.js.map +1 -1
  28. package/dist/cjs/server/registration.js.map +1 -1
  29. package/dist/cjs/server/schema.js.map +1 -1
  30. package/dist/cjs-types/browser/simple_client.d.ts +1 -2
  31. package/dist/cjs-types/browser/simple_client.d.ts.map +1 -1
  32. package/dist/cjs-types/cli/codegen_templates/common.d.ts +12 -0
  33. package/dist/cjs-types/cli/codegen_templates/common.d.ts.map +1 -1
  34. package/dist/cjs-types/cli/codegen_templates/common.test.d.ts +2 -0
  35. package/dist/cjs-types/cli/codegen_templates/common.test.d.ts.map +1 -0
  36. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  37. package/dist/cjs-types/cli/dev.test.d.ts +2 -0
  38. package/dist/cjs-types/cli/dev.test.d.ts.map +1 -0
  39. package/dist/cjs-types/cli/generatedApi.d.ts +0 -1
  40. package/dist/cjs-types/cli/generatedApi.d.ts.map +1 -1
  41. package/dist/cjs-types/cli/lib/api.d.ts +0 -1
  42. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  43. package/dist/cjs-types/cli/lib/codegen.d.ts.map +1 -1
  44. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  45. package/dist/cjs-types/index.d.ts +1 -1
  46. package/dist/cjs-types/react/client.d.ts.map +1 -1
  47. package/dist/cjs-types/react/client_provided_base_client.test.d.ts +2 -0
  48. package/dist/cjs-types/react/client_provided_base_client.test.d.ts.map +1 -0
  49. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -0
  50. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.d.ts.map +1 -1
  51. package/dist/cjs-types/server/database.d.ts.map +1 -1
  52. package/dist/cjs-types/server/impl/query_impl.d.ts.map +1 -1
  53. package/dist/cjs-types/server/meta.d.ts +8 -0
  54. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  55. package/dist/cjs-types/server/query.d.ts.map +1 -1
  56. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  57. package/dist/cjs-types/server/schema.d.ts.map +1 -1
  58. package/dist/cli.bundle.cjs +12 -14
  59. package/dist/cli.bundle.cjs.map +2 -2
  60. package/dist/esm/browser/simple_client.js +5 -3
  61. package/dist/esm/browser/simple_client.js.map +2 -2
  62. package/dist/esm/cli/codegen_templates/common.js +5 -0
  63. package/dist/esm/cli/codegen_templates/common.js.map +2 -2
  64. package/dist/esm/cli/dev.js +3 -1
  65. package/dist/esm/cli/dev.js.map +2 -2
  66. package/dist/esm/cli/lib/api.js.map +2 -2
  67. package/dist/esm/cli/lib/codegen.js +2 -1
  68. package/dist/esm/cli/lib/codegen.js.map +2 -2
  69. package/dist/esm/cli/lib/utils/utils.js +4 -12
  70. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  71. package/dist/esm/index.js +1 -1
  72. package/dist/esm/index.js.map +1 -1
  73. package/dist/esm/react/client.js +1 -1
  74. package/dist/esm/react/client.js.map +2 -2
  75. package/dist/esm/react-clerk/ConvexProviderWithClerk.js +2 -1
  76. package/dist/esm/react-clerk/ConvexProviderWithClerk.js.map +2 -2
  77. package/dist/esm/server/impl/meta_impl.js +2 -2
  78. package/dist/esm/server/impl/meta_impl.js.map +2 -2
  79. package/dist/esm/server/impl/query_impl.js.map +2 -2
  80. package/dist/esm/server/schema.js.map +1 -1
  81. package/dist/esm-types/browser/simple_client.d.ts +1 -2
  82. package/dist/esm-types/browser/simple_client.d.ts.map +1 -1
  83. package/dist/esm-types/cli/codegen_templates/common.d.ts +12 -0
  84. package/dist/esm-types/cli/codegen_templates/common.d.ts.map +1 -1
  85. package/dist/esm-types/cli/codegen_templates/common.test.d.ts +2 -0
  86. package/dist/esm-types/cli/codegen_templates/common.test.d.ts.map +1 -0
  87. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  88. package/dist/esm-types/cli/dev.test.d.ts +2 -0
  89. package/dist/esm-types/cli/dev.test.d.ts.map +1 -0
  90. package/dist/esm-types/cli/generatedApi.d.ts +0 -1
  91. package/dist/esm-types/cli/generatedApi.d.ts.map +1 -1
  92. package/dist/esm-types/cli/lib/api.d.ts +0 -1
  93. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  94. package/dist/esm-types/cli/lib/codegen.d.ts.map +1 -1
  95. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  96. package/dist/esm-types/index.d.ts +1 -1
  97. package/dist/esm-types/react/client.d.ts.map +1 -1
  98. package/dist/esm-types/react/client_provided_base_client.test.d.ts +2 -0
  99. package/dist/esm-types/react/client_provided_base_client.test.d.ts.map +1 -0
  100. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -0
  101. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.d.ts.map +1 -1
  102. package/dist/esm-types/server/database.d.ts.map +1 -1
  103. package/dist/esm-types/server/impl/query_impl.d.ts.map +1 -1
  104. package/dist/esm-types/server/meta.d.ts +8 -0
  105. package/dist/esm-types/server/meta.d.ts.map +1 -1
  106. package/dist/esm-types/server/query.d.ts.map +1 -1
  107. package/dist/esm-types/server/registration.d.ts.map +1 -1
  108. package/dist/esm-types/server/schema.d.ts.map +1 -1
  109. package/dist/react.bundle.js +2 -2
  110. package/dist/react.bundle.js.map +2 -2
  111. package/package.json +2 -2
  112. package/src/browser/simple_client.ts +12 -10
  113. package/src/cli/codegen_templates/common.test.ts +52 -0
  114. package/src/cli/codegen_templates/common.ts +17 -0
  115. package/src/cli/dev.test.ts +157 -0
  116. package/src/cli/dev.ts +7 -0
  117. package/src/cli/generatedApi.ts +0 -1
  118. package/src/cli/lib/api.ts +0 -1
  119. package/src/cli/lib/codegen.ts +2 -1
  120. package/src/cli/lib/config.test.ts +1 -4
  121. package/src/cli/lib/utils/utils.ts +4 -12
  122. package/src/index.ts +1 -1
  123. package/src/react/client.ts +23 -6
  124. package/src/react/client_provided_base_client.test.tsx +56 -0
  125. package/src/react-clerk/ConvexProviderWithClerk.tsx +3 -1
  126. package/src/server/database.ts +6 -4
  127. package/src/server/impl/meta_impl.ts +2 -2
  128. package/src/server/impl/query_impl.ts +1 -3
  129. package/src/server/meta.ts +8 -0
  130. package/src/server/query.ts +9 -6
  131. package/src/server/registration.ts +10 -10
  132. package/src/server/schema.ts +3 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/react/client.ts"],
4
- "sourcesContent": ["import { BaseConvexClient } from \"../browser/index.js\";\nimport type {\n OptimisticUpdate,\n PaginatedQueryToken,\n QueryToken,\n PaginationStatus,\n} from \"../browser/index.js\";\nimport React, { useCallback, useContext, useMemo } from \"react\";\nimport { convexToJson, Value } from \"../values/index.js\";\nimport { QueryJournal } from \"../browser/sync/protocol.js\";\nimport {\n AuthTokenFetcher,\n BaseConvexClientOptions,\n ConnectionState,\n} from \"../browser/sync/client.js\";\nimport type { UserIdentityAttributes } from \"../browser/sync/protocol.js\";\nimport { RequestForQueries, useQueries } from \"./use_queries.js\";\nimport { useSubscription } from \"./use_subscription.js\";\nimport { parseArgs } from \"../common/index.js\";\nimport {\n ArgsAndOptions,\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n getFunctionName,\n makeFunctionReference,\n} from \"../server/api.js\";\nimport { EmptyObject } from \"../server/registration.js\";\nimport {\n instantiateDefaultLogger,\n instantiateNoopLogger,\n Logger,\n} from \"../browser/logging.js\";\nimport type { QueryOptions } from \"../browser/query_options.js\";\nimport { LoadMoreOfPaginatedQuery } from \"../browser/sync/pagination.js\";\nimport {\n PaginatedQueryClient,\n ExtendedTransition,\n} from \"../browser/sync/paginated_query_client.js\";\n\n// When no arguments are passed, extend subscriptions (for APIs that do this by default)\n// for this amount after the subscription would otherwise be dropped.\nconst DEFAULT_EXTEND_SUBSCRIPTION_FOR = 5_000;\n\nif (typeof React === \"undefined\") {\n throw new Error(\"Required dependency 'react' not found\");\n}\n\n// TODO Typedoc doesn't generate documentation for the comment below perhaps\n// because it's a callable interface.\n/**\n * An interface to execute a Convex mutation function on the server.\n *\n * @public\n */\nexport interface ReactMutation<Mutation extends FunctionReference<\"mutation\">> {\n /**\n * Execute the mutation on the server, returning a `Promise` of its return value.\n *\n * @param args - Arguments for the mutation to pass up to the server.\n * @returns The return value of the server-side function call.\n */\n (...args: OptionalRestArgs<Mutation>): Promise<FunctionReturnType<Mutation>>;\n\n /**\n * Define an optimistic update to apply as part of this mutation.\n *\n * This is a temporary update to the local query results to facilitate a\n * fast, interactive UI. It enables query results to update before a mutation\n * executed on the server.\n *\n * When the mutation is invoked, the optimistic update will be applied.\n *\n * Optimistic updates can also be used to temporarily remove queries from the\n * client and create loading experiences until a mutation completes and the\n * new query results are synced.\n *\n * The update will be automatically rolled back when the mutation is fully\n * completed and queries have been updated.\n *\n * @param optimisticUpdate - The optimistic update to apply.\n * @returns A new `ReactMutation` with the update configured.\n *\n * @public\n */\n withOptimisticUpdate<T extends OptimisticUpdate<FunctionArgs<Mutation>>>(\n optimisticUpdate: T &\n (ReturnType<T> extends Promise<any>\n ? \"Optimistic update handlers must be synchronous\"\n : {}),\n ): ReactMutation<Mutation>;\n}\n\n// Exported only for testing.\nexport function createMutation(\n mutationReference: FunctionReference<\"mutation\">,\n client: ConvexReactClient,\n update?: OptimisticUpdate<any>,\n): ReactMutation<any> {\n function mutation(args?: Record<string, Value>): Promise<unknown> {\n assertNotAccidentalArgument(args);\n\n return client.mutation(mutationReference, args, {\n optimisticUpdate: update,\n });\n }\n mutation.withOptimisticUpdate = function withOptimisticUpdate(\n optimisticUpdate: OptimisticUpdate<any>,\n ): ReactMutation<any> {\n if (update !== undefined) {\n throw new Error(\n `Already specified optimistic update for mutation ${getFunctionName(\n mutationReference,\n )}`,\n );\n }\n return createMutation(mutationReference, client, optimisticUpdate);\n };\n return mutation as ReactMutation<any>;\n}\n\n/**\n * An interface to execute a Convex action on the server.\n *\n * @public\n */\nexport interface ReactAction<Action extends FunctionReference<\"action\">> {\n /**\n * Execute the function on the server, returning a `Promise` of its return value.\n *\n * @param args - Arguments for the function to pass up to the server.\n * @returns The return value of the server-side function call.\n * @public\n */\n (...args: OptionalRestArgs<Action>): Promise<FunctionReturnType<Action>>;\n}\n\nfunction createAction(\n actionReference: FunctionReference<\"action\">,\n client: ConvexReactClient,\n): ReactAction<any> {\n return function (args?: Record<string, Value>): Promise<unknown> {\n return client.action(actionReference, args);\n } as ReactAction<any>;\n}\n\n// Watches should be stateless: in QueriesObserver we create a watch just to get\n// the current value.\n/**\n * A watch on the output of a Convex query function.\n *\n * @public\n */\nexport interface Watch<T> {\n /**\n * Initiate a watch on the output of a query.\n *\n * This will subscribe to this query and call\n * the callback whenever the query result changes.\n *\n * **Important: If the client is already subscribed to this query with the\n * same arguments this callback will not be invoked until the query result is\n * updated.** To get the current, local result call\n * {@link react.Watch.localQueryResult}.\n *\n * @param callback - Function that is called whenever the query result changes.\n * @returns - A function that disposes of the subscription.\n */\n onUpdate(callback: () => void): () => void;\n\n /**\n * Get the current result of a query.\n *\n * This will only return a result if we're already subscribed to the query\n * and have received a result from the server or the query value has been set\n * optimistically.\n *\n * @returns The result of the query or `undefined` if it isn't known.\n * @throws An error if the query encountered an error on the server.\n */\n localQueryResult(): T | undefined;\n\n /**\n * @internal\n */\n localQueryLogs(): string[] | undefined;\n\n /**\n * Get the current {@link browser.QueryJournal} for this query.\n *\n * If we have not yet received a result for this query, this will be `undefined`.\n */\n journal(): QueryJournal | undefined;\n}\n\n/**\n * A watch on the output of a paginated Convex query function.\n *\n * @public\n */\nexport interface PaginatedWatch<T> {\n /**\n * Initiate a watch on the output of a paginated query.\n *\n * This will subscribe to this query and call\n * the callback whenever the query result changes.\n *\n * @param callback - Function that is called whenever the query result changes.\n * @returns - A function that disposes of the subscription.\n */\n onUpdate(callback: () => void): () => void;\n\n /**\n * Get the current result of a paginated query.\n *\n * @returns The current results, status, and loadMore function, or `undefined` if not loaded.\n */\n localQueryResult():\n | {\n results: T[];\n status: PaginationStatus;\n loadMore: LoadMoreOfPaginatedQuery;\n }\n | undefined;\n}\n\n/**\n * Options for {@link ConvexReactClient.watchQuery}.\n *\n * @public\n */\nexport interface WatchQueryOptions {\n /**\n * An (optional) journal produced from a previous execution of this query\n * function.\n *\n * If there is an existing subscription to a query function with the same\n * name and arguments, this journal will have no effect.\n */\n journal?: QueryJournal;\n\n /**\n * @internal\n */\n componentPath?: string;\n}\n\n/**\n * Options for {@link ConvexReactClient.watchPaginatedQuery}.\n *\n * @internal\n */\nexport interface WatchPaginatedQueryOptions {\n /**\n * The initial number of items to load.\n */\n initialNumItems: number;\n\n // We may be able to remove this in the future, but to preserve the existing behavior of\n // usePaginatedQuery() it's still here.\n id: number;\n\n /**\n * @internal\n */\n componentPath?: string;\n}\n\n/**\n * Options for {@link ConvexReactClient.mutation}.\n *\n * @public\n */\nexport interface MutationOptions<Args extends Record<string, Value>> {\n /**\n * An optimistic update to apply along with this mutation.\n *\n * An optimistic update locally updates queries while a mutation is pending.\n * Once the mutation completes, the update will be rolled back.\n */\n optimisticUpdate?: OptimisticUpdate<Args> | undefined;\n}\n\n/**\n * Options for {@link ConvexReactClient}.\n *\n * @public\n */\nexport interface ConvexReactClientOptions extends BaseConvexClientOptions {}\n\n/**\n * A Convex client for use within React.\n *\n * This loads reactive queries and executes mutations over a WebSocket.\n *\n * @public\n */\nexport class ConvexReactClient {\n private address: string;\n private cachedSync?: BaseConvexClient | undefined;\n private cachedPaginatedQueryClient?: PaginatedQueryClient | undefined;\n private listeners: Map<QueryToken | PaginatedQueryToken, Set<() => void>>;\n private options: ConvexReactClientOptions;\n // \"closed\" means this client is done, not just that the underlying WS connection is closed.\n private closed = false;\n private _logger: Logger;\n\n private adminAuth?: string;\n private fakeUserIdentity?: UserIdentityAttributes | undefined;\n\n /**\n * @param address - The url of your Convex deployment, often provided\n * by an environment variable. E.g. `https://small-mouse-123.convex.cloud`.\n * @param options - See {@link ConvexReactClientOptions} for a full description.\n */\n constructor(address: string, options?: ConvexReactClientOptions) {\n // Validate address immediately since validation by the lazily-instantiated\n // internal client does not occur synchronously.\n if (address === undefined) {\n throw new Error(\n \"No address provided to ConvexReactClient.\\n\" +\n \"If trying to deploy to production, make sure to follow all the instructions found at https://docs.convex.dev/production/hosting/\\n\" +\n \"If running locally, make sure to run `convex dev` and ensure the .env.local file is populated.\",\n );\n }\n if (typeof address !== \"string\") {\n throw new Error(\n `ConvexReactClient requires a URL like 'https://happy-otter-123.convex.cloud', received something of type ${typeof address} instead.`,\n );\n }\n if (!address.includes(\"://\")) {\n throw new Error(\"Provided address was not an absolute URL.\");\n }\n this.address = address;\n this.listeners = new Map();\n this._logger =\n options?.logger === false\n ? instantiateNoopLogger({ verbose: options?.verbose ?? false })\n : options?.logger !== true && options?.logger\n ? options.logger\n : instantiateDefaultLogger({ verbose: options?.verbose ?? false });\n this.options = { ...options, logger: this._logger };\n }\n\n /**\n * Return the address for this client, useful for creating a new client.\n *\n * Not guaranteed to match the address with which this client was constructed:\n * it may be canonicalized.\n */\n get url() {\n return this.address;\n }\n\n /**\n * Lazily instantiate the `BaseConvexClient` so we don't create the WebSocket\n * when server-side rendering.\n *\n * @internal\n */\n get sync() {\n if (this.closed) {\n throw new Error(\"ConvexReactClient has already been closed.\");\n }\n if (this.cachedSync) {\n return this.cachedSync;\n }\n // BaseConvexClient and paginated query client are always created together.\n this.cachedSync = new BaseConvexClient(\n this.address,\n () => {}, // Use the PaginatedQueryClient's transition instead.\n this.options,\n );\n if (this.adminAuth) {\n this.cachedSync.setAdminAuth(this.adminAuth, this.fakeUserIdentity);\n }\n this.cachedPaginatedQueryClient = new PaginatedQueryClient(\n this.cachedSync,\n (transition) => this.handleTransition(transition),\n );\n return this.cachedSync;\n }\n\n /**\n * Lazily instantiate the `PaginatedQueryClient` so we don't create it\n * when server-side rendering.\n *\n * @internal\n */\n get paginatedQueryClient() {\n // access sync to instantiate the clients\n this.sync;\n if (this.cachedPaginatedQueryClient) {\n return this.cachedPaginatedQueryClient;\n }\n throw new Error(\"Should already be instantiated\");\n }\n\n /**\n * Set the authentication token to be used for subsequent queries and mutations.\n * `fetchToken` will be called automatically again if a token expires.\n * `fetchToken` should return `null` if the token cannot be retrieved, for example\n * when the user's rights were permanently revoked.\n * @param fetchToken - an async function returning the JWT-encoded OpenID Connect Identity Token\n * @param onChange - a callback that will be called when the authentication status changes\n * @param onRefreshChange - a callback called with `true` when the socket is paused to fetch a replacement token after a server rejection, and `false` when refresh completes\n */\n setAuth(\n fetchToken: AuthTokenFetcher,\n onChange?: (isAuthenticated: boolean) => void,\n onRefreshChange?: (isRefreshing: boolean) => void,\n ) {\n if (typeof fetchToken === \"string\") {\n throw new Error(\n \"Passing a string to ConvexReactClient.setAuth is no longer supported, \" +\n \"please upgrade to passing in an async function to handle reauthentication.\",\n );\n }\n this.sync.setAuth(\n fetchToken,\n onChange ??\n (() => {\n // Do nothing\n }),\n onRefreshChange,\n );\n }\n\n /**\n * Clear the current authentication token if set.\n */\n clearAuth() {\n this.sync.clearAuth();\n }\n\n /**\n * @internal\n */\n setAdminAuth(token: string, identity?: UserIdentityAttributes) {\n this.adminAuth = token;\n this.fakeUserIdentity = identity;\n if (this.closed) {\n throw new Error(\"ConvexReactClient has already been closed.\");\n }\n if (this.cachedSync) {\n this.sync.setAdminAuth(token, identity);\n }\n }\n\n /**\n * Construct a new {@link Watch} on a Convex query function.\n *\n * **Most application code should not call this method directly. Instead use\n * the {@link useQuery} hook.**\n *\n * The act of creating a watch does nothing, a Watch is stateless.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - An arguments object for the query. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link WatchQueryOptions} options object for this query.\n *\n * @returns The {@link Watch} object.\n */\n watchQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...argsAndOptions: ArgsAndOptions<Query, WatchQueryOptions>\n ): Watch<FunctionReturnType<Query>> {\n const [args, options] = argsAndOptions;\n const name = getFunctionName(query);\n\n return {\n onUpdate: (callback) => {\n const { queryToken, unsubscribe } = this.sync.subscribe(\n name as string,\n args,\n options,\n );\n\n const currentListeners = this.listeners.get(queryToken);\n if (currentListeners !== undefined) {\n currentListeners.add(callback);\n } else {\n this.listeners.set(queryToken, new Set([callback]));\n }\n\n return () => {\n if (this.closed) {\n return;\n }\n\n const currentListeners = this.listeners.get(queryToken)!;\n currentListeners.delete(callback);\n if (currentListeners.size === 0) {\n this.listeners.delete(queryToken);\n }\n unsubscribe();\n };\n },\n\n localQueryResult: () => {\n // Use the cached client because we can't have a query result if we don't\n // even have a client yet!\n if (this.cachedSync) {\n return this.cachedSync.localQueryResult(name, args);\n }\n return undefined;\n },\n\n localQueryLogs: () => {\n if (this.cachedSync) {\n return this.cachedSync.localQueryLogs(name, args);\n }\n return undefined;\n },\n\n journal: () => {\n if (this.cachedSync) {\n return this.cachedSync.queryJournal(name, args);\n }\n return undefined;\n },\n };\n }\n\n // Let's try out a queryOptions-style API.\n // This method is similar to the React Query API `queryClient.prefetchQuery()`.\n // In the future an ensureQueryData(): Promise<Data> method could exist.\n /**\n * Indicates likely future interest in a query subscription.\n *\n * The implementation currently immediately subscribes to a query. In the future this method\n * may prioritize some queries over others, fetch the query result without subscribing, or\n * do nothing in slow network connections or high load scenarios.\n *\n * To use this in a React component, call useQuery() and ignore the return value.\n *\n * @param queryOptions - A query (function reference from an api object) and its args, plus\n * an optional extendSubscriptionFor for how long to subscribe to the query.\n */\n prewarmQuery<Query extends FunctionReference<\"query\">>(\n queryOptions: QueryOptions<Query> & { extendSubscriptionFor?: number },\n ) {\n const extendSubscriptionFor =\n queryOptions.extendSubscriptionFor ?? DEFAULT_EXTEND_SUBSCRIPTION_FOR;\n const watch = this.watchQuery(queryOptions.query, queryOptions.args || {});\n const unsubscribe = watch.onUpdate(() => {});\n setTimeout(unsubscribe, extendSubscriptionFor);\n }\n\n /**\n * Construct a new {@link PaginatedWatch} on a Convex paginated query function.\n *\n * **Most application code should not call this method directly. Instead use\n * the {@link usePaginatedQuery} hook.**\n *\n * The act of creating a watch does nothing, a Watch is stateless.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - An arguments object for the query. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link WatchPaginatedQueryOptions} options object for this query.\n *\n * @returns The {@link PaginatedWatch} object.\n *\n * @internal\n */\n watchPaginatedQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: Query[\"_args\"],\n options: WatchPaginatedQueryOptions,\n ): PaginatedWatch<FunctionReturnType<Query>> {\n const name = getFunctionName(query);\n\n return {\n onUpdate: (callback) => {\n const { paginatedQueryToken, unsubscribe } =\n this.paginatedQueryClient.subscribe(name, args || {}, options);\n\n const currentListeners = this.listeners.get(paginatedQueryToken);\n if (currentListeners !== undefined) {\n currentListeners.add(callback);\n } else {\n this.listeners.set(paginatedQueryToken, new Set([callback]));\n }\n\n return () => {\n if (this.closed) {\n return;\n }\n\n const currentListeners = this.listeners.get(paginatedQueryToken)!;\n currentListeners.delete(callback);\n if (currentListeners.size === 0) {\n this.listeners.delete(paginatedQueryToken);\n }\n unsubscribe();\n };\n },\n\n localQueryResult: () => {\n // Use our new paginated query client\n return this.paginatedQueryClient.localQueryResult(name, args, options);\n },\n };\n }\n\n /**\n * Execute a mutation function.\n *\n * @param mutation - A {@link server.FunctionReference} for the public mutation\n * to run.\n * @param args - An arguments object for the mutation. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link MutationOptions} options object for the mutation.\n * @returns A promise of the mutation's result.\n */\n mutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n ...argsAndOptions: ArgsAndOptions<\n Mutation,\n MutationOptions<FunctionArgs<Mutation>>\n >\n ): Promise<FunctionReturnType<Mutation>> {\n const [args, options] = argsAndOptions;\n const name = getFunctionName(mutation);\n return this.sync.mutation(name, args, options);\n }\n\n /**\n * Execute an action function.\n *\n * @param action - A {@link server.FunctionReference} for the public action\n * to run.\n * @param args - An arguments object for the action. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the action's result.\n */\n action<Action extends FunctionReference<\"action\">>(\n action: Action,\n ...args: OptionalRestArgs<Action>\n ): Promise<FunctionReturnType<Action>> {\n const name = getFunctionName(action);\n return this.sync.action(name, ...args);\n }\n\n /**\n * Fetch a query result once.\n *\n * **Most application code should subscribe to queries instead, using\n * the {@link useQuery} hook.**\n *\n * @param query - A {@link server.FunctionReference} for the public query\n * to run.\n * @param args - An arguments object for the query. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the query's result.\n */\n query<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): Promise<FunctionReturnType<Query>> {\n const watch = this.watchQuery(query, ...args);\n const existingResult = watch.localQueryResult();\n if (existingResult !== undefined) {\n return Promise.resolve(existingResult);\n }\n return new Promise((resolve, reject) => {\n const unsubscribe = watch.onUpdate(() => {\n unsubscribe();\n try {\n resolve(watch.localQueryResult());\n } catch (e) {\n reject(e);\n }\n });\n });\n }\n\n /**\n * Get the current {@link ConnectionState} between the client and the Convex\n * backend.\n *\n * @returns The {@link ConnectionState} with the Convex backend.\n */\n connectionState(): ConnectionState {\n return this.sync.connectionState();\n }\n\n /**\n * Subscribe to the {@link ConnectionState} between the client and the Convex\n * backend, calling a callback each time it changes.\n *\n * Subscribed callbacks will be called when any part of ConnectionState changes.\n * ConnectionState may grow in future versions (e.g. to provide a array of\n * inflight requests) in which case callbacks would be called more frequently.\n * ConnectionState may also *lose* properties in future versions as we figure\n * out what information is most useful. As such this API is considered unstable.\n *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(\n cb: (connectionState: ConnectionState) => void,\n ): () => void {\n return this.sync.subscribeToConnectionState(cb);\n }\n\n /**\n * Get the logger for this client.\n *\n * @returns The {@link Logger} for this client.\n */\n get logger(): Logger {\n return this._logger;\n }\n\n /**\n * Close any network handles associated with this client and stop all subscriptions.\n *\n * Call this method when you're done with a {@link ConvexReactClient} to\n * dispose of its sockets and resources.\n *\n * @returns A `Promise` fulfilled when the connection has been completely closed.\n */\n async close(): Promise<void> {\n this.closed = true;\n // Prevent outstanding React batched updates from invoking listeners.\n this.listeners = new Map();\n if (this.cachedPaginatedQueryClient) {\n this.cachedPaginatedQueryClient = undefined;\n }\n if (this.cachedSync) {\n const sync = this.cachedSync;\n this.cachedSync = undefined;\n await sync.close();\n }\n }\n\n /**\n * Handle transitions from both base client and paginated client.\n * This ensures all transitions are processed synchronously and in order.\n */\n private handleTransition(transition: ExtendedTransition) {\n const simple = transition.queries.map((q) => q.token);\n const paginated = transition.paginatedQueries.map((q) => q.token);\n this.transition([...simple, ...paginated]);\n }\n\n private transition(updatedQueries: (QueryToken | PaginatedQueryToken)[]) {\n for (const queryToken of updatedQueries) {\n const callbacks = this.listeners.get(queryToken);\n if (callbacks) {\n for (const callback of callbacks) {\n callback();\n }\n }\n }\n }\n}\n\nconst ConvexContext = React.createContext<ConvexReactClient>(\n undefined as unknown as ConvexReactClient, // in the future this will be a mocked client for testing\n);\n\n/**\n * Get the {@link ConvexReactClient} within a React component.\n *\n * This relies on the {@link ConvexProvider} being above in the React component tree.\n *\n * @returns The active {@link ConvexReactClient} object, or `undefined`.\n *\n * @public\n */\nexport function useConvex(): ConvexReactClient {\n return useContext(ConvexContext);\n}\n\n/**\n * Provides an active Convex {@link ConvexReactClient} to descendants of this component.\n *\n * Wrap your app in this component to use Convex hooks `useQuery`,\n * `useMutation`, and `useConvex`.\n *\n * @param props - an object with a `client` property that refers to a {@link ConvexReactClient}.\n *\n * @public\n */\nexport const ConvexProvider: React.FC<{\n client: ConvexReactClient;\n children?: React.ReactNode;\n}> = ({ client, children }) => {\n return React.createElement(\n ConvexContext.Provider,\n { value: client },\n children,\n );\n};\n\nexport type OptionalRestArgsOrSkip<FuncRef extends FunctionReference<any>> =\n FuncRef[\"_args\"] extends EmptyObject\n ? [args?: EmptyObject | \"skip\"]\n : [args: FuncRef[\"_args\"] | \"skip\"];\n\n/**\n * Result returned by object-form {@link useQuery_experimental}.\n *\n * @public\n */\nexport type UseQueryResult<QueryResult, ThrowOnError extends boolean = false> =\n | { status: \"pending\" }\n | { status: \"success\"; data: QueryResult }\n | (ThrowOnError extends true ? never : { status: \"error\"; error: Error });\n\ntype UseQueryOptions<\n Query extends FunctionReference<\"query\">,\n ThrowOnError extends boolean,\n> = {\n query: Query;\n args: FunctionArgs<Query> | \"skip\";\n throwOnError?: ThrowOnError;\n};\n\n/**\n * Load a reactive query within a React component.\n *\n * This React hook subscribes to a Convex query and causes a rerender whenever\n * the query result changes. The subscription is managed automatically --\n * it starts when the component mounts and stops when it unmounts.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @example\n * ```tsx\n * import { useQuery } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function TaskList() {\n * // Reactively loads tasks, re-renders when data changes:\n * const tasks = useQuery(api.tasks.list, { completed: false });\n *\n * // Returns `undefined` while loading:\n * if (tasks === undefined) return <div>Loading...</div>;\n *\n * return tasks.map((task) => <div key={task._id}>{task.text}</div>);\n * }\n *\n * // Pass \"skip\" to conditionally disable the query:\n * function MaybeProfile({ userId }: { userId?: Id<\"users\"> }) {\n * const profile = useQuery(\n * api.users.get,\n * userId ? { userId } : \"skip\",\n * );\n * // ...\n * }\n * ```\n *\n * @param query - a {@link server.FunctionReference} for the public query to run\n * like `api.dir1.dir2.filename.func`.\n * @param args - The arguments to the query function or the string `\"skip\"` if the\n * query should not be loaded.\n * @returns the result of the query. Returns `undefined` while loading.\n *\n * @see https://docs.convex.dev/client/react#fetching-data\n * @public\n */\nexport function useQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgsOrSkip<Query>\n): Query[\"_returnType\"] | undefined {\n const skip = args[0] === \"skip\";\n const argsObject = args[0] === \"skip\" ? {} : parseArgs(args[0]);\n const queryReference =\n typeof query === \"string\"\n ? makeFunctionReference<\"query\", any, any>(query)\n : query;\n\n const queryName = getFunctionName(queryReference);\n\n const queries = useMemo(\n () =>\n skip\n ? ({} as RequestForQueries)\n : { query: { query: queryReference, args: argsObject } },\n // Stringify args so args that are semantically the same don't trigger a\n // rerender. Saves developers from adding `useMemo` on every args usage.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(convexToJson(argsObject)), queryName, skip],\n );\n\n const results = useQueries(queries);\n const result = results[\"query\"];\n\n if (result instanceof Error) {\n throw result;\n }\n return result;\n}\n\n/**\n * Load a reactive query within a React component using an options object.\n *\n * This is an experimental form of {@link useQuery} that accepts a single\n * {@link UseQueryOptions} object instead of positional arguments.\n *\n * Consumers are expected to check the returned object `status` field to\n * make proper use of the result. If an error occurs, it will be present\n * in the result object unless `throwOnError` is `true`, in which case\n * the error will be thrown instead.\n *\n * @example\n * ```tsx\n * import { useQuery_experimental as useQuery } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function TaskList() {\n * const state = useQuery({ query: api.tasks.list, args: { completed: false } });\n *\n * if (state.status === \"pending\") return <div>Loading...</div>;\n * if (state.status === \"error\") return <div>Error: {state.error.message}</div>;\n * return state.data.map((task) => <div key={task._id}>{task.text}</div>);\n * }\n * ```\n *\n * @param options - Query options. Pass `args: \"skip\"` to disable the query.\n * @returns the current query state as a {@link UseQueryResult} object.\n *\n * @see https://docs.convex.dev/client/react#fetching-data\n * @public\n */\nexport function useQuery_experimental<\n Query extends FunctionReference<\"query\">,\n ThrowOnError extends boolean = false,\n>(\n options: UseQueryOptions<Query, ThrowOnError>,\n): UseQueryResult<Query[\"_returnType\"], ThrowOnError>;\n\nexport function useQuery_experimental<\n Query extends FunctionReference<\"query\">,\n ThrowOnError extends boolean = false,\n>(\n options: UseQueryOptions<Query, ThrowOnError>,\n): UseQueryResult<Query[\"_returnType\"], false> {\n const throwOnError = options.throwOnError ?? false;\n const queryReference =\n typeof options.query === \"string\"\n ? (makeFunctionReference<\"query\", any, any>(options.query) as Query)\n : options.query;\n const skip = options.args === \"skip\";\n const argsObject = !skip\n ? parseArgs(options.args as Record<string, Value>)\n : {};\n\n const queryName = getFunctionName(queryReference);\n const queries = useMemo(\n () =>\n skip\n ? ({} as RequestForQueries)\n : { query: { query: queryReference, args: argsObject } },\n // Stringify args so args that are semantically the same don't trigger a\n // rerender. Saves developers from adding `useMemo` on every args usage.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(convexToJson(argsObject)), queryName, skip],\n );\n\n const results = useQueries(queries);\n const result = results[\"query\"];\n\n if (result instanceof Error) {\n if (throwOnError) {\n throw result;\n }\n return {\n error: result,\n status: \"error\",\n };\n }\n\n if (result === undefined) {\n return {\n status: \"pending\",\n };\n }\n\n return {\n data: result,\n status: \"success\",\n };\n}\n\n/**\n * Construct a new {@link ReactMutation}.\n *\n * Returns a function that you can call to execute a Convex mutation. The\n * returned function is stable across renders (same reference identity), so\n * it can be safely used in dependency arrays and memoization.\n *\n * Mutations can optionally be configured with\n * [optimistic updates](https://docs.convex.dev/client/react/optimistic-updates)\n * for instant UI feedback.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @example\n * ```tsx\n * import { useMutation } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function CreateTask() {\n * const createTask = useMutation(api.tasks.create);\n *\n * const handleClick = async () => {\n * await createTask({ text: \"New task\" });\n * };\n *\n * return <button onClick={handleClick}>Add Task</button>;\n * }\n * ```\n *\n * @param mutation - A {@link server.FunctionReference} for the public mutation\n * to run like `api.dir1.dir2.filename.func`.\n * @returns The {@link ReactMutation} object with that name.\n *\n * @see https://docs.convex.dev/client/react#editing-data\n * @public\n */\nexport function useMutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n): ReactMutation<Mutation> {\n const mutationReference =\n typeof mutation === \"string\"\n ? makeFunctionReference<\"mutation\", any, any>(mutation)\n : mutation;\n\n const convex = useContext(ConvexContext);\n if (convex === undefined) {\n throw new Error(\n \"Could not find Convex client! `useMutation` must be used in the React component \" +\n \"tree under `ConvexProvider`. Did you forget it? \" +\n \"See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app\",\n );\n }\n return useMemo(\n () => createMutation(mutationReference, convex),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [convex, getFunctionName(mutationReference)],\n );\n}\n\n/**\n * Construct a new {@link ReactAction}.\n *\n * Returns a function that you can call to execute a Convex action. Actions\n * can call third-party APIs and perform side effects. The returned function\n * is stable across renders (same reference identity).\n *\n * **Error handling:** Actions can fail (e.g., if an external API is down).\n * Always wrap action calls in try/catch or handle the rejected promise.\n *\n * **Note:** In most cases, calling an action directly from a client is an\n * anti-pattern. Prefer having the client call a mutation that captures the\n * user's intent (by writing to the database) and then schedules the action\n * via `ctx.scheduler.runAfter`. This ensures the intent is durably recorded\n * even if the client disconnects.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @example\n * ```tsx\n * import { useAction } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function GenerateSummary() {\n * const generate = useAction(api.ai.generateSummary);\n *\n * const handleClick = async () => {\n * try {\n * const summary = await generate({ text: \"Some long text...\" });\n * console.log(summary);\n * } catch (error) {\n * console.error(\"Action failed:\", error);\n * }\n * };\n *\n * return <button onClick={handleClick}>Generate</button>;\n * }\n * ```\n *\n * @param action - A {@link server.FunctionReference} for the public action\n * to run like `api.dir1.dir2.filename.func`.\n * @returns The {@link ReactAction} object with that name.\n *\n * @see https://docs.convex.dev/functions/actions#calling-actions-from-clients\n * @public\n */\nexport function useAction<Action extends FunctionReference<\"action\">>(\n action: Action,\n): ReactAction<Action> {\n const convex = useContext(ConvexContext);\n const actionReference =\n typeof action === \"string\"\n ? makeFunctionReference<\"action\", any, any>(action)\n : action;\n\n if (convex === undefined) {\n throw new Error(\n \"Could not find Convex client! `useAction` must be used in the React component \" +\n \"tree under `ConvexProvider`. Did you forget it? \" +\n \"See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app\",\n );\n }\n return useMemo(\n () => createAction(actionReference, convex),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [convex, getFunctionName(actionReference)],\n );\n}\n\n/**\n * React hook to get the current {@link ConnectionState} and subscribe to changes.\n *\n * This hook returns the current connection state and automatically rerenders\n * when any part of the connection state changes (e.g., when going online/offline,\n * when requests start/complete, etc.).\n *\n * The shape of ConnectionState may change in the future which may cause this\n * hook to rerender more frequently.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @returns The current {@link ConnectionState} with the Convex backend.\n *\n * @public\n */\nexport function useConvexConnectionState(): ConnectionState {\n const convex = useContext(ConvexContext);\n if (convex === undefined) {\n throw new Error(\n \"Could not find Convex client! `useConvexConnectionState` must be used in the React component \" +\n \"tree under `ConvexProvider`. Did you forget it? \" +\n \"See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app\",\n );\n }\n\n const getCurrentValue = useCallback(() => {\n return convex.connectionState();\n }, [convex]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n return convex.subscribeToConnectionState(() => {\n callback();\n });\n },\n [convex],\n );\n\n return useSubscription({ getCurrentValue, subscribe });\n}\n\n// When a function is called with a single argument that looks like a\n// React SyntheticEvent it was likely called as an event handler.\nfunction assertNotAccidentalArgument(value: any) {\n // these are properties of a React.SyntheticEvent\n // https://reactjs.org/docs/events.html\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"bubbles\" in value &&\n \"persist\" in value &&\n \"isDefaultPrevented\" in value\n ) {\n throw new Error(\n `Convex function called with SyntheticEvent object. Did you use a Convex function as an event handler directly? Event handlers like onClick receive an event object as their first argument. These SyntheticEvent objects are not valid Convex values. Try wrapping the function like \\`const handler = () => myMutation();\\` and using \\`handler\\` in the event handler.`,\n );\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { BaseConvexClient } from \"../browser/index.js\";\nimport type {\n OptimisticUpdate,\n PaginatedQueryToken,\n QueryToken,\n PaginationStatus,\n} from \"../browser/index.js\";\nimport React, { useCallback, useContext, useMemo } from \"react\";\nimport { convexToJson, Value } from \"../values/index.js\";\nimport { QueryJournal } from \"../browser/sync/protocol.js\";\nimport {\n AuthTokenFetcher,\n BaseConvexClientOptions,\n ConnectionState,\n} from \"../browser/sync/client.js\";\nimport type { UserIdentityAttributes } from \"../browser/sync/protocol.js\";\nimport { RequestForQueries, useQueries } from \"./use_queries.js\";\nimport { useSubscription } from \"./use_subscription.js\";\nimport { parseArgs } from \"../common/index.js\";\nimport {\n ArgsAndOptions,\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n getFunctionName,\n makeFunctionReference,\n} from \"../server/api.js\";\nimport { EmptyObject } from \"../server/registration.js\";\nimport {\n instantiateDefaultLogger,\n instantiateNoopLogger,\n Logger,\n} from \"../browser/logging.js\";\nimport type { QueryOptions } from \"../browser/query_options.js\";\nimport { LoadMoreOfPaginatedQuery } from \"../browser/sync/pagination.js\";\nimport {\n PaginatedQueryClient,\n ExtendedTransition,\n} from \"../browser/sync/paginated_query_client.js\";\n\n// When no arguments are passed, extend subscriptions (for APIs that do this by default)\n// for this amount after the subscription would otherwise be dropped.\nconst DEFAULT_EXTEND_SUBSCRIPTION_FOR = 5_000;\n\nif (typeof React === \"undefined\") {\n throw new Error(\"Required dependency 'react' not found\");\n}\n\n// TODO Typedoc doesn't generate documentation for the comment below perhaps\n// because it's a callable interface.\n/**\n * An interface to execute a Convex mutation function on the server.\n *\n * @public\n */\nexport interface ReactMutation<Mutation extends FunctionReference<\"mutation\">> {\n /**\n * Execute the mutation on the server, returning a `Promise` of its return value.\n *\n * @param args - Arguments for the mutation to pass up to the server.\n * @returns The return value of the server-side function call.\n */\n (...args: OptionalRestArgs<Mutation>): Promise<FunctionReturnType<Mutation>>;\n\n /**\n * Define an optimistic update to apply as part of this mutation.\n *\n * This is a temporary update to the local query results to facilitate a\n * fast, interactive UI. It enables query results to update before a mutation\n * executed on the server.\n *\n * When the mutation is invoked, the optimistic update will be applied.\n *\n * Optimistic updates can also be used to temporarily remove queries from the\n * client and create loading experiences until a mutation completes and the\n * new query results are synced.\n *\n * The update will be automatically rolled back when the mutation is fully\n * completed and queries have been updated.\n *\n * @param optimisticUpdate - The optimistic update to apply.\n * @returns A new `ReactMutation` with the update configured.\n *\n * @public\n */\n withOptimisticUpdate<T extends OptimisticUpdate<FunctionArgs<Mutation>>>(\n optimisticUpdate: T &\n (ReturnType<T> extends Promise<any>\n ? \"Optimistic update handlers must be synchronous\"\n : {}),\n ): ReactMutation<Mutation>;\n}\n\n// Exported only for testing.\nexport function createMutation(\n mutationReference: FunctionReference<\"mutation\">,\n client: ConvexReactClient,\n update?: OptimisticUpdate<any>,\n): ReactMutation<any> {\n function mutation(args?: Record<string, Value>): Promise<unknown> {\n assertNotAccidentalArgument(args);\n\n return client.mutation(mutationReference, args, {\n optimisticUpdate: update,\n });\n }\n mutation.withOptimisticUpdate = function withOptimisticUpdate(\n optimisticUpdate: OptimisticUpdate<any>,\n ): ReactMutation<any> {\n if (update !== undefined) {\n throw new Error(\n `Already specified optimistic update for mutation ${getFunctionName(\n mutationReference,\n )}`,\n );\n }\n return createMutation(mutationReference, client, optimisticUpdate);\n };\n return mutation as ReactMutation<any>;\n}\n\n/**\n * An interface to execute a Convex action on the server.\n *\n * @public\n */\nexport interface ReactAction<Action extends FunctionReference<\"action\">> {\n /**\n * Execute the function on the server, returning a `Promise` of its return value.\n *\n * @param args - Arguments for the function to pass up to the server.\n * @returns The return value of the server-side function call.\n * @public\n */\n (...args: OptionalRestArgs<Action>): Promise<FunctionReturnType<Action>>;\n}\n\nfunction createAction(\n actionReference: FunctionReference<\"action\">,\n client: ConvexReactClient,\n): ReactAction<any> {\n return function (args?: Record<string, Value>): Promise<unknown> {\n return client.action(actionReference, args);\n } as ReactAction<any>;\n}\n\n// Watches should be stateless: in QueriesObserver we create a watch just to get\n// the current value.\n/**\n * A watch on the output of a Convex query function.\n *\n * @public\n */\nexport interface Watch<T> {\n /**\n * Initiate a watch on the output of a query.\n *\n * This will subscribe to this query and call\n * the callback whenever the query result changes.\n *\n * **Important: If the client is already subscribed to this query with the\n * same arguments this callback will not be invoked until the query result is\n * updated.** To get the current, local result call\n * {@link react.Watch.localQueryResult}.\n *\n * @param callback - Function that is called whenever the query result changes.\n * @returns - A function that disposes of the subscription.\n */\n onUpdate(callback: () => void): () => void;\n\n /**\n * Get the current result of a query.\n *\n * This will only return a result if we're already subscribed to the query\n * and have received a result from the server or the query value has been set\n * optimistically.\n *\n * @returns The result of the query or `undefined` if it isn't known.\n * @throws An error if the query encountered an error on the server.\n */\n localQueryResult(): T | undefined;\n\n /**\n * @internal\n */\n localQueryLogs(): string[] | undefined;\n\n /**\n * Get the current {@link browser.QueryJournal} for this query.\n *\n * If we have not yet received a result for this query, this will be `undefined`.\n */\n journal(): QueryJournal | undefined;\n}\n\n/**\n * A watch on the output of a paginated Convex query function.\n *\n * @public\n */\nexport interface PaginatedWatch<T> {\n /**\n * Initiate a watch on the output of a paginated query.\n *\n * This will subscribe to this query and call\n * the callback whenever the query result changes.\n *\n * @param callback - Function that is called whenever the query result changes.\n * @returns - A function that disposes of the subscription.\n */\n onUpdate(callback: () => void): () => void;\n\n /**\n * Get the current result of a paginated query.\n *\n * @returns The current results, status, and loadMore function, or `undefined` if not loaded.\n */\n localQueryResult():\n | {\n results: T[];\n status: PaginationStatus;\n loadMore: LoadMoreOfPaginatedQuery;\n }\n | undefined;\n}\n\n/**\n * Options for {@link ConvexReactClient.watchQuery}.\n *\n * @public\n */\nexport interface WatchQueryOptions {\n /**\n * An (optional) journal produced from a previous execution of this query\n * function.\n *\n * If there is an existing subscription to a query function with the same\n * name and arguments, this journal will have no effect.\n */\n journal?: QueryJournal;\n\n /**\n * @internal\n */\n componentPath?: string;\n}\n\n/**\n * Options for {@link ConvexReactClient.watchPaginatedQuery}.\n *\n * @internal\n */\nexport interface WatchPaginatedQueryOptions {\n /**\n * The initial number of items to load.\n */\n initialNumItems: number;\n\n // We may be able to remove this in the future, but to preserve the existing behavior of\n // usePaginatedQuery() it's still here.\n id: number;\n\n /**\n * @internal\n */\n componentPath?: string;\n}\n\n/**\n * Options for {@link ConvexReactClient.mutation}.\n *\n * @public\n */\nexport interface MutationOptions<Args extends Record<string, Value>> {\n /**\n * An optimistic update to apply along with this mutation.\n *\n * An optimistic update locally updates queries while a mutation is pending.\n * Once the mutation completes, the update will be rolled back.\n */\n optimisticUpdate?: OptimisticUpdate<Args> | undefined;\n}\n\n/**\n * Options for {@link ConvexReactClient}.\n *\n * @public\n */\nexport interface ConvexReactClientOptions extends BaseConvexClientOptions {\n /**\n * An already-constructed {@link BaseConvexClient} to use instead of\n * constructing one internally. When provided, this client (and its\n * derived {@link PaginatedQueryClient}) is used for all operations.\n *\n * @internal\n */\n baseClient?: BaseConvexClient;\n\n // FIXME: Ideally we define `ConvexReactClientOptions` as\n // `type ConvexReactClientOptions = BaseConvexClientOptions | { baseClient: BaseConvexClient }`\n // so that callers won\u2019t try to set `BaseConvexClientOptions` attributes that are ineffective.\n // But since `baseClient` is internal at the moment, I don\u2019t think we can do that.\n // We can fix this if we ever make `baseClient` public.\n}\n\n/**\n * A Convex client for use within React.\n *\n * This loads reactive queries and executes mutations over a WebSocket.\n *\n * @public\n */\nexport class ConvexReactClient {\n private address: string;\n private cachedSync?: BaseConvexClient | undefined;\n private cachedPaginatedQueryClient?: PaginatedQueryClient | undefined;\n private listeners: Map<QueryToken | PaginatedQueryToken, Set<() => void>>;\n private options: ConvexReactClientOptions;\n // \"closed\" means this client is done, not just that the underlying WS connection is closed.\n private closed = false;\n private _logger: Logger;\n\n private adminAuth?: string;\n private fakeUserIdentity?: UserIdentityAttributes | undefined;\n\n /**\n * @param address - The url of your Convex deployment, often provided\n * by an environment variable. E.g. `https://small-mouse-123.convex.cloud`.\n * @param options - See {@link ConvexReactClientOptions} for a full description.\n */\n constructor(address: string, options?: ConvexReactClientOptions) {\n // Validate address immediately since validation by the lazily-instantiated\n // internal client does not occur synchronously.\n if (address === undefined) {\n throw new Error(\n \"No address provided to ConvexReactClient.\\n\" +\n \"If trying to deploy to production, make sure to follow all the instructions found at https://docs.convex.dev/production/hosting/\\n\" +\n \"If running locally, make sure to run `convex dev` and ensure the .env.local file is populated.\",\n );\n }\n if (typeof address !== \"string\") {\n throw new Error(\n `ConvexReactClient requires a URL like 'https://happy-otter-123.convex.cloud', received something of type ${typeof address} instead.`,\n );\n }\n if (!address.includes(\"://\")) {\n throw new Error(\"Provided address was not an absolute URL.\");\n }\n this.address = address;\n this.listeners = new Map();\n this._logger =\n options?.logger === false\n ? instantiateNoopLogger({ verbose: options?.verbose ?? false })\n : options?.logger !== true && options?.logger\n ? options.logger\n : instantiateDefaultLogger({ verbose: options?.verbose ?? false });\n this.options = { ...options, logger: this._logger };\n }\n\n /**\n * Return the address for this client, useful for creating a new client.\n *\n * Not guaranteed to match the address with which this client was constructed:\n * it may be canonicalized.\n */\n get url() {\n return this.address;\n }\n\n /**\n * Lazily instantiate the `BaseConvexClient` so we don't create the WebSocket\n * when server-side rendering.\n *\n * @internal\n */\n get sync() {\n if (this.closed) {\n throw new Error(\"ConvexReactClient has already been closed.\");\n }\n if (this.cachedSync) {\n return this.cachedSync;\n }\n // BaseConvexClient and paginated query client are always created together.\n this.cachedSync =\n this.options.baseClient ??\n new BaseConvexClient(\n this.address,\n () => {}, // Use the PaginatedQueryClient's transition instead.\n this.options,\n );\n if (this.adminAuth) {\n this.cachedSync.setAdminAuth(this.adminAuth, this.fakeUserIdentity);\n }\n this.cachedPaginatedQueryClient = new PaginatedQueryClient(\n this.cachedSync,\n (transition) => this.handleTransition(transition),\n );\n return this.cachedSync;\n }\n\n /**\n * Lazily instantiate the `PaginatedQueryClient` so we don't create it\n * when server-side rendering.\n *\n * @internal\n */\n get paginatedQueryClient() {\n // access sync to instantiate the clients\n this.sync;\n if (this.cachedPaginatedQueryClient) {\n return this.cachedPaginatedQueryClient;\n }\n throw new Error(\"Should already be instantiated\");\n }\n\n /**\n * Set the authentication token to be used for subsequent queries and mutations.\n * `fetchToken` will be called automatically again if a token expires.\n * `fetchToken` should return `null` if the token cannot be retrieved, for example\n * when the user's rights were permanently revoked.\n * @param fetchToken - an async function returning the JWT-encoded OpenID Connect Identity Token\n * @param onChange - a callback that will be called when the authentication status changes\n * @param onRefreshChange - a callback called with `true` when the socket is paused to fetch a replacement token after a server rejection, and `false` when refresh completes\n */\n setAuth(\n fetchToken: AuthTokenFetcher,\n onChange?: (isAuthenticated: boolean) => void,\n onRefreshChange?: (isRefreshing: boolean) => void,\n ) {\n if (typeof fetchToken === \"string\") {\n throw new Error(\n \"Passing a string to ConvexReactClient.setAuth is no longer supported, \" +\n \"please upgrade to passing in an async function to handle reauthentication.\",\n );\n }\n this.sync.setAuth(\n fetchToken,\n onChange ??\n (() => {\n // Do nothing\n }),\n onRefreshChange,\n );\n }\n\n /**\n * Clear the current authentication token if set.\n */\n clearAuth() {\n this.sync.clearAuth();\n }\n\n /**\n * @internal\n */\n setAdminAuth(token: string, identity?: UserIdentityAttributes) {\n this.adminAuth = token;\n this.fakeUserIdentity = identity;\n if (this.closed) {\n throw new Error(\"ConvexReactClient has already been closed.\");\n }\n if (this.cachedSync) {\n this.sync.setAdminAuth(token, identity);\n }\n }\n\n /**\n * Construct a new {@link Watch} on a Convex query function.\n *\n * **Most application code should not call this method directly. Instead use\n * the {@link useQuery} hook.**\n *\n * The act of creating a watch does nothing, a Watch is stateless.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - An arguments object for the query. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link WatchQueryOptions} options object for this query.\n *\n * @returns The {@link Watch} object.\n */\n watchQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...argsAndOptions: ArgsAndOptions<Query, WatchQueryOptions>\n ): Watch<FunctionReturnType<Query>> {\n const [args, options] = argsAndOptions;\n const name = getFunctionName(query);\n\n return {\n onUpdate: (callback) => {\n const { queryToken, unsubscribe } = this.sync.subscribe(\n name as string,\n args,\n options,\n );\n\n const currentListeners = this.listeners.get(queryToken);\n if (currentListeners !== undefined) {\n currentListeners.add(callback);\n } else {\n this.listeners.set(queryToken, new Set([callback]));\n }\n\n return () => {\n if (this.closed) {\n return;\n }\n\n const currentListeners = this.listeners.get(queryToken)!;\n currentListeners.delete(callback);\n if (currentListeners.size === 0) {\n this.listeners.delete(queryToken);\n }\n unsubscribe();\n };\n },\n\n localQueryResult: () => {\n // Use the cached client because we can't have a query result if we don't\n // even have a client yet!\n if (this.cachedSync) {\n return this.cachedSync.localQueryResult(name, args);\n }\n return undefined;\n },\n\n localQueryLogs: () => {\n if (this.cachedSync) {\n return this.cachedSync.localQueryLogs(name, args);\n }\n return undefined;\n },\n\n journal: () => {\n if (this.cachedSync) {\n return this.cachedSync.queryJournal(name, args);\n }\n return undefined;\n },\n };\n }\n\n // Let's try out a queryOptions-style API.\n // This method is similar to the React Query API `queryClient.prefetchQuery()`.\n // In the future an ensureQueryData(): Promise<Data> method could exist.\n /**\n * Indicates likely future interest in a query subscription.\n *\n * The implementation currently immediately subscribes to a query. In the future this method\n * may prioritize some queries over others, fetch the query result without subscribing, or\n * do nothing in slow network connections or high load scenarios.\n *\n * To use this in a React component, call useQuery() and ignore the return value.\n *\n * @param queryOptions - A query (function reference from an api object) and its args, plus\n * an optional extendSubscriptionFor for how long to subscribe to the query.\n */\n prewarmQuery<Query extends FunctionReference<\"query\">>(\n queryOptions: QueryOptions<Query> & { extendSubscriptionFor?: number },\n ) {\n const extendSubscriptionFor =\n queryOptions.extendSubscriptionFor ?? DEFAULT_EXTEND_SUBSCRIPTION_FOR;\n const watch = this.watchQuery(queryOptions.query, queryOptions.args || {});\n const unsubscribe = watch.onUpdate(() => {});\n setTimeout(unsubscribe, extendSubscriptionFor);\n }\n\n /**\n * Construct a new {@link PaginatedWatch} on a Convex paginated query function.\n *\n * **Most application code should not call this method directly. Instead use\n * the {@link usePaginatedQuery} hook.**\n *\n * The act of creating a watch does nothing, a Watch is stateless.\n *\n * @param query - A {@link server.FunctionReference} for the public query to run.\n * @param args - An arguments object for the query. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link WatchPaginatedQueryOptions} options object for this query.\n *\n * @returns The {@link PaginatedWatch} object.\n *\n * @internal\n */\n watchPaginatedQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n args: Query[\"_args\"],\n options: WatchPaginatedQueryOptions,\n ): PaginatedWatch<FunctionReturnType<Query>> {\n const name = getFunctionName(query);\n\n return {\n onUpdate: (callback) => {\n const { paginatedQueryToken, unsubscribe } =\n this.paginatedQueryClient.subscribe(name, args || {}, options);\n\n const currentListeners = this.listeners.get(paginatedQueryToken);\n if (currentListeners !== undefined) {\n currentListeners.add(callback);\n } else {\n this.listeners.set(paginatedQueryToken, new Set([callback]));\n }\n\n return () => {\n if (this.closed) {\n return;\n }\n\n const currentListeners = this.listeners.get(paginatedQueryToken)!;\n currentListeners.delete(callback);\n if (currentListeners.size === 0) {\n this.listeners.delete(paginatedQueryToken);\n }\n unsubscribe();\n };\n },\n\n localQueryResult: () => {\n // Use our new paginated query client\n return this.paginatedQueryClient.localQueryResult(name, args, options);\n },\n };\n }\n\n /**\n * Execute a mutation function.\n *\n * @param mutation - A {@link server.FunctionReference} for the public mutation\n * to run.\n * @param args - An arguments object for the mutation. If this is omitted,\n * the arguments will be `{}`.\n * @param options - A {@link MutationOptions} options object for the mutation.\n * @returns A promise of the mutation's result.\n */\n mutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n ...argsAndOptions: ArgsAndOptions<\n Mutation,\n MutationOptions<FunctionArgs<Mutation>>\n >\n ): Promise<FunctionReturnType<Mutation>> {\n const [args, options] = argsAndOptions;\n const name = getFunctionName(mutation);\n return this.sync.mutation(name, args, options);\n }\n\n /**\n * Execute an action function.\n *\n * @param action - A {@link server.FunctionReference} for the public action\n * to run.\n * @param args - An arguments object for the action. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the action's result.\n */\n action<Action extends FunctionReference<\"action\">>(\n action: Action,\n ...args: OptionalRestArgs<Action>\n ): Promise<FunctionReturnType<Action>> {\n const name = getFunctionName(action);\n return this.sync.action(name, ...args);\n }\n\n /**\n * Fetch a query result once.\n *\n * **Most application code should subscribe to queries instead, using\n * the {@link useQuery} hook.**\n *\n * @param query - A {@link server.FunctionReference} for the public query\n * to run.\n * @param args - An arguments object for the query. If this is omitted,\n * the arguments will be `{}`.\n * @returns A promise of the query's result.\n */\n query<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgs<Query>\n ): Promise<FunctionReturnType<Query>> {\n const watch = this.watchQuery(query, ...args);\n const existingResult = watch.localQueryResult();\n if (existingResult !== undefined) {\n return Promise.resolve(existingResult);\n }\n return new Promise((resolve, reject) => {\n const unsubscribe = watch.onUpdate(() => {\n unsubscribe();\n try {\n resolve(watch.localQueryResult());\n } catch (e) {\n reject(e);\n }\n });\n });\n }\n\n /**\n * Get the current {@link ConnectionState} between the client and the Convex\n * backend.\n *\n * @returns The {@link ConnectionState} with the Convex backend.\n */\n connectionState(): ConnectionState {\n return this.sync.connectionState();\n }\n\n /**\n * Subscribe to the {@link ConnectionState} between the client and the Convex\n * backend, calling a callback each time it changes.\n *\n * Subscribed callbacks will be called when any part of ConnectionState changes.\n * ConnectionState may grow in future versions (e.g. to provide a array of\n * inflight requests) in which case callbacks would be called more frequently.\n * ConnectionState may also *lose* properties in future versions as we figure\n * out what information is most useful. As such this API is considered unstable.\n *\n * @returns An unsubscribe function to stop listening.\n */\n subscribeToConnectionState(\n cb: (connectionState: ConnectionState) => void,\n ): () => void {\n return this.sync.subscribeToConnectionState(cb);\n }\n\n /**\n * Get the logger for this client.\n *\n * @returns The {@link Logger} for this client.\n */\n get logger(): Logger {\n return this._logger;\n }\n\n /**\n * Close any network handles associated with this client and stop all subscriptions.\n *\n * Call this method when you're done with a {@link ConvexReactClient} to\n * dispose of its sockets and resources.\n *\n * @returns A `Promise` fulfilled when the connection has been completely closed.\n */\n async close(): Promise<void> {\n this.closed = true;\n // Prevent outstanding React batched updates from invoking listeners.\n this.listeners = new Map();\n if (this.cachedPaginatedQueryClient) {\n this.cachedPaginatedQueryClient = undefined;\n }\n if (this.cachedSync) {\n const sync = this.cachedSync;\n this.cachedSync = undefined;\n await sync.close();\n }\n }\n\n /**\n * Handle transitions from both base client and paginated client.\n * This ensures all transitions are processed synchronously and in order.\n */\n private handleTransition(transition: ExtendedTransition) {\n const simple = transition.queries.map((q) => q.token);\n const paginated = transition.paginatedQueries.map((q) => q.token);\n this.transition([...simple, ...paginated]);\n }\n\n private transition(updatedQueries: (QueryToken | PaginatedQueryToken)[]) {\n for (const queryToken of updatedQueries) {\n const callbacks = this.listeners.get(queryToken);\n if (callbacks) {\n for (const callback of callbacks) {\n callback();\n }\n }\n }\n }\n}\n\nconst ConvexContext = React.createContext<ConvexReactClient>(\n undefined as unknown as ConvexReactClient, // in the future this will be a mocked client for testing\n);\n\n/**\n * Get the {@link ConvexReactClient} within a React component.\n *\n * This relies on the {@link ConvexProvider} being above in the React component tree.\n *\n * @returns The active {@link ConvexReactClient} object, or `undefined`.\n *\n * @public\n */\nexport function useConvex(): ConvexReactClient {\n return useContext(ConvexContext);\n}\n\n/**\n * Provides an active Convex {@link ConvexReactClient} to descendants of this component.\n *\n * Wrap your app in this component to use Convex hooks `useQuery`,\n * `useMutation`, and `useConvex`.\n *\n * @param props - an object with a `client` property that refers to a {@link ConvexReactClient}.\n *\n * @public\n */\nexport const ConvexProvider: React.FC<{\n client: ConvexReactClient;\n children?: React.ReactNode;\n}> = ({ client, children }) => {\n return React.createElement(\n ConvexContext.Provider,\n { value: client },\n children,\n );\n};\n\nexport type OptionalRestArgsOrSkip<FuncRef extends FunctionReference<any>> =\n FuncRef[\"_args\"] extends EmptyObject\n ? [args?: EmptyObject | \"skip\"]\n : [args: FuncRef[\"_args\"] | \"skip\"];\n\n/**\n * Result returned by object-form {@link useQuery_experimental}.\n *\n * @public\n */\nexport type UseQueryResult<QueryResult, ThrowOnError extends boolean = false> =\n | { status: \"pending\" }\n | { status: \"success\"; data: QueryResult }\n | (ThrowOnError extends true ? never : { status: \"error\"; error: Error });\n\ntype UseQueryOptions<\n Query extends FunctionReference<\"query\">,\n ThrowOnError extends boolean,\n> = {\n query: Query;\n args: FunctionArgs<Query> | \"skip\";\n throwOnError?: ThrowOnError;\n};\n\n/**\n * Load a reactive query within a React component.\n *\n * This React hook subscribes to a Convex query and causes a rerender whenever\n * the query result changes. The subscription is managed automatically --\n * it starts when the component mounts and stops when it unmounts.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @example\n * ```tsx\n * import { useQuery } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function TaskList() {\n * // Reactively loads tasks, re-renders when data changes:\n * const tasks = useQuery(api.tasks.list, { completed: false });\n *\n * // Returns `undefined` while loading:\n * if (tasks === undefined) return <div>Loading...</div>;\n *\n * return tasks.map((task) => <div key={task._id}>{task.text}</div>);\n * }\n *\n * // Pass \"skip\" to conditionally disable the query:\n * function MaybeProfile({ userId }: { userId?: Id<\"users\"> }) {\n * const profile = useQuery(\n * api.users.get,\n * userId ? { userId } : \"skip\",\n * );\n * // ...\n * }\n * ```\n *\n * @param query - a {@link server.FunctionReference} for the public query to run\n * like `api.dir1.dir2.filename.func`.\n * @param args - The arguments to the query function or the string `\"skip\"` if the\n * query should not be loaded.\n * @returns the result of the query. Returns `undefined` while loading.\n *\n * @see https://docs.convex.dev/client/react#fetching-data\n * @public\n */\nexport function useQuery<Query extends FunctionReference<\"query\">>(\n query: Query,\n ...args: OptionalRestArgsOrSkip<Query>\n): Query[\"_returnType\"] | undefined {\n const skip = args[0] === \"skip\";\n const argsObject = args[0] === \"skip\" ? {} : parseArgs(args[0]);\n const queryReference =\n typeof query === \"string\"\n ? makeFunctionReference<\"query\", any, any>(query)\n : query;\n\n const queryName = getFunctionName(queryReference);\n\n const queries = useMemo(\n () =>\n skip\n ? ({} as RequestForQueries)\n : { query: { query: queryReference, args: argsObject } },\n // Stringify args so args that are semantically the same don't trigger a\n // rerender. Saves developers from adding `useMemo` on every args usage.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(convexToJson(argsObject)), queryName, skip],\n );\n\n const results = useQueries(queries);\n const result = results[\"query\"];\n\n if (result instanceof Error) {\n throw result;\n }\n return result;\n}\n\n/**\n * Load a reactive query within a React component using an options object.\n *\n * This is an experimental form of {@link useQuery} that accepts a single\n * {@link UseQueryOptions} object instead of positional arguments.\n *\n * Consumers are expected to check the returned object `status` field to\n * make proper use of the result. If an error occurs, it will be present\n * in the result object unless `throwOnError` is `true`, in which case\n * the error will be thrown instead.\n *\n * @example\n * ```tsx\n * import { useQuery_experimental as useQuery } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function TaskList() {\n * const state = useQuery({ query: api.tasks.list, args: { completed: false } });\n *\n * if (state.status === \"pending\") return <div>Loading...</div>;\n * if (state.status === \"error\") return <div>Error: {state.error.message}</div>;\n * return state.data.map((task) => <div key={task._id}>{task.text}</div>);\n * }\n * ```\n *\n * @param options - Query options. Pass `args: \"skip\"` to disable the query.\n * @returns the current query state as a {@link UseQueryResult} object.\n *\n * @see https://docs.convex.dev/client/react#fetching-data\n * @public\n */\nexport function useQuery_experimental<\n Query extends FunctionReference<\"query\">,\n ThrowOnError extends boolean = false,\n>(\n options: UseQueryOptions<Query, ThrowOnError>,\n): UseQueryResult<Query[\"_returnType\"], ThrowOnError>;\n\nexport function useQuery_experimental<\n Query extends FunctionReference<\"query\">,\n ThrowOnError extends boolean = false,\n>(\n options: UseQueryOptions<Query, ThrowOnError>,\n): UseQueryResult<Query[\"_returnType\"], false> {\n const throwOnError = options.throwOnError ?? false;\n const queryReference =\n typeof options.query === \"string\"\n ? (makeFunctionReference<\"query\", any, any>(options.query) as Query)\n : options.query;\n const skip = options.args === \"skip\";\n const argsObject = !skip\n ? parseArgs(options.args as Record<string, Value>)\n : {};\n\n const queryName = getFunctionName(queryReference);\n const queries = useMemo(\n () =>\n skip\n ? ({} as RequestForQueries)\n : { query: { query: queryReference, args: argsObject } },\n // Stringify args so args that are semantically the same don't trigger a\n // rerender. Saves developers from adding `useMemo` on every args usage.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(convexToJson(argsObject)), queryName, skip],\n );\n\n const results = useQueries(queries);\n const result = results[\"query\"];\n\n if (result instanceof Error) {\n if (throwOnError) {\n throw result;\n }\n return {\n error: result,\n status: \"error\",\n };\n }\n\n if (result === undefined) {\n return {\n status: \"pending\",\n };\n }\n\n return {\n data: result,\n status: \"success\",\n };\n}\n\n/**\n * Construct a new {@link ReactMutation}.\n *\n * Returns a function that you can call to execute a Convex mutation. The\n * returned function is stable across renders (same reference identity), so\n * it can be safely used in dependency arrays and memoization.\n *\n * Mutations can optionally be configured with\n * [optimistic updates](https://docs.convex.dev/client/react/optimistic-updates)\n * for instant UI feedback.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @example\n * ```tsx\n * import { useMutation } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function CreateTask() {\n * const createTask = useMutation(api.tasks.create);\n *\n * const handleClick = async () => {\n * await createTask({ text: \"New task\" });\n * };\n *\n * return <button onClick={handleClick}>Add Task</button>;\n * }\n * ```\n *\n * @param mutation - A {@link server.FunctionReference} for the public mutation\n * to run like `api.dir1.dir2.filename.func`.\n * @returns The {@link ReactMutation} object with that name.\n *\n * @see https://docs.convex.dev/client/react#editing-data\n * @public\n */\nexport function useMutation<Mutation extends FunctionReference<\"mutation\">>(\n mutation: Mutation,\n): ReactMutation<Mutation> {\n const mutationReference =\n typeof mutation === \"string\"\n ? makeFunctionReference<\"mutation\", any, any>(mutation)\n : mutation;\n\n const convex = useContext(ConvexContext);\n if (convex === undefined) {\n throw new Error(\n \"Could not find Convex client! `useMutation` must be used in the React component \" +\n \"tree under `ConvexProvider`. Did you forget it? \" +\n \"See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app\",\n );\n }\n return useMemo(\n () => createMutation(mutationReference, convex),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [convex, getFunctionName(mutationReference)],\n );\n}\n\n/**\n * Construct a new {@link ReactAction}.\n *\n * Returns a function that you can call to execute a Convex action. Actions\n * can call third-party APIs and perform side effects. The returned function\n * is stable across renders (same reference identity).\n *\n * **Error handling:** Actions can fail (e.g., if an external API is down).\n * Always wrap action calls in try/catch or handle the rejected promise.\n *\n * **Note:** In most cases, calling an action directly from a client is an\n * anti-pattern. Prefer having the client call a mutation that captures the\n * user's intent (by writing to the database) and then schedules the action\n * via `ctx.scheduler.runAfter`. This ensures the intent is durably recorded\n * even if the client disconnects.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @example\n * ```tsx\n * import { useAction } from \"convex/react\";\n * import { api } from \"../convex/_generated/api\";\n *\n * function GenerateSummary() {\n * const generate = useAction(api.ai.generateSummary);\n *\n * const handleClick = async () => {\n * try {\n * const summary = await generate({ text: \"Some long text...\" });\n * console.log(summary);\n * } catch (error) {\n * console.error(\"Action failed:\", error);\n * }\n * };\n *\n * return <button onClick={handleClick}>Generate</button>;\n * }\n * ```\n *\n * @param action - A {@link server.FunctionReference} for the public action\n * to run like `api.dir1.dir2.filename.func`.\n * @returns The {@link ReactAction} object with that name.\n *\n * @see https://docs.convex.dev/functions/actions#calling-actions-from-clients\n * @public\n */\nexport function useAction<Action extends FunctionReference<\"action\">>(\n action: Action,\n): ReactAction<Action> {\n const convex = useContext(ConvexContext);\n const actionReference =\n typeof action === \"string\"\n ? makeFunctionReference<\"action\", any, any>(action)\n : action;\n\n if (convex === undefined) {\n throw new Error(\n \"Could not find Convex client! `useAction` must be used in the React component \" +\n \"tree under `ConvexProvider`. Did you forget it? \" +\n \"See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app\",\n );\n }\n return useMemo(\n () => createAction(actionReference, convex),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [convex, getFunctionName(actionReference)],\n );\n}\n\n/**\n * React hook to get the current {@link ConnectionState} and subscribe to changes.\n *\n * This hook returns the current connection state and automatically rerenders\n * when any part of the connection state changes (e.g., when going online/offline,\n * when requests start/complete, etc.).\n *\n * The shape of ConnectionState may change in the future which may cause this\n * hook to rerender more frequently.\n *\n * Throws an error if not used under {@link ConvexProvider}.\n *\n * @returns The current {@link ConnectionState} with the Convex backend.\n *\n * @public\n */\nexport function useConvexConnectionState(): ConnectionState {\n const convex = useContext(ConvexContext);\n if (convex === undefined) {\n throw new Error(\n \"Could not find Convex client! `useConvexConnectionState` must be used in the React component \" +\n \"tree under `ConvexProvider`. Did you forget it? \" +\n \"See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app\",\n );\n }\n\n const getCurrentValue = useCallback(() => {\n return convex.connectionState();\n }, [convex]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n return convex.subscribeToConnectionState(() => {\n callback();\n });\n },\n [convex],\n );\n\n return useSubscription({ getCurrentValue, subscribe });\n}\n\n// When a function is called with a single argument that looks like a\n// React SyntheticEvent it was likely called as an event handler.\nfunction assertNotAccidentalArgument(value: any) {\n // these are properties of a React.SyntheticEvent\n // https://reactjs.org/docs/events.html\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"bubbles\" in value &&\n \"persist\" in value &&\n \"isDefaultPrevented\" in value\n ) {\n throw new Error(\n `Convex function called with SyntheticEvent object. Did you use a Convex function as an event handler directly? Event handlers like onClick receive an event object as their first argument. These SyntheticEvent objects are not valid Convex values. Try wrapping the function like \\`const handler = () => myMutation();\\` and using \\`handler\\` in the event handler.`,\n );\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["currentListeners"]
7
7
  }
@@ -19,6 +19,7 @@ function useUseAuthFromClerk(useAuth) {
19
19
  getToken,
20
20
  orgId,
21
21
  orgRole,
22
+ sessionId,
22
23
  sessionClaims
23
24
  } = useAuth();
24
25
  const fetchAccessToken = useCallback(
@@ -42,7 +43,7 @@ function useUseAuthFromClerk(useAuth) {
42
43
  // Anything else from the JWT Clerk wants to be reactive goes here too.
43
44
  // Clerk's Expo useAuth hook is not memoized so we don't include getToken.
44
45
  // eslint-disable-next-line react-hooks/exhaustive-deps
45
- [orgId, orgRole]
46
+ [orgId, orgRole, sessionId]
46
47
  );
47
48
  return useMemo(
48
49
  () => ({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/react-clerk/ConvexProviderWithClerk.tsx"],
4
- "sourcesContent": ["import React from \"react\";\n\nimport { ReactNode, useCallback, useMemo } from \"react\";\nimport { AuthTokenFetcher } from \"../browser/sync/client.js\";\nimport { ConvexProviderWithAuth } from \"../react/ConvexAuthState.js\";\n\n// Until we can import from our own entry points (requires TypeScript 4.7),\n// just describe the interface enough to help users pass the right type.\ntype IConvexReactClient = {\n setAuth(fetchToken: AuthTokenFetcher): void;\n clearAuth(): void;\n};\n\n// https://clerk.com/docs/reference/clerk-react/useauth\ntype UseAuth = () => {\n isLoaded: boolean;\n isSignedIn: boolean | undefined;\n getToken: (options: {\n template?: \"convex\";\n skipCache?: boolean;\n }) => Promise<string | null>;\n // We don't use these properties but they should trigger a new token fetch.\n orgId: string | undefined | null;\n orgRole: string | undefined | null;\n sessionClaims: Record<string, unknown> | undefined | null;\n};\n\n/**\n * A wrapper React component which provides a {@link react.ConvexReactClient}\n * authenticated with Clerk.\n *\n * It must be wrapped by a configured `ClerkProvider`, from\n * `@clerk/react`, `@clerk/clerk-expo`, `@clerk/nextjs` or\n * another React-based Clerk client library and have the corresponding\n * `useAuth` hook passed in.\n *\n * See [Convex Clerk](https://docs.convex.dev/auth/clerk) on how to set up\n * Convex with Clerk.\n *\n * @public\n */\nexport function ConvexProviderWithClerk({\n children,\n client,\n useAuth,\n}: {\n children: ReactNode;\n client: IConvexReactClient;\n useAuth: UseAuth; // useAuth from Clerk\n}) {\n const useAuthFromClerk = useUseAuthFromClerk(useAuth);\n return (\n <ConvexProviderWithAuth client={client} useAuth={useAuthFromClerk}>\n {children}\n </ConvexProviderWithAuth>\n );\n}\n\nfunction useUseAuthFromClerk(useAuth: UseAuth) {\n return useMemo(\n () =>\n function useAuthFromClerk() {\n const {\n isLoaded,\n isSignedIn,\n getToken,\n orgId,\n orgRole,\n sessionClaims,\n } = useAuth();\n const fetchAccessToken = useCallback(\n async ({ forceRefreshToken }: { forceRefreshToken: boolean }) => {\n try {\n if (sessionClaims?.aud === \"convex\") {\n // Using the Convex integration\n return await getToken({\n skipCache: forceRefreshToken,\n });\n } else {\n // Using the JWT token template\n return await getToken({\n template: \"convex\",\n skipCache: forceRefreshToken,\n });\n }\n } catch {\n return null;\n }\n },\n // Build a new fetchAccessToken to trigger setAuth() whenever these change.\n // Anything else from the JWT Clerk wants to be reactive goes here too.\n // Clerk's Expo useAuth hook is not memoized so we don't include getToken.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [orgId, orgRole],\n );\n return useMemo(\n () => ({\n isLoading: !isLoaded,\n isAuthenticated: isSignedIn ?? false,\n fetchAccessToken,\n }),\n [isLoaded, isSignedIn, fetchAccessToken],\n );\n },\n [useAuth],\n );\n}\n"],
5
- "mappings": ";AAAA,OAAO,WAAW;AAElB,SAAoB,aAAa,eAAe;AAEhD,SAAS,8BAA8B;AAqChC,gBAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,mBAAmB,oBAAoB,OAAO;AACpD,SACE,oCAAC,0BAAuB,QAAgB,SAAS,oBAC9C,QACH;AAEJ;AAEA,SAAS,oBAAoB,SAAkB;AAC7C,SAAO;AAAA,IACL,MACE,SAAS,mBAAmB;AAC1B,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI,QAAQ;AACZ,YAAM,mBAAmB;AAAA,QACvB,OAAO,EAAE,kBAAkB,MAAsC;AAC/D,cAAI;AACF,gBAAI,eAAe,QAAQ,UAAU;AAEnC,qBAAO,MAAM,SAAS;AAAA,gBACpB,WAAW;AAAA,cACb,CAAC;AAAA,YACH,OAAO;AAEL,qBAAO,MAAM,SAAS;AAAA,gBACpB,UAAU;AAAA,gBACV,WAAW;AAAA,cACb,CAAC;AAAA,YACH;AAAA,UACF,QAAQ;AACN,mBAAO;AAAA,UACT;AAAA,QACF;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,CAAC,OAAO,OAAO;AAAA,MACjB;AACA,aAAO;AAAA,QACL,OAAO;AAAA,UACL,WAAW,CAAC;AAAA,UACZ,iBAAiB,cAAc;AAAA,UAC/B;AAAA,QACF;AAAA,QACA,CAAC,UAAU,YAAY,gBAAgB;AAAA,MACzC;AAAA,IACF;AAAA,IACF,CAAC,OAAO;AAAA,EACV;AACF;",
4
+ "sourcesContent": ["import React from \"react\";\n\nimport { ReactNode, useCallback, useMemo } from \"react\";\nimport { AuthTokenFetcher } from \"../browser/sync/client.js\";\nimport { ConvexProviderWithAuth } from \"../react/ConvexAuthState.js\";\n\n// Until we can import from our own entry points (requires TypeScript 4.7),\n// just describe the interface enough to help users pass the right type.\ntype IConvexReactClient = {\n setAuth(fetchToken: AuthTokenFetcher): void;\n clearAuth(): void;\n};\n\n// https://clerk.com/docs/reference/clerk-react/useauth\ntype UseAuth = () => {\n isLoaded: boolean;\n isSignedIn: boolean | undefined;\n getToken: (options: {\n template?: \"convex\";\n skipCache?: boolean;\n }) => Promise<string | null>;\n // We don't use these properties but they should trigger a new token fetch.\n orgId: string | undefined | null;\n orgRole: string | undefined | null;\n sessionId: string | undefined | null;\n sessionClaims: Record<string, unknown> | undefined | null;\n};\n\n/**\n * A wrapper React component which provides a {@link react.ConvexReactClient}\n * authenticated with Clerk.\n *\n * It must be wrapped by a configured `ClerkProvider`, from\n * `@clerk/react`, `@clerk/clerk-expo`, `@clerk/nextjs` or\n * another React-based Clerk client library and have the corresponding\n * `useAuth` hook passed in.\n *\n * See [Convex Clerk](https://docs.convex.dev/auth/clerk) on how to set up\n * Convex with Clerk.\n *\n * @public\n */\nexport function ConvexProviderWithClerk({\n children,\n client,\n useAuth,\n}: {\n children: ReactNode;\n client: IConvexReactClient;\n useAuth: UseAuth; // useAuth from Clerk\n}) {\n const useAuthFromClerk = useUseAuthFromClerk(useAuth);\n return (\n <ConvexProviderWithAuth client={client} useAuth={useAuthFromClerk}>\n {children}\n </ConvexProviderWithAuth>\n );\n}\n\nfunction useUseAuthFromClerk(useAuth: UseAuth) {\n return useMemo(\n () =>\n function useAuthFromClerk() {\n const {\n isLoaded,\n isSignedIn,\n getToken,\n orgId,\n orgRole,\n sessionId,\n sessionClaims,\n } = useAuth();\n const fetchAccessToken = useCallback(\n async ({ forceRefreshToken }: { forceRefreshToken: boolean }) => {\n try {\n if (sessionClaims?.aud === \"convex\") {\n // Using the Convex integration\n return await getToken({\n skipCache: forceRefreshToken,\n });\n } else {\n // Using the JWT token template\n return await getToken({\n template: \"convex\",\n skipCache: forceRefreshToken,\n });\n }\n } catch {\n return null;\n }\n },\n // Build a new fetchAccessToken to trigger setAuth() whenever these change.\n // Anything else from the JWT Clerk wants to be reactive goes here too.\n // Clerk's Expo useAuth hook is not memoized so we don't include getToken.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [orgId, orgRole, sessionId],\n );\n return useMemo(\n () => ({\n isLoading: !isLoaded,\n isAuthenticated: isSignedIn ?? false,\n fetchAccessToken,\n }),\n [isLoaded, isSignedIn, fetchAccessToken],\n );\n },\n [useAuth],\n );\n}\n"],
5
+ "mappings": ";AAAA,OAAO,WAAW;AAElB,SAAoB,aAAa,eAAe;AAEhD,SAAS,8BAA8B;AAsChC,gBAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,mBAAmB,oBAAoB,OAAO;AACpD,SACE,oCAAC,0BAAuB,QAAgB,SAAS,oBAC9C,QACH;AAEJ;AAEA,SAAS,oBAAoB,SAAkB;AAC7C,SAAO;AAAA,IACL,MACE,SAAS,mBAAmB;AAC1B,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,IAAI,QAAQ;AACZ,YAAM,mBAAmB;AAAA,QACvB,OAAO,EAAE,kBAAkB,MAAsC;AAC/D,cAAI;AACF,gBAAI,eAAe,QAAQ,UAAU;AAEnC,qBAAO,MAAM,SAAS;AAAA,gBACpB,WAAW;AAAA,cACb,CAAC;AAAA,YACH,OAAO;AAEL,qBAAO,MAAM,SAAS;AAAA,gBACpB,UAAU;AAAA,gBACV,WAAW;AAAA,cACb,CAAC;AAAA,YACH;AAAA,UACF,QAAQ;AACN,mBAAO;AAAA,UACT;AAAA,QACF;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,CAAC,OAAO,SAAS,SAAS;AAAA,MAC5B;AACA,aAAO;AAAA,QACL,OAAO;AAAA,UACL,WAAW,CAAC;AAAA,UACZ,iBAAiB,cAAc;AAAA,UAC/B;AAAA,QACF;AAAA,QACA,CAAC,UAAU,YAAY,gBAAgB;AAAA,MACzC;AAAA,IACF;AAAA,IACF,CAAC,OAAO;AAAA,EACV;AACF;",
6
6
  "names": []
7
7
  }
@@ -38,8 +38,8 @@ async function getDeploymentMetadata() {
38
38
  };
39
39
  }
40
40
  async function getRequestMetadata() {
41
- const { ip, userAgent, requestId, scheduledFunctionId } = await performAsyncSyscall("1.0/getRequestMetadata", {});
42
- return { ip, userAgent, requestId, scheduledFunctionId };
41
+ const { ip, userAgent, requestId, scheduledFunctionId, authToken } = await performAsyncSyscall("1.0/getRequestMetadata", {});
42
+ return { ip, userAgent, requestId, scheduledFunctionId, authToken };
43
43
  }
44
44
  export function setupQueryMeta(visibility) {
45
45
  return {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/server/impl/meta_impl.ts"],
4
- "sourcesContent": ["import { jsonToConvex } from \"../../values/index.js\";\nimport {\n ActionMeta,\n MutationMeta,\n QueryMeta,\n RequestMetadata,\n FunctionMetadata,\n TransactionMetrics,\n DeploymentMetadata,\n} from \"../meta.js\";\nimport { performAsyncSyscall } from \"./syscall.js\";\n\nasync function getTransactionMetrics(): Promise<TransactionMetrics> {\n let syscallJSON;\n try {\n syscallJSON = await performAsyncSyscall(\"1.0/getTransactionMetrics\", {});\n } catch (e: any) {\n if (e.message?.includes(\"Unknown async operation\")) {\n throw new Error(\n \"getTransactionMetrics() can only be called from a query or mutation. \" +\n \"It is not available in actions or outside of a Convex function.\",\n );\n }\n throw e;\n }\n return jsonToConvex(syscallJSON) as any;\n}\n\nasync function getFunctionMetadata(): Promise<{\n name: string;\n componentPath: string;\n}> {\n const { name, componentPath } = await performAsyncSyscall(\n \"1.0/getFunctionMetadata\",\n {},\n );\n return {\n name,\n componentPath,\n };\n}\n\nasync function getDeploymentMetadata(): Promise<DeploymentMetadata> {\n const syscallJSON = await performAsyncSyscall(\n \"1.0/getDeploymentMetadata\",\n {},\n );\n const result = jsonToConvex(syscallJSON) as any;\n return {\n name: result.name,\n region: result.region ?? null,\n class: result.class,\n };\n}\n\nasync function getRequestMetadata(): Promise<RequestMetadata> {\n const { ip, userAgent, requestId, scheduledFunctionId } =\n await performAsyncSyscall(\"1.0/getRequestMetadata\", {});\n return { ip, userAgent, requestId, scheduledFunctionId };\n}\n\nexport function setupQueryMeta(\n visibility: FunctionMetadata[\"visibility\"],\n): QueryMeta {\n return {\n getFunctionMetadata: async () => ({\n ...(await getFunctionMetadata()),\n type: \"query\",\n visibility,\n }),\n getTransactionMetrics,\n getDeploymentMetadata,\n };\n}\n\nexport function setupMutationMeta(\n visibility: FunctionMetadata[\"visibility\"],\n): MutationMeta {\n return {\n getFunctionMetadata: async () => ({\n ...(await getFunctionMetadata()),\n type: \"mutation\",\n visibility,\n }),\n getTransactionMetrics,\n getDeploymentMetadata,\n getRequestMetadata,\n };\n}\n\nexport function setupActionMeta(\n visibility: FunctionMetadata[\"visibility\"],\n): ActionMeta {\n return {\n getFunctionMetadata: async () => ({\n ...(await getFunctionMetadata()),\n type: \"action\",\n visibility,\n }),\n getDeploymentMetadata,\n getRequestMetadata,\n };\n}\n"],
5
- "mappings": ";AAAA,SAAS,oBAAoB;AAU7B,SAAS,2BAA2B;AAEpC,eAAe,wBAAqD;AAClE,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,oBAAoB,6BAA6B,CAAC,CAAC;AAAA,EACzE,SAAS,GAAQ;AACf,QAAI,EAAE,SAAS,SAAS,yBAAyB,GAAG;AAClD,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACA,SAAO,aAAa,WAAW;AACjC;AAEA,eAAe,sBAGZ;AACD,QAAM,EAAE,MAAM,cAAc,IAAI,MAAM;AAAA,IACpC;AAAA,IACA,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,wBAAqD;AAClE,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA,CAAC;AAAA,EACH;AACA,QAAM,SAAS,aAAa,WAAW;AACvC,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO,UAAU;AAAA,IACzB,OAAO,OAAO;AAAA,EAChB;AACF;AAEA,eAAe,qBAA+C;AAC5D,QAAM,EAAE,IAAI,WAAW,WAAW,oBAAoB,IACpD,MAAM,oBAAoB,0BAA0B,CAAC,CAAC;AACxD,SAAO,EAAE,IAAI,WAAW,WAAW,oBAAoB;AACzD;AAEO,gBAAS,eACd,YACW;AACX,SAAO;AAAA,IACL,qBAAqB,aAAa;AAAA,MAChC,GAAI,MAAM,oBAAoB;AAAA,MAC9B,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,gBAAS,kBACd,YACc;AACd,SAAO;AAAA,IACL,qBAAqB,aAAa;AAAA,MAChC,GAAI,MAAM,oBAAoB;AAAA,MAC9B,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,gBAAS,gBACd,YACY;AACZ,SAAO;AAAA,IACL,qBAAqB,aAAa;AAAA,MAChC,GAAI,MAAM,oBAAoB;AAAA,MAC9B,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { jsonToConvex } from \"../../values/index.js\";\nimport {\n ActionMeta,\n MutationMeta,\n QueryMeta,\n RequestMetadata,\n FunctionMetadata,\n TransactionMetrics,\n DeploymentMetadata,\n} from \"../meta.js\";\nimport { performAsyncSyscall } from \"./syscall.js\";\n\nasync function getTransactionMetrics(): Promise<TransactionMetrics> {\n let syscallJSON;\n try {\n syscallJSON = await performAsyncSyscall(\"1.0/getTransactionMetrics\", {});\n } catch (e: any) {\n if (e.message?.includes(\"Unknown async operation\")) {\n throw new Error(\n \"getTransactionMetrics() can only be called from a query or mutation. \" +\n \"It is not available in actions or outside of a Convex function.\",\n );\n }\n throw e;\n }\n return jsonToConvex(syscallJSON) as any;\n}\n\nasync function getFunctionMetadata(): Promise<{\n name: string;\n componentPath: string;\n}> {\n const { name, componentPath } = await performAsyncSyscall(\n \"1.0/getFunctionMetadata\",\n {},\n );\n return {\n name,\n componentPath,\n };\n}\n\nasync function getDeploymentMetadata(): Promise<DeploymentMetadata> {\n const syscallJSON = await performAsyncSyscall(\n \"1.0/getDeploymentMetadata\",\n {},\n );\n const result = jsonToConvex(syscallJSON) as any;\n return {\n name: result.name,\n region: result.region ?? null,\n class: result.class,\n };\n}\n\nasync function getRequestMetadata(): Promise<RequestMetadata> {\n const { ip, userAgent, requestId, scheduledFunctionId, authToken } =\n await performAsyncSyscall(\"1.0/getRequestMetadata\", {});\n return { ip, userAgent, requestId, scheduledFunctionId, authToken };\n}\n\nexport function setupQueryMeta(\n visibility: FunctionMetadata[\"visibility\"],\n): QueryMeta {\n return {\n getFunctionMetadata: async () => ({\n ...(await getFunctionMetadata()),\n type: \"query\",\n visibility,\n }),\n getTransactionMetrics,\n getDeploymentMetadata,\n };\n}\n\nexport function setupMutationMeta(\n visibility: FunctionMetadata[\"visibility\"],\n): MutationMeta {\n return {\n getFunctionMetadata: async () => ({\n ...(await getFunctionMetadata()),\n type: \"mutation\",\n visibility,\n }),\n getTransactionMetrics,\n getDeploymentMetadata,\n getRequestMetadata,\n };\n}\n\nexport function setupActionMeta(\n visibility: FunctionMetadata[\"visibility\"],\n): ActionMeta {\n return {\n getFunctionMetadata: async () => ({\n ...(await getFunctionMetadata()),\n type: \"action\",\n visibility,\n }),\n getDeploymentMetadata,\n getRequestMetadata,\n };\n}\n"],
5
+ "mappings": ";AAAA,SAAS,oBAAoB;AAU7B,SAAS,2BAA2B;AAEpC,eAAe,wBAAqD;AAClE,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,oBAAoB,6BAA6B,CAAC,CAAC;AAAA,EACzE,SAAS,GAAQ;AACf,QAAI,EAAE,SAAS,SAAS,yBAAyB,GAAG;AAClD,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACA,SAAO,aAAa,WAAW;AACjC;AAEA,eAAe,sBAGZ;AACD,QAAM,EAAE,MAAM,cAAc,IAAI,MAAM;AAAA,IACpC;AAAA,IACA,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,wBAAqD;AAClE,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA,CAAC;AAAA,EACH;AACA,QAAM,SAAS,aAAa,WAAW;AACvC,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO,UAAU;AAAA,IACzB,OAAO,OAAO;AAAA,EAChB;AACF;AAEA,eAAe,qBAA+C;AAC5D,QAAM,EAAE,IAAI,WAAW,WAAW,qBAAqB,UAAU,IAC/D,MAAM,oBAAoB,0BAA0B,CAAC,CAAC;AACxD,SAAO,EAAE,IAAI,WAAW,WAAW,qBAAqB,UAAU;AACpE;AAEO,gBAAS,eACd,YACW;AACX,SAAO;AAAA,IACL,qBAAqB,aAAa;AAAA,MAChC,GAAI,MAAM,oBAAoB;AAAA,MAC9B,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,gBAAS,kBACd,YACc;AACd,SAAO;AAAA,IACL,qBAAqB,aAAa;AAAA,MAChC,GAAI,MAAM,oBAAoB;AAAA,MAC9B,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,gBAAS,gBACd,YACY;AACZ,SAAO;AAAA,IACL,qBAAqB,aAAa;AAAA,MAChC,GAAI,MAAM,oBAAoB;AAAA,MAC9B,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/server/impl/query_impl.ts"],
4
- "sourcesContent": ["import { Value, JSONValue, jsonToConvex } from \"../../values/index.js\";\nimport { PaginationResult, PaginationOptions } from \"../pagination.js\";\nimport { performAsyncSyscall, performSyscall } from \"./syscall.js\";\nimport {\n filterBuilderImpl,\n serializeExpression,\n} from \"./filter_builder_impl.js\";\nimport { Query, QueryInitializer } from \"../query.js\";\nimport { ExpressionOrValue, FilterBuilder } from \"../filter_builder.js\";\nimport { GenericTableInfo } from \"../data_model.js\";\nimport {\n IndexRangeBuilderImpl,\n SerializedRangeExpression,\n} from \"./index_range_builder_impl.js\";\nimport {\n SearchFilterBuilderImpl,\n SerializedSearchFilter,\n} from \"./search_filter_builder_impl.js\";\nimport { validateArg, validateArgIsNonNegativeInteger } from \"./validate.js\";\nimport { version } from \"../../index.js\";\n\nconst MAX_QUERY_OPERATORS = 256;\n\ntype QueryOperator = { filter: JSONValue } | { limit: number };\ntype Source =\n | { type: \"FullTableScan\"; tableName: string; order: \"asc\" | \"desc\" | null }\n | {\n type: \"IndexRange\";\n indexName: string;\n range: ReadonlyArray<SerializedRangeExpression>;\n order: \"asc\" | \"desc\" | null;\n }\n | {\n type: \"Search\";\n indexName: string;\n filters: ReadonlyArray<SerializedSearchFilter>;\n };\n\ntype SerializedQuery = {\n source: Source;\n operators: Array<QueryOperator>;\n};\n\nexport class QueryInitializerImpl\n implements QueryInitializer<GenericTableInfo>\n{\n private tableName: string;\n\n constructor(tableName: string) {\n this.tableName = tableName;\n }\n\n withIndex(\n indexName: string,\n indexRange?: (q: IndexRangeBuilderImpl) => IndexRangeBuilderImpl,\n ): QueryImpl {\n validateArg(indexName, 1, \"withIndex\", \"indexName\");\n let rangeBuilder = IndexRangeBuilderImpl.new();\n if (indexRange !== undefined) {\n rangeBuilder = indexRange(rangeBuilder);\n }\n return new QueryImpl({\n source: {\n type: \"IndexRange\",\n indexName: this.tableName + \".\" + indexName,\n range: rangeBuilder.export(),\n order: null,\n },\n operators: [],\n });\n }\n\n withSearchIndex(\n indexName: string,\n searchFilter: (q: SearchFilterBuilderImpl) => SearchFilterBuilderImpl,\n ): QueryImpl {\n validateArg(indexName, 1, \"withSearchIndex\", \"indexName\");\n validateArg(searchFilter, 2, \"withSearchIndex\", \"searchFilter\");\n const searchFilterBuilder = SearchFilterBuilderImpl.new();\n return new QueryImpl({\n source: {\n type: \"Search\",\n indexName: this.tableName + \".\" + indexName,\n filters: searchFilter(searchFilterBuilder).export(),\n },\n operators: [],\n });\n }\n\n fullTableScan(): QueryImpl {\n return new QueryImpl({\n source: {\n type: \"FullTableScan\",\n tableName: this.tableName,\n order: null,\n },\n operators: [],\n });\n }\n\n order(order: \"asc\" | \"desc\"): QueryImpl {\n return this.fullTableScan().order(order);\n }\n\n // This is internal API and should not be exposed to developers yet.\n async count(): Promise<number> {\n const syscallJSON = await performAsyncSyscall(\"1.0/count\", {\n table: this.tableName,\n });\n const syscallResult = jsonToConvex(syscallJSON) as number;\n return syscallResult;\n }\n\n filter(\n predicate: (\n q: FilterBuilder<GenericTableInfo>,\n ) => ExpressionOrValue<boolean>,\n ) {\n return this.fullTableScan().filter(predicate);\n }\n\n limit(n: number) {\n return this.fullTableScan().limit(n);\n }\n\n collect(): Promise<any[]> {\n return this.fullTableScan().collect();\n }\n\n take(n: number): Promise<Array<any>> {\n return this.fullTableScan().take(n);\n }\n\n paginate(paginationOpts: PaginationOptions): Promise<PaginationResult<any>> {\n return this.fullTableScan().paginate(paginationOpts);\n }\n\n first(): Promise<any> {\n return this.fullTableScan().first();\n }\n\n unique(): Promise<any> {\n return this.fullTableScan().unique();\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<any> {\n return this.fullTableScan()[Symbol.asyncIterator]();\n }\n}\n\n/**\n * @param type Whether the query was consumed or closed.\n * @throws An error indicating the query has been closed.\n */\nfunction throwClosedError(type: \"closed\" | \"consumed\"): never {\n throw new Error(\n type === \"consumed\"\n ? \"This query is closed and can't emit any more values.\"\n : \"This query has been chained with another operator and can't be reused.\",\n );\n}\n\nexport class QueryImpl implements Query<GenericTableInfo> {\n private state:\n | { type: \"preparing\"; query: SerializedQuery }\n | { type: \"executing\"; queryId: number }\n | { type: \"closed\" }\n | { type: \"consumed\" };\n private tableNameForErrorMessages: string;\n\n constructor(query: SerializedQuery) {\n this.state = { type: \"preparing\", query };\n if (query.source.type === \"FullTableScan\") {\n this.tableNameForErrorMessages = query.source.tableName;\n } else {\n this.tableNameForErrorMessages = query.source.indexName.split(\".\")[0];\n }\n }\n\n private takeQuery(): SerializedQuery {\n if (this.state.type !== \"preparing\") {\n throw new Error(\n \"A query can only be chained once and can't be chained after iteration begins.\",\n );\n }\n const query = this.state.query;\n this.state = { type: \"closed\" };\n return query;\n }\n\n private startQuery(): number {\n if (this.state.type === \"executing\") {\n throw new Error(\"Iteration can only begin on a query once.\");\n }\n if (this.state.type === \"closed\" || this.state.type === \"consumed\") {\n throwClosedError(this.state.type);\n }\n const query = this.state.query;\n const { queryId } = performSyscall(\"1.0/queryStream\", { query, version });\n this.state = { type: \"executing\", queryId };\n return queryId;\n }\n\n private closeQuery() {\n if (this.state.type === \"executing\") {\n const queryId = this.state.queryId;\n performSyscall(\"1.0/queryCleanup\", { queryId });\n }\n this.state = { type: \"consumed\" };\n }\n\n order(order: \"asc\" | \"desc\"): QueryImpl {\n validateArg(order, 1, \"order\", \"order\");\n const query = this.takeQuery();\n if (query.source.type === \"Search\") {\n throw new Error(\n \"Search queries must always be in relevance order. Can not set order manually.\",\n );\n }\n if (query.source.order !== null) {\n throw new Error(\"Queries may only specify order at most once\");\n }\n query.source.order = order;\n return new QueryImpl(query);\n }\n\n filter(\n predicate: (\n q: FilterBuilder<GenericTableInfo>,\n ) => ExpressionOrValue<boolean>,\n ): any {\n validateArg(predicate, 1, \"filter\", \"predicate\");\n const query = this.takeQuery();\n if (query.operators.length >= MAX_QUERY_OPERATORS) {\n throw new Error(\n `Can't construct query with more than ${MAX_QUERY_OPERATORS} operators`,\n );\n }\n query.operators.push({\n filter: serializeExpression(predicate(filterBuilderImpl)),\n });\n return new QueryImpl(query);\n }\n\n limit(n: number): any {\n validateArg(n, 1, \"limit\", \"n\");\n const query = this.takeQuery();\n query.operators.push({ limit: n });\n return new QueryImpl(query);\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<any> {\n this.startQuery();\n return this;\n }\n\n async next(): Promise<IteratorResult<any>> {\n if (this.state.type === \"closed\" || this.state.type === \"consumed\") {\n throwClosedError(this.state.type);\n }\n // Allow calling `.next()` when the query is in \"preparing\" state to implicitly start the\n // query. This allows the developer to call `.next()` on the query without having to use\n // a `for await` statement.\n const queryId =\n this.state.type === \"preparing\" ? this.startQuery() : this.state.queryId;\n const { value, done } = await performAsyncSyscall(\"1.0/queryStreamNext\", {\n queryId,\n });\n if (done) {\n this.closeQuery();\n }\n const convexValue = jsonToConvex(value);\n return { value: convexValue, done };\n }\n\n return() {\n this.closeQuery();\n return Promise.resolve({ done: true, value: undefined });\n }\n\n async paginate(\n paginationOpts: PaginationOptions,\n ): Promise<PaginationResult<any>> {\n validateArg(paginationOpts, 1, \"paginate\", \"options\");\n if (\n typeof paginationOpts?.numItems !== \"number\" ||\n paginationOpts.numItems < 0\n ) {\n throw new Error(\n `\\`options.numItems\\` must be a positive number. Received \\`${paginationOpts?.numItems}\\`.`,\n );\n }\n const query = this.takeQuery();\n const pageSize = paginationOpts.numItems;\n const cursor = paginationOpts.cursor;\n const endCursor = paginationOpts?.endCursor ?? null;\n const maximumRowsRead = paginationOpts.maximumRowsRead ?? null;\n const { page, isDone, continueCursor, splitCursor, pageStatus } =\n await performAsyncSyscall(\"1.0/queryPage\", {\n query,\n cursor,\n endCursor,\n pageSize,\n maximumRowsRead,\n maximumBytesRead: paginationOpts.maximumBytesRead,\n version,\n });\n return {\n page: page.map((json: string) => jsonToConvex(json)),\n isDone,\n continueCursor,\n splitCursor,\n pageStatus,\n };\n }\n\n async collect(): Promise<Array<any>> {\n const out: Value[] = [];\n for await (const item of this) {\n out.push(item);\n }\n return out;\n }\n\n async take(n: number): Promise<Array<any>> {\n validateArg(n, 1, \"take\", \"n\");\n validateArgIsNonNegativeInteger(n, 1, \"take\", \"n\");\n return this.limit(n).collect();\n }\n\n async first(): Promise<any | null> {\n const first_array = await this.take(1);\n return first_array.length === 0 ? null : first_array[0];\n }\n\n async unique(): Promise<any | null> {\n const first_two_array = await this.take(2);\n if (first_two_array.length === 0) {\n return null;\n }\n if (first_two_array.length === 2) {\n throw new Error(`unique() query returned more than one result from table ${this.tableNameForErrorMessages}:\n [${first_two_array[0]._id}, ${first_two_array[1]._id}, ...]`);\n }\n return first_two_array[0];\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Value, JSONValue, jsonToConvex } from \"../../values/index.js\";\nimport { PaginationResult, PaginationOptions } from \"../pagination.js\";\nimport { performAsyncSyscall, performSyscall } from \"./syscall.js\";\nimport {\n filterBuilderImpl,\n serializeExpression,\n} from \"./filter_builder_impl.js\";\nimport { Query, QueryInitializer } from \"../query.js\";\nimport { ExpressionOrValue, FilterBuilder } from \"../filter_builder.js\";\nimport { GenericTableInfo } from \"../data_model.js\";\nimport {\n IndexRangeBuilderImpl,\n SerializedRangeExpression,\n} from \"./index_range_builder_impl.js\";\nimport {\n SearchFilterBuilderImpl,\n SerializedSearchFilter,\n} from \"./search_filter_builder_impl.js\";\nimport { validateArg, validateArgIsNonNegativeInteger } from \"./validate.js\";\nimport { version } from \"../../index.js\";\n\nconst MAX_QUERY_OPERATORS = 256;\n\ntype QueryOperator = { filter: JSONValue } | { limit: number };\ntype Source =\n | { type: \"FullTableScan\"; tableName: string; order: \"asc\" | \"desc\" | null }\n | {\n type: \"IndexRange\";\n indexName: string;\n range: ReadonlyArray<SerializedRangeExpression>;\n order: \"asc\" | \"desc\" | null;\n }\n | {\n type: \"Search\";\n indexName: string;\n filters: ReadonlyArray<SerializedSearchFilter>;\n };\n\ntype SerializedQuery = {\n source: Source;\n operators: Array<QueryOperator>;\n};\n\nexport class QueryInitializerImpl implements QueryInitializer<GenericTableInfo> {\n private tableName: string;\n\n constructor(tableName: string) {\n this.tableName = tableName;\n }\n\n withIndex(\n indexName: string,\n indexRange?: (q: IndexRangeBuilderImpl) => IndexRangeBuilderImpl,\n ): QueryImpl {\n validateArg(indexName, 1, \"withIndex\", \"indexName\");\n let rangeBuilder = IndexRangeBuilderImpl.new();\n if (indexRange !== undefined) {\n rangeBuilder = indexRange(rangeBuilder);\n }\n return new QueryImpl({\n source: {\n type: \"IndexRange\",\n indexName: this.tableName + \".\" + indexName,\n range: rangeBuilder.export(),\n order: null,\n },\n operators: [],\n });\n }\n\n withSearchIndex(\n indexName: string,\n searchFilter: (q: SearchFilterBuilderImpl) => SearchFilterBuilderImpl,\n ): QueryImpl {\n validateArg(indexName, 1, \"withSearchIndex\", \"indexName\");\n validateArg(searchFilter, 2, \"withSearchIndex\", \"searchFilter\");\n const searchFilterBuilder = SearchFilterBuilderImpl.new();\n return new QueryImpl({\n source: {\n type: \"Search\",\n indexName: this.tableName + \".\" + indexName,\n filters: searchFilter(searchFilterBuilder).export(),\n },\n operators: [],\n });\n }\n\n fullTableScan(): QueryImpl {\n return new QueryImpl({\n source: {\n type: \"FullTableScan\",\n tableName: this.tableName,\n order: null,\n },\n operators: [],\n });\n }\n\n order(order: \"asc\" | \"desc\"): QueryImpl {\n return this.fullTableScan().order(order);\n }\n\n // This is internal API and should not be exposed to developers yet.\n async count(): Promise<number> {\n const syscallJSON = await performAsyncSyscall(\"1.0/count\", {\n table: this.tableName,\n });\n const syscallResult = jsonToConvex(syscallJSON) as number;\n return syscallResult;\n }\n\n filter(\n predicate: (\n q: FilterBuilder<GenericTableInfo>,\n ) => ExpressionOrValue<boolean>,\n ) {\n return this.fullTableScan().filter(predicate);\n }\n\n limit(n: number) {\n return this.fullTableScan().limit(n);\n }\n\n collect(): Promise<any[]> {\n return this.fullTableScan().collect();\n }\n\n take(n: number): Promise<Array<any>> {\n return this.fullTableScan().take(n);\n }\n\n paginate(paginationOpts: PaginationOptions): Promise<PaginationResult<any>> {\n return this.fullTableScan().paginate(paginationOpts);\n }\n\n first(): Promise<any> {\n return this.fullTableScan().first();\n }\n\n unique(): Promise<any> {\n return this.fullTableScan().unique();\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<any> {\n return this.fullTableScan()[Symbol.asyncIterator]();\n }\n}\n\n/**\n * @param type Whether the query was consumed or closed.\n * @throws An error indicating the query has been closed.\n */\nfunction throwClosedError(type: \"closed\" | \"consumed\"): never {\n throw new Error(\n type === \"consumed\"\n ? \"This query is closed and can't emit any more values.\"\n : \"This query has been chained with another operator and can't be reused.\",\n );\n}\n\nexport class QueryImpl implements Query<GenericTableInfo> {\n private state:\n | { type: \"preparing\"; query: SerializedQuery }\n | { type: \"executing\"; queryId: number }\n | { type: \"closed\" }\n | { type: \"consumed\" };\n private tableNameForErrorMessages: string;\n\n constructor(query: SerializedQuery) {\n this.state = { type: \"preparing\", query };\n if (query.source.type === \"FullTableScan\") {\n this.tableNameForErrorMessages = query.source.tableName;\n } else {\n this.tableNameForErrorMessages = query.source.indexName.split(\".\")[0];\n }\n }\n\n private takeQuery(): SerializedQuery {\n if (this.state.type !== \"preparing\") {\n throw new Error(\n \"A query can only be chained once and can't be chained after iteration begins.\",\n );\n }\n const query = this.state.query;\n this.state = { type: \"closed\" };\n return query;\n }\n\n private startQuery(): number {\n if (this.state.type === \"executing\") {\n throw new Error(\"Iteration can only begin on a query once.\");\n }\n if (this.state.type === \"closed\" || this.state.type === \"consumed\") {\n throwClosedError(this.state.type);\n }\n const query = this.state.query;\n const { queryId } = performSyscall(\"1.0/queryStream\", { query, version });\n this.state = { type: \"executing\", queryId };\n return queryId;\n }\n\n private closeQuery() {\n if (this.state.type === \"executing\") {\n const queryId = this.state.queryId;\n performSyscall(\"1.0/queryCleanup\", { queryId });\n }\n this.state = { type: \"consumed\" };\n }\n\n order(order: \"asc\" | \"desc\"): QueryImpl {\n validateArg(order, 1, \"order\", \"order\");\n const query = this.takeQuery();\n if (query.source.type === \"Search\") {\n throw new Error(\n \"Search queries must always be in relevance order. Can not set order manually.\",\n );\n }\n if (query.source.order !== null) {\n throw new Error(\"Queries may only specify order at most once\");\n }\n query.source.order = order;\n return new QueryImpl(query);\n }\n\n filter(\n predicate: (\n q: FilterBuilder<GenericTableInfo>,\n ) => ExpressionOrValue<boolean>,\n ): any {\n validateArg(predicate, 1, \"filter\", \"predicate\");\n const query = this.takeQuery();\n if (query.operators.length >= MAX_QUERY_OPERATORS) {\n throw new Error(\n `Can't construct query with more than ${MAX_QUERY_OPERATORS} operators`,\n );\n }\n query.operators.push({\n filter: serializeExpression(predicate(filterBuilderImpl)),\n });\n return new QueryImpl(query);\n }\n\n limit(n: number): any {\n validateArg(n, 1, \"limit\", \"n\");\n const query = this.takeQuery();\n query.operators.push({ limit: n });\n return new QueryImpl(query);\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<any> {\n this.startQuery();\n return this;\n }\n\n async next(): Promise<IteratorResult<any>> {\n if (this.state.type === \"closed\" || this.state.type === \"consumed\") {\n throwClosedError(this.state.type);\n }\n // Allow calling `.next()` when the query is in \"preparing\" state to implicitly start the\n // query. This allows the developer to call `.next()` on the query without having to use\n // a `for await` statement.\n const queryId =\n this.state.type === \"preparing\" ? this.startQuery() : this.state.queryId;\n const { value, done } = await performAsyncSyscall(\"1.0/queryStreamNext\", {\n queryId,\n });\n if (done) {\n this.closeQuery();\n }\n const convexValue = jsonToConvex(value);\n return { value: convexValue, done };\n }\n\n return() {\n this.closeQuery();\n return Promise.resolve({ done: true, value: undefined });\n }\n\n async paginate(\n paginationOpts: PaginationOptions,\n ): Promise<PaginationResult<any>> {\n validateArg(paginationOpts, 1, \"paginate\", \"options\");\n if (\n typeof paginationOpts?.numItems !== \"number\" ||\n paginationOpts.numItems < 0\n ) {\n throw new Error(\n `\\`options.numItems\\` must be a positive number. Received \\`${paginationOpts?.numItems}\\`.`,\n );\n }\n const query = this.takeQuery();\n const pageSize = paginationOpts.numItems;\n const cursor = paginationOpts.cursor;\n const endCursor = paginationOpts?.endCursor ?? null;\n const maximumRowsRead = paginationOpts.maximumRowsRead ?? null;\n const { page, isDone, continueCursor, splitCursor, pageStatus } =\n await performAsyncSyscall(\"1.0/queryPage\", {\n query,\n cursor,\n endCursor,\n pageSize,\n maximumRowsRead,\n maximumBytesRead: paginationOpts.maximumBytesRead,\n version,\n });\n return {\n page: page.map((json: string) => jsonToConvex(json)),\n isDone,\n continueCursor,\n splitCursor,\n pageStatus,\n };\n }\n\n async collect(): Promise<Array<any>> {\n const out: Value[] = [];\n for await (const item of this) {\n out.push(item);\n }\n return out;\n }\n\n async take(n: number): Promise<Array<any>> {\n validateArg(n, 1, \"take\", \"n\");\n validateArgIsNonNegativeInteger(n, 1, \"take\", \"n\");\n return this.limit(n).collect();\n }\n\n async first(): Promise<any | null> {\n const first_array = await this.take(1);\n return first_array.length === 0 ? null : first_array[0];\n }\n\n async unique(): Promise<any | null> {\n const first_two_array = await this.take(2);\n if (first_two_array.length === 0) {\n return null;\n }\n if (first_two_array.length === 2) {\n throw new Error(`unique() query returned more than one result from table ${this.tableNameForErrorMessages}:\n [${first_two_array[0]._id}, ${first_two_array[1]._id}, ...]`);\n }\n return first_two_array[0];\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/server/schema.ts"],
4
- "sourcesContent": ["/**\n * Utilities for defining the schema of your Convex project.\n *\n * ## Usage\n *\n * Schemas should be placed in a `schema.ts` file in your `convex/` directory.\n *\n * Schema definitions should be built using {@link defineSchema},\n * {@link defineTable}, and {@link values.v}. Make sure to export the schema as the\n * default export.\n *\n * ```ts\n * import { defineSchema, defineTable } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * export default defineSchema({\n * messages: defineTable({\n * body: v.string(),\n * user: v.id(\"users\"),\n * }),\n * users: defineTable({\n * name: v.string(),\n * }),\n * });\n * ```\n *\n * To learn more about schemas, see [Defining a Schema](https://docs.convex.dev/using/schemas).\n * @module\n */\nimport {\n AnyDataModel,\n GenericDataModel,\n GenericTableIndexes,\n GenericTableSearchIndexes,\n GenericTableVectorIndexes,\n TableNamesInDataModel,\n} from \"../server/data_model.js\";\nimport {\n IdField,\n IndexTiebreakerField,\n SystemFields,\n SystemIndexes,\n} from \"../server/system_fields.js\";\nimport { Expand } from \"../type_utils.js\";\nimport {\n GenericValidator,\n ObjectType,\n isValidator,\n v,\n} from \"../values/validator.js\";\nimport { VObject, Validator } from \"../values/validators.js\";\n\n/**\n * Extract all of the index field paths within a {@link Validator}.\n *\n * This is used within {@link defineTable}.\n * @public\n */\ntype ExtractFieldPaths<T extends Validator<any, any, any>> =\n // Add in the system fields available in index definitions.\n // This should be everything except for `_id` because thats added to indexes\n // automatically.\n T[\"fieldPaths\"] | keyof SystemFields;\n\n/**\n * Extract the {@link GenericDocument} within a {@link Validator} and\n * add on the system fields.\n *\n * This is used within {@link defineTable}.\n * @public\n */\ntype ExtractDocument<T extends Validator<any, any, any>> =\n // Add the system fields to `Value` (except `_id` because it depends on\n //the table name) and trick TypeScript into expanding them.\n Expand<SystemFields & T[\"type\"]>;\n\nexport interface DbIndexConfig<\n FirstFieldPath extends string,\n RestFieldPaths extends string[],\n> {\n /**\n * The fields to index, in order. Must specify at least one field.\n */\n fields: [FirstFieldPath, ...RestFieldPaths];\n}\n\n/**\n * The configuration for a full text search index.\n *\n * @public\n */\nexport interface SearchIndexConfig<\n SearchField extends string,\n FilterFields extends string,\n> {\n /**\n * The field to index for full text search.\n *\n * This must be a field of type `string`.\n */\n searchField: SearchField;\n\n /**\n * Additional fields to index for fast filtering when running search queries.\n */\n filterFields?: FilterFields[];\n}\n\n/**\n * The configuration for a vector index.\n *\n * @public\n */\nexport interface VectorIndexConfig<\n VectorField extends string,\n FilterFields extends string,\n> {\n /**\n * The field to index for vector search.\n *\n * This must be a field of type `v.array(v.float64())` (or a union)\n */\n vectorField: VectorField;\n /**\n * The length of the vectors indexed. This must be between 2 and 2048 inclusive.\n */\n dimensions: number;\n /**\n * Additional fields to index for fast filtering when running vector searches.\n */\n filterFields?: FilterFields[];\n}\n\n/**\n * @internal\n */\nexport type VectorIndex = {\n indexDescriptor: string;\n vectorField: string;\n dimensions: number;\n filterFields: string[];\n};\n\n/**\n * @internal\n */\nexport type Index = {\n indexDescriptor: string;\n fields: string[];\n};\n\n/**\n * @internal\n */\nexport type SearchIndex = {\n indexDescriptor: string;\n searchField: string;\n filterFields: string[];\n};\n\n/**\n * Options for defining an index.\n *\n * @public\n */\nexport interface IndexOptions {\n /**\n * Whether the index should be staged.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n */\n staged?: boolean;\n}\n\n/**\n * The definition of a table within a schema.\n *\n * This should be produced by using {@link defineTable}.\n * @public\n */\nexport class TableDefinition<\n DocumentType extends Validator<any, any, any> = Validator<any, any, any>,\n Indexes extends GenericTableIndexes = {},\n SearchIndexes extends GenericTableSearchIndexes = {},\n VectorIndexes extends GenericTableVectorIndexes = {},\n> {\n private indexes: Index[];\n private stagedDbIndexes: Index[];\n private searchIndexes: SearchIndex[];\n private stagedSearchIndexes: SearchIndex[];\n private vectorIndexes: VectorIndex[];\n private stagedVectorIndexes: VectorIndex[];\n // The type of documents stored in this table.\n validator: DocumentType;\n\n /**\n * @internal\n */\n constructor(documentType: DocumentType) {\n this.indexes = [];\n this.stagedDbIndexes = [];\n this.searchIndexes = [];\n this.stagedSearchIndexes = [];\n this.vectorIndexes = [];\n this.stagedVectorIndexes = [];\n this.validator = documentType;\n }\n\n /**\n * This API is experimental: it may change or disappear.\n *\n * Returns indexes defined on this table.\n * Intended for the advanced use cases of dynamically deciding which index to use for a query.\n * If you think you need this, please chime in on ths issue in the Convex JS GitHub repo.\n * https://github.com/get-convex/convex-js/issues/49\n */\n \" indexes\"(): { indexDescriptor: string; fields: string[] }[] {\n return this.indexes;\n }\n\n /**\n * Define an index on this table.\n *\n * Indexes speed up queries by allowing efficient lookups on specific fields.\n * Use `.withIndex()` in your queries to leverage them.\n *\n * Index fields must be queried in the same order they are defined. If you\n * need to query by `field2` then `field1`, create a separate index with\n * that field order.\n *\n * @example\n * ```ts\n * defineTable({\n * userId: v.id(\"users\"),\n * status: v.string(),\n * updatedAt: v.number(),\n * })\n * // Name indexes after their fields:\n * .index(\"by_userId\", [\"userId\"])\n * .index(\"by_status_updatedAt\", [\"status\", \"updatedAt\"])\n * ```\n *\n * **Best practice:** Always include all index fields in the index name\n * (e.g., `\"by_field1_and_field2\"`).\n *\n * @param name - The name of the index.\n * @param indexConfig - The index configuration object.\n * @returns A {@link TableDefinition} with this index included.\n *\n * @see https://docs.convex.dev/database/reading-data/indexes\n */\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n indexConfig: Expand<\n DbIndexConfig<FirstFieldPath, RestFieldPaths> &\n IndexOptions & { staged?: false }\n >,\n ): TableDefinition<\n DocumentType,\n Expand<\n Indexes &\n Record<\n IndexName,\n [FirstFieldPath, ...RestFieldPaths, IndexTiebreakerField]\n >\n >,\n SearchIndexes,\n VectorIndexes\n >;\n\n /**\n * Define an index on this table.\n *\n * To learn about indexes, see [Defining Indexes](https://docs.convex.dev/database/reading-data/indexes).\n *\n * @param name - The name of the index.\n * @param fields - The fields to index, in order. Must specify at least one\n * field.\n * @returns A {@link TableDefinition} with this index included.\n */\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n fields: [FirstFieldPath, ...RestFieldPaths],\n ): TableDefinition<\n DocumentType,\n Expand<\n Indexes &\n Record<\n IndexName,\n [FirstFieldPath, ...RestFieldPaths, IndexTiebreakerField]\n >\n >,\n SearchIndexes,\n VectorIndexes\n >;\n\n /**\n * Define a staged index on this table.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n *\n * To learn about indexes, see [Defining Indexes](https://docs.convex.dev/using/indexes).\n *\n * @param name - The name of the index.\n * @param indexConfig - The index configuration object.\n * @returns A {@link TableDefinition} with this index included.\n */\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n indexConfig: Expand<\n DbIndexConfig<FirstFieldPath, RestFieldPaths> &\n IndexOptions & { staged: true }\n >,\n ): TableDefinition<DocumentType, Indexes, SearchIndexes, VectorIndexes>;\n\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n indexConfig:\n | Expand<DbIndexConfig<FirstFieldPath, RestFieldPaths> & IndexOptions>\n | [FirstFieldPath, ...RestFieldPaths],\n ) {\n if (Array.isArray(indexConfig)) {\n // indexConfig is [FirstFieldPath, ...RestFieldPaths]\n this.indexes.push({\n indexDescriptor: name,\n fields: indexConfig,\n });\n } else if (indexConfig.staged) {\n // indexConfig is object with fields and staged: true\n this.stagedDbIndexes.push({\n indexDescriptor: name,\n fields: indexConfig.fields,\n });\n } else {\n // indexConfig is object with fields (and maybe staged: false/undefined)\n this.indexes.push({\n indexDescriptor: name,\n fields: indexConfig.fields,\n });\n }\n return this;\n }\n\n /**\n * Define a search index on this table.\n *\n * To learn about search indexes, see [Search](https://docs.convex.dev/text-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The search index configuration object.\n * @returns A {@link TableDefinition} with this search index included.\n */\n searchIndex<\n IndexName extends string,\n SearchField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n SearchIndexConfig<SearchField, FilterFields> &\n IndexOptions & { staged?: false }\n >,\n ): TableDefinition<\n DocumentType,\n Indexes,\n // Update `SearchIndexes` to include the new index and use `Expand` to make\n // the types look pretty in editors.\n Expand<\n SearchIndexes &\n Record<\n IndexName,\n {\n searchField: SearchField;\n filterFields: FilterFields;\n }\n >\n >,\n VectorIndexes\n >;\n\n /**\n * Define a staged search index on this table.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n *\n * To learn about search indexes, see [Search](https://docs.convex.dev/text-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The search index configuration object.\n * @returns A {@link TableDefinition} with this search index included.\n */\n searchIndex<\n IndexName extends string,\n SearchField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n SearchIndexConfig<SearchField, FilterFields> &\n IndexOptions & { staged: true }\n >,\n ): TableDefinition<DocumentType, Indexes, SearchIndexes, VectorIndexes>;\n\n searchIndex<\n IndexName extends string,\n SearchField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n SearchIndexConfig<SearchField, FilterFields> & IndexOptions\n >,\n ) {\n if (indexConfig.staged) {\n this.stagedSearchIndexes.push({\n indexDescriptor: name,\n searchField: indexConfig.searchField,\n filterFields: indexConfig.filterFields || [],\n });\n } else {\n this.searchIndexes.push({\n indexDescriptor: name,\n searchField: indexConfig.searchField,\n filterFields: indexConfig.filterFields || [],\n });\n }\n return this;\n }\n\n /**\n * Define a vector index on this table.\n *\n * To learn about vector indexes, see [Vector Search](https://docs.convex.dev/vector-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The vector index configuration object.\n * @returns A {@link TableDefinition} with this vector index included.\n */\n vectorIndex<\n IndexName extends string,\n VectorField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n VectorIndexConfig<VectorField, FilterFields> &\n IndexOptions & { staged?: false }\n >,\n ): TableDefinition<\n DocumentType,\n Indexes,\n SearchIndexes,\n Expand<\n VectorIndexes &\n Record<\n IndexName,\n {\n vectorField: VectorField;\n dimensions: number;\n filterFields: FilterFields;\n }\n >\n >\n >;\n\n /**\n * Define a staged vector index on this table.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n *\n * To learn about vector indexes, see [Vector Search](https://docs.convex.dev/vector-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The vector index configuration object.\n * @returns A {@link TableDefinition} with this vector index included.\n */\n vectorIndex<\n IndexName extends string,\n VectorField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n VectorIndexConfig<VectorField, FilterFields> &\n IndexOptions & { staged: true }\n >,\n ): TableDefinition<DocumentType, Indexes, SearchIndexes, VectorIndexes>;\n\n vectorIndex<\n IndexName extends string,\n VectorField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n VectorIndexConfig<VectorField, FilterFields> & IndexOptions\n >,\n ) {\n if (indexConfig.staged) {\n this.stagedVectorIndexes.push({\n indexDescriptor: name,\n vectorField: indexConfig.vectorField,\n dimensions: indexConfig.dimensions,\n filterFields: indexConfig.filterFields || [],\n });\n } else {\n this.vectorIndexes.push({\n indexDescriptor: name,\n vectorField: indexConfig.vectorField,\n dimensions: indexConfig.dimensions,\n filterFields: indexConfig.filterFields || [],\n });\n }\n return this;\n }\n\n /**\n * Work around for https://github.com/microsoft/TypeScript/issues/57035\n */\n protected self(): TableDefinition<\n DocumentType,\n Indexes,\n SearchIndexes,\n VectorIndexes\n > {\n return this;\n }\n /**\n * Export the contents of this definition.\n *\n * This is called internally by the Convex framework.\n * @internal\n */\n export() {\n const documentType = this.validator.json;\n if (typeof documentType !== \"object\") {\n throw new Error(\n \"Invalid validator: please make sure that the parameter of `defineTable` is valid (see https://docs.convex.dev/database/schemas)\",\n );\n }\n\n return {\n indexes: this.indexes,\n stagedDbIndexes: this.stagedDbIndexes,\n searchIndexes: this.searchIndexes,\n stagedSearchIndexes: this.stagedSearchIndexes,\n vectorIndexes: this.vectorIndexes,\n stagedVectorIndexes: this.stagedVectorIndexes,\n documentType,\n };\n }\n}\n\n/**\n * Define a table in a schema.\n *\n * You can either specify the schema of your documents as an object like\n * ```ts\n * defineTable({\n * field: v.string()\n * });\n * ```\n *\n * or as a schema type like\n * ```ts\n * defineTable(\n * v.union(\n * v.object({...}),\n * v.object({...})\n * )\n * );\n * ```\n *\n * @param documentSchema - The type of documents stored in this table.\n * @returns A {@link TableDefinition} for the table.\n *\n * @public\n */\nexport function defineTable<\n DocumentSchema extends Validator<Record<string, any>, \"required\", any>,\n>(documentSchema: DocumentSchema): TableDefinition<DocumentSchema>;\n/**\n * Define a table in a schema.\n *\n * You can either specify the schema of your documents as an object like\n * ```ts\n * defineTable({\n * field: v.string()\n * });\n * ```\n *\n * or as a schema type like\n * ```ts\n * defineTable(\n * v.union(\n * v.object({...}),\n * v.object({...})\n * )\n * );\n * ```\n *\n * @param documentSchema - The type of documents stored in this table.\n * @returns A {@link TableDefinition} for the table.\n *\n * @public\n */\nexport function defineTable<\n DocumentSchema extends Record<string, GenericValidator>,\n>(\n documentSchema: DocumentSchema,\n): TableDefinition<VObject<ObjectType<DocumentSchema>, DocumentSchema>>;\nexport function defineTable<\n DocumentSchema extends\n | Validator<Record<string, any>, \"required\", any>\n | Record<string, GenericValidator>,\n>(documentSchema: DocumentSchema): TableDefinition<any, any, any> {\n if (isValidator(documentSchema)) {\n return new TableDefinition(documentSchema);\n } else {\n return new TableDefinition(v.object(documentSchema));\n }\n}\n\n/**\n * A type describing the schema of a Convex project.\n *\n * This should be constructed using {@link defineSchema}, {@link defineTable},\n * and {@link v}.\n * @public\n */\nexport type GenericSchema = Record<string, TableDefinition>;\n\n/**\n *\n * The definition of a Convex project schema.\n *\n * This should be produced by using {@link defineSchema}.\n * @public\n */\nexport class SchemaDefinition<\n Schema extends GenericSchema,\n StrictTableTypes extends boolean,\n> {\n public tables: Schema;\n public strictTableNameTypes!: StrictTableTypes;\n public readonly schemaValidation: boolean;\n\n /**\n * @internal\n */\n constructor(tables: Schema, options?: DefineSchemaOptions<StrictTableTypes>) {\n this.tables = tables;\n this.schemaValidation =\n options?.schemaValidation === undefined ? true : options.schemaValidation;\n }\n\n /**\n * Export the contents of this definition.\n *\n * This is called internally by the Convex framework.\n * @internal\n */\n export(): string {\n return JSON.stringify({\n tables: Object.entries(this.tables).map(([tableName, definition]) => {\n const {\n indexes,\n stagedDbIndexes,\n searchIndexes,\n stagedSearchIndexes,\n vectorIndexes,\n stagedVectorIndexes,\n documentType,\n } = definition.export();\n return {\n tableName,\n indexes,\n stagedDbIndexes,\n searchIndexes,\n stagedSearchIndexes,\n vectorIndexes,\n stagedVectorIndexes,\n documentType,\n };\n }),\n schemaValidation: this.schemaValidation,\n });\n }\n}\n\n/**\n * Options for {@link defineSchema}.\n *\n * @public\n */\nexport interface DefineSchemaOptions<StrictTableNameTypes extends boolean> {\n /**\n * Whether Convex should validate at runtime that all documents match\n * your schema.\n *\n * If `schemaValidation` is `true`, Convex will:\n * 1. Check that all existing documents match your schema when your schema\n * is pushed.\n * 2. Check that all insertions and updates match your schema during mutations.\n *\n * If `schemaValidation` is `false`, Convex will not validate that new or\n * existing documents match your schema. You'll still get schema-specific\n * TypeScript types, but there will be no validation at runtime that your\n * documents match those types.\n *\n * By default, `schemaValidation` is `true`.\n */\n schemaValidation?: boolean;\n\n /**\n * Whether the TypeScript types should allow accessing tables not in the schema.\n *\n * If `strictTableNameTypes` is `true`, using tables not listed in the schema\n * will generate a TypeScript compilation error.\n *\n * If `strictTableNameTypes` is `false`, you'll be able to access tables not\n * listed in the schema and their document type will be `any`.\n *\n * `strictTableNameTypes: false` is useful for rapid prototyping.\n *\n * Regardless of the value of `strictTableNameTypes`, your schema will only\n * validate documents in the tables listed in the schema. You can still create\n * and modify other tables on the dashboard or in JavaScript mutations.\n *\n * By default, `strictTableNameTypes` is `true`.\n */\n strictTableNameTypes?: StrictTableNameTypes;\n}\n\n/**\n * Define the schema of this Convex project.\n *\n * This should be exported as the default export from a `schema.ts` file in\n * your `convex/` directory. The schema enables runtime validation of documents\n * and provides end-to-end TypeScript type safety.\n *\n * Every document in Convex automatically has two system fields:\n * - `_id` - a unique document ID with validator `v.id(\"tableName\")`\n * - `_creationTime` - a creation timestamp with validator `v.number()`\n *\n * You do not need to include these in your schema definition, they are added\n * automatically.\n *\n * @example\n * ```ts\n * // convex/schema.ts\n * import { defineSchema, defineTable } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * export default defineSchema({\n * users: defineTable({\n * name: v.string(),\n * email: v.string(),\n * }).index(\"by_email\", [\"email\"]),\n *\n * messages: defineTable({\n * body: v.string(),\n * userId: v.id(\"users\"),\n * channelId: v.id(\"channels\"),\n * }).index(\"by_channel\", [\"channelId\"]),\n *\n * channels: defineTable({\n * name: v.string(),\n * }),\n *\n * // Discriminated union table:\n * results: defineTable(\n * v.union(\n * v.object({ kind: v.literal(\"error\"), message: v.string() }),\n * v.object({ kind: v.literal(\"success\"), value: v.number() }),\n * )\n * ),\n * });\n * ```\n *\n * **Best practice:** Always include all index fields in the index name. For\n * example, an index on `[\"field1\", \"field2\"]` should be named\n * `\"by_field1_field2\"`.\n *\n * @param schema - A map from table name to {@link TableDefinition} for all of\n * the tables in this project.\n * @param options - Optional configuration. See {@link DefineSchemaOptions} for\n * a full description.\n * @returns The schema.\n *\n * @see https://docs.convex.dev/database/schemas\n * @public\n */\nexport function defineSchema<\n Schema extends GenericSchema,\n StrictTableNameTypes extends boolean = true,\n>(\n schema: Schema,\n options?: DefineSchemaOptions<StrictTableNameTypes>,\n): SchemaDefinition<Schema, StrictTableNameTypes> {\n return new SchemaDefinition(schema, options);\n}\n\n/**\n * Internal type used in Convex code generation!\n *\n * Convert a {@link SchemaDefinition} into a {@link server.GenericDataModel}.\n *\n * @public\n */\nexport type DataModelFromSchemaDefinition<\n SchemaDef extends SchemaDefinition<any, boolean>,\n> = MaybeMakeLooseDataModel<\n {\n [TableName in keyof SchemaDef[\"tables\"] &\n string]: SchemaDef[\"tables\"][TableName] extends TableDefinition<\n infer DocumentType,\n infer Indexes,\n infer SearchIndexes,\n infer VectorIndexes\n >\n ? {\n // We've already added all of the system fields except for `_id`.\n // Add that here.\n document: Expand<IdField<TableName> & ExtractDocument<DocumentType>>;\n fieldPaths:\n | keyof IdField<TableName>\n | ExtractFieldPaths<DocumentType>;\n indexes: Expand<Indexes & SystemIndexes>;\n searchIndexes: SearchIndexes;\n vectorIndexes: VectorIndexes;\n }\n : never;\n },\n SchemaDef[\"strictTableNameTypes\"]\n>;\n\ntype MaybeMakeLooseDataModel<\n DataModel extends GenericDataModel,\n StrictTableNameTypes extends boolean,\n> = StrictTableNameTypes extends true\n ? DataModel\n : Expand<DataModel & AnyDataModel>;\n\nconst _systemSchema = defineSchema({\n _scheduled_functions: defineTable({\n name: v.string(),\n args: v.array(v.any()),\n scheduledTime: v.float64(),\n completedTime: v.optional(v.float64()),\n state: v.union(\n v.object({ kind: v.literal(\"pending\") }),\n v.object({ kind: v.literal(\"inProgress\") }),\n v.object({ kind: v.literal(\"success\") }),\n v.object({ kind: v.literal(\"failed\"), error: v.string() }),\n v.object({ kind: v.literal(\"canceled\") }),\n ),\n }),\n _storage: defineTable({\n sha256: v.string(),\n size: v.float64(),\n contentType: v.optional(v.string()),\n }),\n});\n\nexport interface SystemDataModel\n extends DataModelFromSchemaDefinition<typeof _systemSchema> {}\n\nexport type SystemTableNames = TableNamesInDataModel<SystemDataModel>;\n"],
4
+ "sourcesContent": ["/**\n * Utilities for defining the schema of your Convex project.\n *\n * ## Usage\n *\n * Schemas should be placed in a `schema.ts` file in your `convex/` directory.\n *\n * Schema definitions should be built using {@link defineSchema},\n * {@link defineTable}, and {@link values.v}. Make sure to export the schema as the\n * default export.\n *\n * ```ts\n * import { defineSchema, defineTable } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * export default defineSchema({\n * messages: defineTable({\n * body: v.string(),\n * user: v.id(\"users\"),\n * }),\n * users: defineTable({\n * name: v.string(),\n * }),\n * });\n * ```\n *\n * To learn more about schemas, see [Defining a Schema](https://docs.convex.dev/using/schemas).\n * @module\n */\nimport {\n AnyDataModel,\n GenericDataModel,\n GenericTableIndexes,\n GenericTableSearchIndexes,\n GenericTableVectorIndexes,\n TableNamesInDataModel,\n} from \"../server/data_model.js\";\nimport {\n IdField,\n IndexTiebreakerField,\n SystemFields,\n SystemIndexes,\n} from \"../server/system_fields.js\";\nimport { Expand } from \"../type_utils.js\";\nimport {\n GenericValidator,\n ObjectType,\n isValidator,\n v,\n} from \"../values/validator.js\";\nimport { VObject, Validator } from \"../values/validators.js\";\n\n/**\n * Extract all of the index field paths within a {@link Validator}.\n *\n * This is used within {@link defineTable}.\n * @public\n */\ntype ExtractFieldPaths<T extends Validator<any, any, any>> =\n // Add in the system fields available in index definitions.\n // This should be everything except for `_id` because thats added to indexes\n // automatically.\n T[\"fieldPaths\"] | keyof SystemFields;\n\n/**\n * Extract the {@link GenericDocument} within a {@link Validator} and\n * add on the system fields.\n *\n * This is used within {@link defineTable}.\n * @public\n */\ntype ExtractDocument<T extends Validator<any, any, any>> =\n // Add the system fields to `Value` (except `_id` because it depends on\n //the table name) and trick TypeScript into expanding them.\n Expand<SystemFields & T[\"type\"]>;\n\nexport interface DbIndexConfig<\n FirstFieldPath extends string,\n RestFieldPaths extends string[],\n> {\n /**\n * The fields to index, in order. Must specify at least one field.\n */\n fields: [FirstFieldPath, ...RestFieldPaths];\n}\n\n/**\n * The configuration for a full text search index.\n *\n * @public\n */\nexport interface SearchIndexConfig<\n SearchField extends string,\n FilterFields extends string,\n> {\n /**\n * The field to index for full text search.\n *\n * This must be a field of type `string`.\n */\n searchField: SearchField;\n\n /**\n * Additional fields to index for fast filtering when running search queries.\n */\n filterFields?: FilterFields[];\n}\n\n/**\n * The configuration for a vector index.\n *\n * @public\n */\nexport interface VectorIndexConfig<\n VectorField extends string,\n FilterFields extends string,\n> {\n /**\n * The field to index for vector search.\n *\n * This must be a field of type `v.array(v.float64())` (or a union)\n */\n vectorField: VectorField;\n /**\n * The length of the vectors indexed. This must be between 2 and 2048 inclusive.\n */\n dimensions: number;\n /**\n * Additional fields to index for fast filtering when running vector searches.\n */\n filterFields?: FilterFields[];\n}\n\n/**\n * @internal\n */\nexport type VectorIndex = {\n indexDescriptor: string;\n vectorField: string;\n dimensions: number;\n filterFields: string[];\n};\n\n/**\n * @internal\n */\nexport type Index = {\n indexDescriptor: string;\n fields: string[];\n};\n\n/**\n * @internal\n */\nexport type SearchIndex = {\n indexDescriptor: string;\n searchField: string;\n filterFields: string[];\n};\n\n/**\n * Options for defining an index.\n *\n * @public\n */\nexport interface IndexOptions {\n /**\n * Whether the index should be staged.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n */\n staged?: boolean;\n}\n\n/**\n * The definition of a table within a schema.\n *\n * This should be produced by using {@link defineTable}.\n * @public\n */\nexport class TableDefinition<\n DocumentType extends Validator<any, any, any> = Validator<any, any, any>,\n Indexes extends GenericTableIndexes = {},\n SearchIndexes extends GenericTableSearchIndexes = {},\n VectorIndexes extends GenericTableVectorIndexes = {},\n> {\n private indexes: Index[];\n private stagedDbIndexes: Index[];\n private searchIndexes: SearchIndex[];\n private stagedSearchIndexes: SearchIndex[];\n private vectorIndexes: VectorIndex[];\n private stagedVectorIndexes: VectorIndex[];\n // The type of documents stored in this table.\n validator: DocumentType;\n\n /**\n * @internal\n */\n constructor(documentType: DocumentType) {\n this.indexes = [];\n this.stagedDbIndexes = [];\n this.searchIndexes = [];\n this.stagedSearchIndexes = [];\n this.vectorIndexes = [];\n this.stagedVectorIndexes = [];\n this.validator = documentType;\n }\n\n /**\n * This API is experimental: it may change or disappear.\n *\n * Returns indexes defined on this table.\n * Intended for the advanced use cases of dynamically deciding which index to use for a query.\n * If you think you need this, please chime in on ths issue in the Convex JS GitHub repo.\n * https://github.com/get-convex/convex-js/issues/49\n */\n \" indexes\"(): { indexDescriptor: string; fields: string[] }[] {\n return this.indexes;\n }\n\n /**\n * Define an index on this table.\n *\n * Indexes speed up queries by allowing efficient lookups on specific fields.\n * Use `.withIndex()` in your queries to leverage them.\n *\n * Index fields must be queried in the same order they are defined. If you\n * need to query by `field2` then `field1`, create a separate index with\n * that field order.\n *\n * @example\n * ```ts\n * defineTable({\n * userId: v.id(\"users\"),\n * status: v.string(),\n * updatedAt: v.number(),\n * })\n * // Name indexes after their fields:\n * .index(\"by_userId\", [\"userId\"])\n * .index(\"by_status_updatedAt\", [\"status\", \"updatedAt\"])\n * ```\n *\n * **Best practice:** Always include all index fields in the index name\n * (e.g., `\"by_field1_and_field2\"`).\n *\n * @param name - The name of the index.\n * @param indexConfig - The index configuration object.\n * @returns A {@link TableDefinition} with this index included.\n *\n * @see https://docs.convex.dev/database/reading-data/indexes\n */\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n indexConfig: Expand<\n DbIndexConfig<FirstFieldPath, RestFieldPaths> &\n IndexOptions & { staged?: false }\n >,\n ): TableDefinition<\n DocumentType,\n Expand<\n Indexes &\n Record<\n IndexName,\n [FirstFieldPath, ...RestFieldPaths, IndexTiebreakerField]\n >\n >,\n SearchIndexes,\n VectorIndexes\n >;\n\n /**\n * Define an index on this table.\n *\n * To learn about indexes, see [Defining Indexes](https://docs.convex.dev/database/reading-data/indexes).\n *\n * @param name - The name of the index.\n * @param fields - The fields to index, in order. Must specify at least one\n * field.\n * @returns A {@link TableDefinition} with this index included.\n */\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n fields: [FirstFieldPath, ...RestFieldPaths],\n ): TableDefinition<\n DocumentType,\n Expand<\n Indexes &\n Record<\n IndexName,\n [FirstFieldPath, ...RestFieldPaths, IndexTiebreakerField]\n >\n >,\n SearchIndexes,\n VectorIndexes\n >;\n\n /**\n * Define a staged index on this table.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n *\n * To learn about indexes, see [Defining Indexes](https://docs.convex.dev/using/indexes).\n *\n * @param name - The name of the index.\n * @param indexConfig - The index configuration object.\n * @returns A {@link TableDefinition} with this index included.\n */\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n indexConfig: Expand<\n DbIndexConfig<FirstFieldPath, RestFieldPaths> &\n IndexOptions & { staged: true }\n >,\n ): TableDefinition<DocumentType, Indexes, SearchIndexes, VectorIndexes>;\n\n index<\n IndexName extends string,\n FirstFieldPath extends ExtractFieldPaths<DocumentType>,\n RestFieldPaths extends ExtractFieldPaths<DocumentType>[],\n >(\n name: IndexName,\n indexConfig:\n | Expand<DbIndexConfig<FirstFieldPath, RestFieldPaths> & IndexOptions>\n | [FirstFieldPath, ...RestFieldPaths],\n ) {\n if (Array.isArray(indexConfig)) {\n // indexConfig is [FirstFieldPath, ...RestFieldPaths]\n this.indexes.push({\n indexDescriptor: name,\n fields: indexConfig,\n });\n } else if (indexConfig.staged) {\n // indexConfig is object with fields and staged: true\n this.stagedDbIndexes.push({\n indexDescriptor: name,\n fields: indexConfig.fields,\n });\n } else {\n // indexConfig is object with fields (and maybe staged: false/undefined)\n this.indexes.push({\n indexDescriptor: name,\n fields: indexConfig.fields,\n });\n }\n return this;\n }\n\n /**\n * Define a search index on this table.\n *\n * To learn about search indexes, see [Search](https://docs.convex.dev/text-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The search index configuration object.\n * @returns A {@link TableDefinition} with this search index included.\n */\n searchIndex<\n IndexName extends string,\n SearchField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n SearchIndexConfig<SearchField, FilterFields> &\n IndexOptions & { staged?: false }\n >,\n ): TableDefinition<\n DocumentType,\n Indexes,\n // Update `SearchIndexes` to include the new index and use `Expand` to make\n // the types look pretty in editors.\n Expand<\n SearchIndexes &\n Record<\n IndexName,\n {\n searchField: SearchField;\n filterFields: FilterFields;\n }\n >\n >,\n VectorIndexes\n >;\n\n /**\n * Define a staged search index on this table.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n *\n * To learn about search indexes, see [Search](https://docs.convex.dev/text-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The search index configuration object.\n * @returns A {@link TableDefinition} with this search index included.\n */\n searchIndex<\n IndexName extends string,\n SearchField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n SearchIndexConfig<SearchField, FilterFields> &\n IndexOptions & { staged: true }\n >,\n ): TableDefinition<DocumentType, Indexes, SearchIndexes, VectorIndexes>;\n\n searchIndex<\n IndexName extends string,\n SearchField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n SearchIndexConfig<SearchField, FilterFields> & IndexOptions\n >,\n ) {\n if (indexConfig.staged) {\n this.stagedSearchIndexes.push({\n indexDescriptor: name,\n searchField: indexConfig.searchField,\n filterFields: indexConfig.filterFields || [],\n });\n } else {\n this.searchIndexes.push({\n indexDescriptor: name,\n searchField: indexConfig.searchField,\n filterFields: indexConfig.filterFields || [],\n });\n }\n return this;\n }\n\n /**\n * Define a vector index on this table.\n *\n * To learn about vector indexes, see [Vector Search](https://docs.convex.dev/vector-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The vector index configuration object.\n * @returns A {@link TableDefinition} with this vector index included.\n */\n vectorIndex<\n IndexName extends string,\n VectorField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n VectorIndexConfig<VectorField, FilterFields> &\n IndexOptions & { staged?: false }\n >,\n ): TableDefinition<\n DocumentType,\n Indexes,\n SearchIndexes,\n Expand<\n VectorIndexes &\n Record<\n IndexName,\n {\n vectorField: VectorField;\n dimensions: number;\n filterFields: FilterFields;\n }\n >\n >\n >;\n\n /**\n * Define a staged vector index on this table.\n *\n * For large tables, index backfill can be slow. Staging an index allows you\n * to push the schema and enable the index later.\n *\n * If `staged` is `true`, the index will be staged and will not be enabled\n * until the staged flag is removed. Staged indexes do not block push\n * completion. Staged indexes cannot be used in queries.\n *\n * To learn about vector indexes, see [Vector Search](https://docs.convex.dev/vector-search).\n *\n * @param name - The name of the index.\n * @param indexConfig - The vector index configuration object.\n * @returns A {@link TableDefinition} with this vector index included.\n */\n vectorIndex<\n IndexName extends string,\n VectorField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n VectorIndexConfig<VectorField, FilterFields> &\n IndexOptions & { staged: true }\n >,\n ): TableDefinition<DocumentType, Indexes, SearchIndexes, VectorIndexes>;\n\n vectorIndex<\n IndexName extends string,\n VectorField extends ExtractFieldPaths<DocumentType>,\n FilterFields extends ExtractFieldPaths<DocumentType> = never,\n >(\n name: IndexName,\n indexConfig: Expand<\n VectorIndexConfig<VectorField, FilterFields> & IndexOptions\n >,\n ) {\n if (indexConfig.staged) {\n this.stagedVectorIndexes.push({\n indexDescriptor: name,\n vectorField: indexConfig.vectorField,\n dimensions: indexConfig.dimensions,\n filterFields: indexConfig.filterFields || [],\n });\n } else {\n this.vectorIndexes.push({\n indexDescriptor: name,\n vectorField: indexConfig.vectorField,\n dimensions: indexConfig.dimensions,\n filterFields: indexConfig.filterFields || [],\n });\n }\n return this;\n }\n\n /**\n * Work around for https://github.com/microsoft/TypeScript/issues/57035\n */\n protected self(): TableDefinition<\n DocumentType,\n Indexes,\n SearchIndexes,\n VectorIndexes\n > {\n return this;\n }\n /**\n * Export the contents of this definition.\n *\n * This is called internally by the Convex framework.\n * @internal\n */\n export() {\n const documentType = this.validator.json;\n if (typeof documentType !== \"object\") {\n throw new Error(\n \"Invalid validator: please make sure that the parameter of `defineTable` is valid (see https://docs.convex.dev/database/schemas)\",\n );\n }\n\n return {\n indexes: this.indexes,\n stagedDbIndexes: this.stagedDbIndexes,\n searchIndexes: this.searchIndexes,\n stagedSearchIndexes: this.stagedSearchIndexes,\n vectorIndexes: this.vectorIndexes,\n stagedVectorIndexes: this.stagedVectorIndexes,\n documentType,\n };\n }\n}\n\n/**\n * Define a table in a schema.\n *\n * You can either specify the schema of your documents as an object like\n * ```ts\n * defineTable({\n * field: v.string()\n * });\n * ```\n *\n * or as a schema type like\n * ```ts\n * defineTable(\n * v.union(\n * v.object({...}),\n * v.object({...})\n * )\n * );\n * ```\n *\n * @param documentSchema - The type of documents stored in this table.\n * @returns A {@link TableDefinition} for the table.\n *\n * @public\n */\nexport function defineTable<\n DocumentSchema extends Validator<Record<string, any>, \"required\", any>,\n>(documentSchema: DocumentSchema): TableDefinition<DocumentSchema>;\n/**\n * Define a table in a schema.\n *\n * You can either specify the schema of your documents as an object like\n * ```ts\n * defineTable({\n * field: v.string()\n * });\n * ```\n *\n * or as a schema type like\n * ```ts\n * defineTable(\n * v.union(\n * v.object({...}),\n * v.object({...})\n * )\n * );\n * ```\n *\n * @param documentSchema - The type of documents stored in this table.\n * @returns A {@link TableDefinition} for the table.\n *\n * @public\n */\nexport function defineTable<\n DocumentSchema extends Record<string, GenericValidator>,\n>(\n documentSchema: DocumentSchema,\n): TableDefinition<VObject<ObjectType<DocumentSchema>, DocumentSchema>>;\nexport function defineTable<\n DocumentSchema extends\n | Validator<Record<string, any>, \"required\", any>\n | Record<string, GenericValidator>,\n>(documentSchema: DocumentSchema): TableDefinition<any, any, any> {\n if (isValidator(documentSchema)) {\n return new TableDefinition(documentSchema);\n } else {\n return new TableDefinition(v.object(documentSchema));\n }\n}\n\n/**\n * A type describing the schema of a Convex project.\n *\n * This should be constructed using {@link defineSchema}, {@link defineTable},\n * and {@link v}.\n * @public\n */\nexport type GenericSchema = Record<string, TableDefinition>;\n\n/**\n *\n * The definition of a Convex project schema.\n *\n * This should be produced by using {@link defineSchema}.\n * @public\n */\nexport class SchemaDefinition<\n Schema extends GenericSchema,\n StrictTableTypes extends boolean,\n> {\n public tables: Schema;\n public strictTableNameTypes!: StrictTableTypes;\n public readonly schemaValidation: boolean;\n\n /**\n * @internal\n */\n constructor(tables: Schema, options?: DefineSchemaOptions<StrictTableTypes>) {\n this.tables = tables;\n this.schemaValidation =\n options?.schemaValidation === undefined ? true : options.schemaValidation;\n }\n\n /**\n * Export the contents of this definition.\n *\n * This is called internally by the Convex framework.\n * @internal\n */\n export(): string {\n return JSON.stringify({\n tables: Object.entries(this.tables).map(([tableName, definition]) => {\n const {\n indexes,\n stagedDbIndexes,\n searchIndexes,\n stagedSearchIndexes,\n vectorIndexes,\n stagedVectorIndexes,\n documentType,\n } = definition.export();\n return {\n tableName,\n indexes,\n stagedDbIndexes,\n searchIndexes,\n stagedSearchIndexes,\n vectorIndexes,\n stagedVectorIndexes,\n documentType,\n };\n }),\n schemaValidation: this.schemaValidation,\n });\n }\n}\n\n/**\n * Options for {@link defineSchema}.\n *\n * @public\n */\nexport interface DefineSchemaOptions<StrictTableNameTypes extends boolean> {\n /**\n * Whether Convex should validate at runtime that all documents match\n * your schema.\n *\n * If `schemaValidation` is `true`, Convex will:\n * 1. Check that all existing documents match your schema when your schema\n * is pushed.\n * 2. Check that all insertions and updates match your schema during mutations.\n *\n * If `schemaValidation` is `false`, Convex will not validate that new or\n * existing documents match your schema. You'll still get schema-specific\n * TypeScript types, but there will be no validation at runtime that your\n * documents match those types.\n *\n * By default, `schemaValidation` is `true`.\n */\n schemaValidation?: boolean;\n\n /**\n * Whether the TypeScript types should allow accessing tables not in the schema.\n *\n * If `strictTableNameTypes` is `true`, using tables not listed in the schema\n * will generate a TypeScript compilation error.\n *\n * If `strictTableNameTypes` is `false`, you'll be able to access tables not\n * listed in the schema and their document type will be `any`.\n *\n * `strictTableNameTypes: false` is useful for rapid prototyping.\n *\n * Regardless of the value of `strictTableNameTypes`, your schema will only\n * validate documents in the tables listed in the schema. You can still create\n * and modify other tables on the dashboard or in JavaScript mutations.\n *\n * By default, `strictTableNameTypes` is `true`.\n */\n strictTableNameTypes?: StrictTableNameTypes;\n}\n\n/**\n * Define the schema of this Convex project.\n *\n * This should be exported as the default export from a `schema.ts` file in\n * your `convex/` directory. The schema enables runtime validation of documents\n * and provides end-to-end TypeScript type safety.\n *\n * Every document in Convex automatically has two system fields:\n * - `_id` - a unique document ID with validator `v.id(\"tableName\")`\n * - `_creationTime` - a creation timestamp with validator `v.number()`\n *\n * You do not need to include these in your schema definition, they are added\n * automatically.\n *\n * @example\n * ```ts\n * // convex/schema.ts\n * import { defineSchema, defineTable } from \"convex/server\";\n * import { v } from \"convex/values\";\n *\n * export default defineSchema({\n * users: defineTable({\n * name: v.string(),\n * email: v.string(),\n * }).index(\"by_email\", [\"email\"]),\n *\n * messages: defineTable({\n * body: v.string(),\n * userId: v.id(\"users\"),\n * channelId: v.id(\"channels\"),\n * }).index(\"by_channel\", [\"channelId\"]),\n *\n * channels: defineTable({\n * name: v.string(),\n * }),\n *\n * // Discriminated union table:\n * results: defineTable(\n * v.union(\n * v.object({ kind: v.literal(\"error\"), message: v.string() }),\n * v.object({ kind: v.literal(\"success\"), value: v.number() }),\n * )\n * ),\n * });\n * ```\n *\n * **Best practice:** Always include all index fields in the index name. For\n * example, an index on `[\"field1\", \"field2\"]` should be named\n * `\"by_field1_field2\"`.\n *\n * @param schema - A map from table name to {@link TableDefinition} for all of\n * the tables in this project.\n * @param options - Optional configuration. See {@link DefineSchemaOptions} for\n * a full description.\n * @returns The schema.\n *\n * @see https://docs.convex.dev/database/schemas\n * @public\n */\nexport function defineSchema<\n Schema extends GenericSchema,\n StrictTableNameTypes extends boolean = true,\n>(\n schema: Schema,\n options?: DefineSchemaOptions<StrictTableNameTypes>,\n): SchemaDefinition<Schema, StrictTableNameTypes> {\n return new SchemaDefinition(schema, options);\n}\n\n/**\n * Internal type used in Convex code generation!\n *\n * Convert a {@link SchemaDefinition} into a {@link server.GenericDataModel}.\n *\n * @public\n */\nexport type DataModelFromSchemaDefinition<\n SchemaDef extends SchemaDefinition<any, boolean>,\n> = MaybeMakeLooseDataModel<\n {\n [TableName in keyof SchemaDef[\"tables\"] &\n string]: SchemaDef[\"tables\"][TableName] extends TableDefinition<\n infer DocumentType,\n infer Indexes,\n infer SearchIndexes,\n infer VectorIndexes\n >\n ? {\n // We've already added all of the system fields except for `_id`.\n // Add that here.\n document: Expand<IdField<TableName> & ExtractDocument<DocumentType>>;\n fieldPaths:\n | keyof IdField<TableName>\n | ExtractFieldPaths<DocumentType>;\n indexes: Expand<Indexes & SystemIndexes>;\n searchIndexes: SearchIndexes;\n vectorIndexes: VectorIndexes;\n }\n : never;\n },\n SchemaDef[\"strictTableNameTypes\"]\n>;\n\ntype MaybeMakeLooseDataModel<\n DataModel extends GenericDataModel,\n StrictTableNameTypes extends boolean,\n> = StrictTableNameTypes extends true\n ? DataModel\n : Expand<DataModel & AnyDataModel>;\n\nconst _systemSchema = defineSchema({\n _scheduled_functions: defineTable({\n name: v.string(),\n args: v.array(v.any()),\n scheduledTime: v.float64(),\n completedTime: v.optional(v.float64()),\n state: v.union(\n v.object({ kind: v.literal(\"pending\") }),\n v.object({ kind: v.literal(\"inProgress\") }),\n v.object({ kind: v.literal(\"success\") }),\n v.object({ kind: v.literal(\"failed\"), error: v.string() }),\n v.object({ kind: v.literal(\"canceled\") }),\n ),\n }),\n _storage: defineTable({\n sha256: v.string(),\n size: v.float64(),\n contentType: v.optional(v.string()),\n }),\n});\n\nexport interface SystemDataModel extends DataModelFromSchemaDefinition<\n typeof _systemSchema\n> {}\n\nexport type SystemTableNames = TableNamesInDataModel<SystemDataModel>;\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,6 @@
1
- import { BaseConvexClient, BaseConvexClientOptions, MutationOptions } from "./index.js";
2
1
  import { FunctionArgs, FunctionReference, FunctionReturnType, PaginationResult } from "../server/index.js";
3
2
  import { AuthTokenFetcher } from "./sync/authentication_manager.js";
4
- import { ConnectionState } from "./sync/client.js";
3
+ import { BaseConvexClient, BaseConvexClientOptions, ConnectionState, MutationOptions } from "./sync/client.js";
5
4
  import { PaginatedQueryResult } from "./sync/pagination.js";
6
5
  /** internal */
7
6
  export declare function setDefaultWebSocketConstructor(ws: typeof WebSocket): void;